How to Cache Playwright Browsers in GitHub Actions
Playwright downloads hundreds of megabytes of Chromium, Firefox, and WebKit on every fresh runner.
Cache ~/.cache/ms-playwright, keyed on the Playwright version from your lockfile, and only run --with-deps on a cache miss.
Steps
- Resolve the Playwright version (e.g. from package-lock.json) into the cache key.
- Cache
~/.cache/ms-playwrightwith that key. - Run
npx playwright install --with-depsonly when the cache missed. - Always run
install-depsso system libraries are present even on a hit.
Workflow
.github/workflows/e2e.yml
jobs:
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- uses: actions/cache@v4
id: pw
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-pw-${{ hashFiles('package-lock.json') }}
- if: steps.pw.outputs.cache-hit != 'true'
run: npx playwright install --with-deps
- if: steps.pw.outputs.cache-hit == 'true'
run: npx playwright install-deps
- run: npx playwright testGotchas
- Browser binaries are version-pinned; key on the Playwright version or you will run stale browsers.
- System dependencies are not cached, so still run
install-depson a hit. - Latchkey keeps the browser cache warm so e2e suites start cheaper and re-run flaky tests automatically.
Related guides
How to Run E2E Tests Against a Deployed Preview in GitHub ActionsRun end-to-end tests against a live per-PR preview deployment in GitHub Actions, gating the test job on the d…
How to Cache pip Wheels in GitHub ActionsCache the pip wheel cache in GitHub Actions, keyed on requirements files, so Python CI skips rebuilding and r…