Iframes in Cypress: Tutorial

Understand what a frame and iframe are in Cypress and learn how to handle them. Run iFrames tests in Cypress using BrowserStack’s Real Device Cloud to test under real user conditions.

Get Started free
Iframes in Cypress Tutorial
Home Guide Iframes in Cypress: Tutorial

Iframes in Cypress: Tutorial

Testing iframes in Cypress requires a different approach because Cypress cannot directly access the contents of an iframe due to browser security restrictions. To interact with elements inside an iframe, you must first get the iframe’s document and body, then wrap the contents using Cypress commands.

This article explains everything related to iframes in Cypress, including how to automate it.

What is an iFrame in Web Development

An iframe is an HTML element used to embed another HTML page within the current document. It works like a window inside a page that displays external content such as videos, forms, or entire websites without redirecting the user. An iframe has its own DOM and JavaScript context, separate from the parent page.

When to use an iframe in Cypress?

Cypress does not natively support iframe traversal like it does with standard DOM elements. However, you may need to interact with iframe content in scenarios such as:

  • Testing third-party content embedded via iframes (like payment gateways or external forms)
  • Verifying dynamic or modular content loaded inside iframes
  • Simulating user interactions within iframe-hosted components
  • Checking layout, data, or behavior inside embedded applications

Why are iframes in Cypress Challenging?

Cypress runs within a single browser context and tightly controls the DOM to ensure stable and predictable tests. However, iframes create a separate browsing context, which makes automation difficult.

Key challenges include:

  • Separate DOM Context: Since iframes maintain their own DOM, Cypress cannot directly access or interact with elements inside an iframe without special handling.
  • Cross-Origin Restrictions: If the iframe loads content from a different origin, browser security policies prevent Cypress from accessing it.
  • Asynchronous Loading Issues: If iframes are not appropriately handled, Cypress may try to interact with the iframe before fully loading, leading to errors or flaky tests.
  • No Native Support in Core Cypress Commands: Cypress does not provide built-in commands for iframes, so you must rely on custom solutions or third-party plugins.

How to Automate iFrames in Cypress?

You can automate iframe elements using plugins like cypress-iframe or by writing custom commands. However, you can only interact with iframe content on the same origin (domain, port, and protocol) as your main application. Cypress cannot access cross-origin iframes due to browser security restrictions.

What you can do with same-origin iframes:

  • Access and interact with elements inside the iframe.
  • Wait for the iframe to load before performing actions.
  • Use Cypress assertions to validate content within the iframe.

How to Perform iFrames Testing with Cypress?

To test iframe content in Cypress, you can either use the cypress-iframe plugin or define a custom command tailored to your project.

Approach 1: Using the Cypress-iframe Plugin

This plugin simplifies iframe interactions using frameLoaded() and iframe() helpers. It works well for teams looking for a plug-and-play solution.

npm install -D cypress-iframe



import 'cypress-iframe';



cy.frameLoaded('#my-iframe');

cy.iframe('#my-iframe').find('button.submit').click();

Approach 2: Using a Custom Command

This method manually accesses the iframe’s contentDocument.body, waits for it to load, and wraps it so that Cypress can interact with its elements. It’s useful when you need more control or plugins don’t work for your specific iframe structure.

Cypress.Commands.add('getIframeBody', (selector) => {

  return cy.get(selector)

        .its('0.contentDocument.body')

        .should('not.be.empty')

        .then(cy.wrap);

});



cy.getIframeBody('#my-iframe').within(() => {

  cy.get('input#name').type('Ayush');

  cy.get('button#submit').click();

});

How to Test iFrame in Cypress Using Native Commands?

You can test iframe content in Cypress using only native commands if the iframe is on the same origin as your test suite. Cross-origin iframes are blocked due to browser security policies.

Here are the two methods to be used for interacting with iFrames in Cypress:

1. Using .get(0)

This fetches the iframe’s raw DOM node and accesses its contentDocument.body to interact with the content.

cy.get('iframe#my-frame')
  .get(0)

  .then((iframe) => {

const body = iframe.contentDocument.body;

cy.wrap(body)

   .find('h1')

   .should('contain.text', 'Welcome');

  });

2. Using .find(‘body’)

This method uses .its() to access the iframe’s content document and body, then wraps it for further interaction. It supports proper command chaining.

cy.get('iframe#my-frame')

  .its('0.contentDocument')

  .should('exist')

  .its('body')

  .should('not.be.empty')

  .then(cy.wrap)

  .find('input[name="email"]')

  .type('thakurayushsingh82@gmail.com');

How to Handle iframe in Cypress Using a Plugin?

To handle iframes in Cypress, firstly install the plugin cypress-iframe

Execute the below command from the root of your project where the package.json file exist

npm install -D cypress-iframe

This will install the cypress-iframe plugin as dev dependency.

After the installation, open the cypress/support/commands.ts file and add the below line to import the plugin globally

import 'cypress-iframe';
// or
require('cypress-iframe');

Cypress-iframe plugin provides three commands to interact with iframes.

  • frameLoaded
  • iframe
  • enter

cy.frameLoaded(<selector>) will ensure that the frame is loaded within the webpage

Example

cy.frameLoaded("#myframeID")

cy.iframe(<selector>) will get the reference for the iframe based on the iframe selector provided. You can then chain the command to perform further actions on the iframe

Example

cy.iframe("#iframeID").contains("button", "Click Here").click()

cy.enter(<selector>) will allow to perform multiple actions within the iframe.

Example

cy.enter("#myiframeID").then(iframeBody => {
iframeBody().find(".button").click()
iframeBody().contains("p", "someText").should("be.visible")
)

BrowserStack Automate Banner

How to Handle Slow-Loading, Empty, and Nested iframes in Cypress?

iFrame testing becomes more complex when dealing with slow-loading content, dynamic rendering, or nested iframe structures. Below are key strategies to handle these cases effectively.

1. Slow Loading and Empty iFrames Validation

Cypress will fail if the iframe’s body is still empty. To prevent such issues, validate that the iframe has loaded before interacting. Here’s how.

cy.get('iframe#my-frame')

  .its('0.contentDocument.body')

  .should('not.be.empty')

  .then(cy.wrap)

  .find('h1')

  .should('contain.text', 'Welcome');

To improve readability, implement this logic into a custom command:

Cypress.Commands.add('getIframeBody', (selector) => {

  return cy.get(selector)

.its('0.contentDocument.body')

.should('not.be.empty')

.then(cy.wrap);

});

2. Reusing Code for Multiple Tests

Instead of repeating iframe access logic in every test, split it into utility functions or custom commands. This improves test maintainability and makes it easy to update handling in one place if the DOM changes.

Cypress.Commands.add('iframeFind', (iframeSelector, innerSelector) => {

  return cy.get(iframeSelector)

.its('0.contentDocument.body')

.should('not.be.empty')

.then(cy.wrap)

.find(innerSelector);

});

3. Navigating Inside the iframe

Once the iframe’s body is wrapped using cy.wrap(), continue using Cypress commands as usual like .click(), .type(), .select(), and assertions.

cy.getIframeBody('#login-frame').within(() => {

  cy.get('input#username').type('admin');

  cy.get('input#password').type('123456');

  cy.get('button[type="submit"]').click();

});

4. Handling Nested iFrames

Nested iframes are more complex due to the traversal across multiple document layers. To handle this, you’ll need to access the inner iframe through the outer one’s document.

cy.get('iframe#outer-frame')

  .its('0.contentDocument.body')

  .should('not.be.empty')

  .then(cy.wrap)

  .within(() => {

cy.get('iframe#inner-frame')

   .its('0.contentDocument.body')

   .should('not.be.empty')

   .then(cy.wrap)

   .find('p')

   .should('contain.text', 'Nested Content');

  });

5. Cross-Origin Testing with cy.origin()

If the iframe loads content from a different domain, Cypress focuses on browser security and won’t allow direct DOM access. However, starting with Cypress v10+, cy.origin() command can interact with cross-origin content by defining logic inside a special context.

cy.origin('https://external-domain.com', () => {

  cy.visit('/iframe-content');

  cy.get('h2').should('contain.text', 'External Frame');

});

Why Use BrowserStack Automate to Run Cypress Tests?

Here’s why you should run your Cypress tests on Real Devices & Browsers using BrowserStack Automate:

  • Diverse Environment Testing: It enables the execution of Cypress tests across a broad selection of browsers and operating systems, eliminating the necessity for maintaining local testing infrastructure. This ensures consistent application performance across various platforms.
  • Parallel Testing: BrowserStack Automate significantly reduces total testing time by allowing simultaneous execution of multiple Cypress test suites, facilitating quicker iterative feedback and accelerated deployment cycles.
  • CI/CD Integration: The platform seamlessly integrates with major CI/CD systems, including Jenkins, Travis CI, CircleCI, and GitHub Actions, automating the testing process within the development pipeline.
  • Diagnostic Tools for Better Debugging: BrowserStack provides comprehensive diagnostic capabilities, including detailed logs, screenshots, and video recordings of test sessions, aiding in the swift identification and resolution of issues.
  • Testing on Real Devices: Beyond simulated environments, BrowserStack also supports testing on real devices and browsers on the cloud, offering more precise and real-world test outcomes.
  • Customizable Test Execution: Users can tailor test executions to meet specific needs through BrowserStack’s user interface or APIs, enabling adaptable and controlled test runs.

BrowserStack Automate is an excellent choice for running Cypress tests because it offers a scalable, cloud-based infrastructure that eliminates the need for complex local setups.

With support for real-time cross-browser testing, parallel execution, and integrations with CI/CD pipelines, BrowserStack ensures faster test runs and streamlined workflows.

Choose BrowserStack Automate to enhance the reliability and performance of your Cypress test suite with ease.

Talk to an Expert

Best Practices for Testing iframe in Cypress Using Native Methods

Here are some of the best practices for testing iframe in Cypress using native methods:

  • Use Custom Commands: Accessing iframe content with native Cypress methods involves multiple chained steps. Creating custom commands improves readability and reduces duplication. This also centralizes iframe logic, so you can update it in one place when needed.
  • Avoid Cross-Origin iFrames: Cypress cannot access iframe content from a different domain using native methods due to browser security restrictions. Always test iframe content hosted on the same origin as your application.
  • Wait for the iframe to Load Fully: iFrames often load asynchronously. Always verify the iframe’s content has loaded by checking that the body is not empty before interacting with its elements to avoid test failures.
  • Modularize Tests: Instead of embedding iframe logic into every test case, separate it into reusable components or helper functions. This reduces duplication, making tests easier to understand and maintain.
  • Validate the Visibility and State of iFrames: Before interacting with iframe content, ensure that the iframe is visible and interactive. Depending on user behavior or the page’s state, iFrames can be hidden, collapsed, or conditionally rendered.

Conclusion

Testing iframes in Cypress can be challenging due to the complexities of handling slow-loading, nested, and cross-origin frames. However, by leveraging native commands and plugins, you can overcome these challenges and ensure your tests are efficient and reliable.

BrowserStack Automate provides an added advantage by offering real device cloud testing, cross-browser compatibility, and a scalable infrastructure for running Cypress tests. This allows you to ensure that your iframe interactions work seamlessly across different environments.

Try BrowserStack for Free

Useful Resources for Cypress

Understanding Cypress

Use Cases

Tool Comparisons

Tags
Cypress

Get answers on our Discord Community

Join our Discord community to connect with others! Get your questions answered and stay informed.

Join Discord Community
Discord