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:
npm install dotenv --save
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() }) })
Npm start
npm run cypress:open
Result:
newwwww undefined
login-test.cy.js:7 teeest {}
Thanks
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
{
...
"dependencies": {
...
},
"scripts": {
"cy:open": "env-cmd -f .env.dev cypress open",
...
}
}
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'
}
});
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'
}
});