Skip to content

Cypress Environment Variables

Environment variables let you configure values, like API URLs, feature flags, or test credentials, differently across environments without changing test code. This lesson covers every way to set and read them in Cypress.

Cypress.env() and Where Values Come From

Cypress.env(key) reads a value from Cypress's environment variable store, which can be populated from several sources: the env block in cypress.config.js, a cypress.env.json file, CLI flags, or actual OS environment variables prefixed with CYPRESS_.

// cypress.config.js
export default defineConfig({
  e2e: {
    env: {
      apiUrl: 'https://staging-api.example.com',
    },
  },
});

// in a spec file
cy.request(`${Cypress.env('apiUrl')}/health`);

Cypress.env('apiUrl') reads the value configured in the env block, kept separate from Cypress's own core settings like baseUrl.

Ways to Set Environment Variables

// cypress.config.js
env: { apiUrl: '...' }

// cypress.env.json (gitignored for secrets)
{ "apiUrl": "..." }

// CLI flag
npx cypress run --env apiUrl=https://staging-api.example.com

// OS environment variable
CYPRESS_apiUrl=https://staging-api.example.com npx cypress run
  • CLI --env flags override config file and cypress.env.json values.
  • OS variables prefixed with CYPRESS_ are automatically picked up by Cypress.
  • cypress.env.json is a good place for local secrets and should typically be gitignored.
  • Later sources in Cypress's resolution order override earlier ones for the same key.

Environment Variable Precedence Cheat Sheet

From lowest to highest priority when the same key is set in multiple places.

Source Priority
cypress.config.js env block Lowest
cypress.env.json file Low-medium
CYPRESS_* OS environment variables Medium-high
--env CLI flag Highest

Reading Environment Variables in Tests

Cypress.env() called with no arguments returns the entire environment object, useful for debugging what values are actually active during a given run.

it('logs the current environment config', () => {
  cy.log(JSON.stringify(Cypress.env()));
  expect(Cypress.env('apiUrl')).to.be.a('string');
});

Handling Secrets Safely

Never commit real secrets (API keys, test account passwords) directly into cypress.config.js or a tracked cypress.env.json. Instead, inject them via CI-provided environment variables (CYPRESS_*) at runtime, keeping them out of source control entirely.

  • Add cypress.env.json to .gitignore if it will ever contain real secrets.
  • Configure secrets as CI environment variables prefixed with CYPRESS_.
  • Never log full secret values with cy.log() or console.log(), even during debugging.

Supporting Multiple Environments

Cypress's --env flag and Node-level config profiles (via configFile or environment-specific config functions) both support running the same suite against different environments, local, staging, production-like, without duplicating spec files.

npx cypress run --env environmentName=staging --config baseUrl=https://staging.example.com

Common Mistakes

  • Committing real secrets into a tracked cypress.env.json or directly into cypress.config.js.
  • Confusing Cypress.env() (custom values) with core Cypress config like Cypress.config('baseUrl').
  • Not understanding the precedence order, leading to confusion about why a CLI flag isn't taking effect.
  • Hardcoding environment-specific URLs directly in spec files instead of using environment variables.

Key Takeaways

  • Cypress.env(key) reads custom environment variables from several possible sources.
  • CLI --env flags have the highest precedence, overriding config files and cypress.env.json.
  • Secrets should be injected via CI environment variables, never committed to source control.
  • The same suite can target multiple environments by varying environment variables and config, not spec files.

Pro Tip

Log Cypress.env() once at the very start of a suspicious CI run when a test behaves differently than locally, mismatched or missing environment variables are one of the most common, and quickest to diagnose, causes of "works locally, fails in CI."