Skip to content

docs(claude-code): document executablePath wiring for every Playwright consumer (#91)#92

Merged
gatezh merged 1 commit into
masterfrom
playwright-wiring-completeness
Apr 30, 2026
Merged

docs(claude-code): document executablePath wiring for every Playwright consumer (#91)#92
gatezh merged 1 commit into
masterfrom
playwright-wiring-completeness

Conversation

@gatezh
Copy link
Copy Markdown
Owner

@gatezh gatezh commented Apr 30, 2026

What

Close the documentation gap that left @vitest/browser-playwright, direct playwright-core use, and agent-browser undocumented as Playwright entry points in the README. Plus an opportunistic Dockerfile fix that makes agent-browser reliably use the system chromium.

Why

A consumer (the project that filed #91) followed the README end-to-end — wired playwright.config.ts, set up init-plugins.sh, copied the skills — and then their storybook test suite failed at first run with a misleading message:

Executable doesn't exist at /home/node/.cache/ms-playwright/chromium_headless_shell-1217/chrome-linux/headless_shell
Looks like Playwright was just installed or updated.
Please run the following command to download new browsers:
    npx playwright install

The hint pointed at the wrong fix. The actual fix was wiring launchOptions.executablePath in vitest.config.ts — exactly what playwright.config.ts already does. The README only documented one Playwright entry point; this PR documents all of them, with copy-paste snippets, against the latest upstream APIs.

Closes #91.

Changes

  • claude-code/README.md — Playwright Strategy section

    • Replaced the single playwright.config.ts snippet with a per-consumer wiring matrix (table) covering: @playwright/mcp, @playwright/test, @vitest/browser-playwright, direct playwright-core / playwright, agent-browser.
    • Each consumer that needs wiring gets its own subsection with a pasteable snippet against the latest API:
      • @playwright/testuse.launchOptions.executablePath
      • @vitest/browser-playwrightplaywright({ launchOptions: { executablePath } }) (verified against PlaywrightProviderOptions in current vitest source; mergeConfig(viteConfig, …) form is canonical for Vite-based projects)
      • Direct chromium.launch({ executablePath }) for scripts/codegen
    • The vitest section calls out the misleading "Please run npx playwright install" symptom and the correct fix.
    • Added AGENT_BROWSER_EXECUTABLE_PATH=/usr/bin/chromium to the Dockerfile-set env-vars listing.
  • claude-code/.devcontainer/Dockerfile — default target only

    • Add AGENT_BROWSER_EXECUTABLE_PATH=/usr/bin/chromium to the existing ENV block. agent-browser is a Rust CLI with its own env-var family — PLAYWRIGHT_* vars are silently ignored. This is the canonical, documented agent-browser env var per the upstream README. Without it: agent-browser would auto-detect /usr/bin/chromium (works most of the time) or fall back to a Chrome-for-Testing download on first use (fails in firewall, wastes bandwidth elsewhere). Sandbox target is unchanged — agent-browser isn't installed there.
  • claude-code/.claude/skills/sandbox-playwright/SKILL.md

    • Path-picker table now covers @vitest/browser-playwright and direct playwright-core use alongside MCP and @playwright/test.
    • Discovery step Add comprehensive README for devcontainer-hugo-bun image #1 finds vitest.config.* alongside playwright.config.* (using two single-predicate find calls — safe across RTK's compound-predicate rejection).
    • "What NEVER works" gains a row for the misleading "npx playwright install" hint + the correct fix.
    • "Red flags" gains the same.
    • Maintainer footer broadened to enumerate the full env-var family including AGENT_BROWSER_EXECUTABLE_PATH.
  • claude-code/README.md — section heading

    • ### Optional: Claude Code skill for Playwright### Recommended: Claude Code skill for Playwright. The wiring matrix is now well-documented, but the skill encodes how Claude Code actually drives the wired-up entry points.
  • .github/workflows/build-claude-code.yml

    • Default-target verify command (both arches) now asserts \$AGENT_BROWSER_EXECUTABLE_PATH = /usr/bin/chromium. Sandbox lines unchanged.

Notes

The "150MB savings" was overstated — agent-browser's npm postinstall only downloads its Rust binary, not Chromium. Chromium download would only happen on first run; setting AGENT_BROWSER_EXECUTABLE_PATH prevents that fallback. The real wins are reliability (no first-run download attempt, works in firewalled sandbox without surprise) and explicitness (no implicit auto-detection).

API verification:

  • @vitest/browser-playwright PlaywrightProviderOptions { launchOptions?: Omit<LaunchOptions, 'tracesDir'>; ... } — verified current against vitest's source. playwright({ launchOptions: { executablePath } }) is the canonical 2026 form.
  • mergeConfig(viteConfig, …) — current, not deprecated for single-config setups.
  • chromium.launch({ executablePath }) — canonical Playwright BrowserType.launch() API.
  • AGENT_BROWSER_EXECUTABLE_PATH — verified canonical in agent-browser's official README (one of ~30+ documented AGENT_BROWSER_* env vars).

Pre-merge verification:

  • hadolint on the modified Dockerfile (clean)
  • YAML parse of the updated workflow (verifies bash -c will see correctly-quoted test commands)
  • Diff reviewed end-to-end

Why one PR, not many — issue #91 explicitly authorized bundling the agent-browser optimization and the skill update with the README expansion, since they're all consequences of the same Playwright-consumer-completeness pass. Splitting would mean three PRs against overlapping files for one logical change.

…t consumer (#91)

- README Playwright Strategy: replace the single playwright.config.ts
  snippet with a per-consumer wiring matrix (table) covering @playwright/
  test, @vitest/browser-playwright (incl. @storybook/addon-vitest),
  direct playwright-core / playwright use, and agent-browser. Each gets
  its own pasteable snippet. Includes the misleading "npx playwright
  install" symptom + correct fix for the vitest case.
- Dockerfile (default target): add AGENT_BROWSER_EXECUTABLE_PATH=/usr/
  bin/chromium so agent-browser shares the system chromium. agent-browser
  is a Rust CLI with its own env-var family; PLAYWRIGHT_* vars are
  ignored. Eliminates auto-detection ambiguity and prevents a Chrome-for-
  Testing download on first run (which would fail in firewalled setups
  and waste bandwidth elsewhere).
- README skills section: rename "Optional: Claude Code skill for
  Playwright" to "Recommended:" — the wiring matrix is now documented,
  but the skill encodes how Claude Code drives those entry points.
- sandbox-playwright SKILL.md: add @vitest/browser-playwright and direct
  playwright-core to the path-picker table; expand discovery step #1 to
  find vitest.config.* alongside playwright.config.* (RTK-safe single-
  predicate finds); add the "don't run npx playwright install" red flag
  + fix instruction; broaden the maintainer footer to enumerate the full
  env-var family (including AGENT_BROWSER_EXECUTABLE_PATH).
- CI verify: assert AGENT_BROWSER_EXECUTABLE_PATH is set to /usr/bin/
  chromium in the published default image (not added to sandbox — agent-
  browser isn't installed there).
@gatezh gatezh merged commit bddac20 into master Apr 30, 2026
8 checks passed
gatezh added a commit that referenced this pull request Apr 30, 2026
…pansion (#93)

The verify-command from #92 used `test "$AGENT_BROWSER_EXECUTABLE_PATH" = /usr/bin/chromium`. When GitHub Actions interpolates that string into `bash -c "..."`, the runner's bash expands `$AGENT_BROWSER_EXECUTABLE_PATH` from the **runner's** environment (where it's unset) before docker runs, leaving the container's bash to evaluate `test  = /usr/bin/chromium` — malformed, exit 2.

Replace with `printenv AGENT_BROWSER_EXECUTABLE_PATH | grep -qx /usr/bin/chromium`. No shell metacharacters in the substituted string, so the runner shell has nothing to expand; the entire command reaches the container's bash intact, and `printenv` reads the env var from inside the container.

Verified end-to-end against the published image — exits 0 with the expected env var, exits 1 if unset. The image's ENV instruction itself was correct (confirmed via `docker inspect`); only the CI verify step was broken.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Playwright Strategy section: enumerate every consumer that needs executablePath wiring

1 participant