Skip to content

date: 2026-06-12 tags: [pest-browser, playwright, web-env, chromium, no-sandbox, session-start] status: active graduated_to:

Browser tests DO run in the root web container — the "dead end" was an incomplete install

Symptom — [[2026-06-11-pest-browser-no-local-run-in-root-container]] claimed local browser runs were impossible (Chromium refuses root without --no-sandbox; pest-plugin-browser has no launch-args knob). Verified false on 2026-06-12: the full tests/Browser suite passed in this web container — 21 tests, 135 assertions, ~22s.

Root cause (of the wrong claim) — Playwright's Node launcher adds --no-sandbox itself whenever chromiumSandbox !== true, and the option defaults to false (coreBundle.js: if (options2.chromiumSandbox !== true) chromeArguments.push("--no-sandbox"); docs). pest-plugin-browser never sets it, so root needs no knob at all. The observed hang was really the partially provisioned container: vendor/ missing pest-plugin-browser ([[2026-06-11-missing-browser-plugin-kills-pest-collection]], issue #411), node_modules missing playwright@1.60 (the plugin shells out to ./node_modules/.bin/playwright run-server), no Chromium binary, no built Vite assets.

Fix — the SessionStart hook (.claude/hooks/session-start.sh) now provisions all four, so a web session can verify UI out of the box. Manual recipe, if ever needed: COMPOSER_ALLOW_SUPERUSER=1 composer installnpm cinpx playwright install chromiumnpm run build, then run COMPOSER_ALLOW_SUPERUSER=1 composer test:browser (composer hard-aborts as root without that env var). Rebuild assets after JS/Vue edits — browser tests drive the built bundle, not HMR.

Guard — the hook + the Browser-tests row in CLAUDE.md's Commands table. Never conclude UI changes are unverifiable in a web session. Two residual traps: a killed/hung run can orphan a playwright run-server process — kill it before retrying; and pest-plugin-browser genuinely has no launch-args passthrough (open upstream: pest#1556) — irrelevant for sandboxing, only matters if some other Chromium flag is ever needed. CI stays available as independent proof: dispatch frontend.yml on the branch ([[2026-06-10-workflow-dispatch-on-default-branch]]).