Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Playwright has two different snapshot mechanisms, and choosing the right one is the key to reliable tests. Use expect(page).toHaveScreenshot() (or a locator screenshot assertion) when you need to detect visual changes in rendered pixels. Use expect(value).toMatchSnapshot() when you need to compare serialized HTML, text, or other string/binary data. The first run creates a baseline; subsequent runs compare new output with that stored expectation.

Choose a visual snapshot or an HTML snapshot

“HTML snapshot” can mean two different things in a Playwright project:

  • Rendered visual snapshot: a PNG image of the page or an element. This catches layout, spacing, colors, typography, and visible content changes.
  • Serialized-content snapshot: a string or binary value such as page.content(). This catches markup and data changes, but it does not prove that the browser rendered the page correctly.

They answer different questions. A page can have identical HTML but look different because of fonts or CSS, while a visually identical page can contain harmless serialization changes such as attribute ordering. Treat them as complementary rather than interchangeable.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Capture and compare a rendered page

Page-level screenshot assertion

Put this test in a Playwright Test project:

import { test, expect } from '@playwright/test';

test('page visual baseline', async ({ page }) => {
  await page.goto('https://example.com');
  await expect(page).toHaveScreenshot('example.png');
});

On the first execution, Playwright writes example.png as the reference image. Later executions capture the page again and compare it with that file. The screenshot assertion waits for two consecutive screenshots to produce the same result before it compares the final image. That stabilization step helps avoid taking a baseline while the page is still changing.

#1 Best Overall
Sale
Philips 24 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 241V8LB
  • CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
  • INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
  • THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
  • WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
  • A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents

Capture only a component

For a focused regression test, assert on a locator instead of the entire page:

test('checkout summary', async ({ page }) => {
  await page.goto('https://example.com/checkout');
  await expect(page.locator('[data-testid="summary"]'))
    .toHaveScreenshot('checkout/summary.png');
});

A locator snapshot reduces unrelated failures caused by navigation, advertisements, or other parts of the page. Give the file a descriptive name that reflects the component and state being tested.

Capture serialized HTML with toMatchSnapshot()

When you need the DOM as serialized content, read it and pass the result to a generic snapshot assertion:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import { test, expect } from '@playwright/test';

test('serialized HTML snapshot', async ({ page }) => {
  await page.goto('https://example.com');
  const html = await page.content();
  expect(html).toMatchSnapshot('example.html');
});

toMatchSnapshot() accepts strings and binary data, so it can also compare a normalized API response, generated text, or another deterministic value. Normalize fields that are expected to change before asserting. Typical examples include timestamps, random IDs, rotating advertisements, and request-specific tokens.

test('stable article markup', async ({ page }) => {
  await page.goto('https://example.com/article');
  const html = await page.content();
  const stable = html
    .replace(/data-rendered-at="[^"]+"/g, 'data-rendered-at="固定"')
    .replace(/id="session-[^"]+"/g, 'id="session-normalized"');
  expect(stable).toMatchSnapshot('article.html');
});

Only normalize values whose variability is understood. Broadly removing attributes or sections can hide a real regression.

Rank #2
Philips 22 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 221V8LB
  • CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
  • 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
  • SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
  • INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
  • THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors

Generate, review, and update baselines

  1. Run the test once in the environment you intend to use for comparisons. Missing visual or generic snapshots are created as expectations.
  2. Review the generated files in version control. Commit them with the test so a code reviewer can inspect intentional UI changes.
  3. When a change is deliberate, run Playwright’s documented snapshot-update flow, --update-snapshots, then review every changed file.
  4. When a change is unexpected, fix the application or test data instead of updating the baseline.

A baseline is not automatically “correct” because a command generated it. It is a reviewed contract for a particular test, browser, and rendering environment.

Where Playwright stores snapshot files

By default, Playwright associates snapshots with the test file. You can organize them centrally with snapshotPathTemplate. A template can include the test file, project, and assertion kind, which helps separate screenshots, generic snapshots, and other expectation types.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
// playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
  snapshotPathTemplate: '{snapshotDir}/{projectName}/{testFilePath}/{arg}{ext}',
});

The exact template is a team convention. Keep names stable and descriptive, such as checkout/empty-cart.png or article.html; avoid names that depend on test order. If your project uses multiple projects or browsers, include the project in the path so expectations cannot silently overwrite one another.

Make rendering deterministic

Screenshot comparisons are sensitive to the environment. Playwright warns that the host operating system, browser version, browser settings, hardware, power source, headless mode, and other factors can alter rendering. A practical baseline policy is:

  • Pin the Playwright browser version used in CI.
  • Run comparisons in a consistent OS or container image.
  • Set an explicit viewport and use the same device settings for baseline and verification runs.
  • Use fixed test data and freeze or control time-dependent content.
  • Install the same fonts everywhere; a fallback font changes line wrapping and therefore many pixels.
  • Keep animations, carousels, and random content out of the assertion or disable them in test CSS.
  • Prefer one consistent headless/headed mode for both baseline creation and comparison.

These controls reduce noise; they do not make unrelated environments equivalent. If you intentionally change the browser or operating system, expect to review and possibly regenerate baselines.

Rank #3
Sale
Dell 24 Monitor - SE2426H - 23.8-inch FHD (1920x1080) 144Hz 1ms Display, in-Plane Switching (IPS) Technology, AMD FreeSync™, TÜV 3-Star 2X HDMI, Tilt
  • Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
  • Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
  • Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
  • In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
  • Ultra-thin bezels: Maximize your viewing experience with thin bezels.

Set comparison tolerances deliberately

Visual assertions expose three important controls:

  • threshold controls the per-pixel color-distance tolerance.
  • maxDiffPixels permits a fixed maximum number of differing pixels.
  • maxDiffPixelRatio permits a maximum fraction of differing pixels.
await expect(page).toHaveScreenshot('dashboard.png', {
  threshold: 0.2,
  maxDiffPixels: 100,
  maxDiffPixelRatio: 0.001,
});

Start strict. Identify the actual source of variance, correct it where possible, and then use the smallest allowance that reflects known rendering noise. A tolerance should have a review rule; otherwise a genuine layout or content regression can be accepted silently. Do not use thresholds to conceal unexplained differences.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Compare the two strategies before choosing one

Question Screenshot assertion Generic snapshot
What is verified? Rendered pixels, layout, and visible styling Serialized HTML, text, or binary content
Main noise sources Fonts, browser, OS, hardware, headless mode, dynamic content Markup serialization, generated IDs, timestamps, and other changing data
Review experience Image diff is visually intuitive Text diff exposes exact content changes
Scope Whole page or a locator Any string or binary value you provide
Best use Preventing visual regressions Locking down structure or generated output

Many mature suites use both: a small number of page or component screenshots for visual contracts, and focused generic snapshots for markup or generated data where an exact textual diff is more useful.

Common failures and fixes

The first run creates an unexpected image

This is normal: no expectation existed yet. Open the generated file, verify the page state, and commit it only after review.

Every run reports a different screenshot

Look for changing data, animations, delayed fonts, ads, random IDs, or an inconsistent environment. Freeze fixtures, wait for the relevant UI state, install matching fonts, and run the same browser and OS image. Do not immediately increase the tolerance.

The screenshot is taken before content appears

Wait for a meaningful locator or application state before the assertion:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Samsung 27" Essential S3 (S36GD) Series FHD 1800R Curved Computer Monitor
  • CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
  • SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
  • MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
  • KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
  • INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient
await page.goto('https://example.com');
await page.locator('[data-testid="results"]').waitFor({ state: 'visible' });
await expect(page).toHaveScreenshot('results.png');

The screenshot assertion’s stability check helps with in-flight rendering, but it cannot know that an application is still waiting for data if the page has already become visually stable.

HTML snapshots fail because of timestamps or IDs

Normalize only those known variable fields before calling toMatchSnapshot(). If the value is part of the behavior you intend to test, keep it and make the fixture deterministic instead.

A deliberate redesign produces a huge diff

Review the diff as a product change, confirm the test data and environment, then update snapshots deliberately. Updating expectations without reviewing them turns the test into a record of the new output rather than a guard against regressions.

Baselines are difficult to find or are overwritten

Adopt a snapshotPathTemplate that includes project and test-file identity, and use unique, stable assertion names. Check the resulting paths in version control before committing.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance, reliability, and cost considerations

Full-page screenshots and large serialized documents consume more time and storage than focused locators or selected DOM values. Prefer the smallest scope that proves the behavior. Keep expensive end-to-end visual checks focused on critical pages, and use component-level assertions for repeated UI patterns.

Best Value
Sale
Sceptre New 22-Inch Gaming Monitor, FHD 1080p, Up to 144Hz, HDMI, DisplayPort, Built-in Speakers, Machine Black (E225W-FW144 Series, 2026)
  • 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
  • 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
  • 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.

Reliability comes from controlling inputs rather than tolerating more output. Stable fixtures, pinned browsers, deterministic fonts, and explicit waits usually provide more value than a permissive pixel ratio. When a baseline changes, record why in the pull request so future reviewers can distinguish an intentional design change from environmental drift.

Or skip the browser setup

If you need a clean screenshot from a URL rather than a Playwright test baseline, ScreenshotNeo provides a single HTTP request. It accepts the consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. It also provides an MCP server for AI agents such as Claude and Cursor, with take_screenshot, get_page_info, and capture_pdf tools.

Use the API documentation at https://screenshotneo.com/docs/ for authentication and options. A basic call is:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

The same request in Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

And in Node.js:

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(`HTTP ${res.status}`);
const buffer = Buffer.from(await res.arrayBuffer());
require('fs').writeFileSync('shot.webp', buffer);

ScreenshotNeo supports PNG, JPEG, WebP, and PDF output; full-page capture with lazy images, CSS-selector element capture, dark mode, device presets or custom viewports, retina scale, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, configurable caching, signed links, asynchronous jobs with webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Its parameter names are compatible with those used by other screenshot APIs, which can simplify migration.

Every feature is included on every plan: 1,000 shots per month free with no card; Starter is $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000. Yearly billing gives two months free. Create a free ScreenshotNeo account to get 1,000 screenshots a month without a card.

Frequently Asked Questions

Can I snapshot a locator instead of the whole page?

Yes. Call toHaveScreenshot() on a locator to store and compare only that element’s rendered image.

Does toMatchSnapshot() compare screenshots?

No. It compares strings or binary data. Use toHaveScreenshot() for rendered screenshots.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should baselines be committed to version control?

Commit reviewed baselines with their tests so intentional changes and regressions can be inspected together.

What should I do after changing the browser version?

Re-run in the new pinned environment and review any differences before updating expectations.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.