jest-image-snapshot CI vs local rendering mismatch in CI
Image snapshots that pass on a developer laptop can fail in CI because the two environments render differently: different OS font stacks, a different Chromium build, or a different device scale. The fix is to make baselines in the same container CI runs.
What this error means
Snapshots pass on macOS or Windows locally but fail in Linux CI. The diff shows fringing around all text and gradients rather than a discrete layout change, indicating an environment difference, not a code change.
# local: passes
# CI (linux container):
Expected image to match or be a close match to snapshot but was 2.87% different from snapshotCommon causes
Different OS and font rendering than the runner
The baseline was generated on macOS or Windows, but CI renders on Linux with different font hinting and anti-aliasing, so every glyph differs slightly.
A different Chromium/Puppeteer build
Local and CI use different browser versions, which can change how sub-pixel rendering and gradients are drawn.
How to fix it
Generate baselines inside the CI image
- Run the snapshot update inside the same Docker image CI uses (for example a Puppeteer image).
- Commit the regenerated
__image_snapshots__. - Re-run CI so it compares against baselines made in the identical environment.
docker run --rm -v $(pwd):/app -w /app \
ghcr.io/puppeteer/puppeteer:latest \
npx jest --ci --updateSnapshotPin fonts and browser version
Bundle the required fonts into the image and pin the browser version so local and CI rendering stay identical.
RUN apt-get update && apt-get install -y fonts-liberation fonts-noto-color-emojiHow to prevent it
- Always generate baselines in the same container CI uses.
- Pin the browser version across local and CI.
- Install the exact fonts the pages need into the image.