Files
leocrm/tests/test_frontend_pages.py
T

112 lines
4.4 KiB
Python

"""Frontend-Smoke-Tests: verify all 13 HTML pages exist and contain the
expected keywords/structure.
These tests read the HTML files directly from `app/webui/` (rather than
hitting the FastAPI server) because the static-file mount is added in a
later phase by the orchestrator. Once that mount is in place, the same
checks could be re-implemented as `httpx.AsyncClient.get("/…")`.
Each test loads exactly one page and asserts:
- file exists and is non-empty
- contains the page's title text (so a typo / removal is caught)
- has Tailwind-CDN, Alpine-CDN, and the app.css link
- has no x-html attribute (R-5)
"""
from __future__ import annotations
from pathlib import Path
import pytest
WEBUI_DIR = Path(__file__).resolve().parent.parent / "app" / "webui"
def _read(name: str) -> str:
"""Read a file from the webui directory."""
p = WEBUI_DIR / name
assert p.exists(), f"Expected frontend file {p} to exist"
return p.read_text(encoding="utf-8")
# ---------------------------------------------------------------------------
# Each page: (filename, [required substrings])
# ---------------------------------------------------------------------------
PAGES = [
("index.html", ["Login", "Registrieren", "Anmelden", "Konto erstellen"]),
("app.html", ["Dashboard", "Logout", "Pipeline"]),
("accounts.html", ["Accounts", "Suche (Name)", "Branche", "+ New Account"]),
("accounts-detail.html", ["Account-Detail", "Bearbeiten", "Löschen", "Info"]),
("contacts.html", ["Contacts", "Vorname", "Nachname", "+ New Contact"]),
("contacts-detail.html", ["Contact-Detail", "Bearbeiten", "Löschen"]),
("pipeline.html", ["Pipeline", "Owner-ID (optional)", "+ New Deal", "Ziehe Karten"]),
("activities.html", ["Activities", "+ New Activity", "Fällig"]),
("settings-profile.html", ["Mein Profil", "Avatar-URL", "E-Mail-Benachrichtigungen"]),
("settings-users.html", ["User-Verwaltung", "+ New User", "Rolle"]),
("settings-org.html", ["Org-Einstellungen", "Aktuelle Organisation", "v1.1"]),
("404.html", ["404", "Seite nicht gefunden", "Zum Dashboard"]),
# Dashboard: ships inside app.html. We test the marker text directly there.
]
@pytest.mark.parametrize("filename,required", PAGES)
def test_frontend_page_loads(filename, required):
"""Each HTML page must exist and contain its identifying substrings."""
content = _read(filename)
assert len(content) > 200, f"{filename} seems empty or too small"
for needle in required:
assert needle in content, f"{filename} missing required string {needle!r}"
def test_index_html_contains_login_and_register():
"""Index page (auth screen) must show both Login and Register tabs."""
content = _read("index.html")
assert "Login" in content
assert "Registrieren" in content
# Alpine-CDN required
assert "alpinejs" in content
def test_app_html_contains_dashboard_and_logout():
"""app.html is the post-login shell — must show Dashboard + Logout."""
content = _read("app.html")
assert "Dashboard" in content
assert "Logout" in content
def test_13_pages_exist():
"""Exactly 13 HTML pages must be present (index + app + 10 + 404)."""
pages = sorted(p.name for p in WEBUI_DIR.glob("*.html"))
assert len(pages) == 13, f"Expected 13 pages, found {len(pages)}: {pages}"
def test_dashboard_section_inside_app_html():
"""The dashboard content is rendered inside app.html (default landing)."""
content = _read("app.html")
# The 4 KPI labels from the dashboard section
assert "Open Deals" in content
assert "Pipeline Value" in content
assert "Won this Month" in content
assert "Conversion Rate" in content
def test_each_page_links_app_css():
"""Every page must reference /css/app.css."""
for filename, _ in PAGES:
content = _read(filename)
assert "/css/app.css" in content, f"{filename} missing /css/app.css link"
def test_each_page_includes_alpine_cdn():
"""Every page must include the Alpine.js CDN script."""
for filename, _ in PAGES:
content = _read(filename)
assert "alpinejs" in content, f"{filename} missing Alpine.js CDN"
def test_each_page_includes_tailwind_cdn():
"""Every page must include the Tailwind-CDN script (dev-mode)."""
for filename, _ in PAGES:
content = _read(filename)
assert "cdn.tailwindcss.com" in content, f"{filename} missing Tailwind CDN"