Skip to content

ci(playwright): run E2E in parallel and drop redundant browser install#488

Merged
turegjorup merged 3 commits into
release/3.0.0from
feature/playwright-ci-parallel
Jun 9, 2026
Merged

ci(playwright): run E2E in parallel and drop redundant browser install#488
turegjorup merged 3 commits into
release/3.0.0from
feature/playwright-ci-parallel

Conversation

@turegjorup

@turegjorup turegjorup commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

What

Speeds up the Playwright CI job — the slowest check on every PR — with four changes:

  1. 3 parallel workers on CI (playwright.config.ts, was the default 2). Sized to the 4-vCPU public-repo runner (one core for the browser/system).
  2. Propagate CI into the container (-e CI=true on docker compose run). docker compose run doesn't forward host env, so process.env.CI was undefined inside the container and workers/retries silently fell back to defaults — this flag is what actually enables workers: 3 and retries: 2.
  3. ipc: host on the playwright Compose service so parallel Chromium doesn't exhaust Docker's default 64 MB /dev/shm ("Target closed" crashes).
  4. Pre-pull images in parallel — a single up-front docker compose pull instead of on-demand pulls scattered serially across steps.
  5. Drop playwright install --with-deps — the pinned mcr.microsoft.com/playwright:v1.57.0 image already ships the matching browsers.

Measured before / after (total Playwright job)

Configuration Total
Baseline (release/3.0.0) ~257s (270/250/252)
3 workers + dropped install 225s
+ parallel pre-pull (final) 195s

~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: host verified 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 CI never reached the container. The real, measured win is ~1.3×; the parallel pre-pull contributed roughly half of it.

Non-goals (deferred)

retries kept at 2; no cross-runner sharding; no Playwright version bump; build/cache steps untouched. (A parallel pre-pull could also shave ~13–20s off the phpunit/doctrine/apispec jobs, which pull phpfpm+mariadb — a possible follow-up; the --no-deps jobs wouldn't benefit.)

🤖 Generated with Claude Code

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>
@turegjorup turegjorup self-assigned this Jun 9, 2026
turegjorup and others added 2 commits June 9, 2026 16:35
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>
@turegjorup
turegjorup merged commit 1cc39d1 into release/3.0.0 Jun 9, 2026
25 checks passed
@turegjorup
turegjorup deleted the feature/playwright-ci-parallel branch June 9, 2026 14:53
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.

1 participant