""" Step 0 — Scaffolding Tests - test_app_loads: App loads and renders the shell - test_nav_routes: All navigation links route correctly - test_actionbar_shows_title: Action bar displays the current page title - test_responsive_mobile: Navbar moves to bottom on mobile viewport - test_i18n_keys_render: i18n keys render as English text (not raw keys) """ import re from playwright.sync_api import Page, expect def test_app_loads(page: Page, app_url: str): """App loads and renders the navbar with the app name.""" page.goto(app_url) page.wait_for_function( "document.documentElement.getAttribute('data-db-ready') === 'true'" " || document.documentElement.getAttribute('data-db-error') !== null", timeout=15000, ) expect(page.locator(".navbar-brand")).to_have_text("TrainUs") expect(page.locator(".actionbar")).to_be_visible() def test_nav_routes(page: Page, app_url: str): """Clicking each nav link navigates to the correct route.""" page.goto(app_url) page.wait_for_function( "document.documentElement.getAttribute('data-db-ready') === 'true'", timeout=15000, ) routes = { "Home": "#/home", "Exercises": "#/exercises", "Combos": "#/combos", "Sessions": "#/sessions", "Statistics": "#/stats", "Settings": "#/settings", } for label, expected_hash in routes.items(): page.locator(f".navbar a:has-text('{label}')").click() page.wait_for_url(f"**/{expected_hash}") expect(page).to_have_url(re.compile(re.escape(expected_hash))) def test_actionbar_shows_title(page: Page, app_url: str): """Action bar h1 reflects the current page name.""" page.goto(f"{app_url}/#/exercises") page.wait_for_function( "document.documentElement.getAttribute('data-db-ready') === 'true'", timeout=15000, ) expect(page.locator(".actionbar h1")).to_have_text("Exercises") page.goto(f"{app_url}/#/settings") page.wait_for_function( "document.documentElement.getAttribute('data-db-ready') === 'true'", timeout=15000, ) expect(page.locator(".actionbar h1")).to_have_text("Settings") def test_responsive_mobile(page: Page, app_url: str): """On a narrow viewport, navbar should be at the bottom.""" page.set_viewport_size({"width": 375, "height": 667}) page.goto(app_url) page.wait_for_function( "document.documentElement.getAttribute('data-db-ready') === 'true'", timeout=15000, ) navbar = page.locator(".navbar") expect(navbar).to_be_visible() # Brand should be hidden on mobile brand = page.locator(".navbar-brand") expect(brand).to_be_hidden() def test_i18n_keys_render(page: Page, app_url: str): """i18n renders actual text, not raw keys like 'nav.home'.""" page.goto(app_url) page.wait_for_function( "document.documentElement.getAttribute('data-db-ready') === 'true'", timeout=15000, ) # Check that nav links contain real words, not i18n keys nav_text = page.locator(".navbar").inner_text() assert "nav.home" not in nav_text, "i18n keys not resolved" assert "Home" in nav_text assert "Settings" in nav_text