Setting baseUrl in npm script doesn't change it (Cypress)

644 Views Asked by At

I want to be able to run my Cypress scripts on any URL by modifying the value of baseUrl but the command doesn't change it.

"cypress open --env version=development --config baseUrl=https://google.com"

I have tried env variable too but that also doesn't work:

"cypress:open:dev": "cypress open --env version=development,baseUrl=https://google.com"

Config file:

export default defineConfig({
  e2e: {
    async setupNodeEvents(on, config) {
      const version = config.env.version || 'development'
      const configFile = await import(path.join(
        config.projectRoot,
        'cypress/config',
        `${version}.json`
      ));
      const credentialsFile = await import(path.join(
        config.projectRoot,
        'cypress/config',
        'credentials.json'
      ));
      config = {
        ...config,                    // take config defined in this file
        ...configFile                 // merge/override from the external file
      }
      config.env = {
        ...config.env,                // 2nd level merge
        ...credentialsFile[version]   // from git-ignored file 
      }
      config.baseUrl = configFile.baseUrl
      return config
    },
    reporter: 'mochawesome'
  },
});

development.json:

{
    "env": {
        "baseUrl": "https://test.com",
    }
}
4

There are 4 best solutions below

2
On BEST ANSWER

Here is the solution that provides what I was looking for:

The command, URL is optional, if not provided it uses the hard-coded value in development.json:

"cypress:open:dev": "CYPRESS_BASE_URL=$URL cypress open --env version=development"

The only line I needed to change in my config was the following:

config.baseUrl = config.baseUrl || configFile.env.baseUrl

All my tests were using the following:

 cy.visit(Cypress.env('baseUrl'))

So I needed to change to:

 cy.visit('')

With this solution, I can run the script without any argument and it will use default baseUrl, or I can run URL="https://google.com/ npm run cypress:open:dev and the baseUrl will change

1
On

You can use this command in order to set baseUrl:

"cypress:open:dev": "CYPRESS_BASE_URL=https://google.com cypress open --env version=development"
9
On

The config gets merged from multiple sources. It would seem that the code in setupNodeEvents() is the final setting, i.e it runs after command line overrides have been applied.

Therefore config.baseUrl = configFile.baseUrl is causing the problem.

I would change it to

config.baseUrl = config.baseUrl || configFile.baseUrl

Since you don't set baseUrl via a hard-coded property in the config,

e.g

export default defineConfig({
  e2e: {
    baseUrl: "some-hard-coded-url",

it would be undefined when there was no command line override, but have a value if there was a command line override.

So using the OR operator as above, it will only assign configFile.baseUrl if there is not a value already.


Saving .env from the command line

Since you're using --env to pass the override, this section merging config and configFile replaces the config.env section entirely, assuming your development.json has the structure given in the question.

config = {
  ...config,      // env from command-line overrides are on .env property 
  ...configFile   // env from external file replaces that property entirely
}

so anything that follows has no effect.

Instead, save the initial config.env and use it later when merging in the credentialsFile.

Now the OR condition (||) works as expected,

const env = {...config.env}
config = {...config,...configFile}
config.env = {...env,...credentialsFile[version]}

config.baseUrl = config.env.baseUrl || configFile.env.baseUrl  

My results

When I run that, I get baseUrl: 'https://google.com' with

"cypress:open:dev": "cypress open --env version=development,baseUrl=https://google.com"

and I get baseUrl: 'https://test.com' when running

"cypress:open": "cypress open"

configFile has env in the path

Note your development.json has env in the path before baseUrl, so change configFile.baseUrl to configFile.env.baseUrl.

1
On

You are overriding the config.env settings, and must merge them back into the config.

export default defineConfig({
  e2e: {
    async setupNodeEvents(on, config) {
      ...
      config = {
        ...config,                    // take config defined in this file
        ...configFile,                // merge/override from the external file
        env: {...config.env}          // don't merge env
      }
      ...
      return config
    },
    reporter: 'mochawesome',
    // baseUrl: 'http://example.com',     // cannot use this with above merge!!
  },
})

Although, if you do it this way you cannot set baseUrl directly as it will take precedence over development.json.

Question is, why env.baseUrl in development.json? Why not follow standard convention and use

development.json:

{
  "baseUrl": "https://test.com",
}