ADR 0003 — Playwright + Chromium for the agent¶
- Status: Accepted
- Date: 2026-04-26
- Deciders: André Luiz Gallon
Context¶
The brief required real user navigation: the agent has to load not just HTML but also CSS, JavaScript, images, fonts and any third-party resources, while exercising real cookies, redirects and TLS handshakes.
A pure HTTP client (e.g. undici) cannot run third-party JavaScript or
fire load / DOMContentLoaded the way a browser does, and we need
those signals for the per-cycle metrics.
Decision¶
- The agent uses Playwright with the bundled Chromium.
- The runtime image is the official
mcr.microsoft.com/playwright:v1.49.1-noble, which already ships the required system libraries (libnss3,libasound2, etc.) and a matching Chromium build. - One Chromium per agent, reused across cycles, but a fresh
BrowserContextper cycle so cookies / cache / IndexedDB / service workers / DNS are wiped between runs. - A small browser pool keyed by
(httpVersion, host)lets HTTP/3 forcing (--enable-quic --origin-to-force-quic-on=…) coexist with default-protocol navigation.
Consequences¶
- ✅ Real Web Vitals, real TLS handshakes, real subresource fetches.
- ✅ Native HTTP/3 support via Chromium command-line flags.
- ⚠️ Each agent reserves ~300–500 MB of RAM; the practical ceiling is
~10–15 agents on a 16 GB laptop. Kubernetes
HorizontalPodAutoscalerscales to 300 on sized clusters. - ⚠️ Chromium occasionally hangs; mitigated by the per-target circuit breaker, the consecutive-failures Chromium sentinel, and graceful shutdown on SIGTERM.
Alternatives considered¶
- Puppeteer — works but has weaker multi-browser story and less active community.
- Headless Chrome via CDP directly — avoids Playwright but loses the
ergonomics for
BrowserContextlifecycle, Web Vitals helpers and device emulation (Pixel 7 mobile profile). - Headless Firefox / Webkit — inferior HTTP/3 support today.