The linter ran over every Markdown file and Python comment, so full-repo trunk runs on master kept failing on em-dashes that predate it. Replace the existing ones once and drop the check. The AGENTS.md rule stays, the v2 ESLint rule stays, and pr-ready's humanizer pass catches new ones in prose. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01RyamrxVw5BzEidVzm68LY7
End-to-end tests (Playwright)
These drive a real running RomM instance, unlike the Vitest specs, which mount components in isolation. They exist to cover behaviour that only shows up in the assembled app. They live in e2e/ rather than src/ or test/ because Vitest's globs (src/**/*.{test,spec}.ts, test/**/*.{test,spec}.ts) would otherwise try to run them in jsdom.
Running tests
-
Have the app up and reachable (default
http://localhost:3000, override withE2E_BASE_URL), with a populated library; the specs pick the first ROM they find. -
Seed the two fixture users, from the repo root:
uv run python .github/scripts/seed_e2e_users.py # --remove to clean up afterwards -
Run, from
frontend/:npm run test:e2e # headless npm run test:e2e:ui # interactive, for debugging a failure
Authentication
auth.setup.ts runs first as its own project, logs each fixture user in once and saves the session to playwright/.auth/ (gitignored). Specs pick an identity with test.use({ storageState: STORAGE_STATE.viewer }) and start signed in, so the form is driven twice per run rather than once per test.
login.spec.ts is the only spec that drives the form, using the default unauthenticated page. If auth breaks, diagnose there.