UNPKG

@kontextmind/kxm

Version:

KXM local-first multi-agent orchestration and operator dashboard

87 lines (63 loc) • 4.99 kB
--- schema: "kxm.doc.v1" id: "ADR-0005" type: "adr" title: "Obscura is the default browser for Playwright" project: "kxm" status: "accepted" owner: "@operator" created: "2026-09-27" updated: "2026-09-28" authority: "decision" confidence: "verified" summary: "Playwright testing and verification connect to pinned Obscura v0.2.3 over CDP. Steel stays the browser for human takeover, MFA, and the live session viewer." tags: ["architecture", "decision", "browser", "obscura", "playwright", "cdp"] related: ["docs/adr/ADR-0002-browser-automation-steel-doks.md", "docs/adr/ADR-0007-steel-caddy-authentik.md", "docs/guides/browser-automation.md", "docs/kb/how-to-connect-playwright-to-obscura.md"] details: decision_drivers: - "Playwright tests must run without a Steel cluster or a Playwright-managed browser download" - "Local pages, including 127.0.0.1, must load in CI" - "Human takeover, MFA, and the live session viewer stay on Steel" supersedes: null superseded_by: null --- # ADR-0005: Obscura is the default browser for Playwright ## Status Accepted on 2026-09-27. This record does not supersede [ADR-0002](ADR-0002-browser-automation-steel-doks.md). [ADR-0007](ADR-0007-steel-caddy-authentik.md) is the current Steel deployment. Steel remains the browser for remote and hosted sessions, human takeover, MFA, and the live session viewer. ## Context Playwright in this repository had no config, dependency, or CI job. Skills told agents to attach to a Steel session with `chromium.connectOverCDP(STEEL_CDP_URL)`. That makes every UI test depend on a remote Steel deployment, and it launches a local browser when the CDP URL is missing. Obscura v0.2.3 is a headless Chromium build that speaks the Chrome DevTools Protocol on loopback. Playwright can attach with `chromium.connectOverCDP()`. It does not speak Playwright's own protocol (`chromium.connect`, `use.connectOptions`). Loading `127.0.0.1` requires `--allow-private-network`. Video recording is unsupported. ## Decision drivers 1. Playwright testing and verification need a default that runs on a developer machine and on `ubuntu-latest`. 2. A smoke test must assert a page served on `127.0.0.1`, so CI does not depend on the public internet. 3. Tests must not download Playwright's browser builds (`playwright install`). 4. Human takeover, MFA, and the live session viewer still need Steel's session API and viewer. ## Considered options 1. **Pinned Obscura over CDP, Steel only when `KXM_BROWSER=steel`.** 2. **Keep Steel as the Playwright default.** 3. **`playwright install` and `chromium.launch()` on the runner.** ### Option 1: pinned Obscura (chosen) - Good, because the launcher downloads one pinned Apache-2.0 archive and the smoke test talks to loopback. - Good, because `newContext()` still isolates pages, and screenshots work on the rendering build. - Bad, because video recording and full `storageState` are unavailable. - Bad, because Linux needs glibc 2.35 or newer, and a non-loopback bind needs `OBSCURA_CDP_TOKEN`. ### Option 2: Steel for every Playwright run (rejected) - Good, because one CDP path covers tests and takeover. - Bad, because tests then require a Steel deployment, an API key, and a network path that CI does not have. ### Option 3: Playwright's downloaded Chromium (rejected) - Good, because `chromium.launch()` needs no second binary. - Bad, because it is a second browser download, and it is the local browser the skills already tell agents to avoid. ## Decision `resolveBrowserCdpEndpoint()` returns the Obscura CDP URL (`OBSCURA_CDP_URL`, or `http://127.0.0.1:${OBSCURA_PORT:-9222}`). `KXM_BROWSER=steel` returns the existing Steel session URL from `formatCDPEndpoint()`. Any other `KXM_BROWSER` value throws. `scripts/obscura.mjs` downloads Obscura v0.2.3 for the current OS and architecture, checks the pinned sha256, and serves with `--allow-private-network`. `npm run e2e` ensures that server is ready and runs `playwright test`. The worker-scoped `browser` fixture connects with `chromium.connectOverCDP()`. `video` is `off`. ## Consequences - Playwright tests and verification use Obscura unless the operator sets `KXM_BROWSER=steel`. - Steel session create, release, takeover, and the session viewer are unchanged. - CI for this smoke test is `.github/workflows/e2e.yml` on `ubuntu-latest`. The `CI` workflow is on, and `CI / required` is a required check in `protect-main`. `Nightly` and `Real Pi smoke` stay disabled. This ADR does not enable them. - The `node --test` globs do not collect `test/e2e/`. ## Related - [ADR-0002: Self-hosted Steel on DOKS (superseded deployment)](ADR-0002-browser-automation-steel-doks.md) - [ADR-0007: Steel through Caddy and Authentik](ADR-0007-steel-caddy-authentik.md) - [Browser automation](../guides/browser-automation.md) - [How do I connect Playwright to Obscura?](../kb/how-to-connect-playwright-to-obscura.md) - [Environment variables and limits](../reference/configuration.md#browser-automation)