"""Palier 12 (0.15.0): header unifié desktop/mobile (issue #16).""" def test_shared_header_on_app_pages(client, fake_gitea): for path in ("/", "/focus", "/today", "/briefing", "/forecast", "/rules", "/health", "/standup", "/capture"): page = client.get(path) assert page.status_code == 200, path assert page.text.count('id="nav-more-btn"') == 1, path assert page.text.count('id="nav-burger"') == 1, path assert page.text.count('id="mobile-nav"') == 1, path assert "/static/js/nav.js" in page.text, path # Primaires visibles, secondaires dans le menu « Plus ». assert 'href="/today"' in page.text assert 'href="/health"' in page.text # présent (menu Plus/mobile) assert 'class="nav-pills main-nav"' in page.text def test_active_states(client, fake_gitea): home = client.get("/") assert 'href="/" class="nav-pill active"' in home.text forecast = client.get("/forecast") # La page active est dans « Plus » : bouton marqué + lien actif. assert "active-soft" in forecast.text assert 'href="/forecast" class="nav-pill active"' in forecast.text today = client.get("/today") assert 'href="/today" class="nav-pill active"' in today.text def test_board_header_crumb_and_gitea_link(client, fake_gitea): board = client.get("/board/Projets/demo") assert board.status_code == 200 assert 'href="/board/Projets/demo"' in board.text # fil d'Ariane assert "Gitea ↗" in board.text assert 'id="nav-burger"' in board.text def test_wall_has_no_app_header(client, fake_gitea): wall = client.get("/wall") assert wall.status_code == 200 assert 'id="nav-burger"' not in wall.text # plein écran TV assumé def test_nav_js_contract(client, fake_gitea): js = client.get("/static/js/nav.js") assert js.status_code == 200 assert "nav-burger" in js.text assert "Escape" in js.text assert "aria-expanded" in js.text