Supporting multiple configurations in Cypress
By default, Cypress will support a single configuration based on the optional file cypress.json
as described in their documentation here.
Whilst this works fine for most, it would be great if we could have access to a cypress.dev.json
for local development, or even better, a whole host of configuration files for use against a multi-tenant environment – for example cypress.clientA.json
, cypress.clientB.json
etc.
Whilst Cypress accepts a different config file during startup with the --config-file
flag, it would be better if we could just pass the environment name through instead of the full file name and/or location, right?
Uses for environmental variables
I personally use these environmental files to store things like:
- Base URL: Each client has its own SIT/UAT environments with different URLs
- Default username and password for test environments.
Creating the different config files
We can create a root level folder named “Config”. Under here we can create as many files as we need to cover, for example I have config.ClientA.json
which contains:
{
"baseUrl": "http://clientA.internalserver.co.uk/",
"env": {
"someVariable": "Foo"
}
}
And config.ClientB.json
which contains:
{
"baseUrl": "http://clientB.internalserver.co.uk/",
"env": {
"someVariable": "Bar"
}
}
Editing the plugin file
First we need to import “path” and “fs-extra” packages by adding the following at the top of the index.js
file within the /Plugins
folder (if it doesn’t already exist!). These will allow the file to be located and subsequently read.
const path = require("path");
const fs = require("fs-extra");
Next we need the method which will take in a client name/environmental variable, locate the appropriate config file (being /config/config.name.json), and then reading that file back to the calling method.
function getConfigurationFileByEnvName(env) {
const fileLocation = path.resolve("cypress/config", `config.${env}.json`);
return fs.readJson(fileLocation);
}
and finally we need the index.js file to export this file. This will also have a fallback in place if one is not defined.
module.exports = (on, config) => {
const envFile = config.env.configFile || "local";
return getConfigurationFileByEnvName(envFile);
};
The eagle eyed may realise that I am using config.env.configFile
here which will mean passing an environmental flag in the command line rather than making direct use of the --config
flag. This is personal preference, as I aim to expand on the env
flags later so this will look cleaner.
Consuming the configuration
Now, when running the usual open command, we can make use of the --env
flag to pass it the environmental variable. We do so with:
./node_modules/.bin/cypress open --env configFile=clientA
It should now launch the test runner with your different files environmental variables available via Cypress.env('key')
Thanks a lot for shearing