user11961192
user11961192

Reputation:

How to use .env variables inside cypress.json file?

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.

Upvotes: 8

Views: 16994

Answers (9)

jozso39
jozso39

Reputation: 63

I found an easy solution to this if your configs are a JS or TS file, like cypress.config.js. The dotenv config has an option to return parsed .env variables:

  1. install dotenv by npm i -D dotenv
  2. in your cypress.config.js, define the dotenv parsed environment variables like this:
const dotenv = require('dotenv').config({ path: '../../.env' }).parsed;

Now, the variable dotenv contains the env variables from the file .env. The .config({ path: '../../.env' }) has to point to your .env file, usually in the root of your project.

So if you have in your .env looks like this:

FOO=BAR

you can get it anywhere in your project like this:

const dotenv = require('dotenv').config({ path: '../../.env' }).parsed;
const foo = dotenv.FOO

Upvotes: 0

Hamish.Linklater
Hamish.Linklater

Reputation: 217

Since the question was raised, the Cypress configuration was changed from static file cypress.json to javacript-enabled cypress.config.js.

So now it's possible to use the original code in the question, since cypress.config.js is run in Node and has access to process.env directly.

You don't need dotenv for this any more.

const { defineConfig } = require("cypress");

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
    },
  },
  env: {
    HOST: process.env.HOST
  }
});

Upvotes: 8

Felipe Chernicharo
Felipe Chernicharo

Reputation: 4527

Access .env values inside your Cypress tests in a vite/typescript project

expanding on @KienHT's answer

npm install dotenv
  • .env
VITE_ADMIN_PASSWORD=123456
[email protected]
  • cypress.config.ts
import { defineConfig } from "cypress";
import { config } from "dotenv";
config();

export default defineConfig({
  // ...
  env: {
    CY_ADMIN_PASSWORD: process.env.VITE_ADMIN_PASSWORD,
    CY_ADMIN_EMAIL: process.env.VITE_ADMIN_EMAIL,
  },
});

  • cypress/e2e/admin.cy.ts
// example

describe("admin tests", () => {
  it("should be able to login", () => {
    cy.visit("http://localhost:5173");
    
    cy.get('input[data-cy="email"]').type(Cypress.env("CY_ADMIN_EMAIL"));
    cy.get('input[data-cy="login-password"]').type(Cypress.env("CY_ADMIN_PASSWORD"));
    
    cy.get('button[data-cy="login-submit"]').click();
    cy.url().should("include", "/admin");
  });
});

Upvotes: 0

Zeth
Zeth

Reputation: 2598

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
    });
})

Upvotes: -2

Will Munn
Will Munn

Reputation: 7947

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

Upvotes: 2

KienHT
KienHT

Reputation: 1346

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

Upvotes: 7

user2283403
user2283403

Reputation:

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')
})

Upvotes: 3

Fseee
Fseee

Reputation: 2631

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

Cypress.env("env")["HOST"]

Upvotes: -2

FireAnt121
FireAnt121

Reputation: 11

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

Upvotes: 0

Related Questions