max 1 site... support visiting multiple superdomains in one test #944
Comments
Yeah, it can be done. Quick question - is there any reason you need a browser to load up 500 different domains and click a button? Wouldn't it be much much easier to just use For instance, what does clicking the button do? Send an HTTP request is my guess. So instead of using the UI, just send the HTTP request directly using Any additional information about your use case would be helpful. |
Just jumping in to say that I have a use-case where I need to load several sites in the same test (not 500, 2 will do for a test). I'm testing a browser extension that will show a modal (via a content script) on several sites that you can whitelist in its settings. The extension uses a global timer (via its background tab) to synchronise the extension's behaviour across different sites/tabs/link clicks/refreshes (it persists a countdown as you browse those various whitelisted sites, among other things). Because of this restriction, I can't test that the synchronisation works when the sites I visit are on different domains. I can't just make a |
To me the issue is that it is more work to simulate the requests than it is to have Cypress fill in a form. That and it deviates too far from the User flow that my users would be experiencing. |
This is an applicable issue for my organization's test code. We recently implemented OKTA, which requires you to go to a super domain to authenticate then route to the super domain that is going to be tested. When I use "cy.visit()" after authenticating, all authentication data will be wiped out and Cypress will attempt to authenticate the same exact way again, causing either a sid or cross domain error. Due to this issue, we are about to drop Cypress all together and move back to Selenium. |
@alovato88 if you switched to using @MaxwellGBrown we've been down this rabbit hole many times with many different user feedback and the answer is always the same - you can test your login page in isolation away from the main app once, and then use Just visit the OTHER domain in the test and log in. You could even stub the network request if you wanted to prevent the 3rd party server from redirecting you. Once you do that, then use There are many other issues in here in which I've commented providing different approaches and work arounds you all may find useful. Our best practices cover this pretty in depth, and I've even given a talk about this subject and provide real world examples of how to approach this problem.
@ejoubaud You can do this in Cypress - simply visit the domains in different tests, not the same test. As long as you don't visit two different super domains in one test it will all just work. Visit one super domain, test your extension, and then in a separate test visit a different one and test your extension in there. |
@brian-mann Where can I find any of these showcased recipes? |
I think I have a good use case for this. We're migrating from a monolithic Ruby on Rails app, to micro-services on the back-ends and user-type differentiated front-ends. Our new front-ends are React SPAs, and one of them is way too big to replace at once, so for some app routes we just display the original page within an iframe whereas for others we're using React components to render those routes. At present I can't write tests that exercise new and old at the same time. I'm presently working around this by putting every test in its own file, but this is far from ideal. |
We also require this functionality to test a third party integration |
I would love to be able to visit multiple domains. My use case is testing the integration between a front end site and a backend admin. There are certainly ways around not visiting multiple domains, however locally they are only running on different ports (3000, and 3001). There certainly are work arounds:
|
This is an absolute blocker for my current client. They have built a solution that integrates several SaaS systems including Salesforce, and need to be able to test side-effects in integrated systems. For example, that registering in the Web front-end causes a lead to be created in Salesforce. We too will have to abandon Cypress for Selenium, despite significant enthusiasm for Cypress, if this use case can't be addressed. Update: maybe not ... we are able to subsequently test state on the SaaS system in a second context, and reset it in a third. Something of a hack though. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This limitation is a blocker for us as well. I thought I might be able to overcome this limitation by being a bit creative. I tried the following solutions without success: Workaround attempt 1 - Use a custom proxy to remove security headers To solve this I created a proxy which would remove these headers, and passed this proxy to Cypress using environment variables: const fs = require('fs');
const hoxy = require('hoxy');
const hostname = 'localhost';
const port = process.argv[2];
createProxy(hostname, port);
console.log(`Started proxy on ${hostname}:${port}`);
function createProxy(hostname, port) {
const proxy = hoxy
.createServer({
certAuthority: {
key: fs.readFileSync(`${__dirname}/ca/selfsigned-ca.key.pem`),
cert: fs.readFileSync(`${__dirname}/ca/selfsigned-ca.crt.pem`)
}
})
.listen(port, hostname);
proxy.intercept({ phase: 'response' }, removeSecurityHeaders);
}
function removeSecurityHeaders(request, response) {
console.log(request.fullUrl());
delete response.headers['x-frame-options'];
} Passing it to Cypress: Requests where passing through my proxy, but it still didn't work. After a while I found out that only the requests for the AUT where passing though the proxy. Workaround attempt 2 - Load Chrome extension to remove security headers {
"scripts": {
"download-extension": "ced gleekbfjekiniecknbkamfmkohkpodhe extensions/ignore-x-frame-headers"
},
"dependencies": {
"chrome-ext-downloader": "^1.0.4",
}
} And loaded the extension via const path = require('path');
module.exports = (on, config) => {
on('before:browser:launch', (browser = {}, args) => {
console.log(config, browser, args);
if (browser.name === 'chrome') {
const ignoreXFrameHeadersExtension = path.join(__dirname, '../extensions/ignore-x-frame-headers');
args.push(args.push(`--load-extension=${ignoreXFrameHeadersExtension}`));
}
return args;
});
}; With this the external page did load. However, Cypress didn't work on that page. Apparently Cypress uses the proxy to inject itself into the page. Conclusion Now let's discuss this. Things are different when you want to test the integration between different applications. If testing such integrations is the main focus of your tests, you need support for multiple super domains. Often such integrations include more complicated flows such as: Now one can argue that Cypress just isn't meant for use cases like this. Especially if there is a technical limitation which is nearly impossible to overcome. What I am currently missing in this discussion is an explanation on what this technical limitation is. Why does Cypress currently support only one super domain? What would be needed to support multiple? Would implementing that make Cypress a lot more complex? Or would it be, just a lot of work? Related: |
Here's a hacky workaround: Cypress.Commands.add('forceVisit', url => {
cy.get('body').then(body$ => {
const appWindow = body$[0].ownerDocument.defaultView;
const appIframe = appWindow.parent.document.querySelector('iframe');
// We return a promise here because we don't want to
// continue from this command until the new page is
// loaded.
return new Promise(resolve => {
appIframe.onload = () => resolve();
appWindow.location = url;
});
});
}); |
Hi @suchipi this looked like a promising workaround! But unfortunately the x-frame-options issue still remains for us...
|
Tested this with hope it will work, it is already an improvement sa it seems to load the page in the promise but then: Refused to display 'https://****'' in a frame because it set 'X-Frame-Options' to 'sameorigin'. Will watch this post for updates. |
Let me present the use-case I need to visit 2 domains for, to bring in my 2 cents on this issue.
This is the TL;DR version of our onboarding workflow. It is very collaborative between our users and our back-office, and it doesn't make sense to test one without the other. Programming this via Maybe things running on For the record, we tried to use subdomains to address this. It worked fine on developers' environment but it turned out to be very difficult to build in a CI pipeline, in terms of complexity and pipeline time. |
I have this in my cypress.json {
"baseUrl": "https://my-website.com",
"chromeWebSecurity": false
} but I'm still getting this error: CypressError: Cypress detected a cross origin error happened on page load:
Before the page load, you were bound to the origin policy: A cross origin error happens when your application navigates to a new superdomain which does not match the origin policy above. This typically happens in one of three ways:
Cypress does not allow you to change superdomains within a single test. You may need to restructure some of your test code to avoid this problem. Alternatively you can also disable Chrome Web Security which will turn off this restriction by setting { chromeWebSecurity: false } in your 'cypress.json' file. https://on.cypress.io/cross-origin-violation Any ideas as to why explicitly disabling chromeWebSecurity doesn't work? |
Is there a reason cypress suggests changing this config property but it doesn't work? My current workaround is to have separate tests visit the different domains. It works because during dev I have a dummy server keeping up with requests made from the different origins. describe("Do stuff on one site then visit another and check it worked", () => {
it("Can open the first site and do some things", () => {
cy.visit("localhost:8080");
// do stuff that sends data to a dev server running on another port on localhost
});
it("Can see the results in the other place", () => {
cy.visit("localhost:8888");
// validate my things went good
});
}); Test names and descriptions are vague on purpose. It's not best practices since my tests have to be run sequentially and depend on the previous, but it's helped me test my workflow better. |
I'm not sure why the team is not responding to this issue, but I do have a status update: they're working on this as a feature in the roadmap: https://docs.cypress.io/guides/references/roadmap.html#Upcoming-features I asked them to communicate this back to the community before, I'm not sure why they haven't, but they are working on it. Hope that helps! |
Thank you @TheDutchCoder ! |
If you guys follow this issue, it was mentioned on Nov25 that this is
placed on the roadmap.
…On Tue, Dec 22, 2020, 16:37 paolarosanarodrigues ***@***.***> wrote:
I'm not sure why the team is not responding to this issue, but I do have a
status update: they're working on this as a feature in the roadmap:
https://docs.cypress.io/guides/references/roadmap.html#Upcoming-features
I asked them to communicate this back to the community before, I'm not
sure why they haven't, but they *are* working on it.
Hope that helps!
I'm not sure why the team is not responding to this issue, but I do have a
status update: they're working on this as a feature in the roadmap:
https://docs.cypress.io/guides/references/roadmap.html#Upcoming-features
I asked them to communicate this back to the community before, I'm not
sure why they haven't, but they *are* working on it.
Hope that helps!
Thank you @TheDutchCoder <https://github.com/TheDutchCoder> !
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#944 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAKXMIITSJP4RD3PGGCIPP3SWC4KPANCNFSM4EEX7LIQ>
.
|
If you want it to work right now, try this - Authentication. |
Hey, thanks for all the feedback. We are working on multi-domain support with a focus on authentication testing. Outside of authentication, we know there are other needs for multi-domain support. I just want people to be aware that our main focus is on prvoding a solution for testing authentication. This is reflected across many of the features we're currently working on - including the upcoming Sessions API. From our product brief:
At this stage, we're writing our technical brief and will then spike into seeing which technical implementation is best. So we hope to post more updates once that work is a little bit further along. |
Super excited for this. Thank you @jennifer-shehane |
For us the use case is simple (in my head anyway) and requires a full and complete handoff from one domain to another, not simultaneous support for two different sites. Scenario: We do something in our back-office application that has an impact on the clients portal Nothing to do with Authentication, but I suspect a pretty basic and common test scenario |
I can imagine the kind of comments and push back you might get for this, but the fact is that one of the main points of e2e tests from my perspective is to make sure that SYSTEM (which may be composed of one or more applications) works for the user and in some cases that requires crossing boundaries. So yea, I agree. |
Curious why a 3+ year old ticket with obvious user need and utility goes ignored. We are currently evaluating Cypress; and issues like this can be make-or-break it. I understand that it might be on the roadmap. If so, need official confirmation and a promised date. Silence is not acceptable for a company that is asking for money. |
@jeffrey-aguilera This issue is on our roadmap. I posted an update a few weeks ago on the issue. We're doing some more discovery from our Technical Brief. I'll paste some updates from that work below. This is a work in progress, so this may change as we move forward and/or make discoveriesMulti-domain Technical Brief excerptsWe would like to allow users to move between and write Cypress commands for multiple domains in their test. Besides generic tests for multiple domains, this enables users to authenticate in a more end-to-end fashion than is currently possible. It also lays the groundwork for supporting iframes. We need a new API that allows switching into the context of a different domain, passing values into that domain, and retrieving values from that domain. We also need to inject Cypress into any domain that the user visits and set up communication between the main domain and the new domain. Technical Discovery
Domain-switching APIAllows switching into a different domain in order to run Cypress tests. const title = 'My title'
const posts = ['post 1', 'post 2']
cy.switchToDomain('domain2.com', title, posts, (title, posts) => {
cy.on('window:before:unload', () => { })
cy.get('.username').type('username')
cy.get('.password').type('password')
cy.get('button').click()
cy.contains(title)
Cypress._.each(posts, (post) => {
cy.contains(post)
})
}) Cross-domain SnapshotsIn order to support cross-domain snapshots storing and restoring, we can utilize a bridge iframe. Currently we have 2 iframes embedded in the top frame:
For cross-domain support, we can add an AUT-bridge iframe:
Knowing when we are about to navigate to a cross-origin context, the proxy can delay cross-origin HTML response until receiving an ack from the driver if it's a full page load. |
@jennifer-shehane thanks for the update. One thing to consider here is the perspective that users don’t necessarily care about the concept of manually switching to a domain. More that they are able to visit a url in general and that as part of visiting cypress can follow the requests. Would a user have to manually switch in this sort of multi domain scenario between each redirect assuming site, auth and google are different domains? Visit a site, redirects to auth provider. |
Recently found your wonderful tool. Perhaps I will be able to persuade the management to take it, taking into account the work on this problem |
Hey people, my team have the same problem in your test suite, we need test two domains in the same test because the application redirect the user. You have a promised date for this feature? |
Try Playwright. |
@leandro-ugioni-sofist the problem was solved for the scenario when the domain changes during the login (we are using the 6.2.1 version and it already contains the fix). But I think that for other scenarios, it is not ready yet. |
@paolarosanarodrigues many thanks for the heads up! Could be more specific about this?
Did the Azure B2C redirections worked out without changing anything at all? |
No, we only changed for version 6.2.1 and the Cypress didn't break during the login process \o/ |
Awesome, I'll probably give it a go soon (we are currently on Azure B2C too)! Thanks for the feedback, much appreciated :) |
Hey guys, I would like to log in to an application using facebook, but as it is necessary to interact with facebook window, cypress couldn't interact with, someone has an alternative? |
@ana-sofist Try Playwright. |
Any update on this? We need this to visit two or more domains in the same test, it's very very important to us |
@miguel10m10 Yes, please see #944 (comment) for most recent updates. |
@jennifer-shehane Thanks a lot for working on this. Can't tell you how useful this feature will be. We currently have to manually run tests for Apple or Google Authentication flows on our pages and would love to automate this via Cypress asap. |
Using @dudziakm solution. @jeremyimmanuel how does this fail? Cypress.Commands.add('forceVisit', url => {
cy.window().then(win => {
return win.open(url, '_self');
});
}); /// <reference types="cypress" />
context('Force Visit', () => {
it('should be able to visit and assert on two domains', () => {
cy.forceVisit('https://example.cypress.io');
cy.title().should('eq', 'Cypress.io: Kitchen Sink');
cy.forceVisit('https://www.linkedin.com/company/cypress.io/');
cy.title().should('eq', 'Cypress.io | LinkedIn');
})
}); |
Maybe you could document a way for us to remove this limit without having to open an issue to have the core functioning of the app changed ? Maybe allow passing an argument when running the app.
The text was updated successfully, but these errors were encountered: