docs: Sprint 14 — Vitest for useOnboarding (Q4) across all 6 running docs

Sprint 14 (commit 28f3212) adds Vitest + happy-dom +
@testing-library/react + @testing-library/jest-dom as
devDeps and locks the useOnboarding state-transition
contract with 7 unit tests in 25 ms. Lifts the 'no new
npm deps' rule for testing-only. Runtime bundle unchanged
(503.82 kB). No pre-existing WIP files touched.

Sprint 9's bug 1562929 (onComplete wired to .reset, the
inverse op) shipped a post-deploy fix the same day.
Sprint 14 prevents recurrence at npm test time.

This commit updates the 6 running docs that track sprints:

- .agent/plan.md — header changed to 'Active sprint: Sprint
  14'; Sprint 14 section (S14.1-S14.4 + Done when + Out of
  scope) added after the Sprint 13 section.
- .agent/context.md — Sprint 14 decisions (D1-D7), open Q1,
  and file:line references added.
- Review/sprint14-verification.md — NEW: deploy + 7-case
  test table + verification commands + Case 7 S9-bug-catch
  proof + 5-risk table + open Q1 (component-level tests).
- Review/ui-nielsen-audit.md — Sprint 14 status block
  (T7.1-T7.3) added after the Sprint 13 block.
- fix-ui-audit.md — Sprint 14 section (T7.1-T7.5) added
  after the Sprint 13 section.
- Review/handoff-ui-audit.md — Batch J line in deploy
  list, Sprint 14 section after Sprint 13, TL;DR Sprint
  14 line, Last-updated footer updated. (Did NOT replace
  the Sprint 7/8/TL;DR/environment-quirks/active-risks
  content that was at the bottom of the file — that
  material is preserved unchanged.)
- docs/HANDOFF.md — Sprint 14 section added after Sprint
  13, Last-updated footer updated.

All 6 docs now reflect Sprint 14. §Future backlog
remaining: F9-full (local Ollama model pull on the host).
Q4 (Vitest) is now closed. Sprint 14 is the smallest
sprint in the cycle (devDeps + 1 test file + 2 config
files + 2 scripts) and the first that adds a test
infrastructure layer.
This commit is contained in:
2026-06-05 17:30:00 -07:00
parent 28f321298f
commit af4ec793c7
7 changed files with 287 additions and 6 deletions
+32
View File
@@ -469,3 +469,35 @@ The Sprint 11 "Generate Meal Plan" CTA was library-only. Sprint 13 splits it int
- `frontend/src/pages/Dashboard.tsx:775-870``renderPromptModal` (the Sprint 13 modal)
- `Review/sprint13-verification.md` — new file (deploy + 3-step browser smoke + 4 API curls + a11y check + 6-risk table)
---
## Sprint 14 — Vitest for `useOnboarding` (Q4)
### Decisions
- **D1 — Lift "no new npm deps" for testing-only.** Vitest + happy-dom + @testing-library/react + @testing-library/jest-dom go under devDependencies. Runtime bundle size unchanged.
- **D2 — `happy-dom` over `jsdom`.** Lighter (7x smaller), faster startup, sufficient for hooks-only tests. No need for full DOM emulation in Sprint 14.
- **D3 — Test only the hook, not the `<OnboardingTour/>` component.** The S9 bug class is at the hook/callback wiring level. Component tests (focus, arrow keys, dialog a11y) are a different scope and a future sprint.
- **D4 — `renderHook` from `@testing-library/react`** (not a custom harness). The hook is plain React, no router or query client dependencies, so no `wrapper` option is needed.
- **D5 — `npm test` runs `vitest run` (no watch).** CI-friendly. `npm run test:watch` for local dev.
- **D6 — `markComplete` test locks the S9 bug class.** A future refactor that wires `onComplete → reset` (the original bug) would set state to false but leave localStorage at '1'; a future refactor that wires `onReset → markComplete` (the inverse) would set state to true without clearing localStorage. Case 3 (`markComplete` does NOT clear localStorage) + Case 4 (`reset` clears localStorage AND flips state) lock both directions.
- **D7 — No backend tests this sprint.** Venv on `docker-willester` is broken (Nix symlinks to `/run/current-system/sw/bin/python`). Backend pytest skipped. Frontend-only sprint.
### Open questions
- Q1 — Cover the `<OnboardingTour/>` component itself (focus, arrow keys, dialog a11y) in a future sprint? Default: yes, future sprint. Adds @testing-library/user-event for keyboard simulation.
### Sprint 14 file:line references
- `frontend/src/components/OnboardingTour.tsx:78-93``readComplete` / `writeComplete` / `clearComplete` helpers (the localStorage I/O seam)
- `frontend/src/components/OnboardingTour.tsx:103-133``useOnboarding` hook (returns `{reset, show, markComplete, isComplete}`)
- `frontend/src/components/OnboardingTour.tsx:109` — initial `useState<boolean>(readComplete)` (the localStorage → state bridge)
- `frontend/src/components/OnboardingTour.tsx:113-116``reset` callback: clears localStorage + flips state to false
- `frontend/src/components/OnboardingTour.tsx:118-121``show` callback: identical to `reset` (intentional mirror)
- `frontend/src/components/OnboardingTour.tsx:128-130``markComplete` callback: flips state to true only (the inverse op from `reset`)
- `frontend/src/App.tsx:104-117` — wires `onComplete → markComplete` and `onReset → reset` (must not be inverted)
- `frontend/vitest.config.ts` (NEW) — happy-dom env + setup file
- `frontend/vitest-setup.ts` (NEW) — @testing-library/jest-dom matchers
- `frontend/src/components/OnboardingTour.test.tsx` (NEW) — 6 cases (S14.3)
- `frontend/package.json` (MODIFIED) — devDeps + scripts