-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Overriding baseUrl from cypress.env.json #909
Comments
This isn't a bug. https://docs.cypress.io/guides/guides/environment-variables.html#Setting-Environment-Variables To override configuration you'll need to override it from the command line or by using special environment variables prefixed with |
From docs, I got the same idea as OP. This part in particular:
Plus, the cypress runner configuartion "settings" tab doesn't do a good job in explaining that even though |
That is the exact place in the docs that gave me the idea, @dwelle. Too bad it’s not intended to be a feature; this could be of real use to my team. |
But if this is set in stone, I can update the docs to express this more clearly. Just say the word, @brian-mann. |
@brian-mann I'm writing this in order to learn, and I'm respectfully requesting that this issue be re-examined. From the docs: This strategy is useful because if you add cypress.env.json to your .gitignore file, the values in here can be different for each developer machine. // cypress.env.json {
"host": "veronica.dev.local",
"api_server": "http://localhost:8888/api/v1/"
} This documentation states that values in
I develop on a Vagrant box, and in my current project I have a base url of 127.0.0.1:8090 (with the Vagrant configuration file mapping port 8090 to port 80). It seems that baseUrl should be able to be set from the cypress.env.json file. For now, then, I'm doing the following: with cypress.env.json including Am I engaging in an anti-pattern here? I would be glad to propose updated documentation if you would prefer not to allow baseUrl to be directly overridden from cypress.env.json. |
The documentation could be more specific. Conflicting environment variables will be overriden. It doesn't make sense to add If we made Honestly Likely we can just add a new plugin event called |
A file which allows any team member to locally override configuration variables and whose internal structure is the same as that of By the way, I am very glad that we are having this discussion. Even if I don't get my way here, re-opening the discussion makes me feel like Cypress' creators are genuinely interested in hearing their users' opinions. |
@brian-mann I think that the concept of cypress.env.json was a good one but that perhaps expanding it would be more than adequate at this point (as opposed to creating a new plugin event right now). Changing the names/function of the files as follows might be a good approach.
This structure would allow you to keep the cypress.env.json for backward compatibility at this point, but it could be deprecated and then eventually eliminated (same for cypress.json). |
There have been several other issues opened where people want multiple config files based on their environment - QA, dev, staging, prod. I need to read those to come up with a solution that covers all of these use cases. I think what we're going to do is deprecate This is what you will use to specify a different config file other than However I would make the logic that this other file overrides conflicting values found in Adding a programmatic event for |
Thank you - that would be great. A question though: If an overriding config file, as described above, can only be invoked through a command line option, then could it be easily invoked in the local test runner? (Still learning here.) Alternatively (and as I mentioned in my last comment), if cypress.conf.json was the default config file and you then looked for any other file of the form cypress.conf.xxxxxxx.json and used it to override cypress.conf.json, then the ".xxxxxxxx" could be ".local", ".dev", ".staging", ".prod", or whatever. Thanks for your consideration and for this outstanding product. |
If I may offer some advice. Overriding configuration settings via environment variables or config files seems like a separate question from running Cypress. Can we all agree that every configuration setting can be set via an environment variable? If not, open an issue for that setting. So the real question is then how to conveniently start cypress with particular (maybe large) set of environment variables to test some specific Just create a file
Then run Cypress with command No need to create hierarchy of configuration JSON files. |
I created a new issue in our docs to document being clearer about environment variables being overridden here: cypress-io/cypress-documentation#236. Our documentation is open source and contributions are welcome. 😄 |
Thank you @jennifer-shehane. I think I've been confused between baseUrl and the environment variable host. I realize that baseUrl could be made anything (and in this recipe it actually includes the host), but perhaps it would be more clear if |
A bit more explanation: I'm coming from a Django background, and any Django settings variable of the form xxxxx_url (e.g. |
So it sounds like this issue has diverged into 3 distinct issues. I'd like to get buy in that I have this correct and if so I will open these three issues:
@DanAtShenTech as per your latest comment regarding If I'm off on this, it would be helpful to have a more concrete example. Perhaps write the code you wish you had (it can be pseudo code). Or maybe even paste some real Cypress code. |
Thank you @brian-mann and @jennifer-shehane. At this point I don't have more to offer (as far as code or pseudo code) than what I mentioned above about how Django handles things. My purpose in making the suggestion was not to say that things should simply be done as they are in Django because that is the environment that I work in, but rather, I made the suggestion because the Django approach seems the most logical way to handle things since every request goes to some host. However, if Node has a BaseURL concept that is not the same as Django's (in which the base url does not include the host but, rather, comes after the host), then of course a JS testing framework has to lean toward implementing things in a way that makes sense to Node users. That said, the Django ecosystem is quite large, and I'd like to see other Django developers using Cypress. I do think that how Django separates host from base url makes the most sense from a logical standpoint, and so that is why I think it would be a good way for Cypress to handle things in the proposed manner as well. |
I just noticed the interchangeable use of "host" and "baseUrl" in point number 2 here. "baseUrl" seems, therefore, to currently be redundant with "host". Perhaps "baseUrl" could simply be eliminated if you would not like to use it in the above-mentioned fashion. |
We took the concept of
It could mean: `http://localhost:1234" It could also mean: "http://localhost:1234/foo/bar/baz" Whatever it is, we just toss it before what you pass to us in What I was saying is that you can construct and normalize this behavior yourself. If you wanted to split out the path from host - you could make baseUrl just the host, and then set a new env var for path. Upon doing that you could then do something like: // cypress/support/index.js
const url = require('url')
const baseUrl = Cypress.config('baseUrl')
const path = Cypress.env("PATH")
// reset baseUrl by combining the two
Cypress.config("baseUrl", url.resolve(baseUrl, path)) |
Read the whole discussion and surely seems like a workaround we all need How would you suggest for having the baseUrl different for each env: John machine: Dana machine: QA machine: I can manipulate it with tricks with env file, any other suggestions?? Thanks! |
Easiest for you is to use environment variable when running cypress CYPRESS_baseUrl
…Sent from my iPhone
On Dec 8, 2017, at 10:37, Tzook ***@***.***> wrote:
Read the whole discussion and surely seems like a workaround we all need
How would you suggest for having the baseUrl different for each env:
John machine:
john.example.com
Dana machine:
dana.example.com
QA machine:
qa.example.com
I can manipulate it with tricks with env file,
but it doesnt look good.
any other suggestions??
Thanks!
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
@tzookb yah, using CLI args or our module API would override baseUrl for you based on the environment you specify. That's exactly what the use case of Regardless this is about to land and you'll have the ability to programmatically alter configuration and environment variables in code. #1042 |
@tzookb here is how we do it - pointing same tests at different baseUrl locally, on CI, on staging and after deploying to production: https://www.cypress.io/blog/2017/05/30/cypress-and-immutable-deploys/ |
Released in |
brian-mann commented on 22 Nov 2017
This isn't implemented in 1.4.1? Because using it results in an error 'unknown option' :( |
@Konstruktour no but you can do this yourself with the Plugin Configuration API. https://docs.cypress.io/api/plugins/configuration-api.html# We'll likely do this at some point - but I'd like to make it part of breaking changes because currently there are too many ways to set things and its overwhelming for users. |
Just for the record, I tried setting CYPRESS_baseUrl in cypress.env.json before I found this thread; that seemed intuitive with the idea of having cypress.env.json override environmental variables set in other ways and with the idea that environmental variables could override config values... I like the solution of just having a local equivalent to cypress.json and pointing to it using a command line option, and I understand that this solves the same issue in a different way. The reason I'm mentioning this is that I ended up with a set of environment variables in my runtime that didn't reflect my current configuration... in other words I could see a CYPRESS_baseUrl env var, but the value set in my config file was not overridden. It seems mildly valuable to have this tie be unambiguous if possible. |
@facetcounter I understand what you're going for - it makes sense in theory... but doing it this way is really just creating another We are determined to remove support for The best programmatic option for you today is the Plugin Configuration API. https://docs.cypress.io/api/plugins/configuration-api.html# You can literally do anything you want with both config and env vars programmatically under your control in any fashion you desire. That is now the best solution. |
Glad to see I ain't the only one to have a problem with this. (see my issue above) To be fair, the best way could/should be to accept a javascript file retuning json instead of a json file. Like that we could use for instance |
We use docker // plugins/index.js
const fs = require('fs')
const path = require('path')
module.exports = (on, config) => {
// Parse the .env file and inject the settings into the Cypress.env object
// Example .env file:
// SETTING_ONE=123
// SETTING_TWO=blah
const file = fs.readFileSync(path.resolve('.env'), 'utf-8')
file.split('\n').map(line => {
if (line.trim() !== '') {
const [key, value] = line.split('=')
config.env[key] = value
}
})
return config
} |
It doesn't really make sense to me that the testing URL cannot be set per environment in the environment settings. I want to commit cypress.json to GIT, and have cypress.env.json handle environment specific variables. The URL of the testing server is dependent upon the environment. If I put that URL into cypress.json, and commit it to Git, then it will only work on environments that happen to use that same URL. This doesn't make sense to me. I ended up hacking together a solution based on westhomas' post above. With the below code, if you've set baseUrl in cypress.env.json, it will override whatever you may have set in cypress.json: const fs = require('fs');
const path = require('path');
module.exports = (on, config) => {
"use strict";
const file = fs.readFileSync(path.resolve('cypress.env.json'), 'utf-8');
file.split('\n').map((line) => {
if (line.trim() !== '') {
const matches = line.match(/"baseUrl": "(.+)?"/);
if (matches) {
config.baseUrl = matches[1];
}
}
});
return config;
}; |
@jaypan Nice. I was a bit surprised to find out there was no ability to overwrite settings in a cascading manner out-of-the-box. I think that would be helpful. |
Any ETA on making this less confusing? |
Do I understand this correctly? Setting the baseUrl locally should be done using a plugin? Is there some kind of built-in plugin that can read it from a file, maybe even from |
@AndreKR if you don't need to do any overriding, just set it once in |
But |
It is a terrible idea to remove support for .env.json simply because people are using this strategy to setup local runs. Look at popularity of https://www.npmjs.com/package/dotenv - people like to create a local .dev file and gitignore it.
Cypress users need to override it very often hence it should be an env var - not a config var. |
This has been annoying me for years. EDIT This seems like a supported solution:
module.exports = (on, config) => {
const baseUrl = config.env.baseUrl || null;
if (baseUrl) {
config.baseUrl = baseUrl;
}
return config;
}
{
"baseUrl": "https://whatever.test",
} My first attempt, which was very hackyThis is probably a bit of a hack, but this works, for now. This is probably unsupported and a code time bomb, so caveat emptor:
// Allow baseUrl override.
import './baseUrl'
// Import commands.js using ES2015 syntax:
import './commands' `cypress/support/baseUrl.js': // Allow a 'baseUrl' env var in cypress.env.json to override the Cypress baseUrl.
const baseUrl = Cypress.env('baseUrl');
baseUrl && Cypress.config('baseUrl', baseUrl);
{
"baseUrl": "https://whatever.test",
} NOTE: You cannot set Because this is done in support, and outside spec files, When you use the GUI to run tests, it's a little weird, because it first loads on Ultimately, I wish Cypress would let you override config locally in a more elegant way. #5218 is probably the way forward. |
This issue will be closed to further comment as the exact issue here was resolved and tested in version 1.2.0. If you're experiencing a bug similar to this in Cypress or want to request a change in behavior in how Cypress works today, please open a new issue with a fully reproducible example that we can run. Closed issues are not the best place for discussion of wanted feature changes. |
Current behavior:
Setting
baseUrl
incypress.env.json
leads to the keybaseUrl
being created insideenv
(the environment variables), not in the existingbaseUrl
being overridden at the configuration variable level.Desired behavior:
baseUrl
should be overridden, the behavior matching that stated in the section "Overriding Configuration" in the environment variables documentation. (Note: Overriding via the command line works as expected.)How to reproduce/Test Code:
cypress.json:
cypress.env.json:
Screenshot of the resulting configuration:
Additional Info (images, stack traces, etc)
This issue was initially posted and phrased as a question on StackOverflow: https://stackoverflow.com/q/47262338/1858138
The text was updated successfully, but these errors were encountered: