Cypress: Accessing different super domains

Created on 8 Feb 2017  路  8Comments  路  Source: cypress-io/cypress

image

In our use case we have several different apps running in the same instance and we want to test the integration between then, to access the different applications we need to access localhost through a different port, however if we try to use cy.visit for this we end up getting into the limitation that we can't access two different super domains. We need to use cy.visit because we need to do act on the dom of the applications so cy.visit wouldn't do it. Is there any suggestions?

question

Most helpful comment

The trouble is cypress is not really a true e2e testing solution it seems. It's meant to test everything in isolation apparently, more like unit tests, or UI tests. Meaning it does not want/allow to jump between multiple domains in one test. So having a login command that completed a client credentials hand shake is impossible.

If you don't maintain your authentication/authorization services. You might also find that posting form data to servers are completely blocked by anti-forgery tokens as well. Which is a very common practice as the services will consider the test a Cross-site request forgery.

Basically this means you need to mock out every API call that the web application would make. Because your bearer token will not be accepted. This is possible in cypress. (You're not testing the API, your just testing your web page)

I imagine this is a limitation created to force a convention, or belief system on the testers. Or maybe to block malicious behavior Or maybe because it runs from a browser core. Either way, It creates a lot more work, but at least gives confidence in the tests due the limited scope they are testing.

All 8 comments

Is there a reason you have to visit two completely independent applications in the same test?

I see you are just visiting these back to back without doing anything. This seems unnecessary.

Can you provide some additional clarification and maybe a bit more details on the collaboration you're trying to test of each different application?

We have app1 which we can create users in. App2 will receive events about these users in a message queue and will update it's database accordingly. I'm trying to write an integration test which will browse the first app and create an user and will then open app2 and check if the user was replicated into it. The screenshot I uploaded doesn't reflect the actual test because the apps are from company's private repositories and we can't release their details to the public.

I see. You can use cy.request for this. This is really no different than a service which does external authentication like oauth or single sign on.

We have an example of this here: https://github.com/cypress-io/cypress-example-recipes#logging-in---single-sign-on

Basically just use cy.request to generate the users on app1, and then make your visit to app2.

In other tests you can test the UI itself on app1 by just visiting that and not visiting app2.

This enables you to test it both functionally and the integration of these two. Doing the latter with cy.request is also orders of magnitude faster - which I would recommend even if we did enable you to visit two different superdomains.

A recap of what I'm saying.

You need to separate out your tests and their concerns into two separate chunks.

Testing App 1:

  • cy.visit App 1 and use the UI
  • test all the various states like errors
  • these represent your e2e tests of logging in
  • do not ever visit or test App 2

Testing App 2:

  • use cy.request to generate users programmatically on App 1
  • cy.visit App 2
  • drive the UI and test all of its functionality
  • these represent the integration of App 1 + 2
  • and also represent the e2e tests of just App 2

@brian-mann hey there what about if i have a signup process that requires email verification?
Let me explain more: I am working on a website that has a multi-signup step process and the first step requires clicking on confirmation url so i need to access my mail server to get the confirmation url then go back and use that confirmation url to continue signup. How can i achieve that?

You access the mail programmatically, find the URL and use cy.request()

Or better yet you disable that feature in test env on your server so as to not make testing more difficult.

Or you expose this endpoint directly on the server as part of the user's profile information which you could then receive via cy.request().

The solution is always the same - when you're faced with a difficult situation to test - create a seam and make it easier. You have to design testability first class into any given system.

Email does seem like a common scenario that would require an additional domain. The solution we went for was to use https://mailcatcher.me/ to make the emails available in the browser then add a proxy to webpack-dev-server so that it could be accessed on the same host as the webapp. That way you can treat the email as just another page, visit it and click the link. If you need to hit your backend server you can add an additional proxy to make that available on the webapp domain.

The trouble is cypress is not really a true e2e testing solution it seems. It's meant to test everything in isolation apparently, more like unit tests, or UI tests. Meaning it does not want/allow to jump between multiple domains in one test. So having a login command that completed a client credentials hand shake is impossible.

If you don't maintain your authentication/authorization services. You might also find that posting form data to servers are completely blocked by anti-forgery tokens as well. Which is a very common practice as the services will consider the test a Cross-site request forgery.

Basically this means you need to mock out every API call that the web application would make. Because your bearer token will not be accepted. This is possible in cypress. (You're not testing the API, your just testing your web page)

I imagine this is a limitation created to force a convention, or belief system on the testers. Or maybe to block malicious behavior Or maybe because it runs from a browser core. Either way, It creates a lot more work, but at least gives confidence in the tests due the limited scope they are testing.

Was this page helpful?
0 / 5 - 0 ratings