"""Tests that the mobile navigation bar is correctly structured and positioned.""" import re import pytest from httpx import AsyncClient, ASGITransport from tests.registry import app @pytest.fixture async def client(): transport = ASGITransport(app=app) async with AsyncClient(transport=transport, base_url="http://test") as c: yield c @pytest.mark.asyncio async def test_mob_nav_exists(client): """mob-nav element exists in page output.""" resp = await client.get("/") assert resp.status_code == 200 assert 'class="mob-nav"' in resp.text, "mob-nav not found in HTML" @pytest.mark.asyncio async def test_mob_nav_is_direct_body_child(client): """mob-nav must be a direct child of body, not nested in any container.""" resp = await client.get("/") html = resp.text mob_idx = html.find('id="mobNav"') body_close = html.find('') assert mob_idx != -1, "mobNav not found" assert body_close != -1, " not found" between = html[mob_idx:body_close] assert between.count('') == 0, "mob-nav appears to be inside
" assert between.count('') == 0, "mob-nav appears deeply nested" @pytest.mark.asyncio async def test_mob_nav_has_five_items(client): """Bottom bar must have exactly 5 navigation items (4 links + 1 button).""" resp = await client.get("/") html = resp.text start = html.find('id="mobNav"') assert start != -1 # Scope to just the mob-nav element (ends at first after it) end = html.find('', start) chunk = html[start:end] links = len(re.findall(r' as a fallback.""" resp = await client.get("/") html = resp.text head_end = html.find('') head = html[:head_end] assert '.mob-nav' in head, "No inline mob-nav styles found in " assert 'position:fixed' in head, "No position:fixed in inline styles" @pytest.mark.asyncio async def test_mob_nav_not_inside_transformed_parent(client): """No ancestor of mob-nav should have transform that breaks position:fixed.""" resp = await client.get("/") html = resp.text mob_idx = html.find('id="mobNav"') body_start = html.find(']*>', prefix)) closes = prefix.count('') nesting = opens - closes assert nesting <= 1, \ f"mob-nav is nested {nesting} divs deep - must be 0 or 1 (direct body child)" @pytest.mark.asyncio async def test_mob_nav_present_on_all_pages(client): """mob-nav should appear on every page, not just dashboard.""" for path in ["/", "/tasks/", "/focus/", "/capture/", "/contacts/"]: resp = await client.get(path) assert 'id="mobNav"' in resp.text, f"mob-nav missing on {path}"