cypress: Cypress vanishes when redirecting to site that breaks out of iframe

  • Operating System: Windows 10
  • Cypress Version: 2.1.0
  • Browser Version: Chrome 65.0.3325.181 (Official Build) (64-bit)

Is this a Feature or Bug?

Bug or potentially a feature request

Current behavior:

We integrate with Paypal as part of our checkout journey. We need to be able to redirect from our site to Paypal, enter some test credentials, and verify that we get redirected back to the payment complete page on our site. However, when we reach Paypal, they have some code that breaks their page out of the iframe, and Cypress vanishes altogether and the tests stop.

Desired behavior:

Paypal should not be able to break out of the iframe and the tests should continue to run

How to reproduce:

Clone this repo (the smallest I could get it): https://github.com/jpreecedev/cypress-paypal-scratch

run yarn install then yarn start and yarn test in seperate command windows.

Test code:

describe('Kitchen Sink', function() {
  it('.should() - assert that <title> is correct', function() {
    // https://on.cypress.io/visit
    cy.visit('http://localhost:8080/')

    cy.get('button').click()
  })
})

Additional Info (images, stack traces, etc)

In this repo I don’t redirect to Paypal but another page hosted on my server that basically does the same thing, The file is in the repo and is called breakout.html. Here is the code

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <script>
    debugger
    if (top.location != self.location) {
      top.location = self.location.href;
    }
  </script>
</body>

</html>

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 10
  • Comments: 19 (2 by maintainers)

Most upvoted comments

@brian-mann

I want to chime in saying that this would be useful. If we’re making a truly E2E test, then checking out via PayPal/Stripe or doing other things on a 3rd party site may be a critical step in the process. At least with Stripe, they provide a dedicated test sandbox specifically designed for this sort of thing so the points about being blocked due to detected automated activity are not always valid.

I was using webdriverio before, and had a truly E2E test including the checkout with stripe. Sad to see that this isn’t possible with Cypress? Is there no way around it?

Three years later I am here, migrating my webdriver tests to cypress and figuring out, that I can’t simulate a checkout with paypal due to the design of cypress? Come on, I am not testing the paypal page, I am testing our checkout-flow. If I can’t test the most critical function of a webshop, what else should I use cypress for? It should be my decision if my tests depend on an external page, but blocking it by default does not sound right to me.

@WinstonN “You should simply test the integration between your site and the 3rd party without ever going through it.”.

I am hitting this issue when trying to write a true e2e test for the critical path of our application. In my case this is when interacting with the Stripe Checkout (https://stripe.com/docs/payments/checkout).

As @mikob, these tools provide developers with methods for manual testing which would be great to take advantage of for, at least, critical happy path automated tests.

Would it be possible to allow this by exception, to allow developers to write critical path tests? In much the same way as you suggest in this section of your documentation: https://docs.cypress.io/guides/guides/network-requests.html#Use-Server-Responses

Cypress actually strips obstructive 3rd party code that causes this to happen. In fact we explicitly target those kinds of statements: however we only do it for the origin under test.

In both the Paypal example and this example repo: this security code is actually being served from a different origin under test: https://github.com/jpreecedev/cypress-paypal-scratch/blob/master/client/components/App/index.js#L8

In that case, the obstructive code will not be stripped and that’s why it’s happening.

However, I understand what you’re trying to do, and this is in fact a well documented anti pattern of Cypress that’s documented here: https://docs.cypress.io/guides/references/best-practices.html#Visiting-external-sites

I understand why you’re doing it, but relying on or trying to script against 3rd party sites will in most cases not work reliably. You should simply test the integration between your site and the 3rd party without ever going through it. Alternatively you can programmatically interact with the 3rd party site to avoid the issues that commonly plague automated scripts.

Paypal is a sophisticated entity and when writing your tests, you may see it begin to block you and detect that you are a robot.

I’m going to close this issue as won’t fix because we’ve already fixed problems with obstructive code so long as it’s being served under the current origin. Since it’s not the current origin, you are seeing this problem but it’s actually due to another antipattern which we do not support.

To elaborate on what @MartijnHols wrote - finally got it to work for stripe.confirmPayment() by adding this to the top of the test:

cy.intercept('https://js.stripe.com/v3', (req) => {
  req.continue((res) => {
    res.body = res.body.replace(
      'window.top.location.href',
      'window.self.location.href'
    );
    res.send();
  });
});

Found the workaround here: https://github.com/cypress-io/cypress/issues/19234

Perhaps something similar can be done for paypal

Hi guys, The latest version of cypress seems to have fixed it for me using experimentalModifyObstructiveThirdPartyCode:true (for paypal and a credit card checkout located in an iframe)

https://docs.cypress.io/guides/references/changelog#10-4-0

I remember spending more than 20 hours trying to make it work, even mocking, stubs etc but to no avail.

To a company such a feature would be pretty important, as it is the payments that bring revenue.

In fact it seems so important to me, that if/when I will be employed to set up automation from scratch I will not even consider Cypress if this will not be tackled, because incomplete E2E test automation does not help in “Quality Assurance”

@brian-mann I agree with @mikob We have a sandbox environment for Paypal testing and we want to test it with the flow on the browser. Cypress should have this option although its an anti-pattern by Cypress but with the configs it should be allowed. Someone has recommended this library as an alternate: https://github.com/puppeteer/puppeteer

In between thanks for this wonderful testing tool 🌟

You can modify the source for pages you visit using intercept to remove the framebusting. For example:

  cy.intercept("/breakout.html", (req) => {
    req.continue((res) => {
      // Disable framebusting for the page we're going to be redirected to
      res.body = res.body.replaceAll(
        "top.location = self.location.href;",
        ""
      );
    });
  });

For the Adyen PSP test environment I use https://**adyen.com/** instead of /breakout.html, I imagine you can do something similar for Stripe.

I am still trying to figure out how to apply this to Paypal though, since it opens a popup instead.

@brian-mann I understand your comments about this, and appreciate your honest feedback, but if I would need to do this, is there some plugin I could write to strip this out of the HTML? Could you give me a link or some example on how to do that?

Thanks again, for everything you do with Cypress, it’s such an awesome product to work with ❤️