Handling iFrames in Cypress

Short and mostly unnecessary intro

It’s hard to stop thinking about them. Every day, every hour, every minute. They’re the integral part of your wonderful QA life and, sooner or later, we’re all bound to face them. They are — *drum roll* — iFrames.

Bad jokes aside, according to the short definition, iFrames can be described as following:

An iFrame is an inline frame used inside a webpage to load another HTML document inside it. This HTML document may also contain JavaScript and/or CSS which is loaded at the time when iframe tag is parsed by the user’s browser.”

I won’t go into many details about what iFrames are and why it might be a bit complicated to test them, I’ll let you try it for yourself (unless you’re here because you’ve already felt the anxiety).

Cypress can’t handle it

Okay, so there’s a Selenium way of testing iFrames (yes, we all know it) and it’s not really that hard or complicated. But, what’s going on with Cypress and iFrames?

There are three things I’ve heard from people using Cypress to handle them:

  1. Cypress cannot do it (so they say)
  2. You need a plugin just for that (no one likes too many useless plugins :( )
  3. It’s doable, but it’s complicated and a lot of code (and QA time is very valuable)

Let’s go point by point:

  1. Not true
  2. Not true
  3. Absolutely not true

Cypress CAN do it, you don’t need any kind of plugin for that, just good ol’ Cypress, it can be done in just 2 (or 3) lines of code.

Why not to do it at all

Before I explain how to do it, I need to emphasize that iFrames are third-party content and, generally speaking, shouldn’t be tested at all. Yeah, I’ve said it. Now just STOP.

Why?

Well, the main reason is that iFrames are basically someone else’s app. Therefore, if the iFrames fails on the third-party app side, it means that your code might be working correctly, but the iFrames code itself has critical bugs.

The conclusion is pretty obvious: your tests are failing your build process and deployment because someone else’s app is not working properly and your tests are not aware of that (or could be if you ask them nicely).
So, what you just did is that you tested someone else’s app for them (for free!) and they returned that favor by failing your release. Not very nice of them.

But if you really want to do it…

If this didn’t stop you from doing it and your boss is yelling at your silly ideological reasons for leaving his/her app less than 100% automated, here’s the short way of doing it in pure Cypress:

As simple as that. If you want to do multiple commands on the same iframe element, just add further cy.wrap() lines in the same block of code.

Let’s see what I did here:

I got the whole iframe element (get ‘iframe’ part), then I got its “contentDocument” property, which is explained quite well over here (really don’t want to get into that in this article):

https://stackoverflow.com/questions/6581803/contentdocument-for-an-iframe.

So, through its content document property you can access the iframe and its content as a regular document. Once we’re in there, we’re going for its body (the final command in the first line). Whatever element we want to access in it, it has to be located in its body, just like with the regular HTML DOM in tests.

After getting the whole body content, we’re using Cypress’ then command to store the yield of the body in a variable. From there on, we’re wrapping this yield (Cypress rules) and using regular Cypress commands to access elements as if they’re regular HTML DOM elements.

Try it out for yourself and see what happens.

Note that this is just a basic example of how to do it. You can add various exception handlers and logs which would help you through the build process in case iFrames start acting up (see “why not to do it” part above again).

You can also try Googling “Cypress iframe” or something similar and you’ll probably find more in-depth articles dealing with the iframe testing process. Or you can just settle for using the Cypress iFrames plugin (https://www.npmjs.com/package/cypress-iframe) if you’re lazy (there, I’ve said that as well).

Conclusion

Not really much to conclude — Cypress can do it, you don’t need plugins and it’s short, sweet n’ easy. That’s all I can say. The best way is to see and try for yourself.

Still, don’t do it at all unless it’s absolutely necessary.

Making devs sad since 2016.