DEV Community

poponuts
poponuts

Posted on

Using config files for multiple environment variables in Cypress

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"
 }
}
Enter fullscreen mode Exit fullscreen mode

test1.env.json:

{
 "env": {
  "domain": "test1.domain.com",
  "description": "This is awesome company's stage environment",
  "protocol": "https://",
  "subDirectory": "/helloworld"
 }
}
Enter fullscreen mode Exit fullscreen mode

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)
};
Enter fullscreen mode Exit fullscreen mode

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!');
 });
});
Enter fullscreen mode Exit fullscreen mode

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%'"
}
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

Putting it outside makes it cleaner, although a lazy engineer can always make a case to still point it to the cypress folder.

Discussion (0)