“Cypress sucks! It does not support iFrame handling”

“Seriously?”

Hey hey.. Hold ON! Did you try asking “Aren’t there any workarounds?

When someone starts speaking about Cypress (aka Selenium Killer ;)), one of the major drawback that come to the speech is “iframe handling”. Yes of course Cypress is not supporting iframe handling for the moment. Anyway they are working on it.. Till then..

there are workarounds for the so called iframe handling..

If haven’t still figured out how to do it, this article will help you out. Easy peasy! Don’t worry! It’s not that hard to do the workaround..

You can do it in two ways. Choose what you like..

Workaround

First of all, Open cypress.json file and add the following to the file:

chromeWebSecurity: false

This option is true by default. If it’s true our workaround will not work. So now we are good to go!

Find the locator of the iframe (I prefer cssSelectors) and the locator of the element within the iframe. Replace the locators and try the following code:

cy.get("iframeLocator").then($element=> {
const $body = $element.contents().find('body')
let stripe = cy.wrap($body)
stripe.find("elementLocator").eq(0).click()
})

Cool right! NB: replace the action you want to performance according to your need. The example shows a click event.

or

Instead of typing all these lines on every point you come across performing an action on an element within an iframe, you can do it as follows and avoid the repetition of code lines.

Have look on your project folder structure. You will come across a folder named support (be default: cypress/support). There you can find a file as commands.js

Open it up! And add these lines to the file..

Cypress.Commands.add("getIframeElement", (iframeLocator, elementLocator) => { 
cy.get(iframeLocator).then($element=> {
const $body = $element.contents().find('body');
let stripe = cy.wrap($body)
stripe.find(elementLocator).eq(0)
});

Now you can just use the new cypress command you added as follows in your test scripts:

cy.getIframeElement("form.stripe iframe", `input[placeholder="Card number"]`)
.type("4242424242424242");

Was not that hard you thought right? Haha.. Try it out and let me know in the comments, if anything goes wrong..

Senior Quality Engineer @ Wiley

Senior Quality Engineer @ Wiley