Is there a way for GitHub Action to Cache the Playwright Browser Binaries?

💡
I've recently updated this as of 11/16/2022!

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/[email protected]
    - uses: actions/[email protected]
      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/[email protected]
      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/[email protected]
      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.

Example of the GitHub action run creating the cache
Example of GitHub action run utilizing the cache
Cache that is visible from GitHub actions page

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:

[Question]: How to cache on github actions? · Issue #7249 · microsoft/playwright
Hi, I've setup github actions on Linux and it works fine. I'm now running the same tests on MacOS and the binaries are not the same, so caching the installation is not working (for obvious ...