ScreenshotNeo

BlogHow-to

Cypress Screenshot Testing: Capture and Compare Page Changes

Capture Cypress screenshots and compare them against approved baselines. Learn how to stabilize visual tests, review diffs, and troubleshoot failures.

By the ScreenshotNeo team4 October 20267 min read

Cypress can capture a page with cy.screenshot(), but that command does not compare the image with a previous run. To detect visual changes, capture a repeatable page state, compare it with an approved baseline using a visual testing integration, review the diff, and update the baseline when a change is intentional. Cypress supports this workflow through integrations; the comparison and baseline review come from the selected tool.

1. Capture a screenshot with Cypress

You can capture screenshots in both interactive and headless runs. Cypress saves screenshots to cypress/screenshots by default. During cypress run, it also captures screenshots automatically when tests fail; it does not automatically capture failed-test screenshots during cypress open.

// cypress/e2e/product.cy.js
describe('Product page', () => {
  it('captures the rendered product page', () => {
    cy.visit('/products/widget');
    cy.get('h1').should('contain.text', 'Widget');
    cy.screenshot('product-page');
  });
});

The assertion gives Cypress a meaningful condition to wait for before capture. cy.screenshot() is asynchronous and Cypress documents that it takes around 100 ms. Content may change before the capture completes, so establish the intended state first.

Capture one element

Call screenshot() on a command yielding a single DOM element to capture that element rather than the whole viewport:

cy.get('.product-card')
  .should('be.visible')
  .screenshot('product-card');

Capture a full page

cy.screenshot('product-page-full', { capture: 'fullPage' });

Full-page capture scrolls from top to bottom and stitches captures together. Fixed or sticky elements can appear multiple times in the stitched image. If the duplication makes the comparison noisy, capture the relevant element or viewport instead, or use the comparison tool’s supported ignore controls.

Configure screenshot behavior

Set Cypress configuration in cypress.config.js. For example, choose a different output directory and turn off automatic screenshots on test failure:

const { defineConfig } = require('cypress');

module.exports = defineConfig({
  screenshotsFolder: 'artifacts/cypress-screenshots',
  screenshotOnRunFailure: false,
  e2e: {
    baseUrl: 'http://localhost:3000'
  }
});

Keep automatic failure screenshots enabled when they help diagnose failed tests; disable them when your workflow does not need those files. Manual screenshots still work when automatic failure capture is disabled.

2. Add visual comparison and baseline review

A visual regression workflow needs more than image capture. In each run, drive the application to the state under test, capture an image or DOM snapshot, compare it with an approved baseline, inspect any difference, and approve a new baseline when the change is intentional. The comparison tool defines how it measures differences and whether a threshold causes a failure.

Choose an integration based on where rendering and comparison happen, browser and viewport coverage, full-page or component capture, baseline approval, region masking, support for Cypress end-to-end and component tests, CI and pull-request workflow, and compatibility with your Cypress version.

Integration Documented role in Cypress workflow
Applitools Eyes AI-assisted visual comparison, end-to-end and component support, cross-browser rendering, and root-cause analysis features.
Argos Captures screenshots during Cypress runs with CI and pull-request review and approval.
Chromatic Captures a UI archive during Cypress tests, then renders and diffs it in Chromatic’s cloud.
Happo Supports full-page and component snapshots rendered across multiple browsers and screen sizes.
LambdaTest SmartUI Captures through its SDK and compares across browsers and resolutions with configurable comparisons and a review dashboard.
Percy (BrowserStack) Uses cy.percySnapshot() to capture DOM snapshots, then renders across browsers and responsive widths in Percy’s cloud with review and approval.
Sauce Labs Visual Cypress documents an official plugin, automatic baselines, region ignoring, DOM capture, and review on the Sauce Labs platform.
SmartBear VisualTest Provides Cypress visual-regression commands for full-page, element, and multi-device captures with a review dashboard.
Wopee.io Integrates with Cypress and manages and reviews visual-validation baselines on its platform.

For local or community plugins, Cypress’s maintained directory has listed Visual Regression Diff and Cypress Image Snapshot, as well as hosted-service integrations. Package versions and Cypress compatibility change. Check the current directory and each package’s documentation before installing. The directory’s research-time metadata listed @frsource/cypress-plugin-visual-regression-diff@4.2.0 for Cypress 13 or later, @simonsmith/cypress-image-snapshot@11.0.0 for Cypress 15.10 or later, and Sauce Labs plugin 0.10.2 for Cypress 12–15. Treat these as a snapshot of the directory, not a current compatibility guarantee.

Cypress Cloud is an adjacent service for recorded test runs, artifacts, collaboration, UI coverage, and related CI features. Its role in those workflows does not by itself make it the baseline image-comparison tool.

3. Make screenshots repeatable

A useful visual diff depends on consistent inputs and rendering. Differences can come from an intended app change or from changing data, timing, fonts, browser versions, operating systems, display scaling, or other rendering conditions.

  1. Wait for the expected state. Assert that important content is present and visible before taking the snapshot.
  2. Fix the test data. Stub variable API responses with cy.intercept() and a fixture, then wait for the request.
  3. Use a consistent rendering environment. Keep the browser version, operating system, fonts, viewport, and display scaling consistent across runs where possible.
  4. Control animation. Cypress’s waitForAnimations and animationDistanceThreshold affect action commands; they do not stop an unrelated animation from being captured mid-motion. Disable or wait for animations explicitly when they affect the image.
  5. Handle third-party variation narrowly. Mask or hide uncontrollable content such as ads and third-party widgets if the selected comparison tool supports it. Prefer a small ignored region over loosening the comparison for the entire page.
  6. Choose the right capture size. Use element snapshots to isolate components and full-page captures when the page layout itself is what you need to validate.

Component tests can be a good fit for visual checks: they render a component in a controlled environment with a smaller surface area and controlled data, which can make a diff easier to diagnose.

4. Run visual checks in CI and review changes

  1. Run the Cypress test in the same browser and viewport used to establish the baseline.
  2. Let the integration compare the new capture with the approved baseline.
  3. Inspect the visual diff and determine whether it represents a bug, uncontrolled variation, or an intentional UI change.
  4. Fix the implementation or stabilize the test when the difference is unintended.
  5. Approve and commit or publish a replacement baseline through the integration’s documented workflow when the change is intended.

Keep baseline approval deliberate. A baseline is a reference for later runs; updating it without reviewing the diff can make a real regression harder to spot.

5. Troubleshoot common problems

Symptom Likely cause What to do
cy.screenshot() saves an image but the test passes despite a visual change The built-in command captures but does not compare with a baseline. Add a visual-testing integration that compares captures and manages baseline review.
Image differs between otherwise identical runs Dynamic data, timing, animations, browser or OS differences, fonts, or display scaling. Stub data, assert on the rendered state, control animation, and use a consistent rendering environment.
Full-page image repeats a header or floating control Full-page capture scrolls and stitches; fixed and sticky elements can appear multiple times. Capture a smaller region or element, or use an integration’s ignore controls if available.
Screenshot misses content that appears shortly afterward The page was captured before the expected state was ready, or it changed while the asynchronous screenshot command completed. Wait on a functional assertion or the relevant request before capture.
No automatic failure screenshot appears in interactive mode Cypress does not automatically take failure screenshots during cypress open. Call cy.screenshot() manually, or reproduce in cypress run if you need Cypress’s automatic failure capture.
Automatic failure screenshots are missing in headless runs screenshotOnRunFailure may be set to false. Enable it in Cypress configuration if automatic failure captures are desired.
A visual plugin fails after a Cypress upgrade The installed plugin may not support the current Cypress version. Check the current Cypress plugin directory and package documentation, then select a compatible release.
A baseline change causes unexpected widespread diffs The baseline may have been captured with a different browser, viewport, font set, or rendering environment. Align the capture environment and review whether the baseline should be regenerated.

6. Performance, reliability, and cost

Every capture and comparison adds work to the test run and, for hosted services, may add service usage or plan costs. The research sources do not establish comparable prices or a universal performance ranking, so estimate using your own test suite and each provider’s current pricing.

  • Start with key pages, states, and shared components rather than snapshotting every test. This keeps the review queue focused.
  • Use element-level checks where a component is the unit of concern; use full-page images when broad layout is the requirement.
  • Keep screenshots and baselines reproducible by fixing data, viewport, and rendering environment.
  • Include baseline review and storage or hosted-rendering needs when comparing service costs. Verify current plan limits and supported Cypress versions with the provider.
  • Retain Cypress failure screenshots when they help diagnose test failures; otherwise configure their capture behavior to suit your artifact and CI workflow.

Or skip the browser setup

If you need a clean screenshot of a live page rather than a Cypress visual regression test, ScreenshotNeo provides a website screenshot API and MCP server. One request returns an image or PDF; it does not replace Cypress baseline comparison.

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

See the ScreenshotNeo API documentation for request options. Cookie banners are accepted and removed before the shot, along with known newsletter popups and chat widgets. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers identify the page verdict and whether it was billed. An MCP server lets AI agents use screenshot, page-info, and PDF tools. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.

Sign up free for 1,000 screenshots a month, with no card required.

FAQ

Does cy.screenshot() perform visual regression testing by itself?

No. It captures an image; use an integration to compare it with a baseline and review changes.

Can Cypress take a screenshot of one component?

Yes. Call screenshot() on a Cypress command that yields a single element, such as cy.get('.post').screenshot().

Should every test have a visual snapshot?

Usually, focus on important states, shared components, and key pages. A smaller, intentional set is easier to keep stable and review.

Does Cypress Cloud provide the baseline comparison described here?

The documented role cited here for Cypress Cloud is recorded runs, artifacts, collaboration, UI coverage, and related CI features. Select a visual-testing integration for baseline comparison and approval.