How To Switch Between iFrames In Selenium Java [Tutorial]

How To Switch Between iFrames In Selenium Java [Tutorial]

Although automation testing has been around for several years, the tester faces multiple hurdles while performing Selenium automation testing. There are multiple cases that can’t be automated, and there are a few that are hard to implement and have to be handled efficiently. One such case is handling the web pages with iframes. giphy-7.gif

In online shopping or social networking platforms, you might have seen advertisements popping out. All these are handled in iframes on the webpage. While working with such applications, it becomes difficult to switch between iframes, as you cannot interact with frames in the same way you do with other elements.

In this Selenium Java tutorial, we will look into the concept of iframes and how to handle iframes in Selenium Java.

So, let’s get started!

What are iframes in Selenium Java?

An iframe is an inline frame. It is a division of the page that can be loaded separately from the rest of the page. This allows you to show different content in a particular region without needing to load the entire page.

For example, let’s say you have a shopping site that uses an iframe for displaying product information. You can load the product using an iframe and refresh it without loading the rest of the page, so your users don’t need to wait for all of the content to load, thus improving the overall experience. Here’s an example of an iframe present on the Selenium documentation:

unnamed-2021-12-15T211820.998.png

Iframes are majorly used to embed HTML/XML pages or any other hypertext content into a parent web page. This is achieved by defining the source of embedded content as the filename of a major file on another server. Then, the size, structure, and contents get reproduced and included in the parent document without opening new browser windows or tabs.

The iframe tag comes in two flavors: an inline frame and a nested frame.

Inline Frame

An inline frame is used to embed another HTML page into your current HTML page. It is simply inserted inside your document body, just like a normal

element would be but with one big difference: you must set its src attribute to the URL of the page you want to embed, which may reside on a different domain than your current page.

Nested Frame

This type of iframe tag can be placed anywhere within a web page. Still, it’s most commonly associated with HTML forms because it’s often used to submit information from form fields back to their original servers (like when entering your name and address on a website so they can mail you something). You can use iframe in Selenium Java for many purposes like:-

  • To access information that is not available on the current page.
  • To get information from more than one page of a website at once.
  • To open a new window without refreshing the current page so that you don’t lose the information present on the current page.

Switching iframes in Selenium Java

While automating a web page that contains multiple iframes, we have to switch to the particular iframe to interact with the web elements present in that iframe. In order to switch between the iframes in Selenium Java, we can use either of the three different methods mentioned below.

  1. By id or name
  2. By index (index starts from zero)
  3. By WebElement

Did you know? CSS Counters are the counter-increment and counter-reset properties are used to control the value of a counter () in generated content.

Handling elements within the iframe in Selenium Java

In this section of the Selenium Java tutorial on iframes in Selenium Java, we will see how to handle elements within the iframe using Selenium and Java.

Syntax to switch to iframe using id:

driver.switchTo().frame(“id of the element”);

Syntax to switch to iframe using name:

driver.switchTo().frame(“iframe1_name”)

Syntax to switch to iframe using index:

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

Syntax to switch to iframe using webElement:

driver.switchTo().frame(WebElement);

unnamed-2021-12-15T212640.306.png

Let us use rediff.com for our demo.

Test Scenario:

  1. Navigate to rediff.com.
  2. On the main page, get the value of NSE displayed and print it.

If you inspect the NSE web element on the web page, you could see the iframe tag.

unnamed-2021-12-15T212802.539.png

To get the value of NSE, we have to switch to the iframe and then get the value. In this example, let me show you different ways to switch to the iframe in Selenium Java.

Let us leverage the LambdaTest cloud Selenium Grid to run our tests. I have added the code for switching to iframe through id, name, index, and webElement.

LambdaTest is a cloud-based cross browser testing solution that helps software testers and Quality Assurance engineers to automate web application testing across 3000+ browsers, operating systems, and devices. The unique functionality of Selenium testing tools like LambdaTest makes it a central hub for all testers and developers who want to ensure the highest quality of their web applications.

Code Snippet:

package MyTests;

import org.openqa.Selenium.By;
import org.openqa.Selenium.WebElement;
import org.openqa.Selenium.remote.DesiredCapabilities;
import org.openqa.Selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;

public class Demo {

    String username = "user-name"; //Enter your username
    String accesskey = "access-key"; //Enter your accesskey

    static RemoteWebDriver driver;
    String gridURL = "@hub.lambdatest.com/wd/hub";
    String urlToTest = "https://www.rediff.com/";

    @BeforeTest
    @Parameters("browser")
    public void setup(String browser) {
        System.out.println("Setting up the drivers and browsers");

        DesiredCapabilities capabilities = new DesiredCapabilities();

        if(browser.equals("Chrome")) {
            capabilities.setCapability("platform", "Windows 10");// To specify the OS
            capabilities.setCapability("browserName", "Chrome"); //To specify the browser
            capabilities.setCapability("version","94.0");     //To specify the browser
            capabilities.setCapability("build", "ChromeTests");               //To identify the test
            capabilities.setCapability("name", "Handle_iframes");
        }

        else if (browser.equals("Firefox")){
            capabilities.setCapability("browserName", "Firefox");    //To specify the browser
            capabilities.setCapability("version", "93.0");        //To specify the browser version
            capabilities.setCapability("platform", "Windows 10");     // To specify the OS
            capabilities.setCapability("build", "FirefoxTests");               //To identify the test
            capabilities.setCapability("name", "Handle_iframes");
        }

        else if (browser.equals("Edge")){
            capabilities.setCapability("browserName", "MicrosoftEdge");
            capabilities.setCapability("platform", "Windows 10");
            capabilities.setCapability("version","94.0");     // To specify the OS
            capabilities.setCapability("build", "EdgeTests");               //To identify the test
            capabilities.setCapability("name", "Handle_iframes");
        }
        capabilities.setCapability("network", true);      // To enable network logs
        capabilities.setCapability("visual", true);          // To enable step by step screenshot
        capabilities.setCapability("video", true);       // To enable video recording
        capabilities.setCapability("console", true);         // To capture console logs
        try {
            driver = new RemoteWebDriver(new URL("https://" + username + ":" + accesskey + gridURL), capabilities);
        } catch (MalformedURLException e) {
            System.out.println("Invalid grid URL");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }


    @Test
    public void test1_switchUsingId(){
        System.out.println("Switching iFrame using id has started");

        driver.get(urlToTest);
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);

        driver.switchTo().frame("moneyiframe");   //moneyiframe is the id of the iframe
        WebElement option = driver.findElement(By.id("nseindex"));
        String nse_Value = option.getText();
        System.out.println("The NSE value is " +nse_Value);
        System.out.println("Switching iFrame using id has ended");

    }

    @Test
    public void test2_switchUsingName(){
        System.out.println("Switching iFrame using name has started");


        driver.get(urlToTest);
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);

        driver.switchTo().frame("moneyiframe"); //moneyiframe is the name of the iframe
        WebElement option = driver.findElement(By.id("nseindex"));
        String nse_Value = option.getText();
        System.out.println("The NSE value is " +nse_Value);
        System.out.println("Switching iFrame using name has ended");

    }

    @Test
    public void test3_switchUsingIndex(){
        System.out.println("Switching iFrame using index has started");

        driver.get(urlToTest);
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);

        driver.switchTo().frame(0); //switching to 1st frame
        WebElement option = driver.findElement(By.id("nseindex"));
        String nse_Value = option.getText();
        System.out.println("The NSE value is " +nse_Value);
        System.out.println("Switching iFrame using index has ended");

    }
    @Test
    public void test1_switchUsingWebElement(){
        System.out.println("Switching iFrame using a webElement has started");

        driver.get(urlToTest);
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);

        WebElement iframe_element = driver.findElement(By.xpath("//iframe[@class='moneyiframe']"));
        driver.switchTo().frame(iframe_element);
        WebElement option = driver.findElement(By.id("nseindex"));
        String nse_Value = option.getText();
        System.out.println("The NSE value is " +nse_Value);
        System.out.println("Switching iFrame using a webElement has ended");

    }
    @AfterTest
    public void tearDown(){
        driver.close();
        System.out.println("Tests ended successfully");
    }
}

TestNG.xml :-

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="TestSuite" parallel="tests" thread-count="4">
    <test name="ChromeBrowserTest">
        <parameter name="browser" value="Chrome"/>
        <classes>
            <class name="MyTests.Demo">
            </class>
        </classes>
    </test>
</suite>

Console Output:

unnamed-2021-12-15T213326.604.png

Did you know? CSS Cross-Fade Function is used to create a "crossfade" between images. The images are faded based on a percentage value.

Handling elements outside the iframe in Selenium Java

In this Selenium Java tutorial on iframes in Selenium Java, we have understood how to handle the elements within an iframe. Now, how to access elements outside the iframe again?

So, in that case, we have to switch back to the main content and then start accessing the web elements in the main frame.

Syntax to switch to main page using defaultContent:

driver.switchTo().defaultContent();

In addition to this, there is also another method to switch between the frames.

Syntax to switch to main page using parentFrame:

driver.switchTo().parentFrame();

The difference between the two methods is that, driver.switchTo().defaultContent() method switches to the main page irrespective of the number of frames present in the webpage, whereas driver.switchTo().parentFrame() switches to the parent frame of the current frame.

Test Scenario:

  1. Navigate to rediff.com.
  2. Fetch the value of NSE on the webpage.
  3. Click the sign-in option on the main page.
  4. Enter the valid username and password to log in.

Code snippet:

package MyTests;

import org.openqa.Selenium.By;
import org.openqa.Selenium.WebElement;
import org.openqa.Selenium.remote.DesiredCapabilities;
import org.openqa.Selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;

public class Demo {

    String username = "user-name"; //Enter your username
    String accesskey = "access-key"; //Enter your accesskey

    static RemoteWebDriver driver;
    String gridURL = "@hub.lambdatest.com/wd/hub";
    String urlToTest = "https://www.rediff.com/";

    @BeforeTest
    @Parameters("browser")
    public void setup(String browser) {
        System.out.println("Setting up the drivers and browsers");

        DesiredCapabilities capabilities = new DesiredCapabilities();

        if(browser.equals("Chrome")) {
            capabilities.setCapability("platform", "Windows 10");// To specify the OS
            capabilities.setCapability("browserName", "Chrome"); //To specify the browser
            capabilities.setCapability("version","94.0");     //To specify the browser
            capabilities.setCapability("build", "ChromeTests");               //To identify the test
            capabilities.setCapability("name", "Handle_iframes");
        }

        else if (browser.equals("Firefox")){
            capabilities.setCapability("browserName", "Firefox");    //To specify the browser
            capabilities.setCapability("version", "93.0");        //To specify the browser version
            capabilities.setCapability("platform", "Windows 10");     // To specify the OS
            capabilities.setCapability("build", "FirefoxTests");               //To identify the test
            capabilities.setCapability("name", "Handle_iframes");
        }

        else if (browser.equals("Edge")){
            capabilities.setCapability("browserName", "MicrosoftEdge");
            capabilities.setCapability("platform", "Windows 10");
            capabilities.setCapability("version","94.0");     // To specify the OS
            capabilities.setCapability("build", "EdgeTests");               //To identify the test
            capabilities.setCapability("name", "Handle_iframes");
        }
        capabilities.setCapability("network", true);      // To enable network logs
        capabilities.setCapability("visual", true);          // To enable step by step screenshot
        capabilities.setCapability("video", true);       // To enable video recording
        capabilities.setCapability("console", true);         // To capture console logs
        try {
            driver = new RemoteWebDriver(new URL("https://" + username + ":" + accesskey + gridURL), capabilities);
        } catch (MalformedURLException e) {
            System.out.println("Invalid grid URL");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }


    @Test
    public void test1_switchUsingId(){
        System.out.println("Switching iFrame using id has started");

        driver.get(urlToTest);
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);

        driver.switchTo().frame("moneyiframe");   //moneyiframe is the id of the iframe
        WebElement option = driver.findElement(By.id("nseindex"));
        String nse_Value = option.getText();
        System.out.println("The NSE value is " +nse_Value);
        System.out.println("Switching iFrame using id has ended");

        driver.switchTo().defaultContent();
        WebElement signIn_element = driver.findElement(By.className("signin"));
        signIn_element.click();

        WebElement username = driver.findElement(By.id("login1"));
        WebElement password = driver.findElement(By.id("password"));

        username.sendKeys("test12345");
        password.sendKeys("abcd@12344");
    }


    @AfterTest
    public void tearDown(){
        driver.close();
        System.out.println("Tests ended successfully");
    }
}

Code Walkthrough:

As per our use case, we have to first navigate to the website and then get the value of NSE displayed on the web page.

As the web element is present inside the iframe, we have to first switch to the iframe and then access the web element inside it.

driver.switchTo().frame("moneyiframe");   //moneyiframe is the id of the iframe
WebElement option = driver.findElement(By.id("nseindex"));
String nse_Value = option.getText();
System.out.println("The NSE value is " +nse_Value);

To click the Sign In option on the web page, we have to switch back to the main frame.

driver.switchTo().defaultContent();

The above line will help us switch back to the main frame and access the other web elements on the page. If this is not handled in our code, an exception will be thrown as the control is still in the iframe.

unnamed-2021-12-15T213845.376.png

If you’re a developer who’s looking to take your Java development and test engineering skills to the next level, this Selenium Java 101 certification from LambdaTest can help you reach that goal. Here’s a short glimpse of the Selenium Java 101 certification from LambdaTest:

Did you know? Explicit descendant combinator >> descendant combinator is a form of CSS selector. It allows you to target an element that is the child of another element or elements.

Handling nested iframes on the web page

In the earlier section of this Selenium Java tutorial on iframes in Selenium Java, we read about the nested iframe, an element of HTML that contains another HTML document. This lets you create pages that, for example, can be accessed from several different locations or display content from various sources. The nested iframe element is generally used in conjunction with the src attribute to specify the URL of the page to be displayed.

The above video from the Selenium JUnit tutorial will help you learn how to perform geolocation testing of your website or web app and run automated tests from various locations.

However, you can go through the LambdaTest YouTube Channel and stay updated with more such videos on Selenium Testing, Cypress Testing, and more.

In this section of iframes in Selenium Java, we will see how we can handle nested iframes on the web page.

Let us try to automate the login functionality in w3schools.com/tags/tryit.asp?filename=tryht..

unnamed-2021-12-15T214250.009.png

To implement this use case, we might have coded like the below code snippet.

@Test
public void test1_handlingNestediframes(){

    driver.get(urlToTest);
    driver.manage().window().maximize();
    driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
    WebElement login = driver.findElement(By.xpath("//a[@id='w3loginbtn']"));
    login.click();

}

But this never works. It would throw NoSuchElementException.

unnamed-2021-12-15T214344.735.png

If you inspect this element, you might see its presence in an iframe. So, we have to switch to the iframe before clicking the login button. But there comes the complexity. The login webElement is present inside the nested iframe.

unnamed-2021-12-15T214432.512.png

We have to switch to the outer iframe and then the inner iframe and click the Login element.

package MyTests;
import org.openqa.Selenium.By;
import org.openqa.Selenium.WebElement;
import org.openqa.Selenium.remote.DesiredCapabilities;
import org.openqa.Selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;

public class Demo {

    String username = "user-name"; //Enter your username
    String accesskey = "access-key"; //Enter your accesskey

    static RemoteWebDriver driver;
    String gridURL = "@hub.lambdatest.com/wd/hub";
    String urlToTest = "https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_iframe";

    @BeforeTest
    @Parameters("browser")
    public void setup(String browser) {
        System.out.println("Setting up the drivers and browsers");

        DesiredCapabilities capabilities = new DesiredCapabilities();

        if(browser.equals("Chrome")) {
            capabilities.setCapability("platform", "Windows 10");// To specify the OS
            capabilities.setCapability("browserName", "Chrome"); //To specify the browser
            capabilities.setCapability("version","94.0");     //To specify the browser
            capabilities.setCapability("build", "ChromeTests");               //To identify the test
            capabilities.setCapability("name", "Handle_iframes");
        }

        else if (browser.equals("Firefox")){
            capabilities.setCapability("browserName", "Firefox");    //To specify the browser
            capabilities.setCapability("version", "93.0");        //To specify the browser version
            capabilities.setCapability("platform", "Windows 10");     // To specify the OS
            capabilities.setCapability("build", "FirefoxTests");               //To identify the test
            capabilities.setCapability("name", "Handle_iframes");
        }

        else if (browser.equals("Edge")){
            capabilities.setCapability("browserName", "MicrosoftEdge");
            capabilities.setCapability("platform", "Windows 10");
            capabilities.setCapability("version","94.0");     // To specify the OS
            capabilities.setCapability("build", "EdgeTests");               //To identify the test
            capabilities.setCapability("name", "Handle_iframes");
        }
        capabilities.setCapability("network", true);      // To enable network logs
        capabilities.setCapability("visual", true);          // To enable step by step screenshot
        capabilities.setCapability("video", true);       // To enable video recording
        capabilities.setCapability("console", true);         // To capture console logs
        try {
            driver = new RemoteWebDriver(new URL("https://" + username + ":" + accesskey + gridURL), capabilities);
        } catch (MalformedURLException e) {
            System.out.println("Invalid grid URL");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }


    @Test
    public void test1_handlingNestediframes(){

        driver.get(urlToTest);
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);

        System.out.println("Switching to first iFrame has started");
        driver.switchTo().frame("iframeResult");
        System.out.println("Switching to first iFrame has ended");

        System.out.println("Switching to second iFrame has started");
        driver.switchTo().frame(driver.findElement(By.xpath("//*[@title='W3Schools Free Online Web Tutorials']")));
        System.out.println("Switching to second iFrame has ended");


        WebElement login = driver.findElement(By.id("w3loginbtn"));
        System.out.println("Clicking login button has started");
        login.click();
        System.out.println("Clicking login button has ended");

    }

    @AfterTest
    public void tearDown(){
        driver.close();
        System.out.println("Tests ended successfully");
    }
}

Conclusion

Modern web pages are so dynamic and complex in design that they pose a challenge to be handled in automation. Therefore, handling the web elements, especially inside frames and iframes, is very important for a smooth running automation suite.

To sum this Selenium Java tutorial on iframes in Selenium Java, we have looked quickly at iframes and the different ways to handle them in the Selenium framework. In addition, we have also seen how to handle the nested iframes on the webpage. I hope it was really informative and would help you handle the iframes in your test automation script. I would also love to hear your comments on this article.

Happy Testing…!