Cypress offers several powerful mechanisms for defining environment variables, each suited for different use cases. Understanding these options is crucial for building a flexible configuration strategy. It's important to note that since Cypress v10, the primary configuration file has shifted from cypress.json
to cypress.config.js
(or .ts
), which offers more dynamic capabilities. We'll cover both modern and legacy approaches.
1. The Configuration File (cypress.config.js
)
This is the most common and recommended place to set default environment variables for your project. By defining them in cypress.config.js
, you ensure they are available to all tests within the project. You can add an env
key to your configuration object.
Example (cypress.config.js
):
const { defineConfig } = require('cypress');
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
baseUrl: 'http://localhost:3000',
env: {
login_url: '/login',
api_server: 'http://localhost:8080/api/v1',
user_role: 'admin'
}
},
});
This method is excellent for non-sensitive, project-wide defaults. According to official Cypress documentation, this file is the heart of your Cypress setup and the first place you should look for project configuration.
2. The cypress.env.json
File
For values you wish to override or keep separate from the main configuration, Cypress automatically looks for a cypress.env.json
file. This file is often added to .gitignore
to prevent sensitive data like API keys or credentials from being committed to version control. This practice is a cornerstone of secure software development, as highlighted by OWASP's security guidelines.
Example (cypress.env.json
):
{
"api_key": "super_secret_key_12345",
"user_role": "power_user",
"api_server": "https://staging.api.myapp.com"
}
If a variable is defined in both cypress.config.js
and cypress.env.json
, the value from cypress.env.json
will take precedence. This makes it ideal for local overrides.
3. Command Line Flags (--env
)
For ultimate flexibility, especially within CI/CD pipelines, you can pass environment variables directly through the command line when you run Cypress. This is achieved using the --env
flag. This method overrides any values set in the configuration files.
Example (Command Line):
$ npx cypress run --env user_role=guest,api_server=https://prod.api.myapp.com
This dynamic approach is essential for modern DevOps practices. A guide on continuous integration from Atlassian underscores the importance of parameterizing build scripts for different stages, and the --env
flag is Cypress's answer to this need.
4. System Environment Variables (Prefixed with CYPRESS_
)
Cypress can automatically read system-level environment variables from your shell, provided they are prefixed with CYPRESS_
. This is another powerful method for CI/CD environments where secrets are often managed as environment variables on the build agent.
Example (Shell):
$ export CYPRESS_API_KEY="ci_secret_key_from_vault"
$ export CYPRESS_USER_ROLE="ci_runner"
$ npx cypress run
Cypress will automatically strip the CYPRESS_
prefix and convert the variable name to lowercase. So, CYPRESS_API_KEY
becomes available in your tests as api_key
. This is a clean, secure way to inject secrets without them ever touching your codebase, a principle strongly advocated in GitHub Actions documentation for secret management.
5. The Plugins File (setupNodeEvents
)
For the most advanced and dynamic scenarios, you can use the setupNodeEvents
function within your cypress.config.js
. This function runs in a Node.js environment, giving you the power to read files, make API calls, or perform any other Node-based logic to determine your configuration before the tests run. The returned config
object will be the final configuration used by Cypress.
Example (cypress.config.js
):
const { defineConfig } = require('cypress');
const fs = require('fs');
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
// Load a config file based on the target environment
const environment = config.env.target_environment || 'staging';
const configFile = `./config/${environment}.json`;
const settings = JSON.parse(fs.readFileSync(configFile, 'utf8'));
// Merge the new settings into the config.env object
config.env = { ...config.env, ...settings };
// It's important to return the updated config object
return config;
},
},
});
This method allows you to build sophisticated configuration-loading strategies, such as pulling settings from a cloud provider's secret manager or a dedicated configuration service.