Screenery

Home / Guides / Updating Playwright snapshots

playwright --update-snapshots, without the wrong-OS trap

--update-snapshots rewrites the screenshots your toHaveScreenshot assertions compare against. Run it on the wrong machine and CI fails on images that look fine. Here is what each mode writes, and three workflows that keep CI green.

What the flag writes

This guide calls the stored screenshots goldens. Playwright's docs call them snapshots. The flag takes a mode. These are from Playwright's CLI reference and TestConfig reference, checked October 2026:

You runModeWhat it writes
npx playwright test default Missing goldens only, and the tests that wrote them fail.
--update-snapshots changed Goldens that no longer match, plus missing ones. A bare flag means this mode. -u is the short form.
--update-snapshots=all all The golden of every assertion that runs, whether it matched or not.
--update-snapshots=missing missing Missing goldens only. Tests that only wrote one pass.
--update-snapshots=none none Nothing.

updateSnapshots in playwright.config.ts sets the same modes. The flag also updates toMatchSnapshot and toMatchAriaSnapshot expectations, not only screenshots.

Use the narrowest run that covers your change. Each of these rewrites less than the whole suite:

npx playwright test tests/checkout.spec.ts --update-snapshots
npx playwright test --grep "checkout" --update-snapshots
npx playwright test --project=chromium --update-snapshots

Prefer changed over all. A golden that still matches has nothing to update, and rewriting it only adds noise to the commit.

Look before you update

The flag accepts whatever the page renders now, including a bug. Run the tests without it first, and read the failures:

npx playwright test
npx playwright show-report

The HTML report shows each failed screenshot as expected, actual and diff. Update only when every diff is a change you meant. After the update, GitHub's pull-request view can compare the old and new PNGs side by side, so reviewers can check them too.

Stale files are never removed

Rename a test, or delete one, and its goldens stay in the folder. No mode removes them. Playwright closed the request to add that, #16582, as not planned in August 2026. To clean up, delete the snapshot folders and write them again. Do it in the same environment as CI, as described below:

find tests -type d -name '*-snapshots' -prune -exec rm -rf {} +
npx playwright test --update-snapshots=missing
git status

Files that git status now lists as deleted were orphans.

The wrong-OS trap

Playwright puts the operating system in each golden's file name. A golden written on a Mac and one written by a Linux CI runner are different files:

tests/checkout.spec.ts-snapshots/payment-form-chromium-darwin.png   ← your Mac writes this
tests/checkout.spec.ts-snapshots/payment-form-chromium-linux.png    ← CI reads this

So an update on a laptop fails in one of three ways:

Goldens are only valid in the environment that wrote them. Write them in the environment CI runs in.

A Playwright upgrade can change rendering too, because each release ships new browser builds. Update goldens in the same pull request that bumps @playwright/test.

Workflow 1: update in the CI image, on your machine

Run your CI job in Playwright's Docker image, pinned to the version in your package.json. Playwright's CI docs show the setup:

jobs:
  test:
    runs-on: ubuntu-latest
    container:
      image: mcr.microsoft.com/playwright:v1.64.0-noble
      options: --user 1001

Then update with the same image, from a bash shell in your repository:

docker run --rm --ipc=host --platform linux/amd64 \
  -v "$PWD":/work -v /work/node_modules -w /work \
  mcr.microsoft.com/playwright:v1.64.0-noble \
  bash -c "npm ci && npx playwright test --update-snapshots"

Workflow 2: let CI write them

If nobody should run Docker by hand, let a workflow you start yourself update the goldens and commit them to your branch. It runs on the same runner and setup as your tests:

name: update-snapshots
on:
  workflow_dispatch:

jobs:
  update:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: lts/*
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test --update-snapshots
      - name: Commit updated goldens
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git add -- '*-snapshots/*'
          git diff --cached --quiet || git commit -m "Update Playwright goldens"
          git push origin HEAD

Start it on your pull request's branch, from the Actions tab or with the GitHub CLI:

gh workflow run update-snapshots.yml --ref my-branch

Workflow 3: no goldens to update

Both workflows above still keep PNGs in git and still need someone to run an update. The other option is to stop committing goldens. Capture with page.screenshot(), and let the previous build be the baseline. With Screenery the loop looks like this:

  1. A pull request's build pushes its screenshots to @pr-12. Each PNG is graded against the same screenshot on the branch it merges into, or @latest.
  2. A comment on the pull request counts what changed and shows the changed screenshots first. With alertAbove set, the biggest changes are listed at the top. See Pull-request comments.
  3. Merging accepts the change. The build on the default branch moves @latest, and the next pull request is compared with it. See How @latest moves.

Only CI takes screenshots, so no laptop's OS or CPU is ever involved. There is no update step and no PNG to commit. It costs you three things:

If you keep your goldens, Screenery can still publish them from the default branch. Then @latest shows exactly what your tests accept. See Playwright goldens and Argos folders. The full workflow is in Playwright screenshots in GitHub Actions.

Next