mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-29 08:21:00 +00:00
The Fayda redirect URI registered for local testing is http://localhost:3000/callback, matched exactly by the provider, so the portal has to be the thing listening there. Its dev and preview servers move from 4200 to 3000 and the API moves to 3001. Every hardcoded fallback to http://localhost:3000/api follows — six copies of the same default across libs/api, libs/auth, the portal and the backoffice — otherwise a developer without a .env would have had the app calling itself. e2e is unaffected: it binds its own ports (3011/4302/4303) explicitly.
89 lines
3.9 KiB
Markdown
89 lines
3.9 KiB
Markdown
# End-to-end browser tests
|
|
|
|
Playwright, driving the portal and the backoffice in a real browser against a
|
|
real API and a real database.
|
|
|
|
```bash
|
|
# from emaui/
|
|
npx nx e2e @ema-platform/e2e # or: npx playwright test --config apps/e2e/playwright.config.ts
|
|
npx playwright test --config apps/e2e/playwright.config.ts --headed --debug
|
|
npx playwright show-report ../../dist/e2e-report
|
|
```
|
|
|
|
## What it runs against
|
|
|
|
Nothing shared with your own dev stack. The suite starts its own servers, on its
|
|
own ports, against its own database:
|
|
|
|
| | port | notes |
|
|
|---|---|---|
|
|
| API | 3011 | `node dist/main.js` with explicit env |
|
|
| Portal | 4302 | `vite build --mode e2e` then `vite preview` |
|
|
| Backoffice | 4303 | same |
|
|
| Database | — | `ema_e2e` |
|
|
|
|
This is deliberate. A developer's stack is usually already up on 3000/3001/4201,
|
|
and `dev/start.sh` **rewrites** `emaapi/apps/server/emaapi/.env` and the apps'
|
|
`.env.local` on every run — a suite that read those files would point at
|
|
whichever stack was started last. The API is launched with `DATABASE_NAME`,
|
|
`PORT` and the payment flags passed directly, and the frontends are built with
|
|
`--mode e2e`, which picks up `apps/*/.env.e2e.local` (higher precedence than
|
|
`.env.local`, so your own config is left alone).
|
|
|
|
`vite preview` on a production build rather than `nx serve`, because Nx
|
|
serialises `serve` targets per project: with your dev portal already running,
|
|
a second `nx serve @ema-platform/portal` waits forever on the first.
|
|
|
|
### First-time setup
|
|
|
|
The E2E database has to exist and be bootstrapped once:
|
|
|
|
```bash
|
|
DB_NAME=ema_e2e ./dev/start.sh # creates it, migrates, seeds, then starts a stack you can Ctrl-C
|
|
```
|
|
|
|
Afterwards the suite manages its own servers; you do not need `start.sh` again.
|
|
Note that this run leaves the shared `.env` files pointing at the E2E database
|
|
and its ports — rerun `./dev/start.sh` plain to put them back.
|
|
|
|
## How it gets its data
|
|
|
|
- **Accounts are created through the UI.** Every spec signs up its own applicant
|
|
with a timestamped email, and deletes it in `afterEach` (`deleteApplicant`).
|
|
Nothing is shared between specs, so specs can run in any order and the second
|
|
run of the suite behaves exactly like the first.
|
|
- **The one-time code is scraped from the API log.** There is no local SMS
|
|
gateway, `iam.user_verifications.verification_code` is argon2-**hashed**, and
|
|
the notification rows it is delivered through carry an empty body — the log
|
|
line is the only plaintext. The API is therefore started with its output teed
|
|
to `/tmp/ema-e2e-api.log`, and `support/api-log.ts` reads codes written after
|
|
a recorded offset. The test still types the real code into the real screen.
|
|
Because the log line names no recipient, matching is by position, which is
|
|
sound only while the suite runs single-worker — hence `workers: 1`.
|
|
- **Database reads use `psql`**, shelled out from `support/db.ts`, rather than
|
|
adding a `pg` dependency to the frontend workspace for the sake of a few
|
|
assertions.
|
|
|
|
## Conventions
|
|
|
|
- One worker, serial. The officer queue is global state and the log-offset trick
|
|
needs ordering; determinism is worth the wall-clock.
|
|
- Assertions are on what the user sees — headings, badges, buttons — with
|
|
database checks only where the point is that something was *persisted*.
|
|
- No `waitForTimeout`. Wait for a condition.
|
|
- Traces, screenshots and video are retained for failures only.
|
|
|
|
## Debugging a failure
|
|
|
|
Playwright writes `test-results/<test>/error-context.md` with a full
|
|
accessibility snapshot of the page at the moment it failed — usually enough on
|
|
its own. Otherwise `npx playwright show-trace test-results/<test>/trace.zip`.
|
|
|
|
## Status
|
|
|
|
Implemented: signup → OTP → operations gate → dashboard, and the empty-state
|
|
dashboard. See the parent prompt (`dev/prompts/e2e-browser-tests-prompt.md`) for
|
|
the flows still to be written: catalogue filtering, the full application
|
|
lifecycle per licence type, officer review, payment bypass, certificate
|
|
download, expiry, renewal and reminders.
|