DEV Community

Ivan
Ivan

Posted on

How to run autotests for several environments and apps separate in one cypress project. Cypress project monorepo

Hello everyone! I want to show you how to run autotests for several environments separate in one cypress project.

If you have several environments or apps and you don't want to create several cypress projects, you can use this tutorial. It helps to create one project which can run autotests separately for each environment or app.

Result you can find in this github repo

Content

Install Cypress project

Move to the next section if you have installed Cypress project with autotests

1.Install cypress package and dotenv package (for working with .env file) in your project:

npm install cypress
npm install dotenv
Enter fullscreen mode Exit fullscreen mode

2.If you use Github, create .gitignore file:

node_modules
cypress/videos
cypress/screenshots
cypress/downloads
.DS_Store
Enter fullscreen mode Exit fullscreen mode

3.If you use Cypress for the first time, use the next steps. If you used Cypress before, go to step 4.

3.1.Open Cypress:

npx cypress open
Enter fullscreen mode Exit fullscreen mode

3.2.Click on the Continue button in opened window:

Continue button in the first window

3.3.Click on the E2E testing (if you use this type of testing):

E2E button in the second window

3.4.Click on the Continue button for creating necessary files:

Continue button for creating necessary files

3.5.Close window and check that files are created:

New files

3.6.Create files with tests cypress/e2e/tests. If you don't have tests, you can use these examples:

cypress/e2e/tests/bing/bing_test.spec.js:

describe('Test for Bing', () => {
  it('Test login/password data for different environments', () => {
    cy.visit('/');
    cy.get("input[type='search']").type(`${Cypress.env('login')} + ${Cypress.env('password')}`);
  });
});

Enter fullscreen mode Exit fullscreen mode

cypress/e2e/tests/google/google_test.spec.js:

describe('Test for Google', () => {
  it('Test login/password data for different environments', () => {
    cy.visit('/');
    cy.get('textarea[type="search"]').type(`${Cypress.env('login')} + ${Cypress.env('password')}`);
  });
});

Enter fullscreen mode Exit fullscreen mode

Result after creating autotests:

Created tests

Set up config file for using multiple environments and apps

1.Change your cypress.config.js file with this code:

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

require("dotenv").config(); // line for working with .env file

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      // -----config part-------
      // dynamic path to settings
      const settings = require(`./settings/${config.env.envName.toLowerCase()}.settings.json`);

      // add base.Url from file to current config
      if (settings.baseUrl) {
        config.baseUrl = settings.baseUrl;
      }

      // add pattern for autotests from file to current config
      if (settings.specPattern) {
        config.specPattern = settings.specPattern;
      }

      // add all settings from file to current config
      if (settings.env) {
        config.env = {
          ...config.env,
          ...settings.env,
        };

        // add login and password variables from file to current config
        // you can add what ever you want with the same way to current cypress config
        config.env.login = process.env[`${settings.env.login}`];
        config.env.password = process.env[`${settings.env.password}`];
      }
      // -----config part-------

      return config;
    },
  },
});
Enter fullscreen mode Exit fullscreen mode

2.Create settings folder in your project:

Settings folder

3.Add settings for several environments or apps in settings folder with this template: fileName.settings.json or you can use your own template, but change this line in cypress.config.js file:

const settings = require(`./settings/${config.env.envName.toLowerCase()}.settings.json`);
Enter fullscreen mode Exit fullscreen mode

Let's create these files for our example:

local.settings.json:

{
  "baseUrl": "https://www.google.com/",
  "specPattern": "cypress/e2e/tests/google/**/*.spec.{js, jsx, ts, tsx}",
  "env": {
    "login": "GOOGLE_LOCAL_LOGIN",
    "password": "GOOGLE_LOCAL_PASSWORD"
  }
}
Enter fullscreen mode Exit fullscreen mode

newApp.settings.json:

{
  "baseUrl": "https://www.bing.com/",
  "specPattern": "cypress/e2e/tests/bing/**/*.spec.{js, jsx, ts, tsx}",
  "env": {
    "login": "BING_LOGIN",
    "password": "BING_PASSWORD"
  }
}
Enter fullscreen mode Exit fullscreen mode

prod.settings.json:

{
  "baseUrl": "https://www.google.com/",
  "specPattern": "cypress/e2e/tests/google/**/*.spec.{js, jsx, ts, tsx}",
  "env": {
    "login": "GOOGLE_PROD_LOGIN",
    "password": "GOOGLE_PROD_PASSWORD"
  }
}
Enter fullscreen mode Exit fullscreen mode

We created 3 files for different environments and apps. The first environment is local, the next - another app newApp and the last is another environment prod. They have different baseUrl, specPattern and data for our autotests.

Result:

Files for settings

Also, we should create .env file with actual data, because we use login and password, and it's private data. Our cypress.config.js file use these lines for getting data from .env file:

config.env.login = process.env[`${settings.env.login}`];
config.env.password = process.env[`${settings.env.password}`];
Enter fullscreen mode Exit fullscreen mode

Let's create .env file:

GOOGLE_LOCAL_LOGIN=google_local_login
GOOGLE_LOCAL_PASSWORD=google_local_password
GOOGLE_PROD_LOGIN=google_prod_login
GOOGLE_PROD_PASSWORD=google_prod_password
BING_LOGIN=bing_login
BING_PASSWORD=bing_password
Enter fullscreen mode Exit fullscreen mode

Result:

.env file

4.We set up our project for using different environments and apps, let's start to run our autotests.

Run autotests for multiple environments and apps

For our example we have these environments and apps:

  • local
  • newApp
  • prod

The same names we have for our settings. How to run it? It's simple. Use this template in command line:

npx cypress run --env envName=nameForYourEnvronment
Enter fullscreen mode Exit fullscreen mode

Run for local environment:

npx cypress run --env envName=local
Enter fullscreen mode Exit fullscreen mode

Result

Run for newApp app:

npx cypress run --env envName=newApp
Enter fullscreen mode Exit fullscreen mode

Result

Run for prod environment:

npx cypress run --env envName=prod
Enter fullscreen mode Exit fullscreen mode

Result

Conclusion

If you completed all steps, you can use your Cypress project with different environments and apps. Let's repeat steps:

  1. Create settings folder with your settings files, e.g. local.settings.json
  2. Update your cypress.config.js file and add necessary part of code
  3. Add private information into your .env file
  4. Use this command for using your environments and apps separately: npx cypress run -- --env envName=nameForYourEnvronment. You can use all cypress terminal commands with it, e.g. npx cypress open -- --env envName=nameForYourEnvronment (open all autotests in UI mode with settings from settings folder) and others

Full code you can find in this github repo

Thanks for reading this article! I hope it helps you to create a monorepo for your Cypress project. If you have any questions, or you get some errors, ping me in comments section.

Top comments (1)

Collapse
 
dotenv profile image
Dotenv

Great writeup! Clean approach.

Have you seen the successor to the .env file - the .env.vault file? It might allow you to streamline this even further, because you can just set one environment variable on cypress runs. Set DOTENV_KEY and then all your other secrets will be decrypted and injected just in time. We'll add it to our todos to add a guide, but one of the current CI/CD guides would give you a pretty good idea:

dotenv.org/docs#cis