angularcypressangular-e2e

How to read environment files from e2e tests?


Here's the structure of my Angular application:

MyApplication
  apps
      - app1
          - src
              - app
              - assets
              - environments //*****USE THIS FILES ****

      - app1-e2e
          - src
              - fixtures
              - integration
              - plugins
              - supports

I'm using Cypress for the e2e tests. For instance, I want to use the base URL, so that it depends on the environment (local, dev, ...):

it('should redirect to release', () => {
  cy.get('[data-testid="my-link"]').click();
  cy.url().should('include', 'http://localhost.homedepot.com:4200/');
});

if it's the development machine, it will be localhost.homedepot.com:4200. However, if the dev machine it will be myapplication-np.mycompany.com, and so forth.

We already have all this information in the environment files. Should I duplicate them in the e2e folder or is there a way to read them from the environment files.


Solution

  • I came up with a way to quickly switch my environment when I need to, hope it helps.

    To use it, add these lines to your cypress/plugins/index.js

    module.exports = (on, config) => {
      // `on` is used to hook into various events Cypress emits
      // `config` is the resolved Cypress config
    
      // quick env switch
      if (config.env.target) {
          const { baseUrl, ...currentEnv } = config.env[config.env.target];
          config.baseUrl = baseUrl;
          config.env = { ...config.env, ...currentEnv }
      }
    
      return config;
    
    }
    

    Now you need to set your target environment and configure your environments like this:

    In your cypress.json:

      ...
      "env": {
        "target": "dev",
        "dev": {
          "baseUrl": "http://www.myappurl-dev.com",
          "apiUrl": "http://www.myapiurl-dev.com",
          "username": "admin_dev"
        },
        "test": {
          "baseUrl": "http://www.myappurl-test.com",
          "apiUrl": "http://www.myapiurl-test.com",
          "username": "admin_test"
        }
      },
      ...
    

    You can also set an environment in your cypress.env.json which should be in your .gitignore so it won't be pushed to your remote repo.

    cypress.env.json:

    {
      "target": "local",
      "local": {
        "baseUrl": "http://localhost:4000",
        "apiUrl": "http://localhost:22742",
        "username": "admin_local"
    }
    

    Finally, all you need to do is change target in cypress.json or cypress.env.json to quickly switch between your environments. Remember that any value set in cypress.env.json overwrite the ones set in cypress.json.

    And then in your code, you would use it like this:

    it('should redirect to release', () => {
      cy.get('[data-testid="my-link"]').click();
      cy.url().should('include', Cypress.config('baseUrl');
    });
    

    Edit #1
    If your environment config already exists somewhere:
    Have a look at how to set environment values from cypress/plugins/index.js here. They are showing how to get your .env, but you might also be able to read a .config file.


    Edit #2:
    I was able to read my root/src/web.config from cypress/plugins/index.js using fs and xml-js:

    const convert = require('xml-js');
    const fs = require('fs');
    
    module.exports = (on, config) => {
        const xmlAngularConfig = fs.readFileSync('../path/to/your/config/file', 'utf8');
        const jsonAngularConfig = convert.xml2json(xmlAngularConfig, { compact: true, spaces: 4 });
    
        // Then you can add any value of jsonAngularConfig to cypress config
        config.baseUrl = jsonAngularConfig.url;
    
       // Don't forget to return config
       return config;
    }