Handling Frames and iFrames in Cypress
By Gaveen Nayanajith, Community Contributor - October 3, 2022
In today’s world, users have become closely associated to the web. People rely on the internet to get almost anything and everything that they want. Modern web technology has evolved to a more sophisticated manner of convenience regarding access and functionality. In order to facilitate easier access and smoother functional experience for the people. Under these web technologies, Frames and iFrames have been used to give the maximum and optimized functionality with a minimum loading time and easy access as well.
What is a Frame in Web Development
Frame is a web technology which we are using to divide a single HTML document into a few different sections, which can load a separate HTML document. So by using the frames, you can divide and conquer the loading time issue. A set of frames inside an HTML document is known as a “frameset.” Hence from HTML5 onwards <frame> tag was deprecated, and the <frameset> tag, along with rows and cols attributes with which we can define how the set frames are dividing the page, is introduced instead.
What is an iFrame in Web Development
iFrame is a frame which is used in inline style. Hence it got the name Inline Frame (iFrame). iFrame does not belong to <frame> / <frameset> types instead, it can be used in anywhere of the document.<iframe> defines a portion of the document to be used as a separate piece of another document with scrollbars and everything. Basically, iFrame can render another HTML document inside an HTML document within any rectangular portion of the document. iFrames use the “src” attribute to define the path to the HTML document it is rendering.
Difference between Frames and iFrames
Usually, both frames and iframes are used to render multiple HTML documents inside the scope of a single HTML document. So by using the frame layouts, you can give the user the chance to load multiple web pages/ HTML documents at the cost of loading a single HTML page.
Usually, frames are used as placeholders for the information that is being used for the website, and iframes are used for web elements with more volatile and dynamic behavior. With iframes, a designer can only refresh the said iframe without having to require a whole page refresh. So with this advantage with iframes, we can do better optimization for the moving parts of a website while not having to worry about decreased functional capabilities.
With the frames, the users are able to resize them with whatever their measurements or viewing discretion would be. But with iframes, it resizes based on the information or the content that you are feeding to it. So with iframes, the designer does not have to worry about repositioning and spacing.
So with these points, you can decide whether to use a frame/frameset or an inline frame for a given website layout.
How to handle iframes and frames in Cypress
Cypress is an end-to-end testing tool that uses the Document Object Model (DOM) along with Javascript to facilitate the all-in-one testing environment. But with Cypress, one cannot directly test the elements inside a frame or an iframe because it has some issues in finding them, as they act as separate documents relevant to the initial HTML document. Due to this, Cypress stops the operation when it meets an iframe or a frame as the flow is interrupted by finding a document it can’t access within the code.
However, to overcome this, there is an efficient workaround. First, one has to capture the iframe that one wants to use. You can do this by either using CSS/jquery selectors or by using xPaths. After that, you can access the content of the body element by using “.its(‘0.contentDocument.body’)” function.
This query returns the body/document the iframe is holding, so you next have to use that returned body and wrap it inside the “cy” selector. With that, the current document the “cy” variable referring to is changed to whatever the thing that body of the iframe holds so you can easily address the elements we want from inside the iframe itself.
Demo on how to handle iframes and frames in Cypress
For this demo, let us use w3school iframe example live demo.
Code Snippet for the iframeTest.Cy.js:
/// <reference types="cypress" /> describe('The iframe test', () => { beforeEach(() => { cy.visit('https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_iframe') }) // //Scenario 01 // it('The iFrame h1 should not be visible', () => { // cy.xpath('//h1[text()="The iframe element"]').should('not.be.visible'); // //Cypress will not find this as it is inside an iframe. // }) // //Scenario 02 // it('The iFrame h1 should be visible', () => { // cy.xpath('//iframe[@id="iframeResult"]').its('0.contentDocument.body').then(cy.wrap).xpath('//h1[text()="The iframe element"]').should('be.visible'); // /*In here we are accessing the document body through jQuey and wrapping the result of that (the body of iframe itself) // inside the 'cy' element so that we can access it through that. */ // }) })
Here Scenario 1 depicts the error that occurs because the test cannot find the element inside the iframe. While Scenario 2 depicts how the element is found when the iframe is accessed before searching the element. (You can uncomment each code block for each scenario separately and get the idea of how the Cypress is behaving in these situations separately)
Here is a simple guide to running your Cypress tests:
- Clone this Repo
- Run these commands inside the project folder (You can use either the IDE-provided console or the command prompt)
- “npm install cypress”
- “npx run cypress”
- After opening the Cypress console, you can run the test with it. You can remove comments from either scenario while the other is still commented on and experience the differences in those two scenarios.
The above-mentioned steps and example depict how Cypress behaves when you try to access the iframe element without accessing the iframe and the correct method to access the iframe and its element to assert testing criteria. The same criteria can be used to handle frames as well.
Note: The full code for the Demo Project is in Cypress iFrame Handling in Github.
With the use of iframes as well as frames, web technologies have evolved into more versatile and interesting technology, which has inspired many people in the world to connect and interact with the global village concept. Nowadays, one can safely assume that these frames and iframes technology can and will expand further inside the web world.
This article helps you handle frames and iframes in Cypress. It is essential to test your websites and apps that contain frames and iframes on real devices and browsers to ensure compatibility and reliability.