Cypress Screenshot Command Options Explained
A practical reference to cy.screenshot() options, defaults, capture modes, file naming, failure screenshots, and common fixes.
cy.screenshot() captures the application under test, a selected DOM element, or—when using runner capture—the browser viewport together with Cypress’s Command Log. Pass a filename and options object to control the capture. The key choice is capture: viewport captures the visible application area, fullPage scrolls and stitches the page, and runner includes the Cypress runner. Screenshots are saved under the configured screenshots folder, which defaults to cypress/screenshots.
1. Basic usage
Call the command directly to capture the page, or chain it from a command that yields one element to capture that element.
// Capture the application using Cypress's default capture behavior
cy.screenshot()
// Set a name and explicit capture mode
cy.screenshot('checkout-viewport', {
capture: 'viewport',
overwrite: true
})
// Capture one element yielded by a Cypress query
cy.get('[data-testid="order-summary"]').screenshot('order-summary', {
padding: 12
})
The command yields its original subject. Cypress cautions that chaining later commands that rely on that subject is unsafe. Screenshot capture is asynchronous, so the page can change between issuing the command and the actual capture.
2. Choose a capture mode
| Mode | What it captures | Use it for | Watch for |
|---|---|---|---|
viewport |
The application in the current browser viewport. | Checking exactly what is visible at the current scroll position and viewport size. | Content outside the viewport is omitted. |
fullPage |
The whole application by scrolling and stitching captures. | Reviewing long pages or retaining below-the-fold content. | Fixed or sticky elements may appear more than once as Cypress scrolls and stitches. |
runner |
The browser viewport including the Cypress Command Log. | Debugging when the command history and browser context help explain a failure. | blackout does not apply. Cypress coerces scale to true. |
The documented API default for capture is fullPage. For an element screenshot, the capture option is ignored: the yielded element determines the capture target.
// Current viewport only
cy.screenshot('visible-state', { capture: 'viewport' })
// Whole page, including content below the fold
cy.screenshot('whole-page', { capture: 'fullPage' })
// Include the Cypress runner for debugging
cy.screenshot('runner-debug', { capture: 'runner' })
3. Options and defaults
| Option | Documented default | Effect and scope |
|---|---|---|
log |
true |
Shows the command in the Cypress Command Log. |
blackout |
[] |
An array of selectors for elements to black out in applicable captures. It does not apply to runner captures. |
capture |
'fullPage' |
Selects viewport, fullPage, or runner. Ignored for element captures. Failure screenshots are coerced to runner. |
clip |
null |
Crops the final image to a pixel rectangle with x, y, width, and height. |
disableTimersAndAnimations |
true |
Prevents JavaScript timers and CSS animations from running during capture. Set to false to let them continue. |
padding |
null |
Adds space around an element capture. Accepts a number or up to four numbers using CSS shorthand; ignored for other capture types. |
scale |
false |
Scales the application to fit the browser viewport when enabled. Cypress coerces it to true for runner capture. |
timeout |
responseTimeout |
Maximum time for the screenshot command to resolve. |
overwrite |
false |
Overwrites an existing duplicate filename when enabled. Otherwise Cypress creates a numbered duplicate. |
onBeforeScreenshot |
null |
Callback before a non-failure capture. Receives the element for an element capture, otherwise the document. |
onAfterScreenshot |
null |
Callback after a non-failure capture. Receives the element or document and screenshot properties such as saved path and dimensions. |
These are the command API defaults. Cypress also provides shared screenshot defaults so a project can set common behavior centrally; see the Cypress.Screenshot API.
4. Crop, mask, and add element padding
Use clip to keep a rectangular pixel region of a page capture. Use blackout to cover matching selectors in supported capture modes. Use padding for breathing room around a DOM element capture; it is ignored for viewport and full-page captures.
// Crop a 640 × 360 pixel region from the page
cy.screenshot('hero-crop', {
capture: 'viewport',
clip: { x: 0, y: 0, width: 640, height: 360 }
})
// Black out matching page elements
cy.screenshot('masked-account', {
capture: 'viewport',
blackout: ['[data-sensitive]', '.account-number']
})
// Add padding around one selected element
cy.get('.invoice-total').screenshot('invoice-total', {
padding: [8, 16]
})
Masking has scope limits: it does not apply to runner captures. Do not assume that a selector mask protects every screenshot type. Cypress Cloud has separate screenshot and replay data controls; check the Cypress Cloud data controls when deciding what data is retained there.
5. Stabilize the captured state
By default, Cypress disables timers and animations during the capture to reduce movement. That does not freeze all application state or make capture instantaneous. Wait for the UI condition you need, and use the callbacks to temporarily hide or restore volatile elements when appropriate.
cy.get('[data-testid="results"]')
.should('be.visible')
cy.screenshot('stable-results', {
capture: 'viewport',
disableTimersAndAnimations: true,
onBeforeScreenshot(doc) {
doc.querySelector('[data-testid="live-clock"]')?.setAttribute('hidden', '')
},
onAfterScreenshot(doc) {
doc.querySelector('[data-testid="live-clock"]')?.removeAttribute('hidden')
}
})
For an element capture, the callbacks receive the element rather than the document. Callbacks are documented for non-failure screenshots. Keep setup and cleanup narrowly scoped so that hiding a dynamic element does not leak into later test steps.
6. Name and locate screenshot files
Without a custom filename, Cypress derives the image name from the spec and test. A custom filename replaces the suite and test naming. Files go beneath the configured screenshots folder and a spec-relative directory. The default folder is cypress/screenshots.
- Duplicate names get a numeric suffix by default.
- Set
overwrite: truewhen a repeated capture should replace the existing file. - Failure screenshots append
(failed)to the default test name.
Configure the screenshots folder in Cypress project configuration. The configuration reference documents the current configuration option and default.
7. Automatic screenshots on test failure
During cypress run, Cypress takes a screenshot when a test fails by default. It does not automatically take a failure screenshot in cypress open. Failure screenshots use runner capture, even if the regular command is configured for a different capture mode. Set screenshotOnRunFailure: false in configuration or in screenshot defaults to disable them.
// cypress.config.js
const { defineConfig } = require('cypress')
module.exports = defineConfig({
screenshotOnRunFailure: false
})
See the official screenshots and videos guide for how automatic artifacts fit into Cypress runs.
8. Common problems and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| The screenshot contains only the visible viewport. | capture: 'viewport' was selected, or an element capture was used. |
Use page-level capture: 'fullPage' for below-the-fold content. Element captures target only the yielded element. |
| Sticky headers or floating buttons appear several times. | Full-page capture scrolls and stitches the page. | Use viewport capture if you need one frame, or account for repeated fixed elements in the expected artifact. |
| Sensitive elements are visible. | The selector did not match, or the capture is runner, where blackout is unsupported. |
Check the selector and capture mode. Avoid capturing sensitive data where possible; review Cloud data controls for retained artifacts. |
| The saved filename has a numeric suffix. | A file with that name already exists and overwrite is false. |
Choose a unique filename or set overwrite: true. |
| The screenshot differs between runs. | Dynamic content changed, capture is asynchronous, or state was not ready before the command. | Wait on a meaningful DOM condition, disable timers and animations, and hide volatile UI in callbacks if needed. |
| No automatic failure screenshot appears. | The test ran in cypress open, or failure capture was disabled. |
Run with cypress run and check screenshotOnRunFailure and screenshot defaults. |
| The command times out. | The screenshot did not resolve within the configured timeout. | Check that the app is responsive and the requested capture is appropriate; increase the command timeout when a genuinely longer capture is expected. |
| The crop or padding has no effect. | clip and padding apply to different capture needs; padding applies only to element screenshots. |
Use pixel clip for a page region and padding for an element capture. |
9. Performance, reliability, and artifact cost
A viewport screenshot has a smaller capture area than a full-page screenshot, while full-page mode must scroll and stitch the application. On long or dynamic pages that means more opportunities for content to change during capture and for sticky elements to repeat. Runner capture adds the Cypress Command Log to the artifact. Choose the narrowest image scope that answers the test or debugging question.
For repeatability, wait for the page state that matters before capture, avoid time-dependent content in visual assertions, and use the default timer and animation suppression unless the animation itself is under test. Keep filenames deterministic when artifacts are consumed by CI, and decide whether overwriting or numbered duplicates fits the job. Cypress documents screenshot timeout via responseTimeout by default; tune a per-command timeout only when the capture legitimately needs longer.
Screenshot command options do not describe a separate per-image Cypress fee. Operational cost comes from storing and retaining artifacts in the systems where your test results are kept; consult the terms and settings for those systems. If you need screenshots of arbitrary public URLs outside a Cypress test run, a screenshot API may be a simpler fit.
10. Or skip the browser setup
For a screenshot of a URL outside a Cypress test, ScreenshotNeo offers a one-request screenshot API and an MCP server for AI agents. The screenshot options covered above are Cypress command behavior; use ScreenshotNeo when you need a URL-to-image or PDF capture without configuring a browser test.
See the ScreenshotNeo docs for API details. This cURL request saves a WebP screenshot:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Equivalent 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)
Equivalent 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(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));
- Cookie and consent banners are accepted and removed before capture, along with known newsletter popups and chat widgets.
- Bot checks, blank pages, failed loads, timeouts, and cache hits are never billed; response headers say which page verdict occurred and whether it was billed.
- An MCP server lets Claude, Cursor, or another MCP client use screenshot and page information tools.
- The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Create a free ScreenshotNeo account to get 1,000 screenshots a month with no card.
11. Frequently asked questions
Does cy.screenshot() wait for the test to finish?
No. It captures when the command runs in the Cypress command chain. Put it after the assertion or UI action that establishes the state you want.
Can I capture only a chart or component?
Yes. Query the element and call .screenshot() on the yielded element. Use padding if the image needs extra space around its bounds.
Can I use screenshots for visual regression testing?
The command produces image artifacts, but comparison and approval of visual changes require a separate workflow or tool.
Where are runner screenshots useful?
They can preserve the browser view and Cypress Command Log together when diagnosing a failing test. Remember that blackout selectors do not apply in runner mode.


