## Sprint 5A synthetic acceptance audit and test plan ### Current state - **Existing tests pass on the current synthetic fixture:** - `pytest tests/test_health_dashboard_v5.py`: **15 passed** - Playwright Chromium suite: **9 passed** - Current suite covers: - Four viewports: `390×844`, `768×1024`, `1024×768`, `1440×900` - One visible panel, horizontal overflow, 44 px controls - Basic navigation, transient privacy, doctor print content - Reduced motion, basic 200% text reflow - Skip link and modal focus trap - Explorer limits and period-data behavior - Several empty chart states - **Missing required viewport:** `1920×1080` - **No screenshot assertions or captured acceptance screenshots exist.** ### Material Sprint 5A gaps Runtime probes across all five target viewports found no horizontal page overflow and exactly one visible panel, but the current UI is not yet Sprint-5A complete: - Desktop navigation remains a sticky/flex navigation placed after the main content, rather than an asserted desktop horizontal/sidebar mode. - Mobile nav becomes fixed at `≤900px`, but tests do not verify desktop/mobile mode switching or content occlusion. - Six Cockpit cards render, but: - **0 sparklines** - no visible coverage/quality status - date exists, but no explicit measurement age - Cockpit chart is hardcoded to `symptom.total`; no fallback-metric behavior is implemented or tested. - Event track is separate in the DOM, but there is no behavioral test proving events never become a value-series dataset. - `Heute` tests only confirm its heading: - no tests for useful content without a complete symptom day - no source freshness - no short trend - no maximum-two hints - mobile label is “Symptome erfassen,” not the requested central `+ Erfassen` - Fixture includes stale/future rows and partial symptom/nutrition data, but browser tests do not expose/assert the required current/stale/future states, low coverage, visible sparkline gaps, or fallback chart. ### Proposed deterministic Playwright suite Use projects for exactly: ```text desktop-xl 1920×1080 desktop 1440×900 tablet-land 1024×768 tablet-port 768×1024 phone 390×844 ``` Pin locale/timezone, anchor date `2026-06-15`, reduced animation, device scale factor, and Chromium version. Start the real local server against a newly generated temporary fixture; hash the database before and after. #### Core acceptance tests 1. **Shell matrix** - Open each primary view and More. - Assert exactly one visible `[data-dashboard-panel]`. - Assert `scrollWidth <= clientWidth` after every view. - Check console errors, page errors, failed requests, and non-local requests. - Measure all semantic controls, including nested inputs, at ≥44×44 px. 2. **Navigation modes** - At `1024`, `1440`, and `1920`, assert desktop navigation is visible as the designed sidebar/topbar and mobile fixed nav is absent. - At `768` and `390`, assert mobile nav is fixed and desktop nav is absent. - Confirm fixed nav does not cover the last focusable/content element. - Verify active state, roving tabindex, Arrow keys, Home/End, and `Mehr` `aria-expanded` reset. 3. **Today usefulness** - Use a fixture with no complete symptom day but available medication, source, and registry history. - Assert useful snapshot still renders. - Assert ≤3 prioritized tasks, separate administered/planned medication, compact freshness, short history, and ≤2 distinct hints. - On phone, assert a prominent `+ Erfassen`; on desktop, assert it does not displace primary information. 4. **Cockpit cards** - Assert exactly six core cards. - For each card, inspect value/unit, measurement date/age, baseline copy, coverage/quality text, and sparkline. - Inspect chart data, not labels alone: - null dates remain `null` - explicit zero remains `0` - `spanGaps === false` - Low-coverage fixture must show low/partial status and never present a partial symptom day as complete. 5. **Main-chart fallback and event lane** - Fixture A: complete symptom total available → selected chart metric is `symptom.total`. - Fixture B: no complete symptom total, registry metric available → deterministic documented fallback selected and clearly labeled. - Fixture C: no eligible metric → explicit empty state. - Assert event lane is a separate named semantic region and no event label/type appears in chart datasets. - Period changes must alter labels/data counts and event-lane membership. 6. **Screenshots** - Synthetic-only full-page screenshots for Today and Cockpit at all five viewports. - Additional phone navigation-open/check-in and desktop Doctor/print screenshots. - Store under an explicitly ignored artifact directory. - Stabilize fonts, animations, timezone, canvas rendering, and mask the per-request CSRF token if visible. 7. **Privacy** - Enable privacy in every data-bearing view. - Enumerate known sensitive text nodes and canvases; verify computed masking/blur, not merely a root class. - Confirm navigation remains operable, toggle restores content, and reload resets privacy. - Assert URL, storage, console, trace metadata, and network requests contain no fixture health values. 8. **Keyboard/accessibility** - Skip link, complete tab order, visible focus style, roving tabs, all period controls, More, details/summary, dialog open/close, Escape, Shift+Tab wrapping, and restored focus. - Check landmarks, heading order, tab/panel relationships, accessible chart summaries, status text independent of color. - Add automated accessibility scanning, while retaining manual keyboard assertions. 9. **Reduced motion and 200% text** - Run all views under reduced motion; inspect transitions/animations and chart animation configuration. - Test actual browser/CDP text zoom or equivalent 200% text scaling, not only one root CSS declaration. - Assert no horizontal overflow, clipping, overlap, unreachable controls, or fixed-nav occlusion. 10. **Empty/long-label/future anomaly profiles** - Schema-only empty fixture: meaningful state in Today, Cockpit, event lane, Explorer, Nutrition, Doctor, and More. - Long-label fixture: medication, food, lab, metric, and event labels at all narrow viewports. - Future-dated observation: visibly “future/check” and never selected as ordinary latest/fresh. - Current/stale/future states must be textually distinct and describe data quality, not medical risk. ### Important test pitfalls - Existing 200% test only modifies `documentElement.style.fontSize`; this is weaker than browser text zoom. - Existing privacy test can pass by checking only the first blurred panel child while nested content or canvases leak. - Existing reduced-motion scan runs only the initially visible view. - Existing period test mostly checks caption changes; only Explorer checks point counts. - Empty-state interception mutates HTML after generation and can bypass backend contract validation; prefer real validated fixture variants. - Screenshot/report directories are not explicitly ignored, although image/ZIP extensions happen to be broadly ignored. - `CHROMIUM_PATH=/usr/bin/chromium` is environment-specific, and the package script does not start the fixture/server itself; clean-checkout browser execution is not currently one-command reproducible. - Visual baselines must never be refreshed from a non-synthetic server. - Avoid asserting CSS declarations as proof of runtime target size, privacy, nav mode, or reflow—measure computed browser state. ### Repository impact and issues - **No repository files created or modified.** - Temporary fixture, server, browser dependencies, screenshots, and test artifacts were removed. - Concurrent uncommitted changes appeared during the audit in: - `scripts/health/dashboard_v5/data_provider.py` - `scripts/health/dashboard_v5/render.py` - `tests/test_health_dashboard_v5.py` - The Sprint 5A document is currently untracked.