E2E Testing Guide¶
E2E tests verify real user flows in a real browser.
Use them for high-value journeys only - login, scheduling, file upload. Logic that fits in a unit or integration test belongs there instead.
Where Things Live¶
apps/e2e/
playwright.config.ts ← Playwright configuration
tests/
some.spec.ts ← test files go here
Tools¶
| Tool | Role |
|---|---|
| Browser automation (Chromium) |
Local vs CI¶
| Setting | Local | CI |
|---|---|---|
| Workers | Fully parallel | Single worker |
| Retries | 0 | 2 |
| Reporter | HTML (opens on failure) | List + HTML (never auto-opens) |
| Base URL | http://localhost:3001 | $PLAYWRIGHT_BASE_URL env var |
test.only | Allowed | Breaks the build |
What to Run¶
# App must be running first (pnpm run dev)
pnpm --filter e2e run test
# Against a different URL
PLAYWRIGHT_BASE_URL=http://localhost:4000 pnpm --filter e2e run test
# Single file
pnpm --filter e2e exec playwright test tests/login.spec.ts
# View the HTML report
pnpm --filter e2e exec playwright show-report
# First-time browser install
pnpm --filter e2e exec playwright install
E2E is excluded from CI
The pipeline runs pnpm run test:unit which skips apps/e2e. You must run E2E locally before pushing.
What to Worry About¶
The app must be running
Start infrastructure and the app before running tests:
pnpm run dev:infra # Postgres, Redis, MinIO, solver
pnpm run dev # frontend + backend
test.only will break CI
forbidOnly: true is enabled. Remove any test.only before committing.
Definition of Done¶
E2E Checklist
- [ ] Test covers a real user journey - not logic that belongs in a unit test.
- [ ] Test file is in
apps/e2e/tests/. - [ ] No
test.onlyleft in the file. - [ ] App is running and tests pass locally.
- [ ] Test name describes the user action:
test('student can upload PDF and view schedule')