cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
46.87k stars 3.17k forks source link

baseUrl not used in cypress.env.json #22181

Open bvanderneut opened 2 years ago

bvanderneut commented 2 years ago

Current behavior

If you have a baseUrl in the cypress.env.json it's not beeing used.

Desired behavior

just like the previous version I would like to have a local file cypress.env.json where the baseUrl is beeing read and used in my test.

Test code to reproduce

// Tried both ways and did not work

{
    "e2e": {
        "baseUrl": "https://google.com/"
    },
    "baseUrl": "https://google.com/"
}

Cypress Version

10.0.3

Other

It should work according the documentation: https://docs.cypress.io/guides/guides/environment-variables#Option-2-cypress-env-json

tdeekens commented 2 years ago

I think I am experiencing the same resulting in a "Blocked a frame with origin" message using headless mode.

rachelruderman commented 2 years ago

Hi @bvanderneut, thanks for reporting! Can you provide a reproducible example?

I tried to recreate on my kitchensink branch but baseUrl worked as expected for me:

Screen Shot 2022-06-09 at 1 53 34 PM
bvanderneut commented 2 years ago

It's about this line of documentation:

"You can create your own cypress.env.json file that Cypress will automatically check. Values in here will overwrite conflicting environment variables in your Cypress configuration."

On that page there is a way to overwrite the baseUrl. But that does not work in the cypress.env.json. Because you can only overwrite environment (env) settings. Like this part of the config but not the baseUrl in the e2e part.

module.exports = defineConfig({
  env: {
    FOO: 'bar'
  },
  e2e: {
    baseUrl: 'http://localhost:3030',
  }
})

So my real question is: Is there a way to locally overwrite the baseUrl without that beeing checked in by git? Because If I change the baseurl in my cypress.config.js it will be checkedin.

See here my example project.

test-baseurl.zip

lauterry commented 2 years ago

Hi

There is an issue with baseUrl.

The one that is taken into account by cypress is the one on the root of the configuration and not the one into the e2e object

What is written into the documentation is not correct

Capture d’écran 2022-06-10 à 13 46 11
bvanderneut commented 2 years ago

That is not correct what you are telling. If I add it like this:

export default defineConfig({
  e2e: {

  },
  baseUrl: 'https://google.com',
});

I get this error message:

image
lauterry commented 2 years ago

Mhhh it is weird. I do not have this message. I continue to investigate.

Here is my configuration and I manage to run my tests without errors

Capture d’écran 2022-06-10 à 14 57 59 Capture d’écran 2022-06-10 à 14 58 03

Edit : I wish to say that my configuration has been dynamically generated. I have remove any baseUrl from my cypress.config.js

I have created another issue : https://github.com/cypress-io/cypress/issues/22247

rachelruderman commented 2 years ago

@bvanderneut Thank you for the repro and apologies for my earlier response where I looked into cypress.config.js instead 😅 . I can confirm, you've found a buggo! 🐛 I'll be passing this along to the team.

Repo with reproducible example Steps to test: yarn && npx cypress open -> e2e testing -> select baseUrl.cy.js

gagneet commented 2 years ago

Experiencing the same issue with Cypress v10.3.0.

We have been using the baseUrl to define which environment and system to run the tests on, and if it is defined in the /plugins/index.js with an || clause, the cypress.env.json file is not being recognized

// This is being used at the bitbucket-pipeline or cypress run "HOST" to define/override the base url
  const version = config.env.version || '[demo.myorg.org](http://demo.myorg.org/)'; // if not defined, default to stable environment
  config.env = require('../../config/${version}.env.json'); // load env from json

  // change baseUrl
  config.baseUrl = config.env.baseUrl;

So, when we run from the Bitbucket pipeline using the below command, whatever value we provide for $CYPRESS_HOST is disregarded and only the default value provided in /plugins/index.js is being used, which causes us a big issue as we have to change code everytime to run on different servers now:

cypress_version=$CYPRESS_HOST npx cypress run --record --key $CYPRESS_RECORD_KEY --browser $CYPRESS_BROWSER --spec 'cypress/tests/e2e/$CYPRESS_TESTS,cypress/tests/integration/$CYPRESS_TESTS' --parallel --ci-build-id CY_$BITBUCKET_BUILD_NUMBER

a8trejo commented 2 years ago

I believe I have a workaround for you guys @gagneet @bvanderneut , inside the setupNodeEvents I have this code

    const envKey = config.env.envKey || 'default';
    if (envKey !== 'default') {
      return getConfigByFile(envKey, config);
    } else {
      return config;
    }

and with this getConfigByFile function below I'm able to dynamically change the baseUrl or any config or env variable by choosing which config file to pass such as npx cypress open --env envKey=dev

  const fs = require('fs-extra');

  function getConfigByFile(envKey, config) {
  let fileName = `cypress_${envKey}.json`
  console.log("Config file: " + fileName);

  let rawData = fs.readFileSync(`cypress/config/${fileName}`);
  let newConfig = JSON.parse(rawData);

  config = {...config, ...newConfig}
  return config;
  };

I place this function anywhere outside of module.exports but still within the cypress.config.js

repo for reference:

gagneet commented 2 years ago

@a8trejo thank you for this, shall try it out and see how it goes. Might need to do a few modifications to the repo/file you provided, as we have a few additional functions being still called in plugins/index.js

    setupNodeEvents(on, config) {
      //on('file:preprocessor', tagify(config));    
      on('task', {
        log(message) {
          console.log(message);
          return null;
        },
      });
      //return require('./cypress/plugins/index.js')(on, config);
      const envKey = config.env.envKey || 'default';
      if (envKey !== 'default') {
        return getConfigByFile(envKey, config);
      } else {
        return require('./cypress/plugins/index.js')(on, config);
      }
    },
gagneet commented 2 years ago

@a8trejo thank you for this, shall try it out and see how it goes. Might need to do a few modifications to the repo/file you provided, as we have a few additional functions being still called in plugins/index.js

    setupNodeEvents(on, config) {
      //on('file:preprocessor', tagify(config));    
      on('task', {
        log(message) {
          console.log(message);
          return null;
        },
      });
      //return require('./cypress/plugins/index.js')(on, config);
      const envKey = config.env.envKey || 'default';
      if (envKey !== 'default') {
        return getConfigByFile(envKey, config);
      } else {
        return require('./cypress/plugins/index.js')(on, config);
      }
    },

@a8trejo this is not working for me, as we have the following code in our test suite, which is not recognized, even though the value is recognized by Cypress v9.7.0

const prefix = Cypress.env('host').replace(/\./g, '');

image

a8trejo commented 2 years ago

@gagneet It seems you are not creating the host env variable inside setupNodeEvents, maybe rename the variable envKey to host? that was the name I used on my personal repo, and then to actually create the host variable you would have to run cypress with either of these commands:

npx cypress open --env host={YOUR ENVIRONMENT NAME} npx cypress run --env host={YOUR ENVIRONMENT NAME}

or have the host variable on the env property it in your new cypress_dev.json or whatever config file you are using

gagneet commented 2 years ago

or have the host variable on the env property it in your new cypress_dev.json or whatever config file you are using

Thanks for the update on this @a8trejo.

We do have the "host" in our cypress_demo.json file, which is in the path 'config/cypress_demo.json' (so the root has a config folder). This has been working with Cypress v9.7.0, but with v10, this was a breaking change and I have even tried using

         - cypress_version=$CYPRESS_HOST npx cypress run --env host=$CYPRESS_HOST --record --key
            $CYPRESS_RECORD_KEY --browser $CYPRESS_BROWSER --spec
            'cypress/tests/e2e/$CYPRESS_TESTS' --parallel 

Using either of those methods is not working currently

gagneet commented 1 year ago

Hi, has there been any update on this? We are still waiting for this to be resolved, so that we can upgrade to the latest Cypress.

pojocariba commented 1 year ago

i don't remember at what specific version of cypress v11 it was, that it worked, having a baseUrl inside of cypress.env.json file and it overrode the baseUrl in cypress.config.ts file, but when i updated to v12 of cypress it stopped working. i really like to use the lastest cypress features so, I am wondering if this can be looked at again

a8trejo commented 1 year ago

I don´t think the cypress.env.json was ever meant to override the config object of cypress.config.ts, which is why I was proposing my workaround in this comment

Basically on setupNodeEvents(on, config), the config parameter, is an object which includes the env object (which gets overriden by cypress.env.json), but that config object has so much more, env is just one of the object keys that it has.

Still though, you can do any object spreading you want with that config object, we have access to it, which is what I do

I just chose to have a custom file in cypress/config/${fileName} , read that new config object, and spread/merge it with cypress's config object

which happens on this line of my workaround config = {...config, ...newConfig}

You can do the same, I guess in this line let rawData = fs.readFileSync(`cypress/config/${fileName}`); you can straight up pass it the cypress.env.json if you want

But since cypress.env.json is usually part of .gitignore and usually contains secrets, I would advise against it and would split my config variables apart from secrets in a different file.

RiZKiT commented 1 year ago

I have a similar related problem.

My cypress.config.js contains something like:

{
  e2e: {
    baseUrl: "https://example.com"
    specPattern: "cypress/integration/**/*.spec.js",
  }
  env: {
    stage: "production"
  }
}

Which results in the following visible settings in Cypress UI generated, when running e2e tests:

{
  baseUrl: "https://example.com"
  env: {
    stage: "production"
  }
  specPattern: "cypress/integration/**/*.spec.js",
}

Then I'm importing environment based configs via setupNodeEvents() (e.g. cypress.local.json):

{
  e2e: {
    baseUrl: "http://localhost:8080"
  }
  env: {
    stage: "local"
  }
}

This results in the following visible settings in Cypress UI generated:

{
  baseUrl: "https://example.com"
  e2e: {
    baseUrl: "http://localhost:8080"
  }
  env: {
    stage: "local"
  }
  specPattern: "cypress/integration/**/*.spec.js",
}

Assumption This leads me to the assumption, that cypress extracts the e2e part when parsing the config the first time while running e2e tests, but does not do the same in setupNodeEvents wenn returning a config containing an e2e part. Looking at this test for Cypress.config() (https://example.cypress.io/cypress-api#config) it seems to be intended, if not outdated.

Temporary Solutions

  1. While returning the config in setupNodeEvents() move everything from e2e to the returning config object root, so it will overwrite the default values. This feels hacky and unexpected, maybe I did not yet understood the intention of setupNodeEvents().
  2. Merge or better deep merge the default and environment config before or directly inside defineConfig() (same or similar to https://github.com/cypress-io/cypress/discussions/22517#discussioncomment-3517853. Which will be my current approach, because it should always work and I will still understand the behaviour in a year. Update: This fails because I do not have the environment available at config loading time, at least I'm not aware of.
cypress-app-bot commented 5 months ago

This issue has not had any activity in 180 days. Cypress evolves quickly and the reported behavior should be tested on the latest version of Cypress to verify the behavior is still occurring. It will be closed in 14 days if no updates are provided.

cypress-app-bot commented 4 months ago

This issue has been closed due to inactivity.

mwickman commented 1 month ago

I've run into this when doing setup today, would love to see this fixed.