Search code examples
reactjsenvironment-variablescypressdotenv

process.env empty object in Cypress


I am working on a React app bootstraped from create-react-app few years ago.

The app has a .env.dev file with many variables. The start script is "start": "env-cmd -f .env.dev --use-shell \"react-scripts start\"",

React script version: "react-scripts": "^4.0.1",

When I console.log("gggg", process.env); I get all the variables. When I:

describe('Login via API', () => {
  it('Test login', () => {
    console.log('teeest', process.env)
    cy.login()
  })
})

instead I get an empty object.

I tried to read the question How to use process.env variables in browser running by Cypress

however this question does not answer my question on how to make the process.env variables available to Cypress test files.

Also this question says to install dotenv. Dotenv comes with react-scripts, so no need to install it if the app was create by create-react-app.

I also tried this: in cypress.config.js I added:

const { defineConfig } = require("cypress");

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      config.env = process.env
      return config
    }
  }
})

And in the spec I try to get the variable defined in .env.dev file:

  it('Test login', () => {
    console.log('new', Cypress.env('REACT_APP_USERNAME'))
    cy.login()
  })

Still getting undefined.

Can anyone please help me to understand what's wrong? How can I make it work?

Edit: According to an answer here I tried to install dotenv:

  1. npm install dotenv --save

  2. imported in the test:

    import 'dotenv/config'

    describe('Login via API', () => { it('Test login', () => { console.log('newwwww', Cypress.env('REACT_APP_USERNAME')) console.log('teeest', process.env) cy.login() }) })

  3. Npm start

  4. npm run cypress:open

Result:

newwwww undefined
login-test.cy.js:7 teeest {}

Thanks


Solution

  • When you use "start": "env-cmd -f .env.dev --use-shell \"react-scripts start\"", the env-cmd command is specific to the process for the react app.

    You would need the same to run before cypress opens it's process

    package.json

    {
      ...
      "dependencies": {
        ...
      },
      "scripts": {
        "cy:open": "env-cmd  -f .env.dev cypress open",
        ...
      }
    }
    

    Avoiding conflict with other env setting


    I also recommend using the spread operator as shown below, otherwise you would lose any env var added in other ways, e.g command line additions.

    const { defineConfig } = require("cypress");
    
    module.exports = defineConfig({
      e2e: {
        setupNodeEvents(on, config) {
          config.env = {
            ...process.env,                 // add all process env var here
            ...config.env                   // plus any command line overrides
          }
          return config                     // return the altered config
        },
      },
      env: {
        login_url: '/login',                // define some specific env var here
        products_url: '/products'
      }
    });
    

    Avoiding pollution of Cypress settings


    If you take a look at Settings/Project Settings in the Cypress runner, you'll see a huge number of unnecessary settings which come from the general machine env var.

    To pick just those with prefix REACT_,

    const { defineConfig } = require("cypress");
    
    module.exports = defineConfig({
      e2e: {
        setupNodeEvents(on, config) {
    
          const reactEnv = Object.keys(process.env).reduce((obj, key) => {
            if (key.startsWith('REACT_')) {
              obj[key] = process.env[key];
            }
            return obj;
          }, {});
    
          config.env = {
            ...reactEnv,                    // add REACT_ process env var here
            ...config.env                   // plus any command line overrides
          }
          return config                     // return the altered config
        },
      },
      env: {
        login_url: '/login',                // define some specific env var here
        products_url: '/products'
      }
    });