This repo has three testing layers. Use the lightest one that can prove the behavior you care about.
- Unit and component tests
- Web and shared client code:
apps/web/src/**with*.test.tsor*.test.tsx - Convex backend logic:
apps/backend/convex/**with*.test.ts
- Web and shared client code:
- Scenario-driven visual verification
- Named Convex scenarios for stateful app setup
- Storybook states for fast visual review
- Playwright smoke tests
- Browser-level checks for a small set of high-risk flows
- Fast unit checks
pnpm test
- Full repo checks
pnpm ci:check
- Scenario-based browser smoke suite
pnpm test:e2e:smoke
- Full Playwright run
pnpm test:e2e
- Local auto-fix
pnpm fix
Use named scenarios instead of hand-editing the dev database.
- List scenarios
pnpm scenario -- list
- Apply a scenario
pnpm scenario -- apply race_locked_signed_in_complete_h2h_no_results
- Inspect the seeded state
pnpm scenario -- summary --namespace scenario__race_locked_signed_in_complete_h2h_no_results
- Clear a scenario namespace
pnpm scenario -- clear --namespace scenario__race_locked_signed_in_complete_h2h_no_results
- Clear everything e2e seeded (every scenario, plus the
smoke__league fixtures)pnpm scenario -- clear-e2e
pnpm test:e2e runs clear-e2e itself when it finishes
(apps/web/tests/e2e/global-teardown.ts), because the suite shares the dev
deployment with feature work and a leftover scenario race becomes the "next
race" everywhere. Set E2E_KEEP_FIXTURES=1 to keep them for debugging.
The full scenario catalog, matrix, and CI requirements live in testing-scenarios.md.
Keep browser coverage intentionally small.
[public]files cover unauthenticated routes and dev-time controls.[auth]files cover Clerk-backed signed-in state.[flow]files cover real user actions like submit, edit, and lock transitions.
Current smoke ownership lives under apps/web/tests/e2e. The smoke script runs with a single Playwright worker because the suite talks to shared Clerk and Convex test state. Authenticated browser tests use a dedicated Playwright setup project, then refresh the Clerk sign-in for each seeded scenario. The stored setup session can expire while earlier suites run, so authenticated helpers do not rely on that session remaining valid.
- Prefer deterministic fixtures and explicit assertions.
- Add
data-testidonly where Playwright needs a stable hook. - Mock time for unit tests; use the dev-time controls for browser testing.
- Avoid snapshot-heavy tests for business logic.
- Keep smoke flows high-signal and hard to regress, not exhaustive.
web-e2e-smoke is the browser smoke gate and should be required in branch protection.
Required CI secrets for the browser suite are documented in testing-scenarios.md.