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

In Playwright, a screenshot is an image of rendered pixels; a snapshot is saved expected data used for a later comparison. The terms overlap because a screenshot used for visual regression is often called a “screenshot snapshot” or baseline. Choose the assertion by the artifact you need to verify: toHaveScreenshot() for pixels, toMatchSnapshot() for text or other values, and toMatchAriaSnapshot() for the accessibility tree.

Screenshot vs. snapshot: the short answer

A Playwright screenshot is the capture operation itself: the browser renders a page or locator and Playwright writes an image such as PNG. A snapshot is an expected representation retained by the test suite so a later run can compare current output with it. A snapshot can contain text, arbitrary binary data, or an accessibility-tree description; it does not have to be an image.

That means the words are not opposites. A visual-regression test captures a screenshot and stores the approved image as its snapshot (also called a baseline). The distinction is clearer when you look at the API name and the data type being compared.

What you want to verify Playwright API Compared artifact
Visual appearance expect(page).toHaveScreenshot() or a locator equivalent Rendered image pixels
Text, JSON, or other serialized/binary output expect(value).toMatchSnapshot(name) Stored value or file contents
Semantic accessibility structure toMatchAriaSnapshot() Roles, accessible names, hierarchy and related accessibility information

What toHaveScreenshot() actually does

await expect(page).toHaveScreenshot() is a Playwright Test visual assertion. The test runner captures screenshots until two consecutive captures match, then compares the final image with the expected reference. This settling behavior helps avoid asserting while a page is still changing.

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

If no baseline exists, the first run creates one. Subsequent runs compare the newly rendered image with that approved file and report visual differences. You review an intentional change and update the baseline deliberately; an unexpected difference is a test failure to investigate.

Page and locator screenshots

A page assertion checks the whole page viewport (or the configured screenshot scope). A locator assertion narrows the comparison to one component, which is useful when a full page contains animations, timestamps or unrelated content.

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

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

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

The locator example above contains a typo if copied literally; use the balanced form below in real code:

await expect(page.locator('[data-testid="payment-form"]'))
  .toHaveScreenshot('payment-form.png');

Run visual tests through the Playwright test runner, for example:

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

Do not confuse this assertion with calling page.screenshot() directly. The latter is a capture method that writes an image; it does not, by itself, compare the image with an approved baseline.

What toMatchSnapshot() compares

expect(value).toMatchSnapshot(name) is the general snapshot assertion. The value can be text, a serialized object, or arbitrary binary data. Playwright stores the expected representation and compares later runs with it.

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

test('API response shape stays stable', async ({ request }) => {
  const response = await request.get('https://example.com/api/profile');
  const body = await response.json();
  expect(body).toMatchSnapshot('profile.json');
});

You can technically place screenshot bytes in a generic snapshot, but Playwright’s snapshot assertion reference directs page-visual comparisons to toHaveScreenshot(). That specialized API communicates intent and handles visual capture and settling for you.

What toMatchAriaSnapshot() means

An ARIA snapshot is neither a bitmap nor ordinary text copied from the DOM. It describes the accessibility tree: roles, accessible names, hierarchy and related accessibility information. toMatchAriaSnapshot() lets you detect a semantic or accessibility regression even when the pixels still look acceptable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
test('navigation remains accessible', async ({ page }) => {
  await page.goto('https://example.com');
  await expect(page.getByRole('navigation')).toMatchAriaSnapshot();
});

Use this assertion when the contract is how assistive technology perceives the interface. Use a visual assertion when spacing, colors, typography or visual composition are the contract.

Choosing the right assertion

Use a screenshot assertion for visual changes

  • Layout, spacing, alignment and responsive composition.
  • Colors, borders, typography and icon placement.
  • Visual regression checks for a page or component.

Use a generic snapshot for values

  • Rendered text or a stable serialized object.
  • API payloads and other structured output.
  • Binary data when a value-level snapshot is the intended contract.

Use an ARIA snapshot for semantics

  • Roles and accessible names.
  • Heading, landmark and control hierarchy.
  • Changes that affect keyboard and assistive-technology users without necessarily changing pixels.

Baseline creation, review and maintenance

The first successful visual run creates a reference image. Treat that file as a reviewed test artifact, not as an automatic record of whatever happened to render on a developer’s machine. When a change is intentional, inspect the diff, confirm the product requirement, and then update the baseline in the same controlled environment.

Keep baselines versioned with the test code and give them descriptive names. A name such as checkout-dark-mobile.png makes the viewport and mode explicit. Separate references for materially different projects, browsers or device configurations rather than silently overwriting one environment’s files with another’s.

Why identical code can produce different screenshots

Playwright’s visual-comparison guidance warns that browser rendering can vary with the host operating system, browser version, settings, hardware, power source (battery versus power adapter), headless mode and other factors. A baseline generated on one setup can therefore fail on another even when application code is unchanged.

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

Stabilize the rendering environment

  • Generate and compare baselines in the same operating-system image and browser version.
  • Use the same Playwright configuration, viewport, device scale and color scheme.
  • Run visual tests consistently in headless or headed mode; do not mix them casually.
  • Keep fonts and other rendering dependencies identical.
  • Prefer an always-on, reproducible CI environment over laptops that may switch power state.

When a diff appears, first decide whether the environment changed. Only after that check should you investigate CSS or application behavior. Updating a baseline to hide an environment drift weakens the test.

A practical Playwright visual-test workflow

  1. Define the visual boundary. Choose the page or a stable locator. Prefer a component when unrelated page regions are dynamic.
  2. Navigate and prepare state. Log in with test credentials, select the required theme or viewport, and wait for the state your user should see.
  3. Capture with the visual assertion. Call toHaveScreenshot(); the runner waits for two matching captures before comparison.
  4. Review first-run files. Inspect generated baselines as code-review artifacts. Confirm that they represent the intended state.
  5. Investigate failures. Compare the diff, verify browser and host consistency, then determine whether the change is a bug or an approved design update.
  6. Update intentionally. Regenerate only the affected baseline after review; do not accept all changes indiscriminately.

Common mistakes and fixes

“My screenshot test is not creating a baseline”

Ensure the test is running under Playwright Test and that the assertion is toHaveScreenshot(), not only page.screenshot(). Confirm the test process can write to its snapshot directory.

“Every CI run has a large image diff”

Check operating system, browser version, fonts, viewport, device scale, headless mode and power conditions. Recreate the baseline in the same environment used for comparison, as Playwright documents these factors as rendering variables.

“The screenshot catches a loading spinner”

Wait for a stable application state before asserting. A locator-based screenshot can also exclude unrelated dynamic regions. The assertion’s consecutive-capture settling does not replace application-specific readiness checks.

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

“A generic snapshot passed, but the page looks wrong”

A value snapshot verifies the value you supplied, not the page’s pixels. Replace it with toHaveScreenshot() for visual behavior, or add a separate visual assertion.

“The page looks fine, but accessibility broke”

Add an ARIA snapshot assertion. Pixel comparisons cannot reliably detect a changed role, accessible name or hierarchy when the visual design remains the same.

“The test is brittle because the whole page changes”

Narrow the assertion to a stable locator and isolate volatile data in test fixtures. Keep the visual boundary aligned with the behavior you actually want to protect.

Performance, reliability and cost considerations

Visual assertions do more work than a single image write: they capture, wait for consecutive matching images and compare against stored data. Component-level assertions can reduce the amount of changing content and make failures easier to review. Generic and ARIA snapshots are usually smaller artifacts, but they answer different questions and should not replace a needed pixel check.

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

For reliable suites, prioritize deterministic test data, stable fonts and a pinned browser environment. A fast but inconsistent visual test creates review noise; a slightly slower test that fails only for meaningful changes is more useful.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server when you need an image without maintaining a Playwright browser environment. One GET request returns PNG, JPEG, WebP or PDF. Before capture it accepts cookie and consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets; each 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 Claude, Cursor and other MCP clients, with take_screenshot, get_page_info and capture_pdf tools. Every plan includes the feature set: full-page captures with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets or a custom viewport, retina scale, PDF paper and page controls, HTML/CSS-to-image, custom JavaScript and CSS, pre-capture clicks, hidden selectors, waits for a selector, delay or network idle, blocking for ads, trackers, requests or resource types, custom headers/cookies/user agent/Authorization, timezone and geolocation, transparent backgrounds, resizing, selectable-TTL caching, signed links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API and an OpenAPI specification.

Parameter names used by other screenshot APIs also work, which can simplify migration. The free plan includes 1,000 shots per month without a card. Paid plans are Starter $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.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

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

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

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)

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}`);

See the ScreenshotNeo documentation for request options and response handling. If you want the free allowance, create an account at ScreenshotNeo’s free sign-up: 1,000 screenshots per month, no card required.

FAQ

Is a Playwright screenshot automatically a snapshot?

No. An image written by page.screenshot() is simply a screenshot. It becomes a snapshot in the testing sense when retained as expected data for a later comparison.

Can snapshots test accessibility?

Use toMatchAriaSnapshot() for an accessibility-tree representation. A generic value snapshot and a visual screenshot answer different questions.

Should baselines be generated locally?

They can be, but comparisons are most reliable when generation and test execution use the same controlled environment, including OS and browser conditions.

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

Frequently Asked Questions

Is a Playwright screenshot automatically a snapshot?

No. An image from page.screenshot() is a capture; it is a snapshot only when stored as expected data for comparison.

Can snapshots test accessibility?

Yes. Use toMatchAriaSnapshot() for the accessibility-tree structure rather than pixels.

Should baselines be generated locally?

They can be, but matching the operating system, browser and rendering conditions used in comparison gives more reliable results.

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.

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