""" Peer dashboard and My Services page tests. Scenarios: 12. Peer sees their own dashboard (PeerDashboard.jsx renders peer.name as

) 13. Peer's My Services page loads and shows all service sections 14. Peer dashboard shows service icon links (calendar, files, mail, webdav) 15. My Services shows correct CalDAV URL (calendar.dev not radicale.dev:5232) 16. My Services shows email address field (not username) Key selectors from PeerDashboard.jsx: - h1 shows peer.name (peer.name from /api/peer/dashboard) - "VPN Address" stat card label - "Quick Access" section with service icon links from service_urls - "My Services" link Key selectors from MyServices.jsx: - h2 "WireGuard VPN" - h2 "Email", h2 "Calendar & Contacts", h2 "Files" - "Address" label for email (not "Username") - "CalDAV URL" label with calendar.dev value """ import pytest pytestmark = pytest.mark.ui # ── 12. Peer dashboard ─────────────────────────────────────────────────────── def test_peer_sees_peer_dashboard(peer_page, webui_base): """Peer lands on the root route which renders PeerDashboard, not the admin Dashboard.""" page, peer = peer_page page.wait_for_load_state('networkidle') assert '/login' not in page.url def test_peer_dashboard_shows_peer_name(peer_page, webui_base): """PeerDashboard.jsx renders peer.name as the page

.""" page, peer = peer_page page.wait_for_load_state('networkidle') try: # PeerDashboard line 61:

{peer.name || 'My Dashboard'}

page.wait_for_selector( f'h1:has-text("{peer["name"]}")', timeout=6000, ) except Exception: pytest.xfail( f"Peer name '{peer['name']}' not found as

on PeerDashboard. " "Check that the /api/peer/dashboard endpoint returns the peer name " "and that PeerDashboard.jsx renders it." ) def test_peer_dashboard_shows_vpn_address_label(peer_page, webui_base): """PeerDashboard.jsx shows a 'VPN Address' stat card.""" page, _ = peer_page page.wait_for_load_state('networkidle') try: page.wait_for_selector('text=VPN Address', timeout=5000) except Exception: pytest.xfail( "VPN Address stat card not found — check PeerDashboard.jsx stat card labels" ) def test_peer_dashboard_has_my_services_link(peer_page, webui_base): """PeerDashboard.jsx renders a 'My Services' quick-access link.""" page, _ = peer_page page.wait_for_load_state('networkidle') try: page.wait_for_selector('a:has-text("My Services"), button:has-text("My Services")', timeout=5000) except Exception: pytest.xfail( "'My Services' link not found on peer dashboard — check PeerDashboard.jsx Quick Access section" ) # ── 13. My Services page ───────────────────────────────────────────────────── def test_peer_my_services_page_loads(peer_page, webui_base): """Peer can navigate to /my-services without being redirected.""" page, _ = peer_page page.goto(f"{webui_base}/my-services") page.wait_for_load_state('networkidle') assert '/login' not in page.url def test_peer_my_services_shows_wireguard_section(peer_page, webui_base): """MyServices.jsx renders a 'WireGuard VPN' section heading.""" page, _ = peer_page page.goto(f"{webui_base}/my-services") page.wait_for_load_state('networkidle') try: page.wait_for_selector('h2:has-text("WireGuard VPN")', timeout=5000) except Exception: pytest.xfail( "WireGuard VPN section heading not found on /my-services — " "check MyServices.jsx and /api/peer/services endpoint" ) def test_peer_my_services_shows_email_section(peer_page, webui_base): """MyServices.jsx renders an 'Email' section heading.""" page, _ = peer_page page.goto(f"{webui_base}/my-services") page.wait_for_load_state('networkidle') try: page.wait_for_selector('h2:has-text("Email")', timeout=5000) except Exception: pytest.xfail( "Email section heading not found on /my-services" ) def test_peer_my_services_shows_calendar_section(peer_page, webui_base): """MyServices.jsx renders a 'Calendar & Contacts' section heading.""" page, _ = peer_page page.goto(f"{webui_base}/my-services") page.wait_for_load_state('networkidle') try: page.wait_for_selector('h2:has-text("Calendar")', timeout=5000) except Exception: pytest.xfail( "Calendar section heading not found on /my-services" ) def test_peer_my_services_shows_files_section(peer_page, webui_base): """MyServices.jsx renders a 'Files' section heading.""" page, _ = peer_page page.goto(f"{webui_base}/my-services") page.wait_for_load_state('networkidle') try: page.wait_for_selector('h2:has-text("Files")', timeout=5000) except Exception: pytest.xfail( "Files section heading not found on /my-services" ) # ── 14. Service icon links ──────────────────────────────────────────────────── def test_peer_dashboard_has_calendar_link(peer_page, webui_base): """PeerDashboard Quick Access section renders a Calendar icon link.""" page, _ = peer_page page.wait_for_load_state('networkidle') try: page.wait_for_selector('a:has-text("Calendar")', timeout=5000) except Exception: pytest.xfail( "Calendar link not found on peer dashboard Quick Access — " "check that service_urls.calendar is populated and PeerDashboard.jsx renders it" ) def test_peer_dashboard_has_files_link(peer_page, webui_base): """PeerDashboard Quick Access section renders a Files icon link.""" page, _ = peer_page page.wait_for_load_state('networkidle') try: page.wait_for_selector('a:has-text("Files")', timeout=5000) except Exception: pytest.xfail( "Files link not found on peer dashboard Quick Access" ) def test_peer_dashboard_has_mail_link(peer_page, webui_base): """PeerDashboard Quick Access section renders a Mail icon link.""" page, _ = peer_page page.wait_for_load_state('networkidle') try: page.wait_for_selector('a:has-text("Mail")', timeout=5000) except Exception: pytest.xfail( "Mail link not found on peer dashboard Quick Access" ) # ── 15. CalDAV URL correctness ──────────────────────────────────────────────── def test_peer_my_services_caldav_url_no_radicale(peer_page, webui_base): """CalDAV URL shown in My Services must not contain 'radicale' (no DNS record).""" page, _ = peer_page page.goto(f"{webui_base}/my-services") page.wait_for_load_state('networkidle') try: # If radicale.dev appears as CalDAV URL it means the bug is back radicale_url = page.query_selector('text=radicale') assert radicale_url is None, ( "Found 'radicale' text on My Services page — " "CalDAV URL should be calendar.dev, not radicale.dev:5232" ) except AssertionError: raise except Exception: pass # page didn't load — other tests cover that # ── 16. Email address display ───────────────────────────────────────────────── def test_peer_my_services_shows_address_label(peer_page, webui_base): """MyServices.jsx renders 'Address' label for email (reads email.address).""" page, _ = peer_page page.goto(f"{webui_base}/my-services") page.wait_for_load_state('networkidle') try: page.wait_for_selector('text=Address', timeout=5000) except Exception: pytest.xfail( "'Address' label not found on My Services email section — " "check that email.address is populated in /api/peer/services" )