# 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 enable` if 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
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:**
```bash
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.

```bash
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):
```bash
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:
```bash
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
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

```bash
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 | xargs kill -9`, then re-run. |
| 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, `BookingFlow` page-object.
- **Next (Track A):** more `bookOneAdult` variations — 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.
