feat(test): M5.3 — Playwright e2e harness for the dev stack #8

Merged
sharang merged 1 commits from feat/m5.3-playwright into main 2026-05-19 14:53:18 +00:00
Owner

What

M5.3 Playwright e2e harness, scoped to the local dev stack. The CI e2e job is gated behind a RUN_E2E repo variable so it stays off until stage exists.

  • playwright.config.ts — chromium project; baseURL defaults to http://acme.localhost:3000.
  • tests/e2e/apex.spec.ts — landing page renders.
  • tests/e2e/tenant.spec.ts — signed-out dashboard shows the Sign-in button; unknown slug returns 404.
  • tests/e2e/health.spec.ts — every dev-stack endpoint reachable (portal Auth.js, tenant-registry /healthz, KC realm metadata).

Why

After M5.2 the portal has 10 surfaces. A harness now catches the obvious regressions (auth broken, KC misconfigured, tenant-registry down) before they reach stage. Doesn't replace unit tests — fills the integration-shape gap.

Linked milestone: M5.3

How

  • Tests assume the dev stack is up (@needs-stack tag in titles). We don't run them headless against a fully wrapped fixture because Keycloak click-throughs in headless mode are flaky enough that they generate more red herrings than real signal.
  • The OIDC click-through test (signed-in dashboard with product tiles, role-gated nav) is deliberately deferred — it lands when stage has a stable test user + a recorded session storage state file we can replay (M5.x+ when stage is up).
  • CI e2e job is off by default: vars.RUN_E2E must equal 'true' on the repo for it to fire. make e2e works locally regardless.

Test plan

  • pnpm lint clean
  • pnpm typecheck clean (tsconfig excludes tests/e2e so Playwright + tsc don't fight)
  • pnpm test (vitest) — unaffected, 24 cases still green, 100% src/lib coverage
  • pnpm build — unchanged
  • Manual: make e2e end-to-end against the live dev stack — to be run locally; the testing-session for this is what comes next on Sharang's end

Risk

Blast radius: none until RUN_E2E=true is set. The test suite is local-only by default.

What could break:

  • Playwright + Next.js 16 type fit — verified via pnpm typecheck.
  • http://acme.localhost:3000 requires that *.localhost resolves to 127.0.0.1 — true on macOS and most modern Linux out of the box. If a tester is on a network that does weird things to .localhost, override PLAYWRIGHT_BASE_URL=http://localhost:3000 and Next's middleware will still handle the slug via the path (modulo subdomain rewrite assertions).

Rollback plan: revert. CI is unaffected by the revert since the e2e job is gated off.

Checklist

  • Unit tests — n/a (this PR adds tests, not features)
  • Docs updated (README has an e2e section)
  • Secrets via Infisical — none needed locally; CI variables documented
  • Migration — n/a
  • Tenant scoping — n/a (asserts at the boundary)
  • CHANGELOG entry under "Added"
## What M5.3 Playwright e2e harness, scoped to the local dev stack. The CI e2e job is gated behind a `RUN_E2E` repo variable so it stays off until stage exists. - `playwright.config.ts` — chromium project; baseURL defaults to `http://acme.localhost:3000`. - `tests/e2e/apex.spec.ts` — landing page renders. - `tests/e2e/tenant.spec.ts` — signed-out dashboard shows the Sign-in button; unknown slug returns 404. - `tests/e2e/health.spec.ts` — every dev-stack endpoint reachable (portal Auth.js, tenant-registry `/healthz`, KC realm metadata). ## Why After M5.2 the portal has 10 surfaces. A harness now catches the obvious regressions (auth broken, KC misconfigured, tenant-registry down) before they reach stage. Doesn't replace unit tests — fills the integration-shape gap. Linked milestone: **M5.3** ## How - Tests assume the dev stack is up (`@needs-stack` tag in titles). We don't run them headless against a fully wrapped fixture because Keycloak click-throughs in headless mode are flaky enough that they generate more red herrings than real signal. - The OIDC click-through test (signed-in dashboard with product tiles, role-gated nav) is deliberately deferred — it lands when stage has a stable test user + a recorded session storage state file we can replay (M5.x+ when stage is up). - CI e2e job is **off by default**: `vars.RUN_E2E` must equal `'true'` on the repo for it to fire. `make e2e` works locally regardless. ## Test plan - [x] `pnpm lint` clean - [x] `pnpm typecheck` clean (tsconfig excludes `tests/e2e` so Playwright + tsc don't fight) - [x] `pnpm test` (vitest) — unaffected, 24 cases still green, 100% `src/lib` coverage - [x] `pnpm build` — unchanged - [ ] Manual: `make e2e` end-to-end against the live dev stack — to be run locally; the testing-session for this is what comes next on Sharang's end ## Risk **Blast radius:** none until `RUN_E2E=true` is set. The test suite is local-only by default. **What could break:** - Playwright + Next.js 16 type fit — verified via `pnpm typecheck`. - `http://acme.localhost:3000` requires that *.localhost resolves to 127.0.0.1 — true on macOS and most modern Linux out of the box. If a tester is on a network that does weird things to .localhost, override `PLAYWRIGHT_BASE_URL=http://localhost:3000` and Next's middleware will still handle the slug via the path (modulo subdomain rewrite assertions). **Rollback plan:** revert. CI is unaffected by the revert since the e2e job is gated off. ## Checklist - [x] Unit tests — n/a (this PR adds tests, not features) - [x] Docs updated (README has an e2e section) - [x] Secrets via Infisical — none needed locally; CI variables documented - [ ] Migration — n/a - [ ] Tenant scoping — n/a (asserts at the boundary) - [x] CHANGELOG entry under "Added"
sharang added 1 commit 2026-05-19 14:52:27 +00:00
feat(test): M5.3 — Playwright e2e harness for the dev stack
ci / shared (pull_request) Successful in 4s
ci / test (pull_request) Successful in 28s
ci / e2e (pull_request) Has been skipped
ci / image (pull_request) Has been skipped
7b33516686
Adds the M5.3 deliverable scoped to local-dev (stage doesn't exist yet,
so the CI e2e job is gated behind the repo variable RUN_E2E='true' —
defaults off).

Layout:
  playwright.config.ts   chromium project; baseURL defaults to
                         http://acme.localhost:3000 (subdomain routing
                         fires). PLAYWRIGHT_BASE_URL / APEX_URL / etc.
                         env vars override for stage.
  tests/e2e/apex.spec.ts        landing page renders
  tests/e2e/tenant.spec.ts      signed-out dashboard shows Sign in
                                button; unknown slug returns 404
  tests/e2e/health.spec.ts      every dev-stack endpoint reachable
                                (portal /api/auth/providers, tenant-
                                registry /healthz, KC realm metadata)

Run locally with the full dev stack up:

  cd platform/orca-platform && make dev-up
  cd platform/tenant-registry && make dev
  cd platform/portal && make dev
  cd platform/portal && make e2e

OIDC click-through not asserted yet — Keycloak in headless mode is
flaky and depends on a stable test-user password. The current gate
(Sign-in button visible) catches the more common 'auth completely
broken' regression; the deeper smoke lands when stage has its own
test fixture.

tsconfig now excludes tests/e2e so vitest + tsc don't fight over
Playwright type imports.

Refs: M5.3
CODEOWNERS rules requested review from Benjamin_Boenisch 2026-05-19 14:52:28 +00:00
sharang merged commit 99fe3b55b2 into main 2026-05-19 14:53:18 +00:00
sharang deleted branch feat/m5.3-playwright 2026-05-19 14:53:19 +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: platform/portal#8