Easily manage and streamline your Cypress test scripts across multiple environments with the cypress-env npm library. This lightweight utility simplifies the process of handling different environments (such as test, staging, and production) by providing environment-specific settings in your Cypress tests.
- Install
- Breaking Changes in v2.x
- Configuration
- Shared Configurations Feature
- Configuration Priority Order
- Results example
- Little tip for you
- Compatibility with cypress-aws-secrets-manager
$ npm install cypress-env --save-devor as a global module
$ npm install -g cypress-envStarting from version 2.0, cypress-env uses async/await syntax for better compatibility with modern Cypress and other plugins. Update your configuration as follows:
Old syntax (v1.x):
// cypress.config.js - OLD
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
require("cypress-env")(on, config, __dirname)
},
},
})New syntax (v2.x):
// cypress.config.js - NEW
module.exports = defineConfig({
e2e: {
async setupNodeEvents(on, config) {
const { setCypressEnv } = require("cypress-env")
config = await setCypressEnv(config, __dirname)
return config
},
},
})The new syntax provides:
- Better compatibility with async plugins like
cypress-aws-secrets-manager - Explicit function naming for clarity
- Proper async/await support
In your cypress.config.js file:
module.exports = defineConfig({
e2e: {
async setupNodeEvents(on, config) {
const { setCypressEnv } = require("cypress-env")
config = await setCypressEnv(config, __dirname)
return config
},
},
})Then configure a folder named env.config with your environments JSON files:
├── cypress
│ ├── e2e
│ ├── fixtures
│ └── support
├── cypress.config.js
├── env.config
│ ├── test.json
│ ├── stage.json
│ └── prod.json
├── node_modules
├── README.md
├── package-lock.json
├── package.json
└── .gitignoreJSON files must respect this syntax:
// environment.json
{
"baseUrl": "https://www.google.com",
"specPattern": "cypress/e2e/**/**.js",
"excludeSpecPattern": "cypress/e2e/**/toExclude.js",
"supportFile": "cypress/support/customName.js",
"env": {
"var1": "value1",
"var2": "value2",
"var3": "value3",
"envName": "environment"
}
}| Parameter | Mandatory | Overwrites value in cypress.config.js |
Notes |
|---|---|---|---|
| baseUrl | FALSE | TRUE | Overwrites value in cypress.config.js |
| specPattern | FALSE | TRUE | Overwrites value in cypress.config.js |
| excludeSpecPattern | FALSE | TRUE | Overwrites value in cypress.config.js |
| supportFile | FALSE | TRUE | Requires supportFile in the main e2e or component object set to false |
| shared | FALSE | N/A | Boolean: enables loading of shared configurations from _shared.json |
| env | FALSE | FALSE | Merged into env object in cypress.config.js |
The plugin supports different log modes controlled by the ENV_LOG_MODE environment variable. By default, full logs are displayed. To restrict output and show only summary messages, set:
# Open Cypress in silent mode
npx cypress open -e envName=stage -e ENV_LOG_MODE=silentWhen ENV_LOG_MODE is set to 'silent', detailed logs such as configuration extraction paths and parameter listings are suppressed. Only the final success message is shown.
Default verbose logs:
Extracting local configurations from: path/to/environment.json
- baseUrl: "https://www.google.com"
- specPattern: "cypress/e2e/**/**.js"
- excludeSpecPattern: "cypress/e2e/**/toExclude.js"
- supportFile: "cypress/support/customName.js"
- env: {
"var1": "value1",
"var2": "value2",
"var3": "value3",
"envName": "test"
}
√ Configurations loaded correctly for the environment: < TEST >Silent mode logs:
√ Configurations loaded correctly for the environment: < TEST >Open Cypress and inject the envName and optional ENV_LOG_MODE:
npx cypress open -e envName=test
# or silent:
npx cypress open -e envName=test -e ENV_LOG_MODE=silentor run Cypress tests:
npx cypress run -e envName=test
# or silent:
npx cypress run -e envName=test -e ENV_LOG_MODE=silentYou can now use shared configurations across multiple environments! Add a _shared.json file in your env.config folder to define common settings that can be reused across environments.
Structure with shared configurations:
├── env.config
│ ├── _shared.json # ← Common configurations
│ ├── test.json
│ ├── stage.json
│ └── prod.jsonExample _shared.json:
{
"viewportWidth": 1920,
"viewportHeight": 1080,
"supportFile": "cypress/support/env.js",
"env": {
"commonApiUrl": "https://api.example.com",
"defaultTimeout": 10000,
"retries": 2,
"sharedVariable": "This value is shared across environments",
"specificTestVar": "This value is overwritten buy env configurations"
}
}Example environment with shared configurations:
// test.json
{
"shared": true,
"baseUrl": "https://test.example.com",
"specPattern": ["**/*.test.js"],
"env": {
"specificTestVar": "This overrides shared settings"
}
}When "shared": true is set in an environment file:
- Shared configurations are loaded first from
_shared.json - Environment-specific settings override shared ones
- Environment variables are merged, with environment-specific taking precedence
The plugin respects a strict priority order in two different way:
- CLI arguments (highest priority) - Cannot be overridden
- Environment JSON files - Environment-specific settings
- Shared configurations - Common settings from
_shared.json - Default config - Base
cypress.config.jssettings (lowest priority)
- CLI arguments (highest priority) - Cannot be overridden
- Default config - Base
cypress.config.jssettings - Environment JSON files - Environment-specific settings
- Shared configurations - Common settings from
_shared.json(lowest priority)
Why the difference?
- Environment variables have Cypress built-in support to detect CLI vs config source, allowing the plugin to respect the intuitive priority order
- Cypress configurations (baseUrl, specPattern, etc.) don't provide source detection, so the plugin cannot establish intuitive priority order
This means:
- CLI parameters like
-e var=valuewill never be overwritten for both types - For env variables: Environment-specific > Shared > Default
- For configurations: Default > Shared > Environment-specific
Benefits:
- Reuse common configurations across multiple environments
- Override only what's different per environment
- Cleaner environment files with less duplication
- Easier maintenance of shared settings
- Predictable configuration precedence with CLI always taking priority
====================================================================================================
Starting plugin: cypress-env
Extracting local configurations from: "path/to/environment.json"
- baseUrl: "https://www.google.com"
- specPattern: "cypress/e2e/**/**.js"
- excludeSpecPattern: "cypress/e2e/**/toExclude.js"
- supportFile: "cypress/support/customName.js"
- env: "{\n \"var1\": \"value1\",\n \"var2\": \"value2\",\n \"var3\": \"value3\",\n \"envName\": \"test\"\n }"
√ Configurations loaded correctly for the environment: < TEST >
========================================================================================================================================================================================================
Starting plugin: cypress-env
Extracting local configurations from: "path/to/test.json"
Loading shared configurations from: "path/to/_shared.json"
- baseUrl: "https://test.example.com"
- specPattern: ["**/*.test.js"]
- viewportWidth: 1920
- viewportHeight: 1080
- supportFile: "cypress/support/env.js"
- env: {
"commonApiUrl": "https://api.example.com",
"defaultTimeout": 10000,
"retries": 2,
"sharedVariable": "This value is shared across environments",
"envName": "test",
"specificTestVar": "This overrides shared settings"
}
√ Configurations loaded correctly for the environment: < TEST > (with shared configurations)
========================================================================================================================================================================================================
Starting plugin: cypress-env
√ No environment configuration specified, using basic configuration!
========================================================================================================================================================================================================
Starting plugin: cypress-env
ConfigurationError!
You must specify the "__dirname" element in the config, change the require to:
const { setCypressEnv } = require("cypress-env")
config = await setCypressEnv(config, __dirname)
return config
====================================================================================================In your package.json file create scripts like this:
// package.json
{
"scripts": {
"cy:test": "npx cypress open -e envName=test",
"cy:stage": "npx cypress open -e envName=stage",
"cy:prod": "npx cypress open -e envName=prod",
"cy:stage:silent": "npx cypress open -e envName=stage -e ENV_LOG_MODE=silent"
}
}So you'll only have to type:
npm run cy:testcypress-aws-secrets-manager is a plugin that allows secrets stored in AWS Secrets Manager to be loaded into Cypress as environment variables. To make life easier, you can include the key AWS_SECRET_MANAGER_CONFIG inside env.
| Parameter | Mandatory | Overwrites value in cypress.config.js |
Notes |
|---|---|---|---|
| AWS_SECRET_MANAGER_CONFIG | FALSE | TRUE | Object used by cypress-aws-secrets-manager |
Example cypress.config.js with both plugins:
// cypress.config.js
module.exports = defineConfig({
e2e: {
async setupNodeEvents(on, config) {
// Load cypress-env FIRST to set up environment configurations
const { setCypressEnv } = require("cypress-env")
config = await setCypressEnv(config, __dirname)
// Then load AWS secrets using the environment configuration
const { getSecretFromAWS } = require("cypress-aws-secrets-manager")
config.env = await getSecretFromAWS(config.env, __dirname)
require("cypress-aws-secrets-manager/tasks")(on, config)
return config
},
},
})Example environment.json with AWS configuration:
// environment.json
{
"baseUrl": "https://www.google.com",
"specPattern": "cypress/e2e/**/**.js",
"excludeSpecPattern": "cypress/e2e/**/toExclude.js",
"supportFile": "cypress/support/customName.js",
"env": {
"var1": "value1",
"var2": "value2",
"var3": "value3",
"envName": "test",
"AWS_SECRET_MANAGER_CONFIG": {
"secretName": "...",
"profile": "...",
"region": "..."
}
}
}Important: Always import cypress-env before cypress-aws-secrets-manager to ensure environment configurations are loaded first.
Happy testing to everyone! 🎉
ALEC-JS