How to Upgrade Cypress 10, 11, and 12
Upgrade Cypress one major version at a time: migrate Cypress 10 configuration, review Cypress 11 component tests, and prepare for Cypress 12 test isolation.
Upgrade Cypress one major version at a time: first migrate configuration from Cypress 9 to 10, then review Component Testing changes for Cypress 11, and finally prepare tests for Cypress 12’s default test isolation. At each step, verify the Cypress installation and run the project’s tests before continuing.
This guide covers the 9 → 10 → 11 → 12 path. If you are already on Cypress 10 or 11, start at your current version. The exact edits depend on your configuration, framework, tests, and local and CI environments; check the official Cypress migration guide for release-specific details.
1. Before you upgrade
- Find your installed version. Check the project’s package manifest and lockfile, or run
npx cypress versionfrom the project directory. - Confirm the upgrade path. Move to the next major only. Apply its migration changes and verify the project before moving on.
- Inventory the project. Note whether it uses end-to-end testing, Component Testing, or both. Find its Cypress configuration, plugin logic, support files, spec patterns, custom mount helpers, and CI commands.
- Record the environment. Note the Node.js and browser versions used locally and in CI. Check the requirements for each target Cypress release rather than assuming one release’s requirements apply to all of them.
- Start from a known state. Commit or otherwise preserve the current working state. This makes it easier to identify migration edits and recover if a change causes unexpected failures.
Do not combine several major upgrades into one unexplained change. If a test breaks, a single-major step makes it easier to connect the failure to a configuration change or changed behavior.
2. Upgrade from Cypress 9 to Cypress 10
Cypress 10 is chiefly a configuration migration. Cypress 10 requires a JavaScript or TypeScript configuration file and no longer supports cypress.json. Plugin-file event handling moves into setupNodeEvents(), and test-type settings belong under the appropriate e2e or component configuration.
Move configuration out of cypress.json
Create cypress.config.js or cypress.config.ts at the project root. Move the old settings into it, checking each one against the migration guide. For example, settings such as baseUrl, support-file paths, and spec patterns need to be placed in the relevant test-type configuration.
const { defineConfig } = require('cypress')
module.exports = defineConfig({
e2e: {
baseUrl: 'http://localhost:3000',
specPattern: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
supportFile: 'cypress/support/e2e.js',
setupNodeEvents(on, config) {
// Move Node event handlers from the old plugins file here.
return config
},
},
})
This is a structural example, not a complete conversion of every Cypress 9 option. Preserve the project’s real values, move each option to the correct test type, and remove options that the target release no longer supports. Use the TypeScript config form if that matches the project’s setup.
Move plugin event handling
Find the old plugins file and move its Node-side event registration and related setup into setupNodeEvents(on, config) in the configuration. Return the config object when the plugin logic modifies or passes it through. For Component Testing, put dev-server setup in the component devServer configuration rather than treating it as an end-to-end plugin setting.
Review test types, paths, and launch commands
- Put end-to-end settings under
e2eand Component Testing settings undercomponent. - Review paths and patterns, including former
componentFolder,testFiles, and support-file settings. Confirm the effective spec pattern matches the files in the repository. - Check the release’s default spec and support-file locations. Set explicit paths when the project uses a different layout.
- If a script opens Cypress directly to the specs list, update it to include the required testing type and browser arguments for that launch mode.
- Remove
cypress.jsonafter its settings have been migrated so developers do not mistake it for active configuration.
Run Cypress verification and the project’s tests after the configuration move. Fix this step’s errors before upgrading to Cypress 11.
3. Upgrade from Cypress 10 to Cypress 11
Cypress 11 made Component Testing generally available. The official guide says most projects should migrate without code changes, so focus the review on Component Testing behavior and framework-specific mounting APIs the project actually uses.
Check repeated mounts in one test
In Cypress 11, a later cy.mount() call in the same test removes the component mounted previously. If a test needs multiple components present together, compose them into one mounted component instead of relying on earlier mounts remaining on the page.
Check framework mount helpers
Review custom mount wrappers and framework-specific assumptions. For example, in Vue the Cypress 11 mount result contains both a wrapper and a component instance, and the Vue mountCallback helper was removed. Update code that expects the previous return shape or calls that helper. Do not change frameworks or mount code your project does not use.
After these checks, run verification and the Component Testing and end-to-end suites used by the project. Continue to Cypress 12 only when the Cypress 11 step is understood and passing to the project’s standard.
4. Upgrade from Cypress 11 to Cypress 12
Cypress 12 changes test isolation behavior. testIsolation is enabled by default, and its accepted values are booleans (true or false), not the earlier on or off strings. The experimental session and origin flag was removed as cy.origin() and cy.session() became generally available.
Remove the experimental flag
Find and remove experimentalSessionAndOrigin from the project configuration. Update tests to use the now generally available cy.origin() and cy.session() APIs as appropriate for their existing behavior. Consult the migration guide for API details and any project-specific migration.
Audit tests for shared browser state
With test isolation enabled, Cypress resets browser context before each test, including page state, cookies, local storage, and session storage. A test that silently depends on a preceding test’s login, page, or stored data may now fail when run on its own or in a different order.
- Search for tests that assume an earlier test left the browser on a particular page or established a login.
- Run suspect tests individually and in the normal suite to reveal order dependencies.
- Make each test establish the state it needs, for example by visiting the application and performing or restoring its own setup.
- Where session reuse is appropriate, review whether
cy.session()fits the project’s flow. - Keep isolation enabled unless there is a deliberate, documented reason to disable it.
If the project explicitly configures isolation, change 'on' and 'off' to true and false. Disabling isolation is possible, but state can leak between tests and make results order-dependent. The Cypress guide states that the testIsolation config option is enabled by default.
5. Verify each upgrade step
Use this sequence after each major-version migration, not just once at the end:
- Install the intended Cypress version using the project’s package manager and update its lockfile consistently.
- Run
npx cypress versionto confirm the project resolves the intended version. - Run
npx cypress verifyto verify the Cypress installation. - Open Cypress with the project’s normal command and confirm the expected test type, browser, and spec files appear.
- Run the relevant end-to-end and Component Testing suites, locally and in CI where available.
- Review failures for migration-specific causes before moving to the next major.
npx cypress version
npx cypress verify
npx cypress run
cypress run is a common headless suite command; use the scripts and browser configuration the project actually supports. A successful installation verification does not establish that application tests pass, so run both checks.
6. Common upgrade errors and fixes
| Symptom | Likely cause | What to check |
|---|---|---|
| Cypress 10 cannot load configuration | The project still relies on cypress.json, or the new config has invalid syntax or location. |
Confirm a supported cypress.config.js or .ts file exists at the project root, migrate settings into it, and check its syntax. |
| Specs or support code are not found | The migrated spec pattern or support-file path does not match the repository layout. | Review the e2e or component paths and confirm the configured pattern matches actual files. |
| Plugin setup no longer runs | Node event code remains in the old plugins file and was not moved into setupNodeEvents(). |
Move event registration into the appropriate configuration and return the config when required by the setup. |
| Component test behaves differently after a second mount | Cypress 11 removes the previous mounted component when another cy.mount() runs in the same test. |
Mount a composed component when several components must be present at once. |
| Vue mount helper or result access fails | The code relies on the removed Vue mountCallback or the previous mount return shape. |
Use the Cypress 11-supported API and account for the result containing a wrapper and component instance. |
| Tests fail only when run alone or in a different order | A test depended on browser state left by a previous test; Cypress 12 isolation resets that state. | Make the test establish its own page, cookies, and storage assumptions; use a suitable session flow where appropriate. |
Configuration rejects on or off for isolation |
The project retained the old string values. | Use boolean true or false, and decide deliberately whether disabling isolation is appropriate. |
| Direct launch no longer opens the expected spec list | The launch command omits testing-type or browser arguments required for that mode. | Update the command with the required type and browser arguments documented for the release. |
| Works locally but fails in CI | The local and CI Node.js, browser, install, or command environments differ. | Compare the actual environments and scripts, then check the requirements for the specific Cypress release being run. |
7. Performance, reliability, and upgrade cost
The migration guide identifies configuration and behavior changes; it does not establish a general runtime performance gain or a fixed migration duration. The practical effort depends on how much Cypress 9 configuration must move, whether Component Testing APIs are used, and how many tests rely on state shared across test boundaries.
- Reduce debugging time: upgrade one major at a time and run checks after each step, so failures have a smaller set of possible causes.
- Protect reliability: test cases that may have relied on inherited browser state both individually and as a suite after enabling Cypress 12 behavior.
- Account for CI: verify the same target version and relevant Node.js/browser setup in CI as locally. Requirements can vary by release.
- Plan review effort: configuration and test edits are the core work. No physical product is required for this migration.
8. Capture screenshots while debugging browser tests
Cypress screenshots can help document what a test rendered at a point in a run. When the goal is to capture a URL directly as an image or PDF for debugging, reports, or automation, ScreenshotNeo is a website screenshot API and MCP server for developers. It does not upgrade Cypress or replace the project’s test suite.
Or skip the browser setup
Instead of managing a separate browser capture setup for a URL, make one GET request. See the ScreenshotNeo API documentation for the request options.
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}`);
- Cookie and consent banners, newsletter popups, and chat widgets are removed before the shot; each cleanup step can be turned off.
- Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing. Response headers report the page verdict and billing status.
- An MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs.
- The free plan includes 1,000 shots a month with no card. Paid plans start at $5 for 3,000 shots.
Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.
9. Frequently asked questions
Can I jump straight from Cypress 9 to Cypress 12?
Use the sequential migration path: apply and verify the Cypress 10 changes, then Cypress 11, then Cypress 12. This makes it easier to isolate failures tied to each major release.
Do all projects need Cypress 11 Component Testing changes?
No. Review the mount API and related changes if the project uses Component Testing and the affected framework behavior. The official guide says most projects should migrate without code changes.
Should I turn off Cypress 12 test isolation to make old tests pass?
First fix tests that depend on state from previous tests. Isolation can be disabled, but that can cause state leakage and order-dependent failures. Use false only when the project deliberately needs it and the consequences are understood.
Does this upgrade require a paid Cypress tool or physical product?
The migration described here is project configuration and code work. The research for this guide identifies no necessary physical product or verified affiliate resource.


