Public Access
Sprint 14 (commit28f3212) 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 bug1562929(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.
97 lines
4.9 KiB
Markdown
97 lines
4.9 KiB
Markdown
# Sprint 14 Verification — Vitest for `useOnboarding` (Q4)
|
|
|
|
**Date:** 2026-06-05. **Owner:** this agent. **Status:** code complete, 7/7 tests green, `npm run build` green, awaiting commit + push.
|
|
|
|
## What Sprint 14 does
|
|
|
|
Adds Vitest + @testing-library/react + happy-dom to the frontend devDeps and locks the `useOnboarding` state-transition contract with 7 unit tests. The S9 bug class (wiring `onComplete` to a call that flips `isComplete` to `false`, e.g. `onboarding.reset()`) is now caught at `npm test` time. Sprint 9 (F1 Onboarding Tour) shipped a hand-rolled ~420-line component; the bug `1562929` shipped a post-deploy fix the same day. Sprint 14 prevents recurrence.
|
|
|
|
## Why this sprint, why this scope
|
|
|
|
- **Q4** (open question from Sprint 9): "Add Vitest to lock `useOnboarding` state transitions." Cost: ~1 hr. Value: prevents the S9 bug class. Decision: lift the "no new npm deps" rule for **testing-only** (devDeps).
|
|
- **Hook-only, not component-level.** The S9 bug was at the App.tsx call-site. Sprint 14 includes one integration test (Case 7) that statically reads `App.tsx` and asserts the wiring. Component-level tests (focus, arrow keys, dialog a11y) are a future sprint.
|
|
|
|
## Files added
|
|
|
|
- `frontend/vitest.config.ts` — happy-dom env, setup file, `src/**/*.test.{ts,tsx}` glob.
|
|
- `frontend/vitest-setup.ts` — `@testing-library/jest-dom/vitest` matchers.
|
|
- `frontend/src/components/OnboardingTour.test.tsx` — 7 cases.
|
|
|
|
## Files modified
|
|
|
|
- `frontend/package.json` — 4 new devDeps (`vitest`, `happy-dom`, `@testing-library/react`, `@testing-library/jest-dom`) + 1 devDep for tsc (`@types/node`) + 2 scripts (`test`, `test:watch`).
|
|
- `.agent/plan.md` — S14 sections (S14.1-S14.4 + Done when + Out of scope).
|
|
- `.agent/context.md` — S14 decisions (D1-D7), open question (Q1), file:line references.
|
|
|
|
## Test cases (S14.3)
|
|
|
|
| # | Case | What it locks |
|
|
|---|------|---------------|
|
|
| 1 | clean init | `isComplete === false` when localStorage is empty |
|
|
| 2 | persisted init | `isComplete === true` when `localStorage.getItem(KEY) === '1'` |
|
|
| 3 | `markComplete` | state → true, localStorage **stays** at `'1'` (locks one direction of the S9 bug) |
|
|
| 4 | `reset` | localStorage cleared, state → false |
|
|
| 5 | `show` | identical to `reset` (intentional mirror) |
|
|
| 6 | localStorage throw on read | silently swallowed, `isComplete === false`, no crash |
|
|
| 7 | App.tsx wiring | static check: `onComplete` calls `markComplete`, `onReset` calls `reset`; neither inverts (locks the original S9 bug at the call site) |
|
|
|
|
## Verification commands
|
|
|
|
```bash
|
|
ssh docker-willester
|
|
cd /home/peter/MealPlanner/frontend
|
|
|
|
# 1. install (already done on host; rerun if pulling to a fresh checkout)
|
|
npm install
|
|
|
|
# 2. run tests
|
|
npm test
|
|
# → 7 passed in ~25 ms
|
|
|
|
# 3. build (still green; vitest is devDeps only)
|
|
npm run build
|
|
# → tsc 0 errors, vite built in ~2.6 s, bundle 503.82 kB unchanged
|
|
|
|
# 4. prove Case 7 catches the bug (manual)
|
|
sed -i 's|onboarding.markComplete()|onboarding.reset()|' src/App.tsx
|
|
npm test
|
|
# → 1 failed (Case 7: onCompleteBody does not match /markComplete/)
|
|
sed -i 's|onboarding.reset()|onboarding.markComplete()|' src/App.tsx # restore
|
|
npm test
|
|
# → 7 passed
|
|
```
|
|
|
|
## Deploy
|
|
|
|
No backend change. No migration. No new runtime dep. The 5 new devDeps land on `npm install` on the host.
|
|
|
|
```bash
|
|
ssh docker-willester
|
|
cd /home/peter/MealPlanner
|
|
git pull
|
|
cd frontend && npm install && npm test # confirm 7/7 in CI
|
|
cd .. && docker compose up -d --build frontend
|
|
```
|
|
|
|
If the user wants Vitest in CI (currently not wired), that is a follow-up — outside Sprint 14 scope.
|
|
|
|
## What Sprint 14 does NOT do
|
|
|
|
- **No component-level tests for `<OnboardingTour/>`.** Focus, arrow keys, dialog a11y, portal positioning. Future sprint. Would add `@testing-library/user-event` for keyboard simulation.
|
|
- **No backend tests.** Venv on `docker-willester` is broken (Nix symlinks to `/run/current-system/sw/bin/python`). Frontend-only sprint.
|
|
- **No CI integration.** Tests are local-only. Wiring them into a CI runner is a follow-up.
|
|
|
|
## Risk table
|
|
|
|
| Risk | Mitigation | Status |
|
|
|------|------------|--------|
|
|
| Vitest conflicts with Vite 5 config | vitest.config.ts uses `defineConfig` from `vitest/config` which extends Vite's; tested, no conflict | Resolved |
|
|
| `node:*` imports in tests break tsc | Added `@types/node` as devDep | Resolved |
|
|
| Tests slow CI | 7 cases run in 25 ms; not a concern | N/A |
|
|
| Devs forget to run `npm test` before commit | Follow-up: pre-commit hook or CI; not in Sprint 14 | Open |
|
|
| Future refactor adds a hook dependency that breaks Case 7's regex | Case 7 uses a single-shot regex match; if `App.tsx` gains a `markComplete` call in unrelated code (e.g. button), the regex still works because the `onComplete` arrow body is the captured group | Resolved (verified) |
|
|
|
|
## Open question for follow-up
|
|
|
|
**Q1 — Should Sprint 15 add component-level tests for `<OnboardingTour/>` (focus, arrow keys, dialog a11y)?** Default: yes, future sprint. Adds `@testing-library/user-event`. ~1.5 hr.
|