diff --git a/serverAppConfigs-docs/Architecture/E2E Suite.md b/serverAppConfigs-docs/Architecture/E2E Suite.md new file mode 100644 index 0000000..e6e772f --- /dev/null +++ b/serverAppConfigs-docs/Architecture/E2E Suite.md @@ -0,0 +1,63 @@ +# E2E Suite — homepage + guard chain (Playwright) + +`tests/e2e/` drives the **live fleet** through a real browser: fresh contexts +hit `https://www.franksdank.cloud`, log in through the authentik two-stage +flow, and crawl every service link through the Caddy → Anubis → outpost +guard chain. It is the only test in this repo that exercises the chain as a +user sees it; the `bats` seams assert config shape, not behavior. + +## Layout + +| Path | Role | +|------|------| +| `playwright.config.ts` | four projects (below), real-browser UA, trace on failure | +| `specs/00-auth.setup.ts` | setup project: two real authentik logins, saves storage states | +| `specs/10-homepage.spec.ts` | user panel set + open links derived from `services.json` (registry-derived — no hardcoded service lists) | +| `specs/11-admin.spec.ts` | `admin` project: admin grid + `/admin/` RBAC (403 for standard user, members-only 200) | +| `specs/12-crawl.spec.ts` | every user open link reaches its real app through the guard chain | +| `specs/13-sso.spec.ts` | direct guarded-vhost visits resolve silently with ONLY the homepage session (single-login enforcement) | +| `specs/14-guard.spec.ts` | `guest` project, no storage state: unauthenticated traffic lands on the IdP login | +| `lib/login.ts` | `akLogin` helper (two-stage flow, shadow-DOM locators) | +| `lib/env.ts` | loads `.env.local`, exports `REAL_UA` | +| `tests/e2e_scaffold.bats` | bats seam: structure + no-credentials-tracked (never drives the fleet) | + +## Projects and auth + +- **setup** — logs in as `qa-e2e` and `qa-e2e-admin` (fleet-managed IdP test + users; the admin is a `homepage-admins` member), writes + `.auth/qa-e2e{,-admin}.json` storage states. +- **standard** — 10/12/13 with the user state. +- **admin** — 11 with the admin state. +- **guest** — 14 with an empty state. + +Credentials live in `tests/e2e/.env.local` (git-ignored; placeholders in +`.env.local.example`). The scaffold bats seam fails the commit if creds or +auth states are ever tracked. + +## Run + +```bash +cd tests/e2e && npx playwright test # all projects +npx playwright test --project=standard 12-crawl.spec.ts # one slice +``` + +Requires LAN reachability of `www.franksdank.cloud` (Pi-hole DNS or public). +The suite is **not** part of `./tests/run.sh` — it needs the live fleet and +real IdP credentials. + +## Gotchas (all paid for live) + +1. **Fresh context per login.** Reusing a half-finished flow poisons + authentik's `pending_user` stage and the second login hangs. The setup + spec runs each login in its own context. +2. **Lit stage re-render race.** authentik's flow executor can re-render the + password stage right after mount, wiping a programmatic `fill`; the submit + then POSTs an empty form ("This field is required"). `akLogin` fills, + **verifies the value survived**, submits via Enter, and retries. +3. **Headless UA = bot.** Anubis denies obvious headless UAs; the config + overrides `userAgent` with a real Chrome UA (`REAL_UA`). +4. **Cold Anubis PoW.** The first challenge in a fresh context can outlive + default assertion budgets; title asserts carry 60s budgets. +5. **Solve-once cookie.** Since Anubis v1.27.0 + `COOKIE_DOMAIN` (see + [[Anubis]]), one PoW per fresh context covers every guarded vhost — crawl + and SSO specs complete in ~0.5 s per vhost instead of a PoW each. diff --git a/serverAppConfigs-docs/Architecture/Testing Policy.md b/serverAppConfigs-docs/Architecture/Testing Policy.md index 8a68ef0..4cb2e09 100644 --- a/serverAppConfigs-docs/Architecture/Testing Policy.md +++ b/serverAppConfigs-docs/Architecture/Testing Policy.md @@ -12,6 +12,8 @@ This repository tests its configuration at defined seams. The tests run with `ba | Docs completeness | `tests/docs_completeness.bats` | every compose service has a docs page; index links every page | | Script syntax | `tests/scripts_syntax.bats` | `bash -n` clean, executable bits, shellcheck when available | | Deployment flow | `tests/deployment_flow.bats`, `tests/deployment_scoping.bats` | scoped dispatcher exists, targets are known, service plans isolate inference, Caddy ownership is guarded, and SSH reachability is checked (skips offline) | +| Quadlet units | `tests/*quadlet*.bats` | every unit is boot-persistent, self-healing, repo-provenanced, secret-free | +| E2E (browser) | `tests/e2e/` + `tests/e2e_scaffold.bats` | Playwright drives the live guard chain; the bats seam asserts structure and credential hygiene. See [[E2E Suite]] | ## Focused pre-commit testing diff --git a/serverAppConfigs-docs/index.md b/serverAppConfigs-docs/index.md index cf7b6fc..cd3b372 100644 --- a/serverAppConfigs-docs/index.md +++ b/serverAppConfigs-docs/index.md @@ -29,6 +29,7 @@ covers both workloads). - [[Storage Policy]] — bind mounts, data locations, ownership - [[Deployment Flow]] — service-scoped git deploy, target map, and health checks - [[Testing Policy]] — the test seams and how to run them +- [[E2E Suite]] — the Playwright suite that drives the live guard chain ## Dankserver Storage