Use Cypress’s built-in cy.screenshot() command with capture: 'fullPage'. Cypress scrolls the application from top to bottom, captures each position, and stitches the images into one file. A clear baseline is:
cy.visit('/article')
cy.screenshot('article-full-page', { capture: 'fullPage' })
This guide explains capture modes, output paths, stable test setup, masking, viewport control, failure handling, troubleshooting, and an API alternative when you do not need to run a Cypress test.
Capture a complete page in Cypress
Place the screenshot after navigation and after the interactions or assertions that establish the state you want to document:
describe('article capture', () => {
it('saves the whole article', () => {
cy.visit('/article')
cy.get('[data-testid="article"]').should('be.visible')
cy.screenshot('article-full-page', {
capture: 'fullPage',
})
})
})
The fullPage mode scrolls the application under test from top to bottom, takes screenshots at each point, and stitches them together. Cypress documents fullPage as the default for ordinary cy.screenshot() calls, but specifying it explicitly makes the test’s intent obvious.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minute#1 Best Overall
Choose the right capture mode
| Mode | What it includes | Use it for |
|---|---|---|
fullPage |
The document from top to bottom, assembled from scrolling captures | Complete-page artifacts and documentation |
viewport |
Only the currently visible application viewport | Responsive-layout checks at a particular scroll position |
runner |
The browser viewport together with the Cypress Command Log | Debugging test context; Test Replay can hide the Runner UI |
Failure screenshots are coerced to runner captures by Cypress. Use viewport when the visible state—not the entire document—is the subject of the check. Use runner when the Command Log and surrounding Cypress context are needed to diagnose a failure.
Name and locate the output
A descriptive name is optional but recommended:
cy.screenshot('checkout-confirmation', { capture: 'fullPage' })
By default, Cypress writes images under cypress/screenshots. The path is organized in relation to the spec file, so the same name in different specs remains distinguishable. Duplicate names normally receive a numeric suffix. Set overwrite: true when a test should replace an existing image instead.
Manual screenshots work in both cypress open and cypress run. During cypress run, Cypress also captures screenshots automatically when tests fail; it does not automatically take failure screenshots in cypress open. Automatic failure capture can be disabled in Cypress configuration.
Options that control the image
Capture scope and naming
capture:fullPage,viewport, orrunner.fileName: Provide a name when using the options form or use the first string argument, such ascy.screenshot('profile').overwrite: Replace an existing file instead of adding a numeric suffix.
Stability and masking
disableTimersAndAnimationsdefaults totrue, pausing JavaScript timers and CSS animations during capture. Set it tofalseonly when the animation or timer itself is what you need to record.blackoutaccepts selectors whose content should be obscured. Confirm the result in the saved artifact; masking is not a substitute for keeping sensitive test data out of the page. Cypress notes that blackout does not apply to runner captures.onBeforeScreenshotandonAfterScreenshotare synchronous callbacks. Use them to hide a changing clock or other transient element, then restore the DOM.
cy.screenshot('account-page', {
capture: 'fullPage',
blackout: ['[data-sensitive]', '.live-clock'],
disableTimersAndAnimations: true,
overwrite: true,
})
Crop the result
clip crops the final image to a pixel rectangle when a complete page is larger than the useful region. Keep the coordinates tied to a known viewport and verify the output after layout changes.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesPrepare dynamic pages before capture
A screenshot records the page state reached by an asynchronous command, not necessarily the exact instant the command was queued. Cypress warns that the application can change before the image is actually captured. Establish deterministic state first:
Rank #2
- Visit the route.
- Authenticate or seed test data.
- Dismiss consent dialogs and other overlays that are part of neither the test nor the intended artifact.
- Wait for the page’s meaningful content, such as
[data-testid="article"], to be visible. - Freeze or hide clocks, rotating banners, advertisements, cursor effects, and animations that make pixels change between runs.
- Call
cy.screenshot()only after that preparation.
For a changing element that must remain in the DOM, callbacks can temporarily replace it:
cy.screenshot('dashboard', {
capture: 'fullPage',
onBeforeScreenshot($el) {
$el.find('.live-clock').hide()
},
onAfterScreenshot($el) {
$el.find('.live-clock').show()
},
})
Assertions chained to cy.screenshot() run once and are not retried like many Cypress queries. Treat the screenshot as an artifact command, not as a retrying visual assertion.
Control viewport dimensions separately
Full-page mode is independent of viewport size. Set the application viewport with either a command or configuration:
cy.viewport(1280, 800)
cy.visit('/pricing')
cy.screenshot('pricing-desktop', { capture: 'fullPage' })
Cypress documents default viewportWidth and viewportHeight values of 1000 by 660 pixels. You can configure those values globally in Cypress configuration or per test with cy.viewport(width, height). The browser window or display size used in a headless run is a separate setting and does not change viewportWidth or viewportHeight. Making the browser window taller does not turn a viewport capture into a full-page capture.
Full-page edge cases
Sticky and fixed elements
Full-page screenshots are assembled while Cypress scrolls. Sticky headers, fixed chat buttons, and other elements anchored to the viewport can appear repeatedly, move between segments, or overlap content. Cypress’s documentation calls out this class of layout issue without promising one universal result for every browser and page. Inspect the actual saved image. If a fixed element is irrelevant, hide it in onBeforeScreenshot or include its selector in blackout.
Lazy-loaded content
Scrolling can trigger lazy loading, but the page still needs enough waiting and stable test data for images and sections to finish rendering. Assert on the last meaningful section or an image state before capturing when those pixels matter.
Rank #3
Sensitive information
Use dedicated non-production data, selectors for masking, and a review step for generated files. A blackout selector that fails to match does not protect a value that was rendered under a different class or component state.
Recommended Free Tools
Reusable defaults
If every test in a suite needs the same behavior, wrap the command in a custom command or set consistent test conventions in your support file:
Cypress.Commands.add('fullPageShot', (name, options = {}) => {
return cy.screenshot(name, {
capture: 'fullPage',
disableTimersAndAnimations: true,
...options,
})
})
// In a test:
cy.fullPageShot('orders', { blackout: ['[data-sensitive]'] })
Keep page-specific selectors and masking decisions in the test or page object that owns the UI. A global blackout rule can hide useful evidence or silently stop matching after a redesign.
Troubleshooting common problems
Only the visible viewport was saved
Cause: The command used capture: 'viewport', inherited an unintended option, or a different screenshot command is running. Fix: call cy.screenshot('name', { capture: 'fullPage' }) and check the resulting file.
The image is missing sections
Cause: Content was still loading, a lazy-load trigger did not fire, or navigation changed the page during capture. Fix: wait for a specific final section or image, disable unrelated transitions, and capture only after the intended state is stable.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #4
Sticky headers or buttons are duplicated
Cause: The element is fixed while Cypress scrolls and stitches segments. Fix: inspect the artifact, then hide or mask the element in a before-screenshot callback when it is not part of the requirement.
The screenshot has a changing timestamp or animation
Cause: Dynamic content changed before or during the asynchronous capture. Fix: leave disableTimersAndAnimations at its default, freeze test data, or temporarily hide the element in onBeforeScreenshot and restore it afterward.
The file cannot be found
Cause: The path was assumed to be the project root, or duplicate-name suffixes were overlooked. Fix: look under cypress/screenshots in the spec-relative directory and check for a numeric suffix. Set overwrite: true only when replacement is intentional.
Failure screenshots behave differently
Cause: Cypress coerces failure screenshots to runner captures, and automatic failure screenshots occur in cypress run rather than cypress open. Fix: use an explicit manual capture for a full-page failure artifact, or configure automatic failure capture according to the run mode.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →When Cypress is the right tool
Cypress is appropriate when the screenshot belongs to an end-to-end test, needs authenticated application state, or must be taken after user interactions. Its built-in command creates image files but does not perform visual comparison. If you need cross-browser rendering or pixel comparison, add a visual-testing workflow that is designed for comparison rather than treating the capture command as an assertion.
Or skip the browser setup
For a standalone URL screenshot, ScreenshotNeo provides a single HTTP request instead of a Cypress project and browser session. It removes cookie/consent banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, failed loads, timeouts, and cache hits are not billed; and response headers identify the page verdict and whether the request was billed. Its MCP server includes take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
See the ScreenshotNeo documentation for authentication and options. This cURL request returns a WebP file:
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}`);
You can also request PNG, JPEG, or PDF; full-page capture with lazy images, CSS-selector element capture, custom viewport and device presets, retina scale, dark mode, custom CSS or JavaScript, click actions, waits, request blocking, headers, cookies, user agent, timezone, geolocation, transparent backgrounds, resizing, TTL caching, signed image links, asynchronous webhooks, bulk capture of up to 100 URLs per call, and usage data are available. Every plan includes every feature. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 screenshots. Create a free ScreenshotNeo account.
Free tools Windows power users keep installed
One-click scans. No signup required.
Frequently Asked Questions
Does Cypress need a separate screenshot library for full-page images?
No. The built-in cy.screenshot() command supports full-page capture.
Can I capture just one element instead of the whole page?
Cypress’s documented screenshot modes are full page, viewport, and runner. For element-focused evidence, crop with clip or use a separate element-capture workflow.
Does a full-page screenshot compare pixels automatically?
No. Cypress saves the image; visual comparison requires an additional comparison workflow or service.
Quick Recap
The Bottom Line
For a Cypress test, use cy.screenshot('name', { capture: 'fullPage' }) after the page is stable, then inspect the file under cypress/screenshots. Control viewport dimensions separately and account for dynamic, sticky, and sensitive content.
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.




