In this article we will look into how we can test a website that uses iframes like Stripe Elements.
We recently started using Cypress as our E2E testing framework and love it for its simplicity and ease of use. If you haven’t used it before give it a try!
While Cypress is elegant to work with on your own code, it might get tricky when you use third party components in your webapp. In our case the users can pay with credit card. To collect the payment details we use Stripe Elements which loads an iframe into our website. Cypress however doesn’t support iframes yet. Luckily mightyiam found a workaround to access iframes and their contents with Cypress.
Setup
We’re assuming that you set up a Cypress project and ran the example test suite. Your project structure should look like the picture below.
We will start with extending the commands.js file.
Append this code to your commands.js
file. Now you can use cy.getWithinIframe(‘a selector’)
to target any element within the iframe.
If you need greater flexibility you can use iframeLoaded
and getInDocument
as shown on the left. You can chain many Cypress commands after getInDocument
.
Typing into Stripe Elements
Now we’re able to fill out credit card details. In your browser’s dev tools you can see the structure of the iframe being loaded by Stripe Elements.
As you can see in the highlighted area, there’s an input that we can select with [name=”cardnumber”]
. With this information we can tell Cypress to fill out the test credit card number 4242 4242 4242 4242 as well as the other required information. The other input parts are exp-date, cvc and postal.
Integrate the code into your test suite and run it. You should see Cypress filling out the credit details.
That’s it! You can now test your complete order process without any hacks.
Troubleshooting
If you’re running Cypress with Chrome you might have to disable web security by adding “chromeWebSecurity”: false
to the cypress.json file.
Open issues
We haven’t tested how this behaves with multiple iframes.
Top comments (1)
Is this still only supported for chromium based web browsers? I have tried with Firefox and doesn't work, wondering if anyone knows how to tackle this across multiple browsers.