chore(skills): promote runbook skills to managed-skills; drop superseded SKILL.md
- 31 new managed skills (anubis/arr/authentik/hermes/freetoken/podman/llm-swap runbooks etc.) now tracked. - Removed superseded skills: omp_harness_config, peon_ping_integration (replaced by user-authored peon-ping-* managed skills), rocmfp4-strix-benchmark-orchestration. - New memory-root skills: niri_compositor_ops, omp_git_workflow, omp_model_config, quadlet-media-migration, homelab-service-triage, hermes-dankclaw-ops, frank-default-large-ops, caddy-auth-dns-playbook.
This commit is contained in:
1 parent
7be39d60dd
commit
9bfa0be85d
48 files changed
+1361
-42
No files matched your search
@@ -0,0 +1,46 @@
|
||||
---
|
||||
name: authentik-flow-ui-automation
|
||||
description: Drive the authentik two-stage login through real browser UI for E2E tests on Anubis+outpost-guarded routes; hardened against the Lit stage re-render race and Anubis PoW budgets
|
||||
---
|
||||
|
||||
Drive authentik's two-stage login (identification → password) through a real browser UI for E2E tests on routes guarded by the Anubis + Authentik chain (Caddy → Anubis :8923 → outpost :9000). Proven in `tests/e2e/lib/login.ts` (`akLogin`) against authentik 2026.x.
|
||||
|
||||
## Hard rules
|
||||
|
||||
1. **Fresh context per login.** Never reuse a context or page across logins, and never retry a failed login inside the same context — a half-finished flow poisons authentik's `pending_user` stage and the next login hangs on a "Continue as <user>" interstitial that never completes. Each login = new `browser.newContext()`.
|
||||
2. **Real Chrome UA.** Anubis denies obvious headless UAs; set `userAgent` to a real Chrome UA in `use:` (config-level) or `launchOptions`. Headless chromium + REAL_UA solves the PoW fine.
|
||||
3. **Shadow-DOM locators.** authentik stages are Lit web components; locate inputs with `page.locator('input[name=username]')` etc. (Playwright pierces shadow roots) — never `page.$`.
|
||||
|
||||
## The Lit re-render race (the big one)
|
||||
|
||||
The flow executor re-renders a stage right after mount. A programmatic `fill()` can succeed and then be WIPED by the re-render; the submit then POSTs an empty form ("This field is required") and `waitForURL` times out while the page still shows the password stage with an empty field.
|
||||
|
||||
Hardened sequence per stage:
|
||||
|
||||
```ts
|
||||
for (let attempt = 1; attempt <= 3; attempt++) {
|
||||
await page.fill('input[name=password]', pass);
|
||||
// VERIFY the value survived the re-render before submitting
|
||||
if ((await page.inputValue('input[name=password]')) !== pass) continue;
|
||||
await page.keyboard.press('Enter'); // native form path; avoids button re-render races
|
||||
try {
|
||||
await page.waitForURL(u => !u.pathname.includes('/if/flow/'), { timeout: 30_000 });
|
||||
return; // past this stage
|
||||
} catch { /* maybe wiped; retry */ }
|
||||
}
|
||||
throw new Error(`akLogin: stage never advanced after 3 attempts`);
|
||||
```
|
||||
|
||||
- Submit with **Enter**, not a button click — the button can be re-created between snapshot and click.
|
||||
- Verify-after-fill is the load-bearing step; without it you silently submit empty forms.
|
||||
- The identification stage has the same race; apply the same fill-verify-Enter there.
|
||||
|
||||
## Anubis PoW budgets
|
||||
|
||||
The first guarded-vhost hit in a fresh context runs an Anubis proof-of-work; on a cold/loaded box it can outlive default assertion budgets. Give title/URL asserts after `goto` 60 s budgets. With `COOKIE_DOMAIN` set fleet-wide (Anubis ≥ v1.27), every later guarded vhost in the same context skips the challenge (~0.5 s per vhost in the crawl specs).
|
||||
|
||||
## See also
|
||||
|
||||
- `serverAppConfigs-docs/Architecture/E2E Suite.md` — project layout, credentials model (`tests/e2e/.env.local`, git-ignored), run commands, gotcha list.
|
||||
- `serverAppConfigs-docs/Infrastructure/Anubis.md` — chain behavior, v1.27 gotchas (X-Real-Ip mandatory, DENY = HTTP 200 body).
|
||||
- `arr-auth-posture-probe` for non-browser API-posture checks of guarded routes.
|
||||
Reference in new issue
Block a user