3

I want to use my .env variables inside cypress.json file. As an example of usage:

{
    "env": {
        "HOST": `${process.env.HOST}`
    }
}

What I want is this: When I type Cypress.env('HOST') anywhere in Cypress, I want to get the process.env.HOST variable.

Achtung
  • 199
  • 9
osmancalisir
  • 147
  • 2
  • 10

6 Answers6

3

This is a late answer but you can achieve this by creating the variable in Plugins (https://docs.cypress.io/guides/guides/environment-variables#Option-5-Plugins)

Documentation states:

// .env file
USER_NAME=aTester

/

// plugins/index.js
require('dotenv').config()

module.exports = (on, config) => {
  // copy any needed variables from process.env to config.env
  config.env.username = process.env.USER_NAME

  // do not forget to return the changed config object!
  return config
}

// integration/spec.js
it('has username to use', () => {
  expect(Cypress.env('username')).to.be.a('string')
})
mhd031
  • 61
  • 4
2

To make process.env variables available in Cypress, you need to use dotenv package.

npm install dotenv

Make sure this line of code sitting on top of your cypress.config.js

require('dotenv').config()

Now you can use process.env variables in cypress.json file

KienHT
  • 1,098
  • 7
  • 11
2

I used to use @KienHT's solution but this seems to have stopped working when upgrading to cypress 10. Rather than installing plugins or other extra dependencies, I went for running a little script to transform my .env file into a cypress.env.json file before running cypress.

  1. Add the following script to in ./transform-dotenv.js
const fs = require('fs');
const convertDotenvFileToCypressEnvFormat = () => {
  const transformedEnvFile = fs
    .readFileSync('./.env')
    .toString('utf-8')
    .split('\n')
    .map((keyValue) => keyValue.split(/=(.*)/s))
    .reduce(
      (cypressEnv, [key, value]) => ({
        ...cypressEnv,
        [key]: value,
      }),
      {}
    );
  fs.writeFileSync('cypress.env.json', JSON.stringify(transformedEnvFile));
};
convertDotenvFileToCypressEnvFormat();
  1. Add a line in your package.json to run cypress.
{ "scripts": {"cypress": "node ./transform-dotenv.js" && cypress open"}
  1. Add cypress.env.json to your .gitignore
  2. Run your tests using npm run cypress
Will Munn
  • 7,363
  • 4
  • 27
  • 32
1

First of all why not use process.env.HOST inside your spec files. Second if you want to test in different host then what i have been doing is.

  1. Create a folder (eg: configFiles)

  2. Inside this create json files like (eg: host1.json, host2.json)

  3. Inside your json file (in host1.json)

    { "env": { "HOST" : "host1" } }

  4. Inside your plugins folder edit index.js

    const fs = require('fs-extra'); const path = require('path');

    function getConfigurationByFile(file) { const pathToConfigFile = path.resolve( 'cypress/configFiles', ${file}.json );

    return fs.readJson(pathToConfigFile); }

    module.exports = (on, config) => { const file = config.env.host || 'host1';

    return getConfigurationByFile(file); };

  5. Then while running you can use npm cypress run --env host=host1

FireAnt121
  • 21
  • 5
  • hi Tenish, thanks for your answer. I am using cypress in storybook. the cypress spec files does not seen the .env variables. after researching on problem, I see that cypress uses different scope and created a new json file named: cypress.json on the root (next to node_modules) and I can get the data from there. But I need to get the data over .env file into cypress.json – osmancalisir Dec 13 '21 at 11:28
-1

Avoid wrapping your env file in env variable. By the way this should do the job with your file:

Cypress.env("env")["HOST"]
Fseee
  • 2,476
  • 9
  • 40
  • 63
  • 1
    I think when we say Cypress, it looks for the variables inside cypress.json file and .env means inside env array. So, it is multiple to say Cypress.env("env"). Instead, we can directly say Cypress.env("HOST") But sadly, your suggestion does not work for this case. Cypress has its own scope and cannot get .env variables without help – osmancalisir Dec 14 '21 at 14:25
-1

I don't know if this is the smartest way, but it appears to work.

It is to include the .env in the cypress.config.ts

This would be the cleanest solution, where I just include all the variables once - and then they're accessible in all tests. But I can't get it to work.

I think this is my closest attempt:

import {defineConfig} from "cypress";
import * as dotenv from "dotenv";
dotenv.config();

const envVars = Object.keys(process.env).reduce((acc, key) => {
    // console.log( 'LINE', key, process.env[key] ); // For debugging purposes
    acc[key] = process.env[key];
    return acc;
}, {});


export default defineConfig(
    {
        env: {
            NODE_ENV: 'development',
            ...envVars 
        },
        e2e: {
            baseUrl: 'http://localhost:3000',
            setupNodeEvents(on, config) {
                // implement node event listeners here
            },
            specPattern: [
                'src/**/*.cy.{js,jsx,ts,tsx}',
            ]
        },
    });

Then you can see all your env-variables in your tests like this:

Example test

it('Check create user works', () => {
    // Prints all variables (just for show)
    const obj = Cypress.env();
    Object.keys( obj ).forEach( (key) => {
        cy.log( key + ' => ' + obj[key] );
    });
    
    // Use it in a test
    cy.request('GET', 'test-create-user').as('getConnection')
    cy.get('@getConnection').should((response) => {
        expect(response).to.have.property('status');
        expect(response.status).to.eq(200);
        expect(response.body.email).to.eq( Cypress.env('MY_TEST_USER') ); // This passes
    });
})
Zeth
  • 2,273
  • 4
  • 43
  • 91