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

After version 5.5 Stripe Checkout tests break out of the iframe #9447

Open
TuureKaunisto opened this issue Dec 3, 2020 · 36 comments
Open

After version 5.5 Stripe Checkout tests break out of the iframe #9447

TuureKaunisto opened this issue Dec 3, 2020 · 36 comments
Labels
E2E Issue related to end-to-end testing prevent-stale mark an issue so it is ignored by stale[bot] Triaged Issue has been routed to backlog. This is not a commitment to have it prioritized by the team. type: bug

Comments

@TuureKaunisto
Copy link

Current behavior

When testing a Stripe Checkout workflow the stripe.redirectToCheckout or the redirected page breaks out of the iframe and instead of completing the test just hangs.

Desired behavior

I'd expect the application to not break out of the iframe and the test runner to continue working even after being redirected to the Stripe Checkout page. (Like it did with version 5.5.0 and below)

Test code to reproduce

Here's a link to a repo with a simple React app to reproduce the issue.
https://github.com/kide-science/cypress-test-tiny

Unfortunately I was not able to reproduce the issue with vanilla JS. Stripe seems to do the redirect with:

window.top.location.href = redirectUrl

Setting the top.location.href seems to work without breaking out of the iframe, which leads me to believe that there are additional checks before the redirect or on the Stripe hosted Checkout page after the redirect that cause the test to break out of the iframe.

Versions

Cypress version: 6.0.1
Last known working Cypress version: 5.5.0
Browser: Chrome 87
MacOS Mojave

@rangabarath
Copy link

This is a blocker issue for us. thanks for creating a bug @TuureKaunisto

@jennifer-shehane - any ETA or workaround to this issue?

@jennifer-shehane
Copy link
Member

I am able to see the issue of the application taking over the entire Test Runner frame. This is pretty weird because I can only get this test passing on Cypress 5.5.0. Before 5.5.0 and after 5.5.0 break out of the frame.

If I had to guess, I would suspect that this PR made this test work: #8827 and we had to make a patch to that behavior since then because it broke other apps. #9018 (I haven't verified this though).

5.5.0

Screen Shot 2020-12-04 at 2 05 17 PM

5.4.0 / 5.6.0

@cypress-bot cypress-bot bot added the stage: needs investigating Someone from Cypress needs to look at this label Dec 4, 2020
@AmazingTurtle
Copy link

I can reproduce it for other sites as well. Verified on 5.3 and 5.5.

@the-baaron
Copy link

the-baaron commented Feb 14, 2021

yes, having the same issue. Hope it get's resolved soon! I think this is something that Stripe has to fix, as it's happening in other iframed situations too, not only in cypress.

@viewportdesign
Copy link

can confirm the issue, waiting for a fix for this.

@TuureKaunisto
Copy link
Author

yes, having the same issue. Hope it get's resolved soon! I think this is something that Stripe has to fix, as it's happening in other iframed situations too, not only in cypress.

I think Stripe tries to break out of iframes for good security reasons and are unlikely to change that behaviour since it's surely intentional.

@MikeKoval
Copy link

MikeKoval commented Feb 21, 2021

I bumped into the same issue when i tried to prepare E2E test for stripe payment flow.
Here is how i handled it, maybe it will be useful for somebody.

I found that stripe checkout url can be generated with this call.
await stripe._controller.action.createPaymentPageWithSession({ betas: stripe._betas, mids: stripe._mids(), sessionId: '' });
I simply wrote generated url to file and then run another test where read url from file and visit checkout page.

It's usage of not official stripe sdk methods and hack on hack, but i think it's ok for me as i still want to use cypress.

@TuureKaunisto
Copy link
Author

@jennifer-shehane is this issue something that might get fixed in an upcoming version? Perhaps the conflict with existing apps that rely on the current behaviour could be solved by implementing some setting that enables the Stripe compatibility only for those that opt in.

@AlbertMN
Copy link

Having this issue as well, would love a clear statement on whether it's done intentionally like @TuureKaunisto suggested.

@TuureKaunisto
Copy link
Author

TuureKaunisto commented Apr 20, 2021

Having this issue as well, would love a clear statement on whether it's done intentionally like @TuureKaunisto suggested.

I got a reply confirming it's intentional from Stripe support:

Checked-in with our engineering team, and they confirmed that Checkout is behaving as expected.
Additional context:
We intentionally do a top level redirect in Checkout and it is by-design that we don't accommodate iframes (it breaks wallets, certain redirect flows, etc.). It seems like some versions of Cypress hacked around this and their hack now no longer works or they removed the hack.

@AlbertMN
Copy link

@TuureKaunisto yeah, got the same reply some time after my comment - forgot to add it :) Think this means the issue can be closed.

@wilsonpage
Copy link

Before closing it would be good to have a suggested workaround from someone at Cypress. Not being able to test checkout flows is pretty problematic.

@TuureKaunisto
Copy link
Author

For us the best solution would be to have a setting that enables the hack that fixes this in 5.5. If it's off by default, it shouldn't break other apps. Otherwise we're stuck at using 5.5 if no other workaround is found. Not testing the payment workflow is not an option.

The workaround @MikeKoval suggested seems promising, but I would strongly prefer to write a test that tells the runner to click a button rather than calling a Stripe method manually since then I'm not testing if the button works anymore.

Would it perhaps be possible for the runner to detect when the iframe takes over the whole browser tab and handle the case more gracefully? I think the last I checked the whole test just froze.

I'm hoping Stripe Checkout is popular enough to warrant considering these otherwise suboptimal solutions.

@wilsonpage
Copy link

wilsonpage commented Apr 23, 2021

Stripe have a change in beta which exposes the final checkout url when requesting the checkout-session-id. This means you don't need stripe.redirectToCheckout(). You can request beta access by reaching out to them (see my issue).

I've tested it and it works great, but I'm still unable to test the checkout flow as Stripe Checkout fails to run when detecting it's inside an iframe 😩 So we still need something on the Cypress side to spoof checkout.stripe.com into thinking it's not inside an iframe.

For now I'm relying on jest-puppeteer to test my checkout flow fully, but I would rather be able to do this using Cypress.

@jennifer-shehane
Copy link
Member

The response from the Cypress team is that iframe support is coming. I know this isn't a great solution for people today and it's a big feature so will take time to build. But if we take time aside to find workarounds for all the situations for features that aren't truly supported, then it will delay our team delivering the actual feature.

Stripe testing is a big request for iframe testing and we'll definitely cover the most common testing situations. As mentioned earlier, Stripe intentionally doesn't want itself run within an iframe, so we have to address the core issues.

This issue was updated to reflect the API's we're currently working on: #136

@tngflx
Copy link

tngflx commented Jun 29, 2021

oh my fcking god. Now you're telling me not built yet? fuck... I almost launch production with it..

@jacktomlinson
Copy link

Anyone got any ideas how we are meant to test this then?

We still need the stripe webhooks to fire after completing a test with stripe checkout. The best of bad bunch of ideas I had was implementing the creation of the subscription logic (yikes) via the API then hoping could progress to our success screen after that in the tests.

@TuureKaunisto
Copy link
Author

Anyone got any ideas how we are meant to test this then?

We decided to stick to using the only working version: 5.5.0 until there is a fix or a better workaround.

@vojtapol
Copy link

implementing the creation of the subscription logic (yikes) via the API

This is what we did. I hated every second of it but it works fine.

@crispinamuriel
Copy link

crispinamuriel commented Oct 1, 2021

@MikeKoval

I found that stripe checkout url can be generated with this call. await stripe._controller.action.createPaymentPageWithSession({ betas: stripe._betas, mids: stripe._mids(), sessionId: '' }); I simply wrote generated url to file and then run another test where read url from file and visit checkout page.

I am currently trying to implement @MikeKoval's work around but am having trouble generating a session/ sessionId inside of Cypress, can anyone share an implementation for the creation of the subscription logic as discussed above?

@MikeKoval
Copy link

MikeKoval commented Oct 3, 2021

@crispinamuriel what trouble do you have? please provide more details, i can try to help. you can DM also.
My E2E workaround looks like this:

 cy.window()
    .then(async window => {
      const { object: { url } } = await window.stripe._controller.action.createPaymentPageWithSession({ betas: window.stripe._betas, mids: window.stripe._mids(), sessionId });

      cy.writeFile('stripe.json', JSON.stringify({ url }));
    });

In app itself i just listen additional query parameter provided by E2E test to prevent this redirect to checkout page:

await stripe.redirectToCheckout({
          sessionId: data.sessionId,
        });

@crispinamuriel
Copy link

crispinamuriel commented Oct 3, 2021

Thank you @MikeKoval , I will try this. I tried to create a session inside the cypress tests and not my app and was getting stuck there.

@alexbrazier
Copy link

We just started getting an error on our Stripe tests using Cypress 5.5.0 which was fixed by adding the following to the beforeEach in our tests:

cy.on('uncaught:exception', (err) => {
  // Allow stripe error: "paymentRequest Element didn't mount normally"
  if (err.message.includes('paymentRequest')) {
    return false;
  }
});

You can also do the same globally with Cypress.on('.... if required.

@vladmykol
Copy link

vladmykol commented Jan 12, 2022

Recently I was trying to apply some workarounds to this 'Stripe issue' and update cypress to version 9.2.1 but nothing really works well. I had to revert it back to 5.5

@rrabello-asp
Copy link

Is there a hack to set window.top on modern web browsers?

This seems like a security thing and maybe isn't fixable in code (like cypress) that runs alongside stripe. Using a framework like puppeteer might be the way to go since it relays commands to the web browser. Will let you know if I figure something else out tho.
https://docs.cypress.io/guides/references/trade-offs#Inside-the-browser

@cypress-bot cypress-bot bot added stage: backlog and removed stage: needs investigating Someone from Cypress needs to look at this labels Apr 29, 2022
@Quasarman
Copy link

Hello,

I am facing the same issue as well. I am using cypress 9.0.0 and have currently no intention of downgrading just to solve the stripe problem as this will introduce just some other issues. Also downgrading 4 Major versions seems like a bad thing to do.
Are there any updates on this issue? Is there a way to really test the full checkout flow? like pressing a button to open the checkout window.

Thanks.

@doomedramen
Copy link

doomedramen commented Jun 30, 2022

The same issue for me, Have had to just have the test redirect when the pay button is clicked, which means it cant test if there is an error before the redirect.

cy.get('#pay-button').contains('Pay').click()
cy.visit(URL+'/confirmation')

@CrispinaRMuriel
Copy link

using cypress-plugin-stripe-elements to get around this https://www.npmjs.com/package/cypress-plugin-stripe-elements

@rafaelaazevedo
Copy link

This worked for me flawlessly ! Also it removes the iframe issue. Not sure if people would accept it as a real e2e tests tho.

https://github.com/riccardogiorato/cypress-for-everything/blob/main/examples/stripe/cypress/e2e/stripe-checkout.cy.ts

@dmolin
Copy link

dmolin commented Oct 3, 2022

Any update on this issue? it's pretty much impossible to test Stripe checkout atm with Cypress.

@Slashmsu
Copy link

Slashmsu commented Oct 7, 2022

What you can also do, it's check with an interceptor did you received the stripe session id or no.

cy.intercept(
      'https://some-awesome-web-app/api/create-stripe-session'
    ).as('stripeSession');

// and later

cy.wait('@stripeSession').then((interception) => {
          expect(interception.response.body.id).to.be.exist;
        });

I know, that it will not solve your problem, but it is more than nothing.

Docs: https://docs.cypress.io/api/commands/intercept#Aliasing-individual-requests

@vladmykol
Copy link

vladmykol commented Nov 4, 2022

It seems like folks doing some progress here #21603 but it's still not working

@nagash77 nagash77 added the prevent-stale mark an issue so it is ignored by stale[bot] label Apr 3, 2023
@prakharritik
Copy link

The stripe checkout integration test worked for me after adding this:

const { defineConfig } = require('cypress')

module.exports = defineConfig({
  experimentalModifyObstructiveThirdPartyCode: true,
})

Here are the docs.

@nagash77 nagash77 added E2E Issue related to end-to-end testing Triaged Issue has been routed to backlog. This is not a commitment to have it prioritized by the team. labels May 4, 2023
@vladmykol
Copy link

vladmykol commented Jul 14, 2023

Thanks @prakharritik. It works. We updated our test form v5 to v12. There are a lot of breaking changes, so it was like writing everything from scratch, hopefully for a better

@AbbiyG
Copy link

AbbiyG commented Jan 10, 2024

any updates or any solution for this problem i'm still facing same problem on v-13.6.2

@Kartikeybajpai199
Copy link

Hi I am facing a similar issue i.e. sometimes paynow button in razorpay checkout modal is not clicked but consoles after that is logged and execution fails after some time same paynow button is clicked sometimes i am facing this issue from long time can anybody help me with this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
E2E Issue related to end-to-end testing prevent-stale mark an issue so it is ignored by stale[bot] Triaged Issue has been routed to backlog. This is not a commitment to have it prioritized by the team. type: bug
Projects
None yet
Development

No branches or pull requests