Cypress 12’s breaking changes are primarily driven by a significant shift in how it handles dependencies and its internal architecture, specifically impacting plugin loading and configuration.
Common Causes and Fixes
-
cypress.config.tsinstead ofcypress.json:- Diagnosis: Cypress 12 defaults to
cypress.config.ts(or.js) for configuration. If you’re still usingcypress.json, Cypress won’t load your configuration. - Command: Run
ls cypress.config.tsorls cypress.config.jsin your project root. - Fix:
- If you have a
cypress.json, rename it tocypress.config.ts(or.js). - If you have specific TypeScript types you want to leverage, create
cypress.config.tsand migrate your JSON content. For example, ifcypress.jsonhad:
Your{ "baseUrl": "http://localhost:3000", "viewportWidth": 1280, "viewportHeight": 720 }cypress.config.tsshould look like:import { defineConfig } from 'cypress'; export default defineConfig({ e2e: { baseUrl: 'http://localhost:3000', setupNodeEvents(on, config) { // implement node event listeners here }, }, viewportWidth: 1280, viewportHeight: 720, });
- If you have a
- Why it works: Cypress 12 prioritizes the
.config.tsand.config.jsfiles for its primary configuration, offering better type safety and extensibility. Thee2ekey withindefineConfigis now the standard for End-to-End specific configurations.
- Diagnosis: Cypress 12 defaults to
-
Plugin API Changes (
setupNodeEvents):- Diagnosis: The
setupNodeEventsfunction signature in yourcypress.config.ts(or.js) has changed. It no longer directly receives theconfigobject as the second argument. Instead, you access and modify the configuration within thesetupNodeEventsfunction. - Command: Inspect your
cypress.config.tsfile for thesetupNodeEventsfunction. - Fix:
- Before (Cypress < 12):
// cypress/plugins/index.ts (or similar) module.exports = (on, config) => { // modify config here return config; }; - After (Cypress 12+):
// cypress.config.ts import { defineConfig } from 'cypress'; export default defineConfig({ e2e: { setupNodeEvents(on, config) { // `config` object is now passed into setupNodeEvents // Example: Add an environment variable config.env.MY_CUSTOM_VAR = 'some-value'; return config; // MUST return the config object }, }, });
- Before (Cypress < 12):
- Why it works: This change standardizes configuration loading. The
setupNodeEventsfunction is now the single point of entry for modifying the Cypress configuration object before tests run, ensuring consistency and predictability.
- Diagnosis: The
-
Deprecated
cypress.env.json:- Diagnosis: Cypress 12 deprecates
cypress.env.jsonfor defining environment variables. These variables are now expected to be managed via theenvobject incypress.config.tsor through system environment variables. - Command: Check your project for a
cypress.env.jsonfile. - Fix:
- Move the key-value pairs from
cypress.env.jsoninto theenvobject within yourcypress.config.ts. - Before (Cypress < 12):
// cypress.env.json { "API_URL": "http://localhost:5000", "USER_EMAIL": "test@example.com" } - After (Cypress 12+):
// cypress.config.ts import { defineConfig } from 'cypress'; export default defineConfig({ e2e: { setupNodeEvents(on, config) { config.env.API_URL = process.env.API_URL || 'http://localhost:5000'; // Example with fallback to system env var config.env.USER_EMAIL = 'test@example.com'; return config; }, }, // Or directly if not using setupNodeEvents for this: // env: { // API_URL: 'http://localhost:5000', // USER_EMAIL: 'test@example.com', // }, });
- Move the key-value pairs from
- Why it works: Consolidating configuration and environment variables into
cypress.config.tsor system environment variables simplifies management and reduces the number of configuration files Cypress needs to parse.
- Diagnosis: Cypress 12 deprecates
-
browserField incypress.config.ts:- Diagnosis: The
browserfield, which previously allowed specifying a default browser directly incypress.json, is now part of thee2eobject incypress.config.ts. - Command: Look for a top-level
browserkey in yourcypress.json(if you haven’t migrated yet) orcypress.config.ts. - Fix:
- If you had:
// cypress.json { "browser": "chrome" } - Migrate to:
// cypress.config.ts import { defineConfig } from 'cypress'; export default defineConfig({ e2e: { // ... other e2e config browser: 'chrome', // Or 'firefox', 'edge', etc. }, });
- If you had:
- Why it works: This change groups all End-to-End specific configurations under the
e2enamespace, providing a clearer hierarchical structure for your Cypress settings.
- Diagnosis: The
-
componentConfiguration Moved:- Diagnosis: If you use Cypress for Component Testing, the
componentconfiguration object has also moved to be a child of thedefineConfigexport, similar toe2e. - Command: Check your
cypress.config.tsfor a top-levelcomponentobject and ensure it’s nested correctly. - Fix:
- Before (Cypress < 12, if
cypress.jsonwas used for some parts):// cypress.json { "component": { "devServer": { "framework": "react", "bundler": "webpack" } } } - After (Cypress 12+):
// cypress.config.ts import { defineConfig } from 'cypress'; export default defineConfig({ // ... e2e config component: { devServer: { framework: 'react', bundler: 'webpack', }, }, });
- Before (Cypress < 12, if
- Why it works: This mirrors the
e2econfiguration structure, creating a consistent way to define settings for different testing types within a single configuration file.
- Diagnosis: If you use Cypress for Component Testing, the
-
Node.js Version Requirement:
- Diagnosis: Cypress 12 requires Node.js v16 or higher. If your CI environment or local machine is running an older version, Cypress will fail to initialize.
- Command: Run
node -vin your terminal. - Fix: Update your Node.js installation to v16 or a later LTS version (e.g., v18, v20). This often involves using a Node Version Manager (NVM) like
nvmorfnm.- Example using
nvm:nvm install 18 # Installs Node.js v18 nvm use 18 # Sets v18 as the current version node -v # Verify installation
- Example using
- Why it works: Newer Node.js versions include updated JavaScript runtimes and APIs that Cypress leverages for its internal operations and plugin execution.
After fixing these, you’ll likely encounter EACCES permission errors if your node_modules directory has incorrect ownership, requiring you to sudo chown -R $(whoami) node_modules or clear and reinstall dependencies.