test(e2e): add make e2e-full target, full-stack Playwright spec, CI wiring, docs #10

Merged
nsatoshi merged 1 commits from devin/1776540240-test-e2e-full-and-ci-wiring into master 2026-04-18 19:37:40 +00:00
Owner

Summary

PR #10 of the 11-PR completion sequence. Closes the 'e2e tests only hit production; no local full-stack harness' finding from the review. The existing suite (scripts/e2e-explorer-frontend.spec.ts) is a production canary — it can't validate a PR before it merges.

Changes

scripts/e2e-full.sh (new, +x)

  • docker compose -p explorer-e2e up -d postgres elasticsearch redis, waits for pg_isready.
  • Runs database/migrations/migrate.go so schema + seeds (including 0016_jwt_revocations from PR #8) are applied.
  • Starts go run ./backend/api/rest on :8080; waits for /healthz.
  • Builds + starts npm run start on :3000; waits for a 200.
  • npx playwright install --with-deps chromium; runs the full-stack spec; tears down docker and kills backend+frontend via EXIT trap. E2E_KEEP_STACK=1 bypasses teardown.
  • Generates an ephemeral JWT_SECRET per run (so PR #3's fail-fast passes) and a dev-safe CSP_HEADER so PR #3's hardened production CSP doesn't reject localhost.

scripts/e2e-full-stack.spec.ts (new)

  • Exercises /healthz, /, /blocks, /transactions, /addresses, /tokens, /pools, /search, /wallet, /routes, /api/v1/access/products (YAML catalogue from PR #7), /api/v1/auth/nonce (SIWE kickoff).
  • Takes a full-page screenshot of each route into test-results/screenshots/<route>.png.
  • Track-1 only — no wallet-auth setup needed for CI.

playwright.config.ts

  • Broadened testMatch from a single filename to /e2e-.*\.spec\.ts/ so both the production canary and the new full-stack spec are picked up.

Makefile

  • New e2e-full target → ./scripts/e2e-full.sh. Listed in help.
  • Existing test-e2e (production canary) unchanged.

.github/workflows/e2e-full.yml (new)

Dedicated workflow — not on every push/PR (the stack takes minutes + requires docker). Triggers:

  • workflow_dispatch (manual)
  • PRs labelled run-e2e-full (opt-in for changes touching migrations, auth, or routing)
  • Nightly at 04:00 UTC

Uses Go 1.23.x and Node 20 to match PR #5. Uploads e2e-screenshots and playwright-report as artefacts on every run.

docs/TESTING.md (new)

Four-tier test pyramid (unit → static analysis → production canary → full-stack Playwright), env var reference table, and CI trigger matrix.

Verification

  • bash -n scripts/e2e-full.sh — clean.
  • The spec imports compile cleanly against the existing @playwright/test@^1.40 in the root package.json; no new runtime dependencies.
  • Existing scripts/e2e-explorer-frontend.spec.ts still matched by the broadened testMatch regex.

Completion criterion advanced

7. End-to-end coverage — "make e2e-full boots the real stack, Playwright runs against it, CI uploads screenshots, a nightly job catches regressions that only show up when all services are live."

## Summary PR #10 of the 11-PR completion sequence. Closes the 'e2e tests only hit production; no local full-stack harness' finding from the review. The existing suite (`scripts/e2e-explorer-frontend.spec.ts`) is a production canary — it can't validate a PR before it merges. ## Changes ### `scripts/e2e-full.sh` (new, +x) - `docker compose -p explorer-e2e up -d postgres elasticsearch redis`, waits for `pg_isready`. - Runs `database/migrations/migrate.go` so schema + seeds (including `0016_jwt_revocations` from PR #8) are applied. - Starts `go run ./backend/api/rest` on `:8080`; waits for `/healthz`. - Builds + starts `npm run start` on `:3000`; waits for a 200. - `npx playwright install --with-deps chromium`; runs the full-stack spec; tears down docker and kills backend+frontend via `EXIT` trap. `E2E_KEEP_STACK=1` bypasses teardown. - Generates an ephemeral `JWT_SECRET` per run (so PR #3's fail-fast passes) and a dev-safe `CSP_HEADER` so PR #3's hardened production CSP doesn't reject localhost. ### `scripts/e2e-full-stack.spec.ts` (new) - Exercises `/healthz`, `/`, `/blocks`, `/transactions`, `/addresses`, `/tokens`, `/pools`, `/search`, `/wallet`, `/routes`, `/api/v1/access/products` (YAML catalogue from PR #7), `/api/v1/auth/nonce` (SIWE kickoff). - Takes a full-page screenshot of each route into `test-results/screenshots/<route>.png`. - Track-1 only — no wallet-auth setup needed for CI. ### `playwright.config.ts` - Broadened `testMatch` from a single filename to `/e2e-.*\.spec\.ts/` so both the production canary and the new full-stack spec are picked up. ### `Makefile` - New `e2e-full` target → `./scripts/e2e-full.sh`. Listed in `help`. - Existing `test-e2e` (production canary) unchanged. ### `.github/workflows/e2e-full.yml` (new) Dedicated workflow — **not** on every push/PR (the stack takes minutes + requires docker). Triggers: - `workflow_dispatch` (manual) - PRs labelled `run-e2e-full` (opt-in for changes touching migrations, auth, or routing) - Nightly at 04:00 UTC Uses Go 1.23.x and Node 20 to match PR #5. Uploads `e2e-screenshots` and `playwright-report` as artefacts on every run. ### `docs/TESTING.md` (new) Four-tier test pyramid (unit → static analysis → production canary → full-stack Playwright), env var reference table, and CI trigger matrix. ## Verification - `bash -n scripts/e2e-full.sh` — clean. - The spec imports compile cleanly against the existing `@playwright/test@^1.40` in the root `package.json`; no new runtime dependencies. - Existing `scripts/e2e-explorer-frontend.spec.ts` still matched by the broadened `testMatch` regex. ## Completion criterion advanced > **7. End-to-end coverage** — "`make e2e-full` boots the real stack, Playwright runs against it, CI uploads screenshots, a nightly job catches regressions that only show up when all services are live."
nsatoshi added 1 commit 2026-04-18 19:26:52 +00:00
test(e2e): add make e2e-full target, full-stack Playwright spec, CI wiring, docs
All checks were successful
e2e-full / e2e-full (pull_request) Has been skipped
321b0042c4
Closes the 'e2e tests only hit production; no local full-stack harness'
finding from the review. The existing e2e suite
(scripts/e2e-explorer-frontend.spec.ts) runs against explorer.d-bis.org
and so can't validate a PR before it merges -- it's a production canary,
not a pre-merge gate.

This PR adds a parallel harness that stands the entire stack up locally
(postgres + elasticsearch + redis via docker-compose, backend API, and
a production build of the frontend) and runs a Playwright smoke spec
against it. It is wired into Make and into a dedicated CI workflow.

Changes:

scripts/e2e-full.sh (new, chmod +x):
  - docker compose -p explorer-e2e up -d postgres elasticsearch redis.
  - Waits for postgres readiness (pg_isready loop).
  - Runs database/migrations/migrate.go so schema + seeds including
    the new 0016_jwt_revocations table from PR #8 are applied.
  - Starts 'go run ./backend/api/rest' on :8080; waits for /healthz.
  - Builds + starts 'npm run start' on :3000; waits for a 200.
  - npx playwright install --with-deps chromium; runs the full-stack
    spec; tears down docker and kills the backend+frontend processes
    via an EXIT trap. E2E_KEEP_STACK=1 bypasses teardown for
    interactive debugging.
  - Generates an ephemeral JWT_SECRET per run so stale tokens don't
    bleed across runs (and the fail-fast check from PR #3 passes).
  - Provides a dev-safe CSP_HEADER default so PR #3's hardened
    production CSP check doesn't reject localhost connections.

scripts/e2e-full-stack.spec.ts (new):
  - Playwright spec that exercises public routes + a couple of
    backend endpoints. Takes a full-page screenshot of each route
    into test-results/screenshots/<route>.png so reviewers can
    eyeball the render from CI artefacts.
  - Covers: /healthz, /, /blocks, /transactions, /addresses, /tokens,
    /pools, /search, /wallet, /routes, /api/v1/access/products (YAML
    catalogue from PR #7), /api/v1/auth/nonce (SIWE kickoff).
  - Sticks to Track-1 (no wallet auth needed) so it can run in CI
    without provisioning a test wallet.

playwright.config.ts:
  - Broadened testMatch from a single filename to /e2e-.*\.spec\.ts/
    so the new spec is picked up alongside the existing production
    canary spec. fullyParallel, worker, timeout, reporter, and
    project configuration unchanged.

Makefile:
  - New 'e2e-full' target -> ./scripts/e2e-full.sh. Listed in 'help'.
  - test-e2e (production canary) left untouched.

.github/workflows/e2e-full.yml (new):
  - Dedicated workflow, NOT on every push/PR (the full stack takes
    minutes and requires docker). Triggers:
      * workflow_dispatch (manual)
      * PRs labelled run-e2e-full (opt-in for changes that touch
        migrations, auth, or routing)
      * nightly schedule (04:00 UTC)
  - Uses Go 1.23.x and Node 20 to match PR #5's pinning.
  - Uploads two artefacts on every run: e2e-screenshots
    (test-results/screenshots/) and playwright-report.

docs/TESTING.md (new):
  - Four-tier test pyramid: unit -> static analysis -> production
    canary -> full-stack Playwright.
  - Env var reference table for e2e-full.sh.
  - How to trigger the CI workflow.

Verification:
  bash -n scripts/e2e-full.sh                 clean
  The spec imports compile cleanly against the existing @playwright
  /test v1.40 declared in the root package.json; no new runtime
  dependencies are added.
  Existing scripts/e2e-explorer-frontend.spec.ts still matched by
  the broadened testMatch regex.

Advances completion criterion 7 (end-to-end coverage): 'make e2e-full
boots the real stack, Playwright runs against it, CI uploads
screenshots, a nightly job catches regressions that only show up
when all services are live.'
nsatoshi merged commit dc1ff6148e into master 2026-04-18 19:37:40 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: d-bis/explorer-monorepo#10