Skip to content

Instantly share code, notes, and snippets.

@mbrochh
Last active February 8, 2024 13:02
Show Gist options
  • Save mbrochh/460f6d4fce959791c8f947cb30bed6a7 to your computer and use it in GitHub Desktop.
Save mbrochh/460f6d4fce959791c8f947cb30bed6a7 to your computer and use it in GitHub Desktop.
Controlling a Stripe payent popup with Cypress.io
// for this to work you need to set `"chromeWebSecurity": false` in cypress.json
describe('Make Stripe Payment', function() {
before(function() {
cy.visit('http://localhost:3000/en/stripe/checkout/')
Cypress.Cookies.preserveOnce('sessionid')
})
it('should enter credit card details and finalise payment', function() {
cy.get('[data-test="button-FormStripeCart-PayWithCreditCard"]').click()
// there are better ways to get the iFrame in a promise, I think, and there is
// a new API coming up soon to deal with iFrames, but I was lazy and just put a
// wait here - 6secs is usually enough to let the Stripe popup load fully
cy.wait(6000)
cy.get('iframe').then($iframe => {
const doc = $iframe.contents()
let input = doc.find('input')[0]
// super weird stuff here, if you just input '4242424242424242', the value
// that you end up seing in the input element is jumbled up a little,
// probably because of the way how Stripe inserts spaces while you are
// typing. By luck I found out that this issue can get worked around if
// you just chain-call type()
cy
.wrap(input)
.type('4242')
.type('4242')
.type('4242')
.type('4242')
input = doc.find('input')[1]
cy
.wrap(input)
.clear()
.type('12')
.type('20')
input = doc.find('input')[2]
cy
.wrap(input)
.type('123')
.type('{enter}')
})
cy.url({ timeout: 20000 }).should('contain', '/en/profile/my-orders/')
Cypress.Cookies.preserveOnce('sessionid')
})
})
@mannycolon
Copy link

Thanks @dbalatero, very helpful. It worked on my end.

@kaushal0212
Copy link

cy.get("#braint-hosted-number")
.its("0.contentDocument.body")
.then(cy.wrap)
.invoke("val", "4005519200000004")
.click()
.type("4005519200000004");

@dimasambo
Copy link

For the 3D secure I cleaned it up a bit and made it into a utility, so I can both confirm and deny it. Hope it helps someone Note the __privateStripeFrame does not have the number, it could fail on you randomly otherwise :)

function confirm3DSecureDialog (confirm = true) {
    cy.wait(5000)
    cy.get('iframe[name^=__privateStripeFrame]')
      .then(($firstIFrame) => {
        cy.wrap($firstIFrame.contents().find('iframe#challengeFrame'))
          .then(($secondIFrame) => {
            // authorise
            const target = confirm ? '#test-source-authorize-3ds' : '#test-source-fail-3ds'
            cy.wrap($secondIFrame.contents().find(target)).click()
          })
      })
  }

About testing 3DS, has anybody had an issue that after confirming 3ds modal your next code not running?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment