ci(playwright): run E2E in parallel and drop redundant browser install#488
Merged
Conversation
The Playwright job ran single-threaded on CI despite the public-repo runner having 4 vCPUs, and reinstalled browsers on every run even though the pinned mcr.microsoft.com/playwright image already ships them. - playwright.config.ts: use 3 workers on CI (was 1). Tests mock all network traffic per page (assets/tests/**/test-helper.js), so they are isolated and safe to run in parallel. - docker-compose.yml: add `ipc: host` to the playwright service so parallel Chromium does not crash on Docker's default 64 MB /dev/shm. - .github/workflows/playwright.yaml: drop `playwright install --with-deps`; the image's bundled browsers already match @playwright/test, so it only re-ran apt for libraries already present. Retries, the build/cache steps and Playwright versions are unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The first attempt set workers:3 but CI still ran 2 (Playwright's default for a 4-core box) — `docker compose run` doesn't forward host env, so process.env.CI was undefined inside the container and the CI branch of both `workers` and `retries` never triggered (a pre-existing gap: the baseline was already running the default, not 1 worker). Pass `-e CI=true` explicitly, matching how the local verification invokes it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Each image was pulled on demand inside the first step that used it, serially across steps — measured ~90s total on the runner (mariadb+phpfpm during Composer install, node during Build assets, nginx+playwright during Run playwright). Pull them all up front in one `docker compose pull`, which pulls services concurrently, overlapping the smaller images under the large playwright pull. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Speeds up the Playwright CI job — the slowest check on every PR — with four changes:
playwright.config.ts, was the default 2). Sized to the 4-vCPU public-repo runner (one core for the browser/system).CIinto the container (-e CI=trueondocker compose run).docker compose rundoesn't forward host env, soprocess.env.CIwas undefined inside the container andworkers/retriessilently fell back to defaults — this flag is what actually enablesworkers: 3andretries: 2.ipc: hoston theplaywrightCompose service so parallel Chromium doesn't exhaust Docker's default 64 MB/dev/shm("Target closed" crashes).docker compose pullinstead of on-demand pulls scattered serially across steps.playwright install --with-deps— the pinnedmcr.microsoft.com/playwright:v1.57.0image already ships the matching browsers.Measured before / after (total Playwright job)
release/3.0.0)~257s → 195s, ≈ 1.32× faster end-to-end, suite green with 3 workers and 0 flaky on CI.
Step-level (baseline → final): a new 35s parallel pull replaces ~88s of serial on-demand pulls; Composer install 38s→11s, Build assets ~40s→21s, Run playwright 168s→107s.
Why it's safe
Every test mocks all network traffic per page (
assets/tests/**/test-helper.js); no shared mutable backend state —workers: 1/default was a pure throttle, not isolation.ipc: hostverified working (/dev/shm= 12G, zero "Target closed" on CI).Note on the original estimate
The plan predicted ~2.5–3×, computed against a 1-worker baseline — but CI was already running 2 workers (Playwright's default) because
CInever reached the container. The real, measured win is ~1.3×; the parallel pre-pull contributed roughly half of it.Non-goals (deferred)
retrieskept at 2; no cross-runner sharding; no Playwright version bump; build/cache steps untouched. (A parallel pre-pull could also shave ~13–20s off thephpunit/doctrine/apispecjobs, which pull phpfpm+mariadb — a possible follow-up; the--no-depsjobs wouldn't benefit.)🤖 Generated with Claude Code