Free tools Windows power users keep installed
One-click scans. No signup required.
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Short answer: Cypress does not resume later commands in the same it block after an assertion or command has finally failed. To keep useful execution moving, separate independent checks into separate tests, use retries only for genuinely intermittent failures, and make shared hooks reliable. Cypress will run remaining tests after a test and its configured retries are exhausted.
Three behaviors are often confused: Cypress can retry a linked query while it is waiting; it can rerun an entire test; or it can proceed to another test. Each solves a different problem.
What Cypress does when a check fails
A failed assertion stops the current test body
Commands in a Cypress test are queued and executed in order. When an assertion ultimately fails, Cypress marks the current test as failed and does not execute statements that follow that assertion in the same test body. There is no “continue to the next line” switch for a final assertion failure. See Cypress retry-ability.
it('checks the account page', () => {
cy.visit('/account')
cy.get('[data-cy=title]').should('have.text', 'Account')
cy.get('[data-cy=save]').should('be.enabled') // does not run if title fails
})
Query and assertion retry is not continuation
When a command chain contains a retryable query and assertion, Cypress retries the linked chain until it passes or the command timeout expires. Cypress describes this as queries linking and retrying “the entire chain together.” That waiting is useful for asynchronous rendering; it does not allow commands after a failed, timed-out assertion to run.
#1 Best Overall
A failed test does not necessarily stop the spec
After a test’s attempts are exhausted, Cypress records it as failed and normally proceeds to later tests. A failure in a before, beforeEach, after, or afterEach hook can prevent dependent tests from running, however. Test organization and dependable setup therefore determine whether the runner can progress. The test organization guide covers these relationships.
Choose the right way to continue
| Situation | Use | What happens |
|---|---|---|
| The page is eventually consistent or an element appears late | Assertion/query retry | Cypress waits and retries the linked query until it passes or times out; later commands run only if it passes. |
| Two checks should report independently | Separate it tests |
A failure in one test does not prevent the other test from being scheduled, provided shared hooks succeed. |
| The whole scenario sometimes fails because of a transient condition | Test retries | Cypress reruns the complete test, including its beforeEach and afterEach hooks. |
| A known application exception is intentionally expected | Narrow uncaught:exception handling |
The matching exception can be prevented from failing the test; unexpected exceptions still fail it. |
Split independent checks into separate tests
If you want the title result and the button result to appear even when one fails, make them separate tests. Keep each test independent: create its own data, visit its own starting URL, and do not rely on mutations left by a previous test.
describe('Account page', () => {
beforeEach(() => {
cy.visit('/account')
})
it('shows the account title', () => {
cy.get('[data-cy=title]').should('have.text', 'Account')
})
it('enables the save button', () => {
cy.get('[data-cy=save]').should('be.enabled')
})
})
If the beforeEach visit fails, both tests can be blocked. In that case, splitting the assertions is not enough: fix the shared setup, or move genuinely unrelated setup into each test so one fixture failure does not cascade.
Configure retries without hiding real failures
Retries are disabled by default. Configure them in cypress.config.js or cypress.config.ts when a complete rerun is safe and a failure is plausibly intermittent. A value of 2 means two additional attempts, for up to three total attempts.
Rank #2
import { defineConfig } from 'cypress'
export default defineConfig({
retries: {
runMode: 1,
openMode: 0,
},
})
This permits one extra attempt in cypress run (normally CI) and none in interactive cypress open. You can also set retries for a suite or an individual test when only a narrow area is flaky:
describe('checkout', { retries: { runMode: 2, openMode: 1 } }, () => {
it('completes payment', { retries: 1 }, () => {
cy.visit('/checkout')
// scenario
})
})
A retry starts at the beginning. Cypress runs the test again with its beforeEach and afterEach hooks; it does not jump back to the failed command. Make cleanup, seeded data, and external calls safe to repeat. Cypress notes the time cost because every attempt repeats the scenario; see Test retries in Cypress and Optimizing test performance.
Do not use retries to turn a deterministic product defect into a pass. Keep the final failure visible, inspect the attempt details, and remove or reduce retries once the underlying race or environment problem is fixed.
Handle expected application exceptions safely
If “the check failed” actually means the application throws a known exception, Cypress can listen for uncaught:exception. Return false only for the specific, documented error you expect. A broad handler that suppresses every exception can hide real defects.
Rank #3
it('opens the legacy report', () => {
cy.on('uncaught:exception', (error) => {
if (error.message.includes('LegacyReportWidget')) {
return false
}
// Return nothing for all other errors: Cypress fails the test.
})
cy.visit('/reports')
cy.get('[data-cy=report]').should('be.visible')
})
Use cy.on for a per-test exception rule; Cypress removes that listener when the test ends. A Cypress.on listener persists until removed, so global handlers require extra care. Cypress also does not support Cypress commands or assertions inside these event callbacks. Exception suppression only addresses the matched application exception; it cannot make a failed assertion continue.
References: Catalog of Events, Common error messages, and Cypress App FAQ.
Make hooks and test data continuation-safe
Keep before for truly global, stable work
A failing before hook can prevent every test in its suite from running. Use it only for setup that is required by all tests and is unlikely to fail independently. If each test can create its own fixture, prefer per-test setup.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Reset state in beforeEach
Because retries rerun beforeEach, the hook must tolerate repetition. Reset or recreate records instead of assuming a previous attempt left a particular state. Avoid depending on test order.
Rank #4
Make teardown non-destructive to later tests
An afterEach action that fails can mark the test as failed and may leave the environment dirty for the next test. Use idempotent cleanup and collect diagnostics before deleting data.
Common failure symptoms and fixes
- Commands after
should()never appear: the assertion failed finally. Split the independent check into anotherit, or fix the condition; do not expect a resume flag. - The same test runs several times: retries are enabled at configuration, suite, or test scope. Check the effective
retriesvalue and decide whether the rerun is justified. - Later tests are skipped after a setup error: a
beforeorbeforeEachhook failed. Run setup in isolation, stabilize fixtures, and reduce suite-wide dependencies. - A retry passes but the test is still reported as flaky: treat the first failed attempt as evidence of instability. Capture the attempt artifacts and investigate timing, network, data, or resource contention.
- Everything passes after adding an exception handler: verify that the handler matches only the intended message. Remove it temporarily to ensure an unrelated exception is not being hidden.
- Assertions time out while the page is still loading: wait on a meaningful application signal (such as a request alias or stable selector) and keep the assertion linked to the query. Increasing timeouts alone can make runs slower without fixing a race.
Capture failure evidence without changing test flow
Keep diagnostics separate from control flow. Cypress screenshots, videos, command logs, and network logs can explain why a test failed; they should not be used to swallow the failure. If you need an external screenshot of a URL for a report or an AI workflow, ScreenshotNeo provides a website screenshot API and MCP server.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
For a standalone page capture, one GET request returns PNG, JPEG, WebP, or PDF. The API accepts options for full-page or selector captures, device and viewport settings, waiting, custom headers and cookies, JavaScript, CSS, blocking, PDF layout, caching, and more. A clean capture first accepts consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status.
See the ScreenshotNeo API documentation for parameters. Replace the example URL with the page you need.
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}`);
ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots, and every feature is included on every plan. Sign up free to try it.
Performance and reliability decisions
- Prefer test separation for reporting: independent tests expose multiple defects in one run, but each test must establish its own state.
- Prefer assertion retry for readiness: it waits for a real condition and avoids rerunning side effects.
- Use retries sparingly: they multiply execution time and repeat hooks and mutations. Set them where the environment is known to be intermittent, not across every suite by default.
- Keep failures actionable: preserve the original error, attempt number, browser, environment, and artifacts. A green retry should trigger investigation rather than erase the first failure.
A practical decision sequence
- Ask whether the condition is expected to become true shortly. If yes, use a linked Cypress query and assertion, with an appropriate timeout.
- Ask whether later checks are logically independent. If yes, put them in separate
itblocks with isolated data and setup. - Ask whether repeating the entire scenario is safe and likely to overcome an intermittent failure. If yes, configure a small retry count and monitor the added time.
- Ask whether the failure is a known application exception rather than a failed assertion. If yes, add a narrowly matching per-test
cy.on('uncaught:exception')handler. - If none applies, let the test fail. A deterministic failure should remain visible until the application or test is corrected.
Frequently Asked Questions
Can Cypress continue from the command after a failed assertion?
No. Once the assertion fails after its retry period, the current test body stops. Cypress can run another test or rerun the whole test, but it does not resume at the next command.
How many times does retries: 2 run a test?
Up to three total attempts: the initial run plus two additional retries. Every attempt starts from the beginning.
Will a failed test stop all remaining Cypress tests?
Normally no; Cypress proceeds after the test’s attempts are exhausted. A failed shared hook can prevent dependent tests from running.
Should I return false from every uncaught-exception handler?
No. Return false only for a specifically identified exception your test intentionally expects. Let unknown exceptions fail the test.
The Bottom Line
To continue useful Cypress execution, separate independent checks into independent tests, rely on assertion retry only for asynchronous readiness, and configure limited whole-test retries for safe, intermittent failures. Never confuse a rerun or a later test with resuming commands after a failed assertion.
Quick Recap
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.
Recommended Free Tools

