Is there a way for GitHub Action to Cache the Playwright Browser Binaries?
If you've ever run into a situation where you find that you are running your Playwright tests multiple times a day as a GitHub Action, you can save time and money by caching  the downloaded binaries.
To understand how Playwright installs and manages the browsers it's always a great idea to check the docs.
Reading you'll see the default location for each of these can be found in the below section.
Playwright downloads Chromium, WebKit and Firefox browsers into the OS-specific cache folders:
%USERPROFILE%\AppData\Local\ms-playwright
on Windows~/Library/Caches/ms-playwright
on MacOS~/.cache/ms-playwright
on Linux
The below Github Actions YML file includes a section that creates a Cache and stores the playwright binaries so Github Actions doesn't have to re-download every single time the action runs. The trick here is to ensure the 'key' section which is currently set to Linux-playwright-1.27.1
get updated any time you update your version if playwright. This will 'invalidate the cache' and download the latest and playwright version and cache it under the new key.
For example if playwright version 1.28.0 was released, when I updated my package.json file to get 1.28.0 the cache key will automatically be updated to Linux-playwright-1.28.0
and this would download the latest version of playwright and cache it under the key value.
One other thing to note, the below line of code is important as it is what does the check to validate the cache is still valid or if it should be rebuilt.
if: steps.playwright-cache.outputs.cache-hit != 'true'
name: Playwright Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v2
with:
node-version: '16.x'
- name: Get installed Playwright version
id: playwright-version
run: echo "PLAYWRIGHT_VERSION=$(node -e "console.log(require('./package-lock.json').dependencies['@playwright/test'].version)")" >> $GITHUB_ENV
- name: Cache playwright binaries
uses: actions/cache@v3
id: playwright-cache
with:
path: |
~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }}
- run: npm ci
- run: npx playwright install --with-deps
if: steps.playwright-cache.outputs.cache-hit != 'true'
- run: npx playwright install-deps
if: steps.playwright-cache.outputs.cache-hit != 'true'
- name: Run Playwright tests
run: npx playwright test
- uses: actions/upload-artifact@v2
if: always()
with:
name: playwright-test-results
path: test-results/
Below are some screenshots from what it looks like in action from GitHub actions. Example repo can be found here.
In my testing, this will save time in your playwright test runs (at least 3 minutes). Though I did have a few days where the playwright install process was taking upwards of 8 minutes. This issue caused me to dive down this rabbit hole.
If you come up with any creative ways to utilize caching or you found this helpful, reach out and let me know on Twitter @butchmayhew  or consider buying me a cup of coffee.
Useful Links: