6.1 KiB
EDR Passenger — Testing Runbook
How to run everything: the API bug-hunt harness and the UI (browser) harness, view the reports, run a single test, and troubleshoot. Both are hermetic (their own Postgres on 5544 — never prod).
- Findings:
docs/ISSUES.md· Fixes:docs/SOLUTIONS.md - Test plans:
docs/e2e-test-matrix.md(API) ·docs/ui-e2e-test-matrix.md(UI)
0. Prerequisites (one time)
- Docker Desktop running (the harness starts Postgres + RabbitMQ containers).
- Node ≥ 20, pnpm 11 (
corepack enableif needed). - Install deps once:
pnpm install(from repo root).
That's it — no manual DB, env, or auth setup. The scripts handle migrations, seeding, and auth.
1. Run the API harness (fast — no browser)
Covers pricing math, FX, wallet/refund/payment integrity, config validation, auth gaps, and the authenticated-booking regression. 25 tests.
bash e2e/run.sh # infra + migrate + run + open HTML report
# or: pnpm test:e2e:passenger
Flags: bash e2e/run.sh --down (tear DB down after) · --no-open (don't open the browser).
Report → apps/edr-passenger-api/e2e-report/index.html.
Run a single API suite / test:
cd apps/edr-passenger-api
npx jest --config ./test/jest-e2e.json test/pricing-fare-engine.e2e-spec.ts
npx jest --config ./test/jest-e2e.json -t "double-spend" # by test name
(The test DB must be up — run bash e2e/prepare.sh once if you skipped e2e/run.sh.)
2. Run the UI harness (browser — Playwright)
Covers the real portal booking flow (search → pay → confirm) with the price cross-check, plus backoffice auth. One command boots the whole stack (Postgres + RabbitMQ + passenger-api + portal + backoffice), seeds a bookable trip, mints passenger + staff auth, runs, and opens the report.
pnpm test:e2e:ui # = bash e2e-ui/run.sh (turnkey)
First run takes ~1–2 min (it builds @edr/types and boots the Next.js apps). If the stack is already
running, it reuses it. Report → e2e-ui-report/index.html.
Run a subset / single UI test (stack already up):
pnpm test:e2e:ui:only --project=portal # just the portal booking tests
pnpm test:e2e:ui:only --project=backoffice
npx playwright test -c e2e-ui/playwright.config.ts ua1 # by file name
Watch it run in a real browser (headed) or step through it:
npx playwright test -c e2e-ui/playwright.config.ts --project=portal --headed
npx playwright test -c e2e-ui/playwright.config.ts --project=portal --debug # Playwright Inspector
npx playwright show-report e2e-ui-report # open a past report
npx playwright show-trace test-results/**/trace.zip # trace of a failed run
Projects: portal (logged-in passenger), guest (no auth), backoffice (staff), propagation
(Track B — staff writes config via API → passenger portal reads; 4 tests).
3. Run absolutely everything
bash e2e/run.sh --no-open # API: 25 tests
pnpm test:e2e:ui # UI: 9 tests (boots the stack)
Or the standalone hermetic API DB only: bash e2e/prepare.sh then pnpm --filter @edr/passenger-api test:e2e.
4. What each harness contains
| Harness | Location | What it proves |
|---|---|---|
| API | apps/edr-passenger-api/test/*.e2e-spec.ts + e2e/ |
fare/FX math, promo/negative-total, wallet double-spend, refund-never-paid, FX-write authz gap, DTO validation gaps, C-10 authed-booking FK regression |
| UI | e2e-ui/ |
UA-1 booking money cross-check; UA-13 🔴 client-forged total (C-1); UA-8 🔴 promo dropped (H-13); Track B — fare change propagates live (PB-2), C-8 passenger rewrites FX, M-1 negative price accepted; smokes |
A test name with 🔴 encodes buggy behavior — when it passes, the bug is present. After you
apply a fix from docs/SOLUTIONS.md, flip that test to assert the corrected behavior.
Seed for the UI flow: apps/edr-passenger-api/test/fixtures/seed-ui.ts (bookable Train/Schedule/
Coach/Seats + WALLET/TELEBIRR payment methods + promos + funded wallet). Standalone:
DATABASE_URL=…5544 npx ts-node test/fixtures/seed-ui.ts.
5. Teardown
docker compose -f e2e/docker-compose.yml down # stops + wipes the test DB + RabbitMQ
The dev app processes (api/portal/backoffice) started by Playwright's webServer stop with the run;
if you booted them manually, lsof -ti :4000 :5174 :5184 | xargs kill.
6. Troubleshooting
| Symptom | Cause / fix |
|---|---|
Cannot find module '@edr/types' on API boot |
Types not built → pnpm --filter @edr/types build (the run scripts do this). |
API boot hangs on AmqpConnection … ECONNREFUSED |
RabbitMQ not up → docker compose -f e2e/docker-compose.yml up -d rabbitmq-e2e. |
EADDRINUSE :::4000 |
A stale API instance is bound → `lsof -ti :4000 |
Backoffice test redirects to /login |
Staff storageState missing/expired → it's re-minted every run by global-setup; ensure SEED_PASSENGER_STAFF=true in apps/edr-passenger-api/.env. |
Portal booking 400 Booking_passengerId_fkey |
This is finding C-10 (real bug). The harness seeds Passenger.id == iamUserId to work around it — see docs/ISSUES.md C-10. |
| Docker daemon not running | open -a Docker, wait ~15s, re-run. |
| Ports differ | api 4000, portal 5174, backoffice 5184, payment 3003, Postgres 5544, RabbitMQ 5672. Override via PORTAL_URL / BACKOFFICE_URL / API_URL / DATABASE_URL env. |
7. Coverage status & what's next
- Done: full hermetic harness, 34 green tests (25 API + 9 UI). UA-1 keystone + UA-8/UA-13 abuse
rows, Track B propagation (PB-2, C-8, M-1), both auth roles,
BookingFlowpage-object. - Next (Track A): more
bookOneAdultvariations — UA-2 (USD), UA-6 (round-trip); multi-passenger free-child (UA-4/5) + gateway/DJF (UA-3) need helper extensions (per-pax form, forged webhook). - Next (Track B): PB-5 (disable station→gone), PB-10 (delete FX→1.0 fallback), config-mid-flight.
See docs/ui-e2e-test-matrix.md for the full row-by-row plan.