If you want a readable, easy-to-change, independent, and other superlatives you can think of, in terms of scaling your Cypress framework, then I suggest using configuration files π. It is actually not as hard as some other options on environment variables manipulation can do.
First, create a config
folder under the project's root directory (a.k.a. outside the cypress
folder). Your extreme patience is needed to answer the question why I would like it placed there.
Next, create two env.json
files, namely,
local.env.json
:
{
"env": {
"domain": "localhost:8080",
"description": "This is my local machine!",
"protocol": "http://",
"subDirectory": "helloworld"
}
}
test1.env.json
:
{
"env": {
"domain": "test1.domain.com",
"description": "This is awesome company's stage environment",
"protocol": "https://",
"subDirectory": "/helloworld"
}
}
Then, go to plugins/index.js
and insert the following script:
const fs = require('fs-extra');
const path = require('path');
function getConfigurationByFile (file) {
const pathToConfigFile = path.resolve('config', `${file}.json`);
return fs.readJson(pathToConfigFile)
}
// plugins file
module.exports = (on, config) => {
// accept a configFile value or use local by default
const file = config.env.configFile || 'local';
return getConfigurationByFile(file)
};
Something I forgot: You may need to install the package fs-extra as a pre-requisite (npm i --save-dev fs-extra
)
Lastly, you can just invoke the environment variables on your tests under the integration
folder:
CheckTheUrl.js
const helloWorldUrl = Cypress.env('protocol') + Cypress.env('domain') + Cypress.env('subDirectory')
describe('Run this baby!', ()=> {
it('Run this baby, I said!', ()=> {
cy.visit(helloWorldUrl);
cy.log('This is for demo purpose so I am not doing assertion!');
});
});
And, drop-dead last step is to execute the test via the CLI (whether it's your IDE's terminal or your CI pipeline) with the command below:
npx cypress run --env configFile=local
and if you are feeling nerdy π€, remove the hard-coding and parameterise the value for configFile
with something like %envName%
where you can always interchange the value on your CI configurations / parameters.
As a bonus, you can also include this script on your package.json
with the following line:
"scripts": {
"cy:run": "node scripts/cypress.js",
"e2e:ci": "cypress run --env 'configFile=%envName%'"
}
So, why did I place the config
sub-folder outside the cypress
folder? Sorry for the anti-climax but it is simply due to the fact that I want to re-use these environment variables for my other frameworks such as k6 (since these are just data in json format). I can create something like this:
import http from `k6/http`;
const config = JSON.parse(open('../config/local.env.json'));
import { sleep } from 'k6';
const helloWorldUrl = `${config.env.protocol}${config.env.domain}${config.env.subDirectory}`;
export let options = {
vus: 50, // no. of virtual users
duration: '30s',
};
export default function() {
console.log(`Attacking the Hello World page, baby!`);
http.get(`${helloWorldUrl}`);
sleep(1);
}
Putting it outside makes it cleaner, although a lazy engineer can always make a case to still point it to the cypress
folder.
Top comments (2)
Hey @poponuts , I wonder if you can help me wth my query. I'm also working on that piece where I wanna call different environment files (qa.json, uat.json)
I've followed your steps above as well as other forum but to no avail.
I'm always getting this error
The function exported by the plugins file threw an error.
We invoked the function exported by
/Users/xxxxx/Cypress/projectfolder/cypress/plugins/index.js
, but it threw an error.Error: ENOENT: no such file or directory, open '/Users/xxxxx/Cypress/projectfolder/config/uat.json'
Note: my config is outside the Cypress folder as you mentioned above
Looks like I'm having issue with path.resolve() or the readJson() and Im not sure if I'm missing here such as packages, set up, version? Hope to hear from you.
Probably a sample github code might help. Thanks
I'm not sure if you have resolved this issue and apologies for the late response (I usually check my dev.to account only when I'm about to write something).
It's hard to know the context of your issue but this is my "stab-in-the-dark" solution:
Try changing this line to the following:
`
const pathToConfigFile = path.resolve('../../config',
${file}.json);
../..