EDIT: Very important to note this only happens when target of redirect has x-frame-options set to sameorigin
Should chromeWebSecurity: false prevent this error?
Bug
Setting chromeWebSecurity to false is not turning off web security when destination of redirect has x-frame-options set to sameorigin
Setting chromeWebSecurity to false should turn off web security
Try do to a javascript redirect (see example code) during a cypress test.
window.location.href = 'https://www.google.com'
This was working for me last week. Same code this week is not working. The site I'm redirecting to has X-Frame-Origin set to sameorigin.
Closing because this isn't a cypress issue.
Cypress automatically strips X-Frame-Origin headers - but it does so only for the origin under test - it does not do it for requests coming from other origins.
What is it that you're actually trying to do?
@brian-mann
My app does a javascript redirect, the destination page (on a server I don't control), has x-frame-options header set to sameorigin, which causes chrome to prevent the redirect.
Are you saying that the x-frame-options header be getting stripped off by cypress?
It is stripped only for the domain under test. It is not stripped for external requests.
Why are you redirecting to an external page? You can usually just prevent this from happening by stubbing out those functions directly, or programmatically interacting with the other service via cy.request().
Just trying to understand your use case.
It's a partner integration where we hand off users to a partner. It would be nice if I could stub out the response with cy.server(), but that doesn't seem to work for a url outside the test's original domain.
@brian-mann {"chromeWebSecurity": false} does not work for me either . I want my test execution to not stop when javaScript error is thrown by application.
Any update?
{"chromeWebSecurity": false} does not work for me either.
I think it works well before version 2.10
@asos-arun @CaiYiLiang there is nothing to do here. The option works as advertised. Stripping x-frame-options from remote servers requires funneling all requests through the proxy which is a significant change and is a separate issue altogether and has nothing to do with disabling web security. Previous works all work the same way.
@brian-mann - clearly there is an issue here. If you just see how many people are complaining about this issue post v2.10. I appreciate this is an open source project BUT there is still a commercial part to it.
Currently, we have invested in Cypress only to find things go worse with new releases. That is not a good way to build trust in a new platform. I am saying this with all the love in the world and I would like you guys to be successful.
Suggestion: find a solution or clarify in the docs how to get around it. Most of the discussions are too technical for people to follow (me included).
Our case: we are getting this issue when calling our API with with invalid credentials and want to ensure the app redirects (outside domain) to re-login. The app works fine but the test causes the issue due to the redirect.
Thanks!
@brian-mann there is a case where one could have more then one domain under test when following a user journey with data handover. How should this be solved if there a things like this which are only available for one domain?
@checklist @fahrradflucht the solution today is to change your approach and not change Cypress. I / we understand the need to journey across domains but it is not possible to build a tool that is superior to all existing tools (architecturally) without introducing trade offs. We don't control W3C or browsers or the security rules that govern how the entire web fits together.
We've created a superior product to test the vast majority of situations - namely where you reside on a single superdomain. This is the domain that you control. With that said, we're aware there are situations that involves exchanging data between services. However, you can always bypass these. What we're saying is that rather than making Cypress do backflips to try to accommodate this situation, we believe it can by entirely bypassed altogether by approaching it differently - and one that is within your control that will work deterministically 100% of the time.
Will this take more work up front - rather than writing a script that behaves exactly the way your application does to real users? Yes, in this one case it will, but it will better set you up for long term success and enable you to still test all of the edge cases and situations without leaving yourself vulnerable to things outside of your control. This is a core tenant of Cypress, it makes the hard things easy, but it makes some seemingly simple situations harder. There is no free lunch here because we don't control everything at our whim to make this possible. If we updated our architecture to make this one particular situation easy, then we would be inheriting the entire zoo of problems that Cypress itself has bypassed by redesigning the automation layers from the ground up. If you specifically need the functionality that enables you to cross domain services, you can already use the myriad of other automation tools that enable you to do just that. The problem is though, is that approach on those tools doesn't work well for the reasons why we don't actively support them in Cypress.
Read these two best practices for more information:
You can with nearly 100% guarantee bypass the need to interact with the other domain by simply using cy.request or using cy.stub in your application. When you want to interact with the other service, you don't "start there" - you use cy.request to get the thing out of the service and then you "start" with your application already having received that state. Maybe it's a token in the URL you set as a cookie or in local storage.
As far as wanting to test redirection to another domain - that part is easy too. Why do you even need a browser to do that? Couldn't you just make an invalid API request and see that your server send a 301 redirect to the correct URL? Because Cypress attaches your browsers cookies to cy.request you could simply use that to know whether the redirect is happening. You could even involve the DOM if this event is triggered by something in your application.
cy.get('a').then(($a) => {
const href = $a.prop('href')
cy.request(href).then((resp) => {
// make sure we've been redirected
// to where we expect to be
expect(resp.redirectedTo).to.eq(....)
})
})
If your server is hard coded to send the redirect to another domain, perhaps you could force it not to do that in the test environment. Maybe instead it could send you to a page within your domain that you could then test for using the browser.
Is all this a little bit of extra work? No doubt... but if you tease apart the fundamentals of good testing and application building you'll find these are the same principles you use when writing good unit tests. It's up to you to make an application easier to test. You need to expose seams that you can tap into so you balance the need for confidence and coverage with those that enable you to write fast performing, deterministic tests.
If you go a bit further out of the box you'll realize that these are the same principles of why we even write automated tests that a robot could perform. Why not just have a human perform all these steps manually? Easy - it's not scalable, its slow, and it's expensive. All of these decisions are a trade off. We potentially lose some form of confidence (because a human has intuition) and we spend engineering resources writing tests, but we get a faster, more scalable system that can be run over and over again at low cost, and it can pivot and change better as the given system under test changes over time too. Creating these seams is the same answer - you invest a bit more time maybe up front designing a more testable system (since you're likely introducing tests after the fact - a problem you likely would have avoided building the system with tests in mind) but the end result is better.
Most helpful comment
@brian-mann {"chromeWebSecurity": false} does not work for me either . I want my test execution to not stop when javaScript error is thrown by application.