How to Compare Website Screenshots on Linux CI Without Font Differences
Compare screenshots reliably in Linux CI by pinning the container, Playwright and browser versions, fonts, and capture settings used to create your baselines.
To avoid font differences in Linux CI screenshot comparisons, create and compare baselines in the same pinned Linux environment. Keep the container image, Playwright release, browser binaries, installed fonts and fallbacks, browser mode, viewport, device scale, and screenshot settings aligned. A container helps control the environment, but matching container tags, browser versions, fonts, and capture settings still matters. Playwright warns that rendering can vary with the host OS, version, settings, hardware, power source, headless mode, and other factors, and recommends running tests in the environment where the baseline was generated. Playwright: Visual comparisons
This guide uses Playwright Test on Linux. It covers the setup, baseline workflow, font and rendering controls, diff policy, troubleshooting, and ways to inspect a page screenshot when you need to diagnose a mismatch.
1. Choose the Linux environment your baseline represents
If CI on Linux is the rendering target, generate and review the canonical baseline in the same Linux image used by CI. A macOS or Windows screenshot is not a universal pixel baseline: platform and font differences can change rendering. If your project deliberately tests multiple operating systems or browsers, create and review separate snapshots for each project/platform combination.
There are two common ways to provide a stable Linux environment:
| Approach | What you control | Trade-off |
|---|---|---|
| Use an official Playwright Docker image | Linux distribution, installed system dependencies, and browser build when the image tag is pinned | You maintain the image tag and rebuild it deliberately when upgrading. |
| Install dependencies on the CI runner | Browser and system dependencies installed through Playwright’s CLI; the runner still determines the base OS and other environment details | Less container management, but more reliance on runner configuration and maintenance. |
Playwright supports both its Docker image and installing dependencies with the CLI. Its CI documentation describes containers as useful for keeping environments consistent, including visual regression across platforms. Playwright: Continuous Integration
2. Pin Playwright and its browser binaries
Commit the package lockfile and install dependencies reproducibly with npm ci. Use a Docker image tag that corresponds to the Playwright package version in that lockfile; avoid floating tags for baseline creation and comparison. Playwright browser binaries are specific to Playwright releases, so upgrade the package and image as a coordinated change, then intentionally regenerate and review baselines if rendering changes. Playwright: Browsers
A minimal project setup:
npm init playwright@latest
npm ci
npx playwright install --with-deps chromium
npx playwright test
For a container-based CI job, use the official Playwright image tag matching your package version, then install project dependencies from the lockfile and run the tests. The following illustrates the commands inside that pinned image; replace the image tag in your CI configuration with the version matching the installed package.
npm ci
npx playwright test
If you install only Chromium dependencies on a Linux runner, Playwright documents these commands:
npx playwright install-deps chromium
# Or install the browser and its system dependencies together:
npx playwright install --with-deps chromium
See the official Playwright installation guide and CI guide for the current setup details.
3. Control fonts and fallbacks
Make the intended font files and their installation part of the versioned image or build configuration. Include fonts used by the page and the fallback fonts that may be selected when a requested font is unavailable. Check that the CI image contains the files your application expects and that the rendered page actually resolves to those fonts.
Playwright’s documentation identifies fonts and platform differences as causes of screenshot variation, but does not prescribe a universal font package list or font verification command. Font selection is application-specific, so record the fonts and installation steps your project requires and validate them in the pinned image.
4. Make the page state and capture settings repeatable
A matching font environment is only one part of repeatable screenshots. Keep the following capture conditions consistent between baseline generation and CI:
- Browser project and browser mode, including headless mode.
- Viewport size and device scale factor.
- Locale, color scheme, and other settings that affect page rendering.
- Application state, test data, and any content that changes over time.
- Screenshot options, including full-page behavior and any masks or styles used to hide volatile content.
Wait for the application to reach the intended state and for its web fonts to be available before capture. Choose a readiness condition that matches the page and test; there is no single universal font-readiness setting prescribed by the cited Playwright pages. Stabilize animations or dynamic content when they are not part of what the test is meant to verify.
Playwright’s visual assertion captures repeatedly until two consecutive screenshots match. Screenshot options also let you mask volatile elements with a stylesheet. Use those controls to manage known page variation, while keeping the screenshot representative of the behavior under test. Playwright: Visual comparisons
5. Generate, review, and update baselines deliberately
- Run the test in the pinned Linux environment used by CI.
- Create the initial baseline there, or review an existing baseline against a capture from that same environment.
- When CI reports a mismatch, inspect the expected image, actual image, and diff before changing the baseline or tolerance.
- If you upgrade Playwright, its image, browser binaries, fonts, or capture settings, treat the change as a possible rendering change. Recreate and review the relevant baselines intentionally.
- For multi-platform coverage, keep a matching reviewed baseline for each platform/browser project rather than sharing one image across them.
Playwright names snapshots with browser and platform information and supports project-specific visual comparisons. The baseline represents the environment and browser that produced it; reviewing updates is part of keeping that baseline meaningful. Playwright: Visual comparisons
6. Set a diff policy that catches real regressions
Start with strict screenshot comparisons, then inspect the actual, expected, and diff images for any failure. Playwright exposes pixel-difference options such as maxDiffPixels. If you set a nonzero tolerance, document which known rendering noise it accommodates and why that allowance still catches the changes your test is meant to detect.
A tolerance can make a test less sensitive to small changes, including real regressions. Mask or hide a region only when it is genuinely volatile and outside the behavior the test needs to cover. Do not normalize an unexplained mismatch by raising the threshold or updating the snapshot without understanding its cause. Playwright: Visual comparisons
7. Troubleshoot font and rendering mismatches
| Symptom | Likely cause | What to check or fix |
|---|---|---|
| Text wraps differently or glyph shapes change | A font or fallback differs, or the page did not use the expected font at capture time. | Check that the expected font files are installed in the pinned image and that the page has reached the state where its web fonts are available. Keep fallback fonts under build control too. |
| Many elements shift after a CI image update | The Linux image, system dependencies, or fonts changed. | Compare the baseline and CI image tags and build inputs. Restore the intended pinned image or deliberately review new baselines after the upgrade. |
| Only CI differs from a local screenshot | The local and CI operating systems, browser builds, headless modes, settings, or hardware differ. | Reproduce the baseline in the same pinned Linux environment as CI. Do not expect a cross-platform screenshot to pixel-match. |
| Visual tests fail after a Playwright upgrade | The browser binaries are tied to the Playwright release and may have changed with the upgrade. | Keep the package and official image/browser version aligned. Review the resulting diffs and update baselines intentionally if the new rendering is accepted. |
| Intermittent diffs in otherwise stable pages | Dynamic content, animation, delayed loading, or other changing page state affects capture. | Wait for the intended state, stabilize irrelevant animation or dynamic regions, and mask only content that should not be compared. |
| Diffs continue despite matching fonts | Another capture condition differs, such as viewport, scale, browser mode, host settings, or application state. | Compare the full capture setup and runtime, not just installed fonts. Playwright lists host OS, settings, hardware, and headless mode among rendering variables. |
| A tolerance hides a mismatch but the cause is unclear | The allowed pixel difference is too broad or is being used to suppress an unexplained change. | Inspect the diff, remove or reduce the tolerance, and find the source of variation before accepting the comparison policy. |
8. Performance, reliability, and maintenance
Playwright recommends one worker in CI for stability unless a powerful self-hosted system supports parallelism. Start with that documented default, then make any parallel execution choice based on your CI environment and project needs. Playwright: Continuous Integration
Pinning reduces accidental environment drift but creates an intentional maintenance task: upgrade the Playwright package, matching browser image, and any controlled fonts together, then review visual changes. The reviewed sources do not provide a quantified speed or reliability gain for pinning, so treat environment consistency as a reproducibility practice rather than a performance claim.
9. Inspect a page screenshot when diagnosing a mismatch
Playwright visual assertions are the core comparison workflow. For a separate screenshot of a page while investigating a rendering issue, a browser screenshot API can be another useful diagnostic tool. ScreenshotNeo is a website screenshot API and MCP server by Yorker Media. It can capture a URL as PNG, JPEG, WebP, or PDF; its API supports viewport and device presets, full-page capture, custom CSS and JavaScript, waits, cookies, headers, and other capture controls. Use the same relevant viewport and page state when comparing a diagnostic capture. An API capture does not replace a baseline produced in your pinned Playwright CI environment.
Or skip the browser setup
If you need a quick diagnostic capture without setting up a browser locally, ScreenshotNeo returns a screenshot with one request. See the ScreenshotNeo API documentation for request options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`ScreenshotNeo returned HTTP ${res.status}`);
const shot = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(({ writeFile }) => writeFile('shot.webp', shot));
- Cookie banners, newsletter popups, and chat widgets are removed before the shot; each cleanup step can be turned off.
- Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed; response headers report the page verdict and billing status.
- An MCP server lets AI agents using Claude, Cursor, or another MCP client take screenshots.
- The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo and get 1,000 screenshots a month free, with no card.
Frequently asked questions
Can one screenshot baseline work across Linux, macOS, and Windows?
Use platform-specific baselines when you intend to validate more than one operating system. Rendering and fonts can vary by platform.
Does pinning the container guarantee identical pixels?
No. It controls important parts of the environment, but browser version, fonts, capture settings, page state, and other rendering variables must also be controlled.
Which exact fonts should I install?
That depends on the fonts your application uses and its fallback stack. The cited Playwright documentation does not prescribe a universal font package list.
Should I allow a pixel difference threshold?
Only when the inspected diff shows known noise that does not undermine the behavior being tested. Record why the tolerance is acceptable and keep it as narrow as practical.


