I believe a bug. I was hoping #600 would fix it, but it didn't.
cypress.json
has "chromeWebSecurity": false
. My test visits two sites, with URLs that look like https://foo.example.org
and http://bar.baz.example.org:8080
This throws a "second unique domain" error.
Ideally this test would work without error. If that's just impossible for some reason, then a fallback desired behavior: https://on.cypress.io/web-security#One-Superdomain-per-Test explains why these are considered different super domains.
Sorry, I'm not sure. The exact domains I'm testing on are not publicly available and I haven't found a publicly available example that uses the same pattern.
It considers the 2nd to be a unique domain because they share different origin policies. One has a port of 8080
and the other has a port of 443
- these are not the same.
It is possible to relax these rules when chromeWebSecurity
is set to false
and there is another issue open describing this. However - needing to cross completely different origins like this is always indicative of an anti pattern and is never necessary. Different origins cannot communicate with each other via local storage or cookies or anything else - and therefore can always be tested in isolation.
We have written a guide for this because this is almost always due to logging in which can be bypassed and achieved with cy.request
. Can you provide more of a use case?
https://on.cypress.io/best-practices#Visiting-external-sites
What I'm trying to test is session persistence across two sites, which happens via cookie. I can manually complete the test I'm trying to do with Cypress, and it works, so I'm surprised to hear these sites can't communicate by cookie. It certainly looks like they can.
Here's what the relevant code looks like:
beforeEach(function () {
cy.visit(login_url)
cy.get('#inputEmail')
.type(email)
cy.get('#inputPassword')
.type(pass)
cy.get('input[value=Login]').click()
cy.visit(other_url)
})
it('has authenticated nav', function () {
cy.get('#header').should('contain', username)
})
Where login_url
is something like http://bar.baz.example.org:8080/login/
and other_url
is something like https://foo.example.org
.
I do have "chromeWebSecurity": false
in cypress.json
, but still get the error. https://on.cypress.io/web-security#One-Superdomain-per-Test made me believe that would remove the error, and you seem to be saying it will as well. But my experience contradicts both of those. I'm not sure how to demonstrate what I'm seeing, as I'm not aware of any public domain doing this. Nonetheless, I do believe my lying eyes.
Okay you are correct in regards to same origin policy for cookies. For historical reasons - port and scheme are not considered when setting cookies. Even though browsers restrict same origin policy to scheme and port, cookies are the exception. So in your case, yes they can set cookies.
For historical reasons, cookies contain a number of security and privacy infelicities. For example, a server can indicate that a given cookie is intended for "secure" connections, but the Secure attribute does not provide integrity in the presence of an active network attacker. Similarly, cookies for a given host are shared across all the ports on that host, even though the usual "same-origin policy" used by web browsers isolates content retrieved via different ports.
To clarify - what I meant was that with chromeWebSecurity
disable we should lift the same origin restriction but that we don't. We would be able to do though and everything "just work". What I meant was is that there is an open issue for that feature.
When we do that your situation will work. As of today, these are still not considered same origin to the browser or Cypress and therefore the error message is correct (even though the cookies are accessible).
I'm curious though - you should still be able to test this situation by using cy.request
and avoid manually typing into the form. Cypress will still properly set cookies under the hood for that cy.request
which would mean you'd still get coverage on what it is you're trying to test.
It would go something like..
cy.request(...) // to the auth server and get back cookies
cy.visit(...) // the app server which should have the cookies and be logged in
@brian-mann Is there some documentation on how to make the cy.visit()
not have the domain limitation?
I'm also trying to specifically test the OAuth process between two websites and I need domains to be different. This seems like a very common scenario. I know it can be solved with cy.request(...)
but that requires to have a much deeper understanding of the other site, how their cookies work, be able to end back multiple fields including CSRF tokens to fake the FORM post to auth the user and so on.
I'd rather have cy.visit()
work so we can clearly automate the OAuth process.
Thanks.
needing to cross completely different origins like this is always indicative of an anti pattern and is never necessary.
I have a login server I have no control over, and stubbing responses is too complicated and feels incorrect, since I also have other api requests that rely on cookies I get from said login server.
Since that login server is on a different URL, trying to do a cy.visit('/')
to my local env results in the single unique domain error. I have no way around that.
Duplicate of https://github.com/cypress-io/cypress/issues/944
Most helpful comment
@brian-mann Is there some documentation on how to make the
cy.visit()
not have the domain limitation?I'm also trying to specifically test the OAuth process between two websites and I need domains to be different. This seems like a very common scenario. I know it can be solved with
cy.request(...)
but that requires to have a much deeper understanding of the other site, how their cookies work, be able to end back multiple fields including CSRF tokens to fake the FORM post to auth the user and so on.I'd rather have
cy.visit()
work so we can clearly automate the OAuth process.Thanks.