Context
0022 says where tests live and that a greenpnpm verify proves less than it seems; it does not say which kinds of test exist or how much
is enough. Tenant isolation is the failure that costs most, and a mock database cannot show it. The repository is public, so GitHub-hosted runners are free.
Decision
- Vitest covers logic in packages, services, web and mobile.
- Maestro covers mobile E2E, on GitHub-hosted runners; a local Maestro run is the fallback. Flows sit with the app.
- Playwright covers web. A shared preset runs a smoke suite on every PR and the full suite nightly. Suites live in
apps/<app>/e2e/__tests__/(0022 rule 3). - Service tests use
encore testagainst a real Postgres. Each tenant-owned table has a mandatory isolation test: tenant A cannot read or write tenant B’s rows. - Coverage floors: 80 and 70 for packages and services. Reading them as lines and branches is an assumption (
TODOconfirm). Apps have no floor. - Generated clients are type-checked; screenshots serve visual checks; no Storybook.
- Accessibility and load: axe in the Playwright suite, k6 for load (0070).
- No self-hosted runners on the public repository. Heavy agent runs use a personal box, not CI.
Consequences
- Real-Postgres tests are slower than mocks; they are the only evidence for tenancy.
- A floor can be gamed; review still reads the tests.
Enforcement
Planned: coverage thresholds in@stackra/vitest-config, a check that every tenant-owned table has an isolation test, and the Playwright and Maestro workflows.
Test placement is already enforced by tools/scripts/validate-repository.mjs (checkTestPlacement).