Open TuureKaunisto opened 3 years ago
This is a blocker issue for us. thanks for creating a bug @TuureKaunisto
@jennifer-shehane - any ETA or workaround to this issue?
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: https://github.com/cypress-io/cypress/pull/8827 and we had to make a patch to that behavior since then because it broke other apps. https://github.com/cypress-io/cypress/pull/9018 (I haven't verified this though).
I can reproduce it for other sites as well. Verified on 5.3 and 5.5.
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.
can confirm the issue, waiting for a fix for this.
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.
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: '
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.
@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.
Having this issue as well, would love a clear statement on whether it's done intentionally like @TuureKaunisto suggested.
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.
@TuureKaunisto yeah, got the same reply some time after my comment - forgot to add it :) Think this means the issue can be closed.
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.
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.
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.
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: https://github.com/cypress-io/cypress/issues/136
oh my fcking god. Now you're telling me not built yet? fuck... I almost launch production with it..
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.
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.
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.
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?
@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,
});
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.
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.
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
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
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.
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')
using cypress-plugin-stripe-elements
to get around this https://www.npmjs.com/package/cypress-plugin-stripe-elements
This worked for me flawlessly ! Also it removes the iframe issue. Not sure if people would accept it as a real e2e tests tho.
Any update on this issue? it's pretty much impossible to test Stripe checkout atm with Cypress.
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
It seems like folks doing some progress here #21603 but it's still not working
The stripe checkout integration test worked for me after adding this:
const { defineConfig } = require('cypress')
module.exports = defineConfig({
experimentalModifyObstructiveThirdPartyCode: true,
})
Here are the docs.
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
any updates or any solution for this problem i'm still facing same problem on v-13.6.2
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
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:
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