How to Stop Cypress Tests at the Right Time
Choose the right way to stop Cypress work: end one test, skip the rest of a spec, or cancel a recorded Cloud run after a failure threshold.
Short answer: Use Cypress.stop() to stop the remaining tests in the current spec. To end one test successfully at a condition, keep optional follow-up commands inside a .then() callback and return before queuing them. To stop a recorded, parallel Cypress Cloud run after a failure threshold, use Cloud Auto Cancellation. These mechanisms have different scopes: Cypress.stop() does not cancel every spec in a Cloud run.
Pick the mechanism by the work you want to stop and the outcome you want recorded. Cypress tests finish as passed, failed, or pending/skipped; there is no partial-pass result for a test that simply stopped halfway through.
1. Choose the stop mechanism by scope
| Goal | Use | Scope and outcome |
|---|---|---|
| Stop later tests in this spec after a failure | Cypress.stop(), commonly in afterEach |
Stops the current spec. In cypress run, later tests in that spec are skipped. In cypress open, execution stops and the app stays open for inspection. |
| Finish this test successfully once a condition is satisfied | Conditionally avoid queuing the optional commands | The test can pass, provided the commands to skip were not already queued elsewhere. |
| Stop one test as a failure | Throw an error when the condition is detected | The test fails; remaining test commands do not provide a successful early exit. |
| Mark one test skipped at runtime | Mocha this.skip() |
The test is pending/skipped, not passed. Call it from a regular function callback so Mocha supplies this. |
| Stop assigning new specs in a recorded parallel run after failures | Cypress Cloud Auto Cancellation | Cloud cancels the run at its configured threshold. Specs already in progress finish. |
Before changing a suite, decide whether you need a fast local feedback loop, a complete release result, a nightly full-suite result, or an audit/coverage run. A stop rule that saves time locally may hide useful failures in a workflow that is meant to report every result.
2. Stop the remaining tests in the current spec
Use Cypress.stop() when a failure makes the rest of the current spec unhelpful or expensive. A support-file afterEach hook can stop after a failed test:
// cypress/support/e2e.js
// This hook applies to specs that load this support file.
afterEach(function () {
if (this.currentTest.state === 'failed') {
Cypress.stop()
return
}
})
The return exits this hook after stopping Cypress. Statements later in the same hook would otherwise continue to run. The return does not undo commands already queued elsewhere.
In cypress run, remaining tests in the current spec are skipped. In cypress open, Cypress stops execution and leaves the app open so you can inspect it. The stop is spec-scoped: other specs in a Cloud run are not thereby cancelled.
When to use this pattern
- Later tests depend on state that the failed test should have established.
- The remaining tests in the spec are costly and unlikely to provide useful diagnostics after this failure.
- You want to inspect the browser after the first failure during interactive debugging.
Avoid applying this indiscriminately to jobs whose purpose is to collect all independent failures. In those jobs, allow the spec to finish and use the complete result to guide fixes.
3. End one test successfully at a condition
Cypress commands are queued. Returning from a .then() callback prevents commands that would have been queued later inside that callback from being added. It does not cancel commands that were already queued outside it. Put conditional follow-up work inside the callback when it may need to be skipped.
it('opens the dashboard when it is available', () => {
cy.get('a').then(($links) => {
const hasDashboard = [...$links].some(
(el) => el.innerText.trim() === 'Dashboard'
)
if (hasDashboard) {
// Do not queue the optional follow-up commands.
return
}
// These commands are queued only when the condition is false.
cy.get('[data-cy="open-dashboard"]').click()
cy.get('[data-cy="dashboard"]').should('be.visible')
})
})
This test passes at the condition only if all necessary assertions have already succeeded and no later commands outside the callback still need to run. It is not a way to quietly hide a failure: if the condition indicates a broken requirement, fail explicitly instead.
Fail early when the condition is an error
it('requires the dashboard link', () => {
cy.get('a').then(($links) => {
const hasDashboard = [...$links].some(
(el) => el.innerText.trim() === 'Dashboard'
)
if (!hasDashboard) {
throw new Error('Expected a Dashboard link')
}
cy.get('[data-cy="dashboard"]').should('be.visible')
})
})
Skip when the test does not apply
Use Mocha’s runtime skip when the test is not applicable in the current situation. Use a regular function callback because an arrow function does not bind Mocha’s this.
it('checks an optional feature', function () {
cy.get('body').then(($body) => {
if (!$body.find('[data-cy="optional-feature"]').length) {
this.skip()
}
cy.get('[data-cy="optional-feature"]').should('be.visible')
})
})
Choose skip only when a pending result accurately describes the test. A feature that should exist but is missing is usually a failure, not a reason to skip.
4. Cancel a recorded Cypress Cloud run after a threshold
For a recorded parallel run, configure Auto Cancellation in Cypress Cloud project settings or override the threshold for a specific run. For example, set the threshold to five failed tests:
npx cypress run --record --key YOUR_RECORD_KEY --auto-cancel-after-failures 5
To disable the project setting for one run, pass false:
npx cypress run --record --key YOUR_RECORD_KEY --auto-cancel-after-failures false
Auto Cancellation controls the recorded run across machines. Once the threshold is reached, Cloud stops handing out new specs and marks the run cancelled; specs already running finish. The documented default threshold is one failed test. The feature is documented for Business and Enterprise plans, and plan availability or defaults can change, so confirm current Cloud settings before relying on them.
Set a threshold that matches the workflow
- Fast feedback: A low threshold can avoid spending time on a run that is already known to be unhealthy.
- Release validation: Keep enough execution to learn whether failures are isolated or broad; disabling cancellation for that run may be appropriate.
- Nightly, audit, or coverage work: Prefer a complete suite result when the goal is to discover all failing areas.
Cloud cancellation is not an instantaneous kill of every browser process. Account for already-running specs when estimating how much work remains after the threshold is crossed.
5. Configure retries deliberately
Retries rerun a failing test; they do not stop a suite. Cypress documents retries as zero by default in both run and open modes. When enabled, a retry repeats the test and its beforeEach and afterEach hooks. Failures in before and after hooks do not trigger retries. The configured retry count is the number of additional attempts beyond the first.
// cypress.config.js
const { defineConfig } = require('cypress')
module.exports = defineConfig({
retries: {
runMode: 2,
openMode: 0,
},
})
Choose retry counts for the workflow rather than using retries as an indirect stop policy. More attempts can increase runtime, especially when each failing attempt reruns setup and cleanup hooks. If a test is flaky, retries may provide diagnostic signal, but they do not replace fixing unstable setup or controlling which commands are queued.
6. Troubleshoot common stopping problems
| Symptom | Likely cause | Fix |
|---|---|---|
Cypress.stop() does not stop every Cloud spec |
It stops the current spec, not the entire recorded parallel run. | Use Cloud Auto Cancellation for a run-wide failure threshold. |
Statements after Cypress.stop() in a hook still execute |
Stopping Cypress does not exit the JavaScript function. | Return immediately after the call if the remainder of that hook must not run. |
A test continues after returning from .then() |
Later commands were already queued outside that callback. | Move conditional commands into the callback so they are not enqueued before the condition is checked. |
| A conditionally-ended test is marked failed | An assertion or command already failed, or an error was thrown. | Use a passing early return only when the completed work satisfies the test. Throw only when the requirement should fail. |
this.skip() has no Mocha context |
The test uses an arrow function, which does not bind Mocha’s this. |
Use function () {} for the test callback and call this.skip() there. |
| A Cloud run is cancelled but some specs keep running | Specs already in progress are allowed to finish. | Expect cancellation to stop new spec assignment, not forcibly terminate in-progress specs. |
| Retries make the run longer than expected | Each retry reruns the test and its beforeEach/afterEach hooks. |
Set an intentional retry count per mode and account for repeated setup work. |
| Auto Cancellation setting is unavailable | The feature is documented for Cypress Cloud Business and Enterprise plans. | Check current plan eligibility and project settings; use a spec-scoped stop or queue control if those match the need. |
7. Reliability, performance, and cost trade-offs
Stopping work saves time only when the remaining results have low value for the workflow. A stop at the first failure can shorten feedback, but it also reduces the failures and coverage information available from that run. Full execution costs more runtime when many tests are independent, while retries can multiply the work for each failing test and rerun per-test hooks.
For predictable results, keep the stop scope explicit: use command queue control inside a single test, Cypress.stop() inside a spec, and Cloud Auto Cancellation for the recorded parallel run. Check that tests later in a spec do not need to run for release, audit, or coverage reporting. Track the threshold and retry count in versioned configuration or the run command so a workflow’s behavior is reviewable.
8. Or skip the browser setup
If a test or debugging workflow also needs a clean screenshot of a page, ScreenshotNeo captures a URL with one API request, without setting up a browser automation project:
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. Cookie banners are accepted and removed before the shot, along with known newsletter popups and chat widgets. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
Sign up for 1,000 free screenshots a month, with no card.
9. FAQ
Does Cypress.stop() stop the whole test suite?
It stops the current spec. It does not by itself cancel other specs in a recorded Cloud run.
Can a Cypress test pass after stopping partway through?
There is no partial-pass state. A test can pass if it reaches a valid condition and avoids queuing unnecessary commands; otherwise it can fail or be skipped.
Do retries stop Cypress after the first failure?
No. Retries rerun failing tests. Use a stop mechanism with the scope and outcome you intend.
Does Cloud Auto Cancellation stop specs that are already running?
No. It stops Cloud from assigning new specs and cancels the run; specs already in progress finish.


