How to handle iframes using Selenium WebDriver

The Blog To Learn Selenium and Test Automation

How to handle iframes using Selenium WebDriver

In this tutorial we will learn how to handle iframes using Java and Python Selenium WebDriver.

What is iFrame?

An iframe is used to embed HTML documents in other HTML documents. And iframe content can be changed without requiring the user to reload the surrounding page. The iframe HTML element is often used to insert content from same/another source, such as an advertisement, into a Web page. This functionality is now largely replaced by AJAX and becoming less common. The <iframe> tag specifies an inline frame.

How to handle iframes in Selenium?

We cannot click on elements present in iframe directly. To click on an element inside an iframe using XPath or any other locator, we need to switch to the frame first and then click. All other operations like getText(), isEnabled() etc… follows the same procedure.

Step 1: Invoke browser and load web page
Step 2: Identify iframe using any locators
Step 3: Switch to iframe using switchTo method
Step 4: Act on elements inside iframe
Step 5: switch back to default content

Operations like locating element, click(), isEnabled() etc… inside of an iframes is similar to actions in main page. Once the frame is selected or navigated, all subsequent calls on the WebDriver interface are made to that frame. i.e the driver focus will be now on the frame. What ever operations we try to perform on pages will not work and throws element not found as we navigated / switched to Frame.

Total iframes Count

We can get total number of iframes inside a page by using below code snippet.

Java Example

int size = driver.findElements(By.tagName("iframe")).size();

Python example

iframe_list = driver.find_elements_by_tag_name(“iframe”)
print len(iframe_list)

Switch to iframe

Basically, we can switch to frames using 3 ways.

  • By using index of the frame
  • By using Name or Id of the frame
  • By using frame Web Element

Switch to iframe by index

Index is the position at which an iframe occurs in the HTML page. Using this index we can switch to it. Index of the iframe starts with ‘0’. Suppose if there are 100 frames in page, we can switch to the iframe by using index like below.

driver.switchTo().frame(0);
driver.switchTo().frame(1);

Switch to iframe by Name or ID

Name and ID are attributes of iframe through which we can switch to it.

#'dynamic-table' is ID of iframe element
driver.switchTo().frame("dynamic-table");
#'book-table' is 'name' of iframe element
driver.switchTo().frame("book-table");

Switch to iframe by WebElement

Now we can switch to an iFrame by simply passing the iFrame WebElement to the driver.switchTo().frame() command. First find the iFrame element using any of the locator strategies and then pass it to switchTo.frame() command.

element = driver.findElement("//iframe[@id='dynamic-table']")
driver.switchTo().frame(element)

Switch back to Main Frame/Page

Once completed all actions inside iframe, you need to switch back to original page/main page using the switchTo().defaultContent(). Main page is the page in which iframes are embedded.

To move back to the parent frame in case of nested iframe i.e. iframes inside iframe, you can either use switchTo().parentFrame() or if you want to get back to the main page, you can use switchTo().defaultContent();

Nested iframes

There are some scenarios where you can find an iframe inside another iframe, outer frame and an inner frame. In the case of this nested frames scenario, we must switch to the outer frame by either Index or ID of the iframe. Once we switch to the outer iframe, we can find iframes inside of it and again switch to it by any of the known methods. While exiting out of the inner frame, we can either use driver.switchTo.defaultContent() to switch back to main page or driver.switchTo.parentFrame() to switch back to outer frame.

NoSuchFrameException

NoSuchFrameException will be thrown if the iframe mentioned by name or id or web element is not found.

Example Page Source

<html>
<head>
<title> iframe Test </title>
</head>
<body>
<div>
<h3>iframe content are inserted dynamically</h3>
<iframe src="iframe-table.html" name='book-table' id='dynamic-table' width="80%" height="75%" scrolling="yes">
<html>
<body>
<table border="1" >
<tbody>
<tr>
<th>BookName</th>
<th>Published Year</th>
</tr>
<tr>
<td>Python Programming</td>
<td>2015</td>
<td><button id="buy-python-programming" onclick="alert('Buying python programming book');">Buy</button></td>
</tr>
<tr>
<td>Java Programming</td>
<td>2010</td>
<td><button id="buy-java-programming" onclick="alert('Buying Java programming book');">Buy</button></td>
</tr>
</tbody>
</table>
</body>
</html>
</iframe>
</div>
</body>
</html>

Java Code Example

Save the above example html code in a file named index.html or name of your choice. Below is the sample code to click on ‘Buy’ button of ‘Java Programming’ row.

public void testBrowserInvoke() {
  System.setProperty("webdriver.chrome.driver", "/Path/to/chromedriver");
  WebDriver driver = new ChromeDriver();
  driver.get("http://www.example.com/iframe.html");
/* Use any one of the strategies */
/* By index of the iframe */
  driver.switchTo().frame(0);
/* By ID of the iframe */
driver.switchTo().frame("dynamic-table");
/* By Name of the iframe */
driver.switchTo().frame("book-table");
/* By finding iframe as web element */
  WebElement frame = driver.findElement(By.id("dynamic-table"));
  driver.switchTo().frame(frame);

  driver.findElement(By.id("buy-java-programming")).click();
  Thread.sleep(10000);
driver.switchTo().defaultContent();
#Do some other operations on main page
  driver.quit();
}

Python Example

from selenium import webdriver
import time

driver = webdriver.Firefox(executable_path="/path/to/geckodriver")
driver.get("http://www.example.com/iframe.html")
# Use any one of the strategies
# By index of the iframe
driver.switch_to_frame(0)
# By ID of the iframe
driver.switch_to_frame("dynamic-table")
# By Name of the iframe
driver.switch_to_frame("book-table")
# By finding iframe as web element
frame_element = driver.find_element_by_id("dynamic-table")
driver.switch_to_frame(frame_element)

driver.find_element_by_id("buy-java-programming").click()
time.sleep(10)
driver.switch_to_default_content()
driver.quit()

You can alternatively use driver.switch_to.frame() as well as driver.switch_to.default_content().

Happy reading. Please let us know your thoughts in comments.

Leave a Reply

Your email address will not be published. Required fields are marked *