Skip to content
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

Web Security - multiple superdomains #1394

Closed
tomboon opened this issue Mar 1, 2018 · 4 comments
Closed

Web Security - multiple superdomains #1394

tomboon opened this issue Mar 1, 2018 · 4 comments
Labels
type: duplicate This issue or pull request already exists

Comments

@tomboon
Copy link

tomboon commented Mar 1, 2018

  • Operating System: windows 10
  • Cypress Version: 2.0.3
  • Browser Version: Chrome 63

Is this a Feature or Bug? Feature

Current behavior:

As per the documentation found on cypress web security it is not allowed to visit multiple superdomains.

Desired behavior:

Our application consists of a GUI that runs on localhost:80/app and a windows service that runs batchjobs, which has a dashboard running at localhost:81/dashboard.

We are investigating if we can use Cypress to create an automated testplan that runs on an isolated environment. So we are deploying our GUI and our batchjob service on a single machine. An example of what we want to achieve is:

  • copy an xml file to a certain directory
  • visit localhost:81/dashboard to trigger and followup the batchjob that imports that xml file
  • when finished, visit localhost:80/app and browse to a certain page and assert that the imported data is accessible

We have everything working except for the fact that Cypress blocks the call the visit localhost:80/app because it is a different superdomain than localhost:81/dashboard.

Do you have any suggestions on how to solve this issue?
I have read that this limitation is artificial and can be removed.

Thank you for any advice.

@brian-mann
Copy link
Member

So you're basically running two completely separate apps with a two different GUI's - but they are connected because they're running on the same machine and likely query from the same service. Hopefully I have that right.

Typically apps separated by origin are completely disconnected from each other - because it's the same thing as google.com vs apple.com. I get the only difference here is the port - but the origin policy of the browser see it a different way.

There are a number of things you could do or we could change to make this happen.

  1. Remove the origin policy restriction when disabling chromeWebSecurity. This is pretty long overdue, but it's just not as high of a priority as other things. Removing this would allow you to navigate between super domains and test it the way you're suggesting.
  2. You could use a proxy server so that the applications are separated only by subdomain, but not by port. For instance you could have app1.dev.localhost:8080 and app2.dev.localhost:8080. Those will share the same super domain and you'll be able to navigate between them. Your proxy server would then sit in the middle and know how to route requests based on the request host.
  3. Another even better option with a proxy server is just to use the same host but divide by the path name. For instance have localhost:8080/app and localhost:8080/dashboard automatically be routed to separate services. This is a really common implementation across the internet that bypasses all kinds of CORS issues and it's actually even better than sharing subdomains.
  4. You could split out your tests and test each service in isolation. This is also ideal, and doesn't require any proxies. You would only visit one app in each test and then use cy.request programmatically to interact with the other app. This is most common in SSO scenarios or oauth.

You say you want to do 3 things:

  1. copy an xml file
  2. visit the dashboard + trigger some action and wait for it to complete
  3. visit another site and make sure it can get the data.

I understand why it seems easier to test 2 + 3 together, but you could just as easily and with 100% confidence test them in isolation without building up or sharing the state.

You could just do step 1 programmatically from within your tests. Easy.

You could then visit the dashboard and trigger the action. Easy.

Instead of going to step 3 - you should programmatically validate that step 1 + 2 generated the correct state. That may mean doing database queries, or using cy.request() for polling requests until it's finished and that it sends the right data.

That's it. Stop.

Then when you want to test step 3 - skip step 1 and 2. Just seed the condition / state that step 1 and 2 create. Maybe its a database record. If you're only testing that the data that feeds the app is a simple JSON payload - you don't even need to seed the state. Just stub the response using Cypress and test that your UI displays the right thing.

Doing it this way requires a different mindset and approach - but it's the secret for creating fast and scalable tests. Once you test the underlying mechanisms directly you can bypass those and just test the side effects without setting up the state of the world.

Another option which you could probably get by with today is building up state between your test. This is an anti pattern with a lot of problems, but it would technically work to get around the super domain restrictions.

describe('your app', () => {
  context('dashboard', () => {
    it('triggers the job', () => {
      cy.visit('localhost:8080')
    })
  })

  context('app', () => {
    it('checks the job', () => {
      // this structure works but it sucks because
      // running this test requires that the first run
      // successfully before it. best practice is to write
     //  tests that don't build up or rely on the state of previous ones
      cy.visit('localhost:8081')
    })
  })
})

@brian-mann
Copy link
Member

Also see this answer for additional help: #1392 (comment)

@marklagendijk
Copy link

This is a duplicate of #944.

@jennifer-shehane
Copy link
Member

@marklagendijk Thanks! Closing as duplicate of #944

@jennifer-shehane jennifer-shehane added the type: duplicate This issue or pull request already exists label Nov 28, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

4 participants