ScreenshotNeo

BlogGuides

Cypress Screenshot Review: Limits for Website Capture

Understand Cypress screenshot modes, failure captures, retries, and why a screenshot may not show the whole page or the exact failure state.

By the ScreenshotNeo team4 October 20268 min read

Cypress screenshots are debugging snapshots, not a continuous recording of a test. A viewport capture shows the current viewport; a full-page capture scrolls and stitches images; a runner capture includes the app and Cypress Command Log. Automatic failure screenshots in cypress run use runner mode. Capture timing, run mode, retries, and the selected mode explain many cases where an image does not show the whole page or the failure you expected.

1. Choose the capture mode that answers your question

Mode What appears Useful for Limit
viewport The application’s current browser viewport Inspecting what a user could see without scrolling Content outside the viewport is absent
fullPage The application page, captured while Cypress scrolls and stitched into an image Reviewing a long page in one artifact It is not one instantaneous frame; fixed and sticky elements need attention
runner The application viewport and Cypress Command Log Debugging a failed command with its surrounding runner context It does not show the whole page

The documented Screenshot API default capture type is fullPage. Set the mode explicitly when the distinction matters. Element screenshots ignore the capture setting. Cypress also forces automatic failure screenshots to runner mode. There is a documented exception when Test Replay is enabled and the Runner UI is hidden: runner capture shows the application in the current viewport without the Runner UI.

2. Take a manual screenshot

cy.screenshot() works in both cypress open and cypress run. For a viewport capture:

cy.screenshot('checkout-viewport', { capture: 'viewport' })

For a stitched full-page capture:

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

For an element capture, select the element and call the command on it. The capture mode does not control an element screenshot:

cy.get('[data-testid="checkout-summary"]').screenshot('checkout-summary')

Use a stable selector that identifies the intended element. If the selector matches more than one element or the element is not present, fix the selector or wait for the application state that creates it.

3. Configure screenshots in Cypress

Screenshot options can be supplied per call or configured for the run. The documented defaults include capture: 'fullPage', disableTimersAndAnimations: true, and scale: false. These defaults do not guarantee stable application rendering: data, fonts, images, and app-specific asynchronous work can still be changing.

// cypress.config.js
const { defineConfig } = require('cypress')

module.exports = defineConfig({
  video: false,
  screenshotOnRunFailure: true,
  trashAssetsBeforeRuns: true,
  screenshotsFolder: 'cypress/screenshots',
  e2e: {
    setupNodeEvents(on, config) {
      return config
    },
  },
})
Option or behavior What to know
capture Selects viewport, fullPage, or runner for ordinary screenshots. Element screenshots ignore it; automatic failure screenshots are runner captures.
scale Controls scaling; documented default is false. Set deliberately if output dimensions matter.
blackout Selectors to obscure in viewport captures. Blackout does not apply to runner captures.
disableTimersAndAnimations Documented default is true. It can help reduce animation-related variation, but does not freeze all app state.
screenshotOnRunFailure Automatic failure screenshots are enabled for cypress run by default. Set to false to disable them.
trashAssetsBeforeRuns Cypress clears the screenshots folder and nested files before a run by default. Set to false when earlier artifacts must persist.
screenshotsFolder Defaults to cypress/screenshots; change it if your artifact collection expects another path.

Confirm option names and defaults against the Cypress version used by your project. The configuration above uses documented option names; keep unrelated project configuration in place when adapting it.

4. Understand automatic failure screenshots and run mode

  • cypress run: Cypress automatically captures screenshots on test failures unless screenshotOnRunFailure is disabled.
  • cypress open: Cypress does not automatically take failure screenshots. Call cy.screenshot() explicitly when you need a manual artifact.
  • Storage: screenshots go to cypress/screenshots by default. Cypress can make CI screenshots available in Cypress Cloud; exporting them into a CI provider’s own interface depends on that provider.

Automatic failure captures use runner mode regardless of a requested capture mode. If you specifically need a full-page application image, add a manual screenshot at a point where the app is in the relevant state. A manual screenshot is not a replacement for the automatic failure artifact; give it a distinct name so both are easy to identify.

5. Account for capture timing and full-page stitching

Cypress documents that screenshotting is asynchronous and takes around 100 ms. The application can change before capture completes, and the Command Log may not have finished rendering. As a result, the screenshot may differ from the exact instant a failing command was issued or may omit the error text you expected.

Full-page mode scrolls from top to bottom, captures along the way, then stitches the images. Check your page for fixed headers, sticky controls, lazy-loaded content, and state that changes during scrolling. These are practical checks for your application; the result depends on how that page renders.

cy.screenshot() is not a retrying assertion: Cypress runs chained assertions once rather than retrying them. Establish the required application state before capture using the test’s normal assertions and waits. Do not use a screenshot command as proof that an asynchronous condition has completed.

6. Add video when a still image is inconclusive

Video is a separate artifact and is disabled by default. When enabled, Cypress records each spec during cypress run; it does not record specs in cypress open. A video can show sequence and timing around a failure that a still image cannot.

// cypress.config.js
module.exports = {
  video: true,
}

With --record, Cypress processes and uploads videos to Cypress Cloud after each spec. Recording and uploading are separate workflow choices. Cypress documents configuration to remove videos for specs without retries or failures, which can reduce retained artifacts; check the current configuration reference for the exact option supported by your version.

7. Inspect retries and preserve the artifact you need

With test retries enabled, Cypress can save screenshots for failed attempts. Later attempt screenshots include an (attempt n) suffix. When investigating a flaky test, inspect the artifact for the attempt that failed, as well as any final passing attempt; do not assume the first screenshot corresponds to the final outcome.

By default, Cypress clears the screenshots folder before cypress run, including nested folders and files. Use trashAssetsBeforeRuns: false if your workflow must preserve existing files. Ensure your CI artifact upload runs after Cypress and points to the configured screenshots folder.

8. Troubleshooting common screenshot problems

Symptom Likely cause What to do
No automatic screenshot after a failure in cypress open Automatic failure screenshots are a cypress run behavior. Call cy.screenshot() manually, or reproduce the failure in cypress run.
Failure image shows the viewport instead of the whole page Automatic failure screenshots are forced to runner mode. Add a manual capture: 'fullPage' screenshot at the relevant point in the test.
Expected error text is missing The Command Log may not have finished rendering when the asynchronous capture occurred. Use the screenshot to inspect page state, and use video or run debugging for timing and command sequence.
Full-page image has repeated or misplaced sticky content Full-page mode scrolls and stitches; fixed or sticky page elements can affect the result. Inspect the page’s sticky behavior and compare against a viewport screenshot. If you need the initial visible state, capture the viewport.
Lazy content is absent or inconsistent Content may load as the capture scrolls or may depend on app-specific timing. Make the content’s readiness part of the test, then capture. Check the application’s lazy-load behavior at each relevant scroll position.
Previous screenshots disappeared The screenshots folder is cleared before a run by default. Set trashAssetsBeforeRuns: false if prior artifacts must remain, and check the CI artifact path.
Several failure images exist for one test Retries may produce attempt-specific screenshots. Check the attempt suffix and correlate each artifact with the test result.
Screenshot does not wait for the condition being checked cy.screenshot() does not retry chained assertions. Wait for the app’s condition using a retrying Cypress assertion before invoking the screenshot.
Blackout selectors do not obscure runner content blackout applies to viewport captures, not runner captures. Use a viewport capture when blackout behavior is required, and avoid including sensitive content in other artifacts.
No video appears Video is opt-in and records specs in cypress run, not cypress open. Enable video and run the spec with cypress run; separately configure any recording or upload workflow you need.

9. Decide when Cypress screenshots are enough

For a single failure, start with the capture mode, retry artifacts, and optional video. If the task is visual regression review across baselines, browsers, or viewport widths, evaluate a visual testing service on capture scope, browser and viewport coverage, CI integration, review and approval workflow, and image storage. Cypress’s visual testing guide describes local image comparison plugins and hosted services, including Argos and SmartBear VisualTest; confirm their current capabilities and terms directly before choosing one.

10. Or skip the browser setup

If your goal is to capture a website outside a Cypress test, ScreenshotNeo is a website screenshot API and MCP server. It returns a PNG, JPEG, WebP, or PDF from one GET request. See the ScreenshotNeo API documentation for parameters and 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}`);
  • Cookie banners are accepted and removed before capture, along with 60+ known consent platforms, newsletter popups, and chat widgets; each step can be turned off.
  • Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed. Response headers report the page verdict and billing status.
  • An MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.
  • The free plan includes 1,000 screenshots a month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is on every plan.

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

11. FAQ

Does cy.screenshot() capture the whole browser history?

No. It captures an image for the selected mode at a point in the test. Use video when you need sequence and timing context.

Can I use an element screenshot and still request full-page mode?

The element screenshot ignores the capture mode. Select the element you want and treat it as its own capture.

Why does the screenshot timing not match the failing command exactly?

Screenshot capture is asynchronous, and Cypress documents an approximate duration of 100 ms. The app and runner can change while the capture completes.

Will disabling timers make my screenshot deterministic?

No. The documented default disables timers and animations, but application data and other rendering work can still change.