Files
familysync/.planning/phases/17-ui-optimization-polish/17-VALIDATION.md
T

111 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
phase: 17
slug: ui-optimization-polish
status: draft
nyquist_compliant: false
wave_0_complete: false
created: 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
> AD (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** | ~4590 seconds (quick: ~15s; full 3-profile suite: ~6090s) |
| **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 to `apps/pwa/e2e/admin.spec.ts` (or append to `layout.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-generator` devDependency** — install in `apps/pwa` (pulls `sharp` + `sharp-ico`; the only new package) before Workstream B asset derivation runs.
*Existing infrastructure (Playwright 3-profile config + `layout.spec.ts` Rules 14 + 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 run` are one-shot)
- [ ] Feedback latency < 90s
- [ ] `nyquist_compliant: true` set in frontmatter
**Approval:** pending