cypress-extends icon indicating copy to clipboard operation
cypress-extends copied to clipboard

Extending configuration file with Cypress 10

Open Deop opened this issue 3 years ago • 8 comments

More of a question rather than a bug. With changes in Cypress 10 (switching from .json to .js or .ts configs) could you please explain/update on how do we extend configs now?

Deop avatar Jun 16 '22 10:06 Deop

Ok, it seems I've figured out how to do it (not sure if it's the best way though). This solution does not require cypress-extends plugin to be used at all. I'll leave my solution for reference if someone else might need it. First, you need to import your base config into your current config const baseConfig = require('../config/base.config.js') Then you can either assign it's properties to be used in your current config by doing: env: baseConfig.env, or combine properties from both base and current config files by creating two objects and merging them:

let baseE2e = baseConfig.e2e;
let currentE2e = {
    baseUrl: "https://google.com",
}

module.exports = defineConfig({
  e2e: {
      ...baseE2e,
      ...currentE2e
  }
})

Deop avatar Jun 16 '22 11:06 Deop

Nice idea. In my case, I needed to do a deep merge between configs, so I ended up using lodash.merge for this.

Here is a quick sample of a config file, in case it could be helpful for anyone:

const {defineConfig} = require('cypress');
const baseConfig = require('../cypress.config.js').e2e;
const _ = require('lodash.merge');

const currentConfig = {
  projectId: 'someValue',
  env: {
    someProperty: 'someValue'
  }
};

module.exports = defineConfig({
  e2e: _(baseConfig, currentConfig)
});

mmitchell3590 avatar Jun 22 '22 18:06 mmitchell3590

Did this an easy way in v10

your config files are straight json with what you want to overwrite

//cypress/config/myConfig.json
{
baseUrl: "myUrl",
env: { 
   myKey: "myValue"
  }
}

then to specify what override file you would like:

//cypress.config.js
  e2e: {
    setupNodeEvents(on, config) {
      config.extends = `./cypress/config/${config.env.envName}.json`
      return  require('@bahmutov/cypress-extends')(config.configFile)
    },
}

npx cypress open --env envName=myConfig

jrockefeller avatar Jun 29 '22 15:06 jrockefeller

Excellent solutions, but unfortunately, none of them met my expectations.

I needed to create a solution that would allow me to switch between environments quickly, and from cypress.config.ts I could not retrieve environment variables to add the appropriate config. The following solution works for me, but I don’t know how about performance.

Cypress: 10.3.0 System: MacOS Monterey

package.json

"scripts": {
    "cypress:alpha": "npx cypress run --env ENV=alpha",
  },

cypress.env.json

{
    "projectId": "xxxxxxx",
    "baseUrl": "https://example.com/",
    "viewports": {
      "desktop": {
        "name": "Desktop",
        "width": 1920,
        "height": 1080
      },
      "desktop-small": {
        "name": "Small desktop",
        "width": 1366,
        "height": 768
      },
      "tablet": {
        "name": "Tablet",
        "width": 768,
        "height": 1024
      },
      "mobile": {
        "name": "Mobile",
        "width": 414,
        "height": 896
      },
      "mobile-small": {
        "name": "Small mobile",
        "width": 360,
        "height": 640
      }
    }
}

cypress/support/e2e.js

Cypress.env( {
    ...Cypress.env(),
    ...require( '../../config/' + Cypress.env( 'ENV' ) + '.json' )
} );

config/alpha.json

{
  "baseUrl": "https://alpha-example.com/",
  "credentials": {
    "d2c": {
      "username": "user",
      "password": "password"
    }
  }
}

kamil220 avatar Jul 04 '22 16:07 kamil220

Did this an easy way in v10

your config files are straight json with what you want to overwrite

//cypress/config/myConfig.json
{
baseUrl: "myUrl",
env: { 
   myKey: "myValue"
  }
}

then to specify what override file you would like:

//cypress.config.js
  e2e: {
    setupNodeEvents(on, config) {
      config.extends = `./cypress/config/${config.env.envName}.json`
      return  require('@bahmutov/cypress-extends')(config.configFile)
    },
}

npx cypress open --env envName=myConfig

Are you sure? On my side, extending config via this way is impossible.

kamil220 avatar Jul 06 '22 09:07 kamil220

Question for all of you that did this, it seems like all of these assumes you are extending everything under "e2e" section of the configuration (which is new with Cypress10). Does that mean you have moved everything into that section now? Meaning I have somethings outside of e2e that these solutions won't extend. A brief example:

module.exports = defineConfig({
  chromeWebSecurity: false,
  experimentalInteractiveRunEvents: true,
  retries: {
    runMode: 1,
  },

  //more stuff here

  e2e: {
    baseUrl: 'https://myurl.place.com',
    experimentalSessionAndOrigin: true,
    setupNodeEvents(on, config) {
      on('before:browser:launch', (browser, launchOptions) => {
        if (browser.name === 'chrome' && browser.isHeadless) {
          launchOptions.args.push('--disable-gpu');
          launchOptions.args.push('--disable-gpu-sandbox');
          launchOptions.args.push("--incognito");
        }
        return launchOptions
      });

     //more stuff under setupNodeEvents
    }
  }
})

The solutions above only seem to deal with merging the e2e sections...also I assume that means each of your files has to have its own "setUpNodeEvents" section (which could have duplicates between files) because the e2e extension/merge is going to overwrite the entire e2e section (even a deep merge didn't see to work for that section). Any tips or tricks? Right now I've just gone to individual config files and that seems like a silly amount of duplication! Hope this rambling makes sense.

nerrante avatar Aug 29 '22 13:08 nerrante

Question for all of you that did this, it seems like all of these assumes you are extending everything under "e2e" section of the configuration (which is new with Cypress10). Does that mean you have moved everything into that section now? Meaning I have somethings outside of e2e that these solutions won't extend. A brief example:

module.exports = defineConfig({
  chromeWebSecurity: false,
  experimentalInteractiveRunEvents: true,
  retries: {
    runMode: 1,
  },

  //more stuff here

  e2e: {
    baseUrl: 'https://myurl.place.com',
    experimentalSessionAndOrigin: true,
    setupNodeEvents(on, config) {
      on('before:browser:launch', (browser, launchOptions) => {
        if (browser.name === 'chrome' && browser.isHeadless) {
          launchOptions.args.push('--disable-gpu');
          launchOptions.args.push('--disable-gpu-sandbox');
          launchOptions.args.push("--incognito");
        }
        return launchOptions
      });

     //more stuff under setupNodeEvents
    }
  }
})

The solutions above only seem to deal with merging the e2e sections...also I assume that means each of your files has to have its own "setUpNodeEvents" section (which could have duplicates between files) because the e2e extension/merge is going to overwrite the entire e2e section (even a deep merge didn't see to work for that section). Any tips or tricks? Right now I've just gone to individual config files and that seems like a silly amount of duplication! Hope this rambling makes sense.

I'm in the same situation as you. I want to extend everything in the config file.

Any help would be appreciated

damosull avatar Sep 22 '22 15:09 damosull

Excellent solutions, but unfortunately, none of them met my expectations.

I needed to create a solution that would allow me to switch between environments quickly, and from cypress.config.ts I could not retrieve environment variables to add the appropriate config. The following solution works for me, but I don’t know how about performance.

Cypress: 10.3.0 System: MacOS Monterey

package.json

"scripts": {
    "cypress:alpha": "npx cypress run --env ENV=alpha",
  },

cypress.env.json

{
    "projectId": "xxxxxxx",
    "baseUrl": "https://example.com/",
    "viewports": {
      "desktop": {
        "name": "Desktop",
        "width": 1920,
        "height": 1080
      },
      "desktop-small": {
        "name": "Small desktop",
        "width": 1366,
        "height": 768
      },
      "tablet": {
        "name": "Tablet",
        "width": 768,
        "height": 1024
      },
      "mobile": {
        "name": "Mobile",
        "width": 414,
        "height": 896
      },
      "mobile-small": {
        "name": "Small mobile",
        "width": 360,
        "height": 640
      }
    }
}

cypress/support/e2e.js

Cypress.env( {
    ...Cypress.env(),
    ...require( '../../config/' + Cypress.env( 'ENV' ) + '.json' )
} );

config/alpha.json

{
  "baseUrl": "https://alpha-example.com/",
  "credentials": {
    "d2c": {
      "username": "user",
      "password": "password"
    }
  }
}

image I tried your method, but the configuration doesn't seem to take effect,Are there any other treatments?

luqy avatar Sep 26 '22 07:09 luqy