ScreenshotNeo

BlogHow-to

How to Set Screen Resolution in Cypress

Set Cypress viewport dimensions for responsive tests, configure headless display size, and avoid common screenshot and video mismatches.

By the ScreenshotNeo team1 October 20267 min read

Use cy.viewport(width, height) to set the application viewport during a Cypress test. To set the default for tests, configure viewportWidth and viewportHeight in cypress.config.js or cypress.config.ts. If you mean the size of the headless browser display used for screenshots or videos, change browser launch options in before:browser:launch. These controls affect different dimensions.

Cypress calls the application dimensions a viewport. They are not the physical resolution of a monitor. The headless display size is a separate browser setting and does not change the application’s configured viewport.

1. Set the viewport inside a test

Call cy.viewport() with width and height in CSS pixels:

describe('responsive navigation', () => {
  it('shows the mobile menu at a narrow viewport', () => {
    cy.viewport(375, 667)
    cy.visit('/')

    cy.get('.desktop-menu').should('not.be.visible')
    cy.get('.mobile-menu').should('be.visible')
  })
})

The command applies to the current test. Cypress restores the configured default viewport between tests. Choose dimensions that represent your application’s breakpoints rather than copying a device size without checking your CSS.

Use a named device preset

Cypress also accepts documented preset names and an optional orientation:

cy.viewport('iphone-6')
cy.viewport('ipad-2', 'landscape')

Examples include:

Preset Viewport
iphone-5 320 × 568
iphone-6 375 × 667
ipad-2 768 × 1024
macbook-13 1280 × 800

Use numeric dimensions when a specific breakpoint, design token, or visual-baseline size matters. See the official cy.viewport() reference for the current preset list.

2. Set a default viewport in Cypress configuration

Put a default in cypress.config.js:

const { defineConfig } = require('cypress')

module.exports = defineConfig({
  viewportWidth: 1280,
  viewportHeight: 720,
})

The equivalent TypeScript configuration is:

import { defineConfig } from 'cypress'

export default defineConfig({
  viewportWidth: 1280,
  viewportHeight: 720,
})

Cypress documents defaults of 1000 × 660 pixels. Configuration values apply across tests unless a suite, test, or cy.viewport() call overrides them. Configuration details are in Cypress configuration documentation.

Scope a size to a suite or test

Use test configuration when only part of the test suite needs another size:

describe('tablet layout', {
  viewportWidth: 768,
  viewportHeight: 1024,
}, () => {
  it('renders the tablet navigation', () => {
    cy.visit('/')
    cy.get('.tablet-menu').should('be.visible')
  })
})

it('uses a desktop layout', {
  viewportWidth: 1440,
  viewportHeight: 900,
}, () => {
  cy.visit('/')
  cy.get('.desktop-menu').should('be.visible')
})

Suite and test settings are temporary scopes. Cypress returns to the configured defaults when that scope ends.

3. Test several responsive breakpoints

A separate test for each important breakpoint makes failures easier to diagnose:

const cases = [
  { name: 'mobile', width: 375, height: 667, selector: '.mobile-menu' },
  { name: 'tablet', width: 768, height: 1024, selector: '.tablet-menu' },
  { name: 'desktop', width: 1280, height: 720, selector: '.desktop-menu' },
]

describe('responsive navigation', () => {
  for (const testCase of cases) {
    it(`shows the ${testCase.name} navigation`, () => {
      cy.viewport(testCase.width, testCase.height)
      cy.visit('/')
      cy.get(testCase.selector).should('be.visible')
    })
  }
})

Set the viewport before cy.visit() when the initial page load, server-side rendering, or responsive JavaScript depends on the width.

4. Change the headless browser display size

If screenshots or videos have the wrong outer dimensions, configure the browser launch options. Cypress documents a default headless display size of 1280 × 720 with device pixel ratio (DPR) 1. This setting changes the display size used by the browser; it does not change viewportWidth or viewportHeight.

const { defineConfig } = require('cypress')

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on('before:browser:launch', (browser, launchOptions) => {
        if (browser.name === 'chrome' && browser.isHeadless) {
          launchOptions.args.push('--window-size=1400,1200')
          launchOptions.args.push('--force-device-scale-factor=1')
        }

        return launchOptions
      })
    },
  },
})

For DPR 2, use --force-device-scale-factor=2. Cypress provides browser-specific examples for Chrome, Electron, and Firefox in the before:browser:launch API. Keep the browser condition and headless check appropriate for the browser your CI job actually starts.

5. Understand viewport, display size, DPR, and runner scaling

Setting Controls Typical use
cy.viewport() Application CSS viewport Responsive behavior and layout assertions
viewportWidth/viewportHeight Default application viewport Consistent suite-wide dimensions
Browser launch arguments Headless display/window size Screenshot and video output dimensions
--force-device-scale-factor Browser device pixel ratio High-DPI capture behavior
Cypress runner scaling How the preview is fitted in the runner Interactive viewing only

The Cypress runner may scale and center a large application viewport to fit its panel. That visual preview scaling does not change application calculations. A preview that looks smaller is not evidence that your test received a smaller viewport.

cy.viewport() does not simulate devicePixelRatio. For visual comparisons, keep the browser version, operating system, display scaling, fonts, viewport, and DPR consistent. Stabilize animations and time-dependent content as needed; dimensions alone cannot make a changing page deterministic. See Cypress guidance on visual testing.

6. Cypress version and configuration rules

Starting with Cypress 16.0.0, changing viewportWidth or viewportHeight through Cypress.config() during test execution throws an error. Use cy.viewport() for a change during a test, or suite/test configuration for a scoped value. The Cypress.config() reference documents this behavior.

7. A practical setup checklist

  • Decide whether you need application layout dimensions or headless output dimensions.
  • Use numeric CSS-pixel values when matching a breakpoint or visual baseline.
  • Set the viewport before visiting the page when initial load behavior is responsive.
  • Use suite/test configuration for scoped defaults and cy.viewport() for runtime changes.
  • Configure browser launch options only when the outer screenshot/video display or DPR is the problem.
  • Run visual checks in the same browser and operating-system environment.
  • Remove or freeze animations, clocks, random data, and asynchronous content that make images vary.

8. Troubleshooting common problems

The page still behaves like desktop

Cause: The viewport was changed after cy.visit(), or the test changed the headless display instead of the application viewport.

Fix: Call cy.viewport(width, height) before visiting, or set viewportWidth and viewportHeight in configuration.

The runner preview looks smaller than the configured size

Cause: Cypress scales the preview to fit the runner panel.

Fix: Trust the configured dimensions and assert layout behavior. Preview scaling does not redefine the application viewport.

The screenshot or video has unexpected outer dimensions

Cause: The headless browser display size is separate from the application viewport.

Fix: Add browser-specific before:browser:launch arguments such as Chrome’s --window-size. Keep the application viewport setting as well if responsive layout matters.

Changing Cypress.config() throws in Cypress 16

Cause: Cypress 16.0.0 and later rejects changing viewport configuration values during test execution.

Fix: Replace it with cy.viewport() or test/suite configuration.

High-DPI screenshots are larger than expected

Cause: A device scale factor changes device pixels without changing CSS viewport values.

Fix: Set --force-device-scale-factor=1 for one device pixel per CSS pixel, or choose a consistent higher factor such as 2 for retina-style output.

Visual diffs appear at the same dimensions

Cause: Fonts, browser versions, operating-system rendering, animations, network timing, or changing data differ between runs.

Fix: Pin the rendering environment, wait for stable content, disable animations where appropriate, and use deterministic fixtures.

A named preset does not match the product breakpoint

Cause: Device presets are convenient labels, not a guarantee that they match your design system.

Fix: Use the exact numeric width and height required by the breakpoint or visual specification.

9. Performance, reliability, and cost considerations

Changing viewport dimensions is a local browser operation and normally adds negligible test time. The expensive parts of a responsive test suite are page loads, API calls, animations, video encoding, and visual-diff processing. Keep the number of widths focused on real breakpoints, reuse stable fixtures, and avoid repeating a full end-to-end flow at every size when a component-level check is sufficient.

For reliable screenshots, use fixed dimensions, fixed DPR, pinned browser and OS versions, stable fonts, and deterministic data. Treat the application viewport and headless display as two independent values in CI configuration so a change to one does not silently alter the other.

10. Or skip the browser setup

If you only need a rendered screenshot or PDF of a URL, ScreenshotNeo provides a single HTTP request. Its capture options include full-page screenshots with lazy images loaded, element capture, dark mode, device presets or custom viewports, retina scale, custom CSS and JavaScript, waits, request blocking, cookies, headers, timezone, geolocation, caching, signed links, asynchronous jobs, bulk capture, and PDF settings. See the ScreenshotNeo documentation.

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,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const fs = require('node:fs/promises');

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 failed: ${res.status}`);
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

Before capture, ScreenshotNeo accepts cookie and consent banners and removes more than 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, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server includes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account.

11. FAQ

Does cy.viewport() change the monitor resolution?

No. It changes the application’s browser viewport in CSS pixels.

Can I set width without height?

Use both dimensions so tests have an explicit, repeatable viewport.

Should I use a device preset for responsive testing?

Use a preset for convenience; use numeric dimensions when matching an exact breakpoint or visual baseline.

Why do screenshots differ at the same viewport?

Check DPR, fonts, browser and OS versions, animations, timing, and dynamic data.

Which setting controls Cypress video dimensions?

The headless browser display size influences capture dimensions; configure it through the browser launch hook while keeping the application viewport configured separately.