Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8.6 KiB
8.6 KiB
phase, slug, status, nyquist_compliant, wave_0_complete, created
| phase | slug | status | nyquist_compliant | wave_0_complete | created |
|---|---|---|---|---|---|
| 17 | ui-optimization-polish | draft | false | false | 2026-06-18 |
Phase 17 — Validation Strategy
Per-phase validation contract for feedback sampling during execution. Source:
17-RESEARCH.md§Validation Architecture. Requirement IDs are TBD for this phase (UI/UX polish + branding) — decisions D-01…D-10 (CONTEXT.md) and workstreams A–D (UI-SPEC.md) stand in for REQ-IDs until promoted in plan-phase.
Test Infrastructure
| Property | Value |
|---|---|
| E2E Framework | Playwright 1.60.0 |
| Unit Framework | Vitest ^4.1.8 |
| E2E config file | apps/pwa/playwright.config.ts (profiles: iphone 390×844 WebKit, pixel 412×915 Chromium, desktop 1280×720) |
| Unit config file | apps/pwa/vitest.config.ts |
| Quick run command | pnpm --filter @familysync/pwa exec playwright test --project=pixel layout.spec.ts |
| Full suite command | pnpm --filter @familysync/pwa test:e2e |
| Build gate | pnpm --filter @familysync/pwa build |
| Estimated runtime | ~45–90 seconds (quick: ~15s; full 3-profile suite: ~60–90s) |
| Browser-verification skill | playwright-cli (desktop/Chromium UI checks the spec suite cannot cover) |
Sampling Rate
- After every task commit: Run
pnpm --filter @familysync/pwa exec playwright test --project=pixel layout.spec.ts(phone profile covers the primary fix geometry) - After every plan wave: Run
pnpm --filter @familysync/pwa test:e2e(full 3-profile suite) +pnpm --filter @familysync/pwa build - Before
/gsd-verify-work: Full Playwright suite green + playwright-cli visual sweeps passed + human logo approval received (Workstream B checkpoint) - Max feedback latency: ~90 seconds
Per-Task Verification Map
Task IDs are assigned by the planner. This map is workstream/decision-keyed; the executor binds each task ID to the matching row's automated command during execution.
| Decision | Workstream | Behavior | Test Type | Automated Command / Method | Automated? | Status |
|---|---|---|---|---|---|---|
| D-01/D-02 | A | FAB bottom edge ≤ BottomTabBar top edge on iphone/pixel | Playwright geometry assertion | New assertion in apps/pwa/e2e/layout.spec.ts (skipped on desktop) |
CI (iphone + pixel) | ⬜ pending |
| D-01 | A | Color-legend chips visible; content scrollable above bar | Playwright + playwright-cli sweep | layout.spec.ts full suite + manual scroll |
Partial | ⬜ pending |
| D-01 | A | No horizontal overflow after fix (scrollWidth ≤ clientWidth) |
Playwright Rule 2 | Existing layout.spec.ts Rule 2 |
CI (all profiles) | ⬜ pending |
| D-01 | A | Tap targets preserved (≥44px / ≥56px) | Playwright Rule 1 | Existing layout.spec.ts Rule 1 |
CI (all profiles) | ⬜ pending |
| D-03/D-04 | B | All 7 asset files present in apps/pwa/public/ |
Shell existence check | ls apps/pwa/public/{logo.svg,favicon.svg,favicon.ico,icon-192.png,icon-512.png,icon-maskable-512.png,apple-touch-icon.png} |
CI gate / Wave 0 | ⬜ pending |
| D-04 | B | favicon.ico is multi-size & non-trivial (>100 bytes) |
Shell | test $(wc -c < apps/pwa/public/favicon.ico) -gt 100 |
CI gate | ⬜ pending |
| D-04 | B | icon-maskable-512.png is exactly 512×512 (real safe-zone) |
Node + sharp metadata | node -e "require('sharp')('apps/pwa/public/icon-maskable-512.png').metadata().then(m=>console.log(m.width,m.height))" |
Scripted | ⬜ pending |
| D-04 | B | PWA manifest + index.html icon links resolve (no 404) | Playwright | page.goto('/'), devtools manifest / network check |
playwright-cli | ⬜ pending |
| D-03 | B | Logo meets warm/rounded/at-home brief | Human review | playwright-cli screenshot + operator approval | Human checkpoint | ⬜ pending |
| D-05 | B | BrandSlot swap: no LoginPage layout shift; <h1> retains name; img alt="" |
Playwright + playwright-cli | login route render + a11y name check | playwright-cli | ⬜ pending |
| D-06 | C | No hard-coded hex/px literals in component files | grep |
grep -rnE '#[0-9a-fA-F]{3,6}|[0-9]+px' apps/pwa/src/components/ apps/pwa/src/routes/ (expect token refs only) |
CI gate | ⬜ pending |
| D-06 | C | Schedule-X --sx-color-* overrides still apply post-restructure |
playwright-cli | visual sweep of /calendar |
playwright-cli | ⬜ pending |
| D-06 | C | TypeScript + Vite build exits 0 | Build | pnpm --filter @familysync/pwa build |
CI | ⬜ pending |
| D-07 | D | "Sign out" control renders in SettingsSheet | Playwright + playwright-cli | open settings sheet, confirm button + aria-label | playwright-cli | ⬜ pending |
| D-07 | D | Logout calls fetchLocalLogout() then navigates to /login |
Playwright interaction | click Sign out, confirm redirect | playwright-cli | ⬜ pending |
| D-08 | D | "Member added." toast on create success | Playwright interaction | admin: create member, confirm toast (role=status) | playwright-cli (admin) | ⬜ pending |
| D-08 | D | "Password reset." toast on reset success | Playwright interaction | admin: reset password, confirm toast | playwright-cli (admin) | ⬜ pending |
| D-08 | D | Toast auto-dismisses after ~3s | Playwright interaction | wait 3.5s, confirm gone | playwright-cli | ⬜ pending |
| D-09 | D | Sheet centered on desktop (top/left 50%, transform) |
Playwright geometry | playwright-cli @1280×720 SettingsSheet geometry | playwright-cli (desktop) | ⬜ pending |
| D-09 | D | Sheet renders as bottom-sheet on phone | Playwright geometry | playwright-cli @390×844 geometry | playwright-cli (phone) | ⬜ pending |
| D-10 | D | Admin two-tab strip renders with correct labels | Playwright | /admin: confirm "Members & Accounts" + "Settings" |
playwright-cli (admin) | ⬜ pending |
| D-10 | D | ArrowLeft/ArrowRight switches tabs (roving tabindex) | Playwright keyboard | focus tab, ArrowRight, confirm active | playwright-cli | ⬜ pending |
| D-10 | D | Admin tab ARIA roles present (tablist/tab/aria-selected/tabpanel) |
Playwright | New assertion in admin.spec.ts or layout.spec.ts via getByRole |
CI | ⬜ pending |
Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky
Wave 0 Requirements
- Overlap regression assertion — add the FAB↔BottomTabBar geometry test to
apps/pwa/e2e/layout.spec.ts(Workstream A; runs on iphone + pixel, skipped on desktop). Contract in UI-SPEC §"Regression guard". - Admin tab ARIA assertion — add
role="tablist"/role="tab"/aria-selected/role="tabpanel"checks toapps/pwa/e2e/admin.spec.ts(or append tolayout.spec.ts) (Workstream D-10). - Asset existence check — Wave 0 npm script or inline CI step asserting all 7
apps/pwa/public/assets exist with valid format (ICO size, maskable dimensions). @vite-pwa/assets-generatordevDependency — install inapps/pwa(pullssharp+sharp-ico; the only new package) before Workstream B asset derivation runs.
Existing infrastructure (Playwright 3-profile config + layout.spec.ts Rules 1–4 + Vitest) covers the bulk of the structural assertions.
Manual-Only Verifications
| Behavior | Decision | Why Manual | Test Instructions |
|---|---|---|---|
| Logo / icon set meets warm/rounded/at-home brief | D-03 | Aesthetic judgment; AI-generated art needs operator sign-off | playwright-cli screenshot of BrandSlot on /login + favicon in tab; operator approves at checkpoint before wiring is committed |
| Brand accent selection (cool-blue vs warm rose/amber) | UI-SPEC Q1 | Subjective brand decision | Present both variants (one-line token swap); operator selects at logo checkpoint |
| Maskable adaptive-icon render on a real device | D-04 | iOS/Android home-screen mask is device-only (cannot be driven by playwright-cli) | Install PWA on a device, confirm logo within safe-zone (optional spot-check; format validated automatically) |
| Schedule-X calendar colors visually unchanged post-restructure | D-06 | Visual regression of third-party calendar theme | playwright-cli sweep of /calendar before/after the tokens.css restructure |
Validation Sign-Off
- All tasks have an automated verify command or a Wave 0 dependency
- Sampling continuity: no 3 consecutive tasks without automated verify
- Wave 0 covers all MISSING references (overlap assertion, admin ARIA assertion, asset-existence check, assets-generator install)
- No watch-mode flags (
playwright test/vitest runare one-shot) - Feedback latency < 90s
nyquist_compliant: trueset in frontmatter
Approval: pending