Skip to content

perf(ci): cache Playwright browsers in integration tests - #7286

Draft
maverbiest wants to merge 1 commit into
mainfrom
cache-playwright-browsers
Draft

perf(ci): cache Playwright browsers in integration tests#7286
maverbiest wants to merge 1 commit into
mainfrom
cache-playwright-browsers

Conversation

@maverbiest

@maverbiest maverbiest commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

🤖 Generated with Claude Code

What

Caches ~/.cache/ms-playwright in the integration-tests workflow so the Playwright browser binaries aren't re-downloaded on every run.

Why this key

The cache key is ${{ runner.os }}-playwright-<browser>-<playwright version>, and both variables are load-bearing:

  • Browser set — the jobs don't install the same browsers. The firefox job installs chromium firefox, while the chromium and cli jobs install chromium only. Sharing one key would
    let a chromium-only cache restore into the firefox job and leave firefox missing.
  • Resolved Playwright version, not a lockfile hash — browser builds are pinned to the Playwright version (1.62.1 currently ships chromium-headless-shell v1234 and firefox v1538), so that's the granularity that actually matters. integration-tests/package-lock.json changed 25 times in the last 90 days, essentially all dependabot bumps of things unrelated to
    browsers (eslint-plugin-unicorn, browserslist, @humanfs/node, brace-expansion); Playwright itself moved once, in chore(deps-dev): bump to playwright with new firefox version #7049. Keying on the lockfile would evict the browsers ~25 times a quarter to track ~1 real change, and would leave every one of those dependabot PRs starting cold. The version also makes the cache list readable at a glance (Linux-playwright-firefox-1.62.1) when something needs debugging.

The version is read from node_modules, so the resolve step has to run after npm ci — it sits directly above the cache step to keep that dependency visible.

What this saves, honestly

About 29s per job, not the couple of minutes you might expect from the step's total duration.

playwright install --with-deps spends most of its time on apt-level system dependencies (ffmpeg codecs, fonts), which live outside ~/.cache/ms-playwright and can't be cached this way. Breaking down the install step on a recent green run (34334463748):

job step total apt system deps browser downloads
chromium 1m16s ~46s ~29s
firefox 2m01s ~1m29s ~29s

So this is ~20-30s off a ~21m30s critical path — modest on its own. It's worth having mainly because the saving is per-job, so it scales if we shard the browser jobs across runners later.

Notes

  • playwright install is left unchanged. It's idempotent, so on a cache hit it skips the downloads by itself and just runs the system-dependency install; no conditional needed.
  • No restore-keys deliberately. A partial restore on a Playwright bump would leave the old browser version sitting in the directory next to the newly downloaded one and bake both into the next cache.
  • .github is excluded from yamlfmt (.yamlfmt.yaml), so there's no formatting check to satisfy here.

🤖 Generated with Claude Code

PR Checklist

  • All necessary documentation has been adapted.
  • The implemented feature is covered by appropriate, automated tests.
  • Any manual testing that has been done is documented (i.e. what exactly was tested?)

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