|
| 1 | +# Live-Playground E2E Suite |
| 2 | + |
| 3 | +A real, live-server end-to-end test suite for Authorizer. Every spec drives a real `authorizer` binary (built from this repo's source) plus a real browser (Playwright) — no unit-level mocking of Authorizer itself. Third-party services (Google/GitHub/Discord/etc. OAuth, SMS delivery, an external SAML IdP) are stood in for by small local mock servers under `mocks/`, wired in via `authorizer`'s own test-only mechanism (`--env=e2e`) — every behavior it enables is a documented no-op unless that exact env value is set, so none of this affects production behavior. |
| 4 | + |
| 5 | +## Coverage |
| 6 | + |
| 7 | +- OIDC provider (signup/login/PKCE/token issuance) and OIDC SSO relying-party (home-realm discovery) |
| 8 | +- SAML SP and SAML IdP |
| 9 | +- SCIM (CRUD, filter operators, webhooks — including real webhook delivery with HMAC verification) |
| 10 | +- 10 social OAuth providers (Google, GitHub, Facebook, LinkedIn, Apple, Discord, Twitter, Microsoft, Twitch, Roblox) |
| 11 | +- WebAuthn/passkeys (via Playwright's CDP-backed virtual authenticator) |
| 12 | +- TOTP, SMS-OTP, WebOTP auto-fill, magic-link |
| 13 | +- MFA enforcement routing matrix |
| 14 | +- OTP brute-force lockout |
| 15 | +- Dashboard verified-domains UI |
| 16 | + |
| 17 | +## Prerequisites |
| 18 | + |
| 19 | +- Docker + Docker Compose (everything else — Node, Playwright browsers, the `authorizer` binary — is built into containers; nothing needs to be installed on the host). |
| 20 | + |
| 21 | +## Run the full suite |
| 22 | + |
| 23 | +From the repository root: |
| 24 | + |
| 25 | +```bash |
| 26 | +make e2e-playground |
| 27 | +``` |
| 28 | + |
| 29 | +This builds and starts the full docker-compose stack (six `authorizer` instances configured for different scenarios, the mock OAuth/SAML/SMS/webhook servers, Mailpit for email), runs the entire Playwright suite in a containerized runner, and **always** tears the stack down afterward (`docker compose down -v`) — including on failure or if the stack fails to start. |
| 30 | + |
| 31 | +Equivalent to, run manually: |
| 32 | + |
| 33 | +```bash |
| 34 | +docker compose -f e2e-playground/docker-compose.yml up -d --wait authorizer authorizer-sso mock-oauth mock-saml-idp mailpit sms-sink |
| 35 | +docker compose -f e2e-playground/docker-compose.yml run --rm playwright npx playwright test |
| 36 | +docker compose -f e2e-playground/docker-compose.yml down -v |
| 37 | +``` |
| 38 | + |
| 39 | +(The `playwright` service's own `depends_on` brings up the remaining instances — `authorizer-webauthn`, `authorizer-magic-link`, `authorizer-mfa-enforced`, `authorizer-mfa-magic-link`, `webhook-sink` — automatically; they don't need to be named in the `up` step.) |
| 40 | + |
| 41 | +## Run a subset |
| 42 | + |
| 43 | +Any Playwright CLI filter works. From `e2e-playground/`, after starting the stack: |
| 44 | + |
| 45 | +```bash |
| 46 | +# One spec file |
| 47 | +docker compose run --rm --build playwright npx playwright test totp.spec.ts |
| 48 | + |
| 49 | +# By name pattern |
| 50 | +docker compose run --rm --build playwright npx playwright test -g "SCIM" |
| 51 | + |
| 52 | +# A whole directory |
| 53 | +docker compose run --rm --build playwright npx playwright test social/ |
| 54 | +``` |
| 55 | + |
| 56 | +**`--build` is required whenever a spec file (or anything else under `e2e-playground/`) has changed** — the `playwright` service's Dockerfile bakes test files into the image at build time rather than mounting them live; without `--build` you'll run stale tests, or Playwright will report "No tests found" if a new file was added since the image was last built. |
| 57 | + |
| 58 | +Don't forget to tear down afterward: `docker compose -f e2e-playground/docker-compose.yml down -v`. |
| 59 | + |
| 60 | +## Verify results after a run |
| 61 | + |
| 62 | +Playwright's HTML report is written to `e2e-playground/playwright-report/` on the host (mounted, survives container teardown). To view it: |
| 63 | + |
| 64 | +```bash |
| 65 | +npx playwright show-report e2e-playground/playwright-report |
| 66 | +``` |
| 67 | + |
| 68 | +or open `e2e-playground/playwright-report/index.html` directly in a browser. It shows every test's pass/fail status, timing, and — for failures — a full trace (screenshots, network log, action-by-action replay). |
| 69 | + |
| 70 | +Raw output (traces, videos on retry, etc.) is under `e2e-playground/test-results/`, also host-mounted. |
| 71 | + |
| 72 | +A clean run's terminal output ends with a summary line, e.g.: |
| 73 | + |
| 74 | +``` |
| 75 | +XX passed (NNs) |
| 76 | +``` |
| 77 | + |
| 78 | +Any skip is intentional and self-documenting — read the `test.skip(...)` call's message in the relevant spec file for the reason. As of this writing there are no skips tied to real product gaps. |
| 79 | + |
| 80 | +## Notes |
| 81 | + |
| 82 | +- Every spec seeds its own state (org, users, connections) — specs are independently runnable and safe to run in parallel or in any order. |
| 83 | +- `authorizer-sso` runs a second, separately-configured instance (port 8081) specifically because `--enable-org-discovery=true` is a global login-UX toggle that would otherwise change behavior for every other spec sharing the default instance. |
| 84 | +- Test-only secrets (SAML certs, JWT signing keys) live under `fixtures/certs/`, are checked in, and sign nothing real — the same pattern `make dev`'s embedded dev RSA keys already use. |
0 commit comments