Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When a Cypress test passes locally but fails in continuous integration, first find out whether the failure follows the test or the environment. Re-run the same commit and test, compare the CI browser and machine settings with local settings, and inspect the failed run before changing waits or adding retries. The most common differences to investigate are browser and operating system, viewport and timezone, app build and server readiness, timing and network state, test data and feature flags, and CI resource limits.

1. Classify the failure before changing the test

Start with the same commit, test, and data where possible. Ask whether the test fails every time in CI, passes and fails across CI attempts, or only fails in CI while remaining consistent locally. A repeatable failure can indicate a product regression or a broken CI build; variation across attempts makes flakiness more likely. A pass/fail history from recorded runs can help distinguish a new regression from an intermittent test.

  • Repeatable failure: inspect the assertion, the application build, and any service or environment dependency that is consistently different in CI.
  • Intermittent failure: look for unobserved network or UI state, timing assumptions, state leakage, and resource pressure.
  • Failure limited to a particular browser or runner: compare browser version, operating system, viewport, timezone, and available CPU and memory.

Do not assume every local-versus-CI mismatch is a flaky test. Cypress identifies browser-specific issues, CI build-process problems, timing variation, and machine differences as possible causes. The fix depends on which difference the evidence supports.

2. Verify the CI build and wait for the app to be ready

A Cypress command can run successfully while the test is pointed at an old, incomplete, or unavailable application. Check the job log to confirm that the intended build completed, the application server started in the job, and Cypress waits until the app URL is reachable before it begins. Cypress documents using wait-on and concurrently for this sort of startup flow.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Confirm the job checks out and builds the same application revision the test is meant to cover.
  2. Confirm the server process starts in the CI job and uses the expected port and configuration.
  3. Wait for a reachable application URL before invoking cypress run; do not rely on a fixed startup delay as proof the server is ready.
  4. Check the server output and Cypress base URL together if the job reports connection errors or serves an unexpected page.

A simple shell pattern, when the app is already running on the stated URL, is:

npx wait-on http://localhost:3000 && npx cypress run

Replace the URL with the address served in your job. If the server must be started in the same command, arrange for the server and Cypress processes to run together, and make the Cypress process wait on that URL. A server that exits, binds to a different interface, or starts with a failed build can otherwise look like a Cypress timing problem.

3. Match the browser and machine conditions

“Chrome locally” and “Chrome in CI” are not necessarily the same execution environment. Compare the actual browser and version, operating system, viewport, timezone, CPU resources, and environment variables. Seed data and feature flags can also change what the application renders. Record these inputs for both environments instead of relying on memory.

Run locally with the CI browser

Use Cypress’s --browser option to run with the browser CI uses, for example:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
npx cypress run --browser chrome

Use the browser name and installation available on your machine. If the failure appears only in a particular browser, investigate that browser-specific behavior rather than treating the test as universally broken. Cypress also notes that evergreen Chrome updates can affect automation. Where reproducibility matters, standardize or pin the browser image or version used by the CI job and compare it with the local run.

Compare configuration and input data

Make a compact environment record for a failing run. Include the CI runner’s operating system, browser and version, viewport, timezone, relevant environment variables, seed data, feature flags, and the identity or revision of the built application artifact. Compare these with the local run. Avoid printing secrets into logs: record whether a required setting is present and which non-sensitive configuration value was selected, not the secret itself.

A mismatch in any one of these inputs can make a test render different content or take a different path. If the mismatch is intentional, make the test setup explicit and deterministic where possible; if it is accidental, correct the CI configuration rather than weakening the assertion.

4. Replace timing guesses with observable state

A fixed delay only waits for a duration. It does not establish that the request finished or that the UI reached the state the next assertion needs. Cypress’s debugging guidance points to missing assertions around actions and network requests as a common source of flaky tests: assert that each required step occurred before moving on, so the failure identifies the step that did not complete.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Synchronize a request and assert its UI result

For a page that loads a list from an API, intercept the relevant request, wait for its completion, and then assert on the rendered result. Adapt the route, method, and expected text to the application:

describe('items page', () => {
  it('shows the items returned by the API', () => {
    cy.intercept('GET', '/api/items').as('getItems');
    cy.visit('/items');

    cy.wait('@getItems');
    cy.get('[data-cy="item-list"]').should('be.visible');
    cy.get('[data-cy="item-list"]').should('contain', 'Expected item');
  });
});

The alias and wait make the network dependency explicit; the DOM assertions verify that the application rendered the state the test actually cares about. If the UI can issue multiple matching requests, narrow the intercept to the relevant request or assert the expected response and resulting state. For non-network actions, assert the visible result of the action before continuing instead of inserting an arbitrary sleep.

5. Capture evidence from the failed run

Enable Cypress screenshots and video as a baseline, then inspect the failed attempt rather than only the final pass/fail line. A screenshot can show what was on screen at failure; video can show the sequence that led there. These artifacts help answer whether the page was blank, a loading state persisted, an expected control was absent, or the test reached a different screen.

For teams using Cypress Cloud, recorded runs can provide retry and pass/fail history, artifacts, and the commits associated with changes to a test. Test Replay offers a more detailed view than passive video: it exposes the DOM, network requests and responses, console logs, and JavaScript errors at points in the CI run. Use that evidence to locate the first state that diverged, rather than adjusting the final assertion without understanding why it failed.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep the failure context with the run: commit, test name, runner configuration, browser version, and any relevant seed or feature-flag selection. That makes a later comparison meaningful if a subsequent run passes.

6. Check whether the CI runner is under resource pressure

CI containers may have less CPU or memory available than a developer’s machine. Cypress notes that video can freeze or drop frames when the container lacks CPU, so a poor recording is not necessarily proof that the application itself froze. Compare the test behavior with runner load and inspect Cypress process usage if the failure or artifacts suggest resource pressure.

For deeper diagnostics, Cypress supports the DEBUG=cypress:* environment setting and a process-profiler stream for inspecting Cypress CPU and memory. Use these when ordinary logs and artifacts do not explain the failure. If the runner is saturated, investigate runner sizing or competing job processes before adding longer waits that conceal the symptom.

7. Use retries as evidence, not as the fix

Cypress retries are disabled by default. Configure runMode separately from openMode, so the retry behavior for CI runs is not confused with interactive local runs. Two configured retries in run mode permit up to three total attempts. If a test passes on retry, that is useful evidence of intermittent behavior, but it does not identify or repair its cause.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Retries rerun beforeEach and afterEach. Review those hooks and the test’s setup for state leakage or side effects that can make later attempts behave differently. A missing environment variable, failed build, unavailable service, or incorrect deployment is systemic; retrying it can waste CI time or obscure the real problem. Fix that underlying failure instead of treating retries as a reliability guarantee.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

8. Troubleshooting by symptom

Symptom Likely area to inspect Next action
Connection error or app does not load Build completion, server process, URL, port, and readiness Confirm the server is running in the job and wait for its URL to become reachable before Cypress starts.
Failure appears only in one browser Browser-specific behavior or browser version drift Reproduce locally with the CI browser using --browser; standardize the CI browser version if consistent reproduction is needed.
Assertion fails intermittently after navigation or an action Unobserved network or application state Intercept and wait for the relevant request, then assert the dependent UI state instead of using a fixed sleep.
Different page content or test path in CI Viewport, timezone, seed data, feature flags, environment variables, or app artifact Record and compare those inputs across the local and CI executions.
Video freezes or drops frames Runner CPU pressure Check runner load and Cypress CPU and memory diagnostics; do not infer an application failure from recording quality alone.
First attempt fails but retry passes Flaky timing, transient dependency, or attempt-sensitive setup Inspect the failed attempt’s evidence and test hooks; identify why it passed on a later attempt before retaining retries.

Or skip the browser setup

If you need a separate screenshot of a page for visual context, ScreenshotNeo can return an image from one GET request. It is a website screenshot API, not a substitute for Cypress’s failed-run screenshots, video, or Test Replay: use Cypress artifacts to diagnose the test execution itself.

For example, capture a page as WebP with cURL:

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. ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each of those steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. More details are at ScreenshotNeo.

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

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Does Cypress rerun setup and cleanup hooks on a retry?

Yes. Each retry reruns beforeEach and afterEach, so hooks that mutate shared state can affect later attempts.

How many attempts do two run-mode retries allow?

Two configured retries allow up to three total attempts: the original run and two retries.

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.