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

Use Playwright Test’s screenshot assertions to compare each new browser rendering with an approved image. In a Next.js project, install Playwright, run the app in a controlled environment, capture important routes and states with expect(page).toHaveScreenshot(), commit the reviewed baseline images, and run the same tests in CI. A changed screenshot fails the test until you either fix the regression or intentionally approve the new baseline.

This approach complements functional tests: a functional assertion can confirm that a button works, while a visual assertion can detect a shifted layout, missing style, incorrect font, or unexpected responsive change.

What visual regression testing checks

A visual regression test renders a page in a real browser, captures an image, and compares it with a reference image. The reference represents an approved appearance. Playwright stores the reference when the snapshot does not yet exist; subsequent runs produce a pass when the rendering is within the configured tolerance and a failure when it is not. The failure includes actual, expected, and diff images for review.

Choose coverage deliberately. Start with revenue-critical pages, shared layouts, major responsive widths, authenticated and unauthenticated states, and UI states that have historically broken. You do not need a snapshot for every route and every possible state.

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.

Install Playwright in a Next.js project

Use the official example

Next.js provides a with-playwright example through create-next-app. It is the quickest route when starting a project because the test files and configuration are already wired for the example’s structure. Follow the current Next.js Playwright guide for the command that matches your package manager.

Add Playwright manually

For an existing application, run:

pnpm create playwright

The setup wizard creates a Playwright configuration, a test directory, and an example test. Accept the browser installation prompt, then inspect the generated files before adding your own projects, base URL, and scripts.

Keep the versions declared in your lockfile and install the browser binaries in every environment that runs the tests. A browser version change can alter antialiasing, fonts, layout metrics, and image output.

Run Next.js in a testable environment

Prefer production behavior for CI

The Next.js guide recommends testing production code when practical. Build and start the application, then execute Playwright:

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.
npm run build
npm run start
npx playwright test

This catches differences that only appear after compilation, server rendering, asset optimization, or production routing. For local iteration, a development server is convenient, but do not assume that a development rendering is identical to a production deployment.

Let Playwright manage the server

You can configure the webServer option so Playwright starts the app and waits for it before the first test. A minimal configuration is:

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  use: {
    baseURL: 'http://127.0.0.1:3000',
    trace: 'on-first-retry',
  },
  webServer: {
    command: 'npm run start',
    url: 'http://127.0.0.1:3000',
    reuseExistingServer: !process.env.CI,
  },
  projects: [
    { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
  ],
});

Build before invoking this configuration in CI, or use a separate command that performs the build and starts the server. If your start command needs environment variables, provide them in the CI job or the webServer entry.

Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

Write your first screenshot test

Create tests/home.spec.ts:

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

test('home page matches the approved design', async ({ page }) => {
  await page.goto('/');
  await expect(page).toHaveScreenshot('home.png', {
    fullPage: true,
  });
});

On the first run, Playwright creates the reference image in its snapshot directory. Review that image, commit it with the test, and treat it as versioned test data. On later runs, a changed rendering fails the assertion.

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

Capture one component instead of the whole page

Element screenshots are useful when the surrounding page contains intentionally changing content:

test('pricing card remains stable', async ({ page }) => {
  await page.goto('/pricing');
  const card = page.locator('[data-testid="pro-plan"]');
  await expect(card).toHaveScreenshot('pro-plan.png');
});

Add stable test IDs or selectors to components that are part of your visual contract. A locator that depends on generated class names is more likely to break for reasons unrelated to appearance.

Test responsive widths and browsers intentionally

Use Playwright projects for the widths and browser engines that matter to your users. For example, define separate projects for a desktop viewport and a mobile device. Each project has its own snapshot set, so a mobile change does not overwrite the desktop reference. Expand browser coverage only when it answers a real compatibility question; every additional permutation increases snapshot storage and review work.

Create deterministic screenshots

Screenshot comparisons are only useful when the same inputs produce nearly the same pixels. Rendering can vary by operating system, browser version, font availability, hardware, power source, and headless mode. Generate baselines and CI results in a consistent environment, ideally using the same container image and Playwright browser version.

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

Control application data

  • Use fixed fixtures or a test database for records, prices, and permissions.
  • Freeze or mock clocks when the UI displays dates, countdowns, or relative times.
  • Use deterministic image URLs and avoid random placeholders.
  • Stub rotating banners, advertisements, analytics-driven content, and remote APIs that are not part of the behavior under test.
  • Wait for the page state you actually need instead of relying on an arbitrary sleep. For example, wait for a key heading or loaded table.

Neutralize animations and volatile elements

Playwright supports a screenshot stylesheet through stylePath. Create tests/visual.css:

*, *::before, *::after {
  animation: none !important;
  transition: none !important;
  caret-color: transparent !important;
}

[data-visual-unstable] {
  visibility: hidden !important;
}

Apply it to an assertion:

await expect(page).toHaveScreenshot('dashboard.png', {
  fullPage: true,
  stylePath: 'tests/visual.css',
});

Prefer hiding or replacing only genuinely volatile regions. Do not hide a component merely because it is difficult to stabilize; that can conceal a real regression.

Wait for meaningful readiness

await page.goto('/dashboard');
await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
await expect(page.locator('[data-testid="orders"]')).toHaveAttribute('data-loaded', 'true');
await expect(page).toHaveScreenshot('dashboard.png', { fullPage: true });

Ensure web fonts have loaded before capture when typography matters. A late font swap can create a large diff even though the CSS is correct.

Choose comparison tolerance carefully

Playwright offers pixel and color tolerances for cases where tiny rendering differences are understood and acceptable. Set the smallest tolerance that removes known noise. Increasing a threshold until a failed change passes without inspecting the diff weakens the test and can hide a broken layout. Keep tolerance settings with the test so reviewers can see why they exist.

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

Review and update baselines safely

  1. Run the failing test locally or download its CI artifacts.
  2. Open the expected, actual, and diff images.
  3. Decide whether the difference is an unintended regression, an unstable test, or an intentional design change.
  4. Fix the application or test determinism issue when the change is not intended.
  5. When the change is intentional, update the reference with npx playwright test --update-snapshots.
  6. Review the updated image in the same pull request; never update snapshots blindly just to make CI green.

Store snapshots alongside the test code in version control. Include the image diff in pull-request checks so a reviewer can approve visual changes with the code that caused them.

Run visual tests in CI

A typical CI job should check out the repository, install dependencies from the lockfile, install Playwright browser dependencies, build the Next.js app, start it (directly or through webServer), and run npx playwright test. Upload the Playwright report and failure artifacts, including actual, expected, and diff images.

Use a fixed OS image and avoid running screenshot jobs on a mix of local machines. If you need multiple browser projects, make the matrix explicit and retain separate snapshot directories. Keep retries limited: a retry can help diagnose transient infrastructure failures, but it should not turn a nondeterministic screenshot into a passing test.

Async Server Components caveat

The Next.js testing overview, updated February 27, 2026, notes that some tools do not fully support async Server Components and recommends end-to-end testing over unit testing for those components for now. Browser-rendered Playwright tests are therefore a practical place to verify their final output. Recheck the current testing overview when your Next.js version changes.

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

Common failures and fixes

“Snapshot does not exist” on the first run

This is expected for a new assertion. Run it in the intended baseline environment, inspect the image, and commit the approved snapshot. Do not generate baselines on an unrepresentative laptop and immediately use them as the CI contract.

Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Large diffs after a harmless dependency update

Check the Playwright browser version, OS image, installed fonts, device scale factor, and headless mode. Pin versions and regenerate all affected snapshots in one reviewed change if the rendering change is intentional.

Only dates, ads, or animated regions differ

Replace those inputs with fixtures, freeze time, wait for a stable state, or hide the region with a narrowly scoped screenshot stylesheet. Keep the rest of the page visible so meaningful changes still fail.

Images are blank or intermittently missing

Wait for the image or its loaded state, use deterministic local fixtures, and verify that CI can reach required resources. Avoid depending on an external service whose response is outside the test’s control.

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

Tests time out before capture

Confirm that the production server started, the configured URL matches baseURL, and the CI job exposes required environment variables. Inspect the trace on the first retry and increase a timeout only after fixing startup or readiness problems.

A small intended change creates many failures

Shared CSS, fonts, layout primitives, or a global theme can affect many snapshots. Review the diff as a set, verify the new appearance at each viewport, and update references only after the change is approved.

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

Local Playwright versus hosted visual review

Local snapshots keep references in your repository and fit directly into Playwright’s browser workflow. You own the execution environment, storage, review process, browser matrix, and artifact retention. This is often the simplest starting point.

A hosted service can add centralized review, broader browser or responsive coverage, and a team-oriented approval workflow. Compare the current terms before committing because allowances and pricing change.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Approach Useful when Questions to check
Playwright screenshots You want repository-owned baselines and direct CI control How will you stabilize rendering, store artifacts, cover browsers, and review updates?
Percy visual testing You prefer hosted review and vendor-managed visual workflows What browser and responsive permutations are included, how is screenshot usage counted, and what are the current CI and review terms?
Chromatic for Playwright You want hosted review for Playwright-driven pages, especially alongside Storybook Which browsers, integrations, review features, and snapshot allowances match your workflow?

BrowserStack currently documents 5,000 free Percy screenshots per month, with unlimited users and projects; each browser and responsive-width rendering contributes to usage. Chromatic currently lists a free tier with 5,000 billed snapshots and Git/CI integrations. These are vendor-published plan terms, not independent performance measurements, so verify them on the linked pages before budgeting.

Or skip the browser setup

ScreenshotNeo provides a website screenshot API and MCP server when you need a rendered image or PDF without maintaining browser-launch code. A request can remove cookie-consent banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in headers. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

For API parameters and all 63 options, see the ScreenshotNeo documentation. Options include full-page or CSS-selector captures, dark mode, device presets or custom viewports, retina scale, PDF settings, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, TTL-based caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, usage reporting, and an OpenAPI specification.

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

The free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Sign up free for ScreenshotNeo before wiring it into a capture pipeline.

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

Frequently Asked Questions

Should visual snapshots replace unit or functional tests?

No. Keep functional assertions for behavior and use visual assertions for rendered appearance; the two catch different classes of defects.

Where should Playwright snapshot images live?

Keep the generated snapshot directories in version control next to the tests, using separate projects or directories when browser and viewport coverage differs.

When should I use a hosted service instead of repository snapshots?

Choose hosted review when centralized approvals, vendor-managed browser coverage, or a team workflow outweighs the simplicity and control of local Playwright artifacts.

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.