Files
serverAppConfigs/serverAppConfigs-docs/Architecture/E2E Suite.md
T
Frank 2930431052 frank-small: repoint the deployer payload gate and unit seam at the Ornith-1.5-9B payload
The 17:47 Ornith-1.5-9B swap (77decb5) updated frank-small.env and
serve-frank-small.sh but left two consumers on the MiMo-Q6K paths:
deploy-remote.sh's LLM_SMALL_MODEL_FILE/LLM_SMALL_MMPROJ defaults (the
payload-existence gate checked files the unit no longer loads) and
frank_small_unit.bats (stubs + env assertion), which held the whole
bats suite red. Both now point at the Ornith-Q8 payload; docs updated
with the conditional frankbook e2e project.
2026-10-05 18:13:01 -07:00

4.4 KiB

type, description, tags, timestamp
type description tags timestamp
reference `tests/e2e/` drives the **live fleet** through a real browser: fresh contexts
architecture
e2e
homepage
2026-09-01

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 five 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/19-frankbook.spec.ts frankbook project: walks the six admin links that terminate on FrankBook-Pro (192.168.0.112) — conditional, see below
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/15 with an empty state.
  • frankbook — 19 with the admin state. Excluded from every default run: the *arr/qBittorrent links terminate on FrankBook-Pro, which sleeps when idle, and a sleeping Mac mini must never fail an unrelated deploy. The project joins only when E2E_INCLUDE_FRANKBOOK=1 (set by scripts/deploy.sh when a frankbook trigger path changed: tests/e2e/specs/19-frankbook.spec.ts, frankbook-pro/**, shared/homepage/services.json, or the dankclaw/Caddyfile serving the arr vhosts) or when an explicit --project argument names it. An 11-admin edit that touches the arr links must therefore be paired with a 19-frankbook run against an awake host before it is trusted live.

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

tests/e2e/run.sh                          # default set — frankbook project excluded
E2E_INCLUDE_FRANKBOOK=1 tests/e2e/run.sh  # default set + the frankbook walk
cd tests/e2e && npx playwright test       # ALL projects, frankbook included

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.