- axe is clean across every screen in both themes, phone and desktop. Fixed:
the hidden file inputs (aria-hidden + tabIndex -1 — they are opened by
labelled buttons, so they should not be in the accessibility tree), the
heading order (deck/homework/smart-review cards are h2 under the page h1;
LearningSection takes a level so it stays h2 on the library and h3 inside
the settings dialog) and landmarks around the study and review feeds.
- tests/contrast.mjs (new diagnostic): samples rendered pixels, because axe
cannot judge text on blurred glass — it reports those nodes as incomplete.
It skips disabled controls (1.4.3 exempts them) and content behind an open
sheet. Result: no below-minimum text on any scanned screen.
- The report control exists in the homework guide too: under each "Try it
yourself" exercise, labelled "Report exercise", without a skip (there is no
queue to skip). lib/question-reports now takes deckId/deckTitle directly.
- The rail's two creation actions are buttons now (.nav-action) rather than
quiet nav rows — once the library is full they were the only way to start
something on desktop and read as just more navigation. "Make my homework"
is "New homework" wherever it is an action (rail, empty state, share
chooser, manifest shortcut); the page title and mode switch keep their
wording.
Version 0.1.6 (three task bumps), SW -> freezmo-v52.
Versioning: package.json carries the app version (0.1.2 here; one bump per
task with `npm run version:bump`, patch 0-9 rolling into the minor at 10),
baked into the build via lib/version.ts, reported by /api/healthz and shown
in Settings next to the running commit. AGENTS.md documents the rule; the
native suite checks both the API and the Settings row.
Fix: on desktop the app header is hidden, so every page owns its top padding —
/create was the only one without `lg:pt-10`, which slammed the Study deck /
Make my homework switch against the top of the window while /homework had a
comfortable gap. Both now sit at 40px; the wizard suite asserts the clearance
and that the two pages stay in step (90 checks).
SW -> freezmo-v50.
The browser harness lived in /tmp/opencode and an overnight reboot
wiped it. It now lives in tests/ and survives reboots, is versioned
and runs with one command.
- tests/lib.mjs: shared helpers (Chromium auto-detect, seeding,
IndexedDB fixtures, stub/extra instance spawn with process-group
cleanup, check/finish).
- tests/run-all.mjs + npm run test:e2e [filter]: runs the ten suites
in order with a summary; suites that need a stub Ollama or VAPID
keys start their own next start instance on 3208/3209, verify the
port is free and kill the group on exit. Test scratch in
tests/.tmp/ (gitignored).
- Suites rebuilt and green against the current build: regression 38,
mobile 94 (tab matrix, ... sheet, settings sheet, axe), wizard 83,
native 31 (PWA/offline/share/back/undo/haptics/draft), i18n 13,
freeze-loading 6, review 15, phase1 36 (backup/sync/usage limits),
phase2 42 (learning engine/reminders), phase3 21 (homework check).
379 checks, 10/10 suites in one full run.
- playwright-core + axe-core added as devDependencies; CHROME env or
the newest ~/.cache/ms-playwright chromium is used.
- README: new decision 45 documenting the harness; decision 44's
verification note updated.
The older suites' exact sources were lost with the wipe, so the
rebuilt versions reconstruct the same feature areas rather than
being byte-identical.