DEV Community

Cover image for Selenium C# Tutorial: Handling Frames & iFrames With Examples
himanshuseth004
himanshuseth004

Posted on • Edited on • Originally published at lambdatest.com

Selenium C# Tutorial: Handling Frames & iFrames With Examples

As an automation tester, one of the challenges you might face while writing your Selenium test automation scripts is handling frames or iFrames in Selenium while performing automated browser testing. While frames are used to split-screen vertically or horizontally, iFrames are used to insert content from other sources such as ads into your website.

While writing your Selenium test automation scripts, you need to know how to handle frames and iFrames in Selenium. The switch command in Selenium C# is used for automating scenarios involving frames or iFrames in Selenium.

In this Selenium C# tutorial, I’ll show you how to handle nested frames and iFrames in Selenium, using SwitchTo() command.

Switch Window Commands For Frames & iFrames in Selenium C

In order to handle frames and iFrames in Selenium, you first need to know how to identify them. Every window, frames or iFrame in a website has a unique ID called window handle. This window handle remains unchanged throughout the execution of the test scenario and is used to identify different frames or iFrame in Selenium C#.

The window handle is used to switch from one window to another. The switch commands in Selenium C# is accessed by using the SwitchTo method in Selenium WebDriver API.

In this Data driven testing tutorial, let us deep dive into what data driven testing is, its pros & cons, its types, data driven testing in an agile environment, benefits, and their best practices.

Here are the Switch Window commands, you’ll require for switching frame or iFrame in Selenium:

1. SwitchTo Frame

A frame is a part of the web page or web browser window that displays content independent of the web container. An inline frame (or iFrame) is an HTML document that is embedded inside another HTML document. Many websites make use of frames and iFrames for showcasing content.

driver.SwitchTo().Frame(frame-id);
driver.SwitchTo().Frame("frame-name");

/* weblocator can be XPath, CssSelector, Id, Name, etc. */
driver.SwitchTo().Frame(driver.FindElement(By.weblocator("web-locator-property")));
Enter fullscreen mode Exit fullscreen mode

2. SwitchTo DefaultContent

This command selects either the first frame on the web page or the main document (i.e. < main >) when the page contains iFrames.

driver.SwitchTo().DefaultContent();
Enter fullscreen mode Exit fullscreen mode

3. SwitchTo ParentFrame

This command selects the parent frame of the currently selected frame.

driver.SwitchTo().ParentFrame();
Enter fullscreen mode Exit fullscreen mode

Whether it is a frame, alert, or new window (or tab), each of these is identified with their unique Window Handle. It is a unique identifier of the type string that is a pointer to the window as it holds the address to the window.

Run your Jest testing in massive parallel across multiple browser and OS combinations with LambdaTest.

Take this certification to master the fundamentals of Selenium automation testing with C# and prove your credibility as a tester.

Here’s a short glimpse of the Selenium C# 101 certification from LambdaTest:

Handling Nested Frames & iFrames in Selenium C

Nested Frames and iFrames in Selenium testing are particularly used in websites that have multiple sections and each section has to load a separate HTML document. A frameset is a collection of frames in the browser window. The frameset acts as a parent to the child frames in the window.

The Selenium Java official website uses frames to divide the content into three different sections. Switching between different frames is done using the SwitchTo() command for frames.

The SwitchTo frame command is used to switch to the intended frame (or iFrame). Frame id, frame name, and web element locator are used with the SwitchTo command for switching to the intended frame.

driver.SwitchTo().Frame(frame-id);
driver.SwitchTo().Frame("frame-name");

/* weblocator can be XPath, CssSelector, Id, Name, etc. */
driver.SwitchTo().Frame(driver.FindElement(By.weblocator("web-locator-property")));
Enter fullscreen mode Exit fullscreen mode

It is necessary to first switch to the Parent Frame before switching to the intended Child Frame.

/* Switching back to the parent frame */
driver.SwitchTo().ParentFrame();
Enter fullscreen mode Exit fullscreen mode

Handling Nested Frames Using SwitchTo() Method

A nested frame is a frameset that contains a collection of frames (or sub-frames). A frameset contains three different frames — LEFT, MIDDLE, and RIGHT. The BOTTOM frame is an independent frame.

I’ve used http://the-internet.herokuapp.com/nested_frames, for the demonstration of a frameset.

Before switching to frames, we first switch to the frameset (i.e. parent frame) and use the SwitchTo() command to switch to the Child frame. If you want to switch to MIDDLE frame; first you’d have to switch to its container, i.e. frameset — frame-top, then switch to the intended frame i.e. frame-middle.

Similarly, for switching to the BOTTOM frame, you need to switch to the ParentFrame using the driver.SwitchTo().ParentFrame() command, and then switch to the intended frame by using the SwitchTo() command for BOTTOM frame.

I’ve used NUnit framework for this Selenium C# tutorial, In case you want to know about NUnit in detail, you can refer to NUnit framework for Selenium C#.

Here is the implementation for handling Nested frames in Selenium C#:

/* Handling Nested frames in this Selenium C# tutorial for Selenium test automation*/
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
using SeleniumExtras.WaitHelpers;
using System;

namespace Selenium_Frame_Demo
{
    class Selenium_Frame_Demo
    {
        IWebDriver driver;

        [SetUp]
        public void start_Browser()
        {
            // Local Selenium WebDriver
            driver = new ChromeDriver();
            driver.Manage().Window.Maximize();
        }

        [Test, Order(1)]
        public void test_frame_left()
        {
            String test_url = "http://the-internet.herokuapp.com/nested_frames";

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));

            driver.Url = test_url;

            /**************** Switching to the Left Frame ****************/
            /* Switch to the Parent frame before switching to any of the Child frames */
            driver.SwitchTo().ParentFrame();

            /* Since the top frame is a Framset, switch to that frameset first */
            driver.SwitchTo().Frame(driver.FindElement(By.CssSelector("[name = 'frame-top']")));

            /* As we are already in the frameset, we can now switch to the new frame */
            driver.SwitchTo().Frame(driver.FindElement(By.CssSelector("[name = 'frame-left']")));

            /* Reference - https://stackoverflow.com/questions/37791547/selenium-webdriver-get-current-frame-before-switch */

            IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)driver;
            var currentFrame = jsExecutor.ExecuteScript("return self.name");
            Console.WriteLine(currentFrame);
        }

        [Test, Order(2)]
        public void test_frame_middle()
        {
            String test_url = "http://the-internet.herokuapp.com/nested_frames";

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));

            driver.Url = test_url;

            /**************** Switching to the Left Frame ****************/
            /* Switch to the Parent frame before switching to any of the Child frames */
            driver.SwitchTo().ParentFrame();

            /* Since the top frame is a Framset, switch to that frameset first */
            driver.SwitchTo().Frame(driver.FindElement(By.CssSelector("[name = 'frame-top']")));

            /* As we are already in the frameset, we can now switch to the new frame */
            driver.SwitchTo().Frame(driver.FindElement(By.CssSelector("[name = 'frame-middle']")));

            /* Reference - https://stackoverflow.com/questions/37791547/selenium-webdriver-get-current-frame-before-switch */

            IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)driver;
            var currentFrame = jsExecutor.ExecuteScript("return self.name");
            Console.WriteLine(currentFrame);
        }

        [Test, Order(3)]
        public void test_frame_right()
        {
            String test_url = "http://the-internet.herokuapp.com/nested_frames";

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));

            driver.Url = test_url;

            /**************** Switching to the Left Frame ****************/
            /* Switch to the Parent frame before switching to any of the Child frames */
            driver.SwitchTo().ParentFrame();

            /* Since the top frame is a Framset, switch to that frameset first */
            driver.SwitchTo().Frame(driver.FindElement(By.CssSelector("[name = 'frame-top']")));

            /* As we are already in the frameset, we can now switch to the new frame */
            driver.SwitchTo().Frame(driver.FindElement(By.CssSelector("[name = 'frame-right']")));

            /* Reference - https://stackoverflow.com/questions/37791547/selenium-webdriver-get-current-frame-before-switch */

            IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)driver;
            var currentFrame = jsExecutor.ExecuteScript("return self.name");
            Console.WriteLine(currentFrame);
        }

        [Test, Order(4)]
        public void test_single_frame()
        {
            String test_url = "http://the-internet.herokuapp.com/nested_frames";

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));

            driver.Url = test_url;

            /**************** Switching to the Left Frame ****************/
            /* Switch to the Parent frame before switching to any of the Child frames */
            driver.SwitchTo().ParentFrame();

            /* Directly switch to the new frame */
            driver.SwitchTo().Frame(driver.FindElement(By.CssSelector("[name = 'frame-bottom']")));

            /* Reference - https://stackoverflow.com/questions/37791547/selenium-webdriver-get-current-frame-before-switch */

            IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)driver;
            var currentFrame = jsExecutor.ExecuteScript("return self.name");
            Console.WriteLine(currentFrame);
        }

        [TearDown]
        public void close_Browser()
        {
            driver.Quit();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

For switching to the LEFT frame, you need to perform these steps:

  1. Switch to the Parent Frame

  2. Switch to the frameset (or container of the LEFT frame): frame-top

  3. Switch to the LEFT frame using the CssSelector property. Use the Inspect Tool in Chrome/Firefox to get this property.

  4. Use the executescript method of the JavaScriptExecutor interface to run JavaScript on the page so that the current frame can be compared with the intended frame.

    [Test, Order(1)]
    public void test_frame_left()
    {
    String test_url = "http://the-internet.herokuapp.com/nested_frames";

      WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    
      driver.Url = test_url;
    
      /**************** Switching to the Left Frame ****************/
      /* Switch to the Parent frame before switching to any of the Child frames */
      driver.SwitchTo().ParentFrame();
    
      /* Since the top frame is a Framset, switch to that frameset first */
       driver.SwitchTo().Frame(driver.FindElement(By.CssSelector("[name = 'frame-top']")));
    
       /* As we are already in the frameset, we can now switch to the new frame */
       driver.SwitchTo().Frame(driver.FindElement(By.CssSelector("[name = 'frame-left']")));
    
       /* Reference - https://stackoverflow.com/questions/37791547/selenium-webdriver-get-current-frame-before-switch */
    
       IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)driver;
       var currentFrame = jsExecutor.ExecuteScript("return self.name");
       Console.WriteLine(currentFrame);
    

    }

To switch to the BOTTOM frame, first switch to the Parent frame and then to the BOTTOM frame.

[Test, Order(4)]
public void test_single_frame()
{
    String test_url = "http://the-internet.herokuapp.com/nested_frames";

    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));

    driver.Url = test_url;
    driver.SwitchTo().ParentFrame();

    /* Directly switch to the new frame */
    driver.SwitchTo().Frame(driver.FindElement(By.CssSelector("[name = 'frame-bottom']")));

     IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)driver;
     var currentFrame = jsExecutor.ExecuteScript("return self.name");
     Console.WriteLine(currentFrame);
}
Enter fullscreen mode Exit fullscreen mode

As seen in the Visual Studio snapshot, the test scenarios pass as the SwitchTo() command is successful in switching to the intended frames.

You can also refer to the below video tutorial on how to handle Windows and Frames in selenium.

Test your Puppeteer testing scripts online. Deploy a quality build faster by running automated checks across over 3000+ browsers and OS combinations with the LambdaTest cloud.

Handling iFrames In Selenium Using SwitchTo() Method

For this Selenium C# tutorial, I’ve used Selenium.dev as a test URL for the Selenium test automation case on iFrame handling using SwitchTo(). Switching to an iFrame is done using frame name, frame id, or web selector for the iFrame.

Details of the frames in frameset are obtained using the Inspect Tool in Firefox. The site consists of three separate iFrames — packageListFrame, packageFrame, and classFrame.

Three variants of SwitchTo.Frame() are demonstrated in the example for Selenium C# tutorial for Selenium iFrames:

  1. Using Frame Name — SwitchTo().Frame(“frame-name”)

  2. Using Frame ID — SwitchTo().Frame(“frame-id”)

  3. Using web locators — SwitchTo().Frame(web-driver.FindElement(By.web-locator))

    /* Selenium C# tutorial: Handling iframes in Selenium test automation for automated browser testing*/
    using NUnit.Framework;
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;
    using OpenQA.Selenium.Firefox;
    using OpenQA.Selenium.Support.UI;
    using SeleniumExtras.WaitHelpers;
    using System;
    using System.Collections.ObjectModel;

    namespace Selenium_Frame_Demo
    {
    class Selenium_Frame_Demo
    {
    IWebDriver driver;
    String final_frame_xpath = "/html/frameset/frame";

        [SetUp]
        public void start_Browser()
        {
            // Local Selenium WebDriver
            driver = new ChromeDriver();
            driver.Manage().Window.Maximize();
        }
    
        [Test, Order(1)]
        public void test_frame_number()
        {
            String test_url = "https://www.selenium.dev/selenium/docs/api/java/index.html";
    
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    
            driver.Url = test_url;
    
            IWebElement SearchResult = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(By.XPath(final_frame_xpath)));
    
            /* Switch to the Parent frame before switching to any of the Child frames */
            driver.SwitchTo().ParentFrame();
    
            /* Frame Number | Frame Name        | Frame XPath */
            /* 0            | packageListFrame  | /html/frameset/frameset/frame[1] */
            /* 1            | packageFrame      | /html/frameset/frameset/frame[2] */
            /* 2            | classFrame        | /html/frameset/frame */
    
            /* Switching to a new frame by frame number. The new frame will be packageListFrame */
            driver.SwitchTo().Frame(0);
    
            /* Reference - https://stackoverflow.com/questions/37791547/selenium-webdriver-get-current-frame-before-switch */
    
            IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)driver;
            var currentFrame = jsExecutor.ExecuteScript("return self.name");
            Console.WriteLine(currentFrame);
        }
    
        [Test, Order(2)]
        public void test_frame_name()
        {
            String test_url = "https://www.selenium.dev/selenium/docs/api/java/index.html";
    
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    
            driver.Url = test_url;
    
            IWebElement SearchResult = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(By.XPath(final_frame_xpath)));
    
            /* Switch to the Parent frame before switching to any of the Child frames */
            driver.SwitchTo().ParentFrame();
    
            /* Frame Number | Frame Name        | Frame XPath */
            /* 0            | packageListFrame  | /html/frameset/frameset/frame[1] */
            /* 1            | packageFrame      | /html/frameset/frameset/frame[2] */
            /* 2            | classFrame        | /html/frameset/frame */
    
            /* Switching to a new frame by frame number for iframe selenium. The new frame will be packageFrame */
            driver.SwitchTo().Frame("packageFrame");
    
            IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)driver;
            var currentFrame = jsExecutor.ExecuteScript("return self.name");
            Console.WriteLine(currentFrame);
        }
    
        [Test, Order(3)]
        public void test_frame_identifier()
        {
            String test_url = "https://www.selenium.dev/selenium/docs/api/java/index.html";
    
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    
            driver.Url = test_url;
    
            IWebElement SearchResult = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(By.XPath(final_frame_xpath)));
    
            /* Switch to the Parent frame before switching to any of the Child frames for Selenium iframe for automated browser testing*/
            driver.SwitchTo().ParentFrame();
    
            /* Frame Number | Frame Name        | Frame XPath */
            /* 0            | packageListFrame  | /html/frameset/frameset/frame[1] */
            /* 1            | packageFrame      | /html/frameset/frameset/frame[2] */
            /* 2            | classFrame        | /html/frameset/frame */
    
            /* Switching to a new frame by frame number for handing Selenium iframe for automated browser testing. The new frame will be classFrame */
            driver.SwitchTo().Frame(driver.FindElement(By.XPath("/html/frameset/frame")));
    
            IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)driver;
            var currentFrame = jsExecutor.ExecuteScript("return self.name");
            Console.WriteLine(currentFrame);
        }
    
        [TearDown]
        public void close_Browser()
        {
            driver.Quit();
        }
    }
    

    }

The implementation consists of three test cases. The basic premise of each test case is the same, switching first to the Parent Frame before moving to the intended iFrame. Only difference is the manner in which frames are addressed i.e. id, name, etc.

[Test, Order(3)]
public void test_frame_identifier()
{
    String test_url = "https://www.selenium.dev/selenium/docs/api/java/index.html";

    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    driver.Url = test_url;

    IWebElement SearchResult = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(By.XPath(final_frame_xpath)));

    /* Switch to the Parent frame before switching to any of the Child frames for handing Selenium iframe for automated browser testing in Selenium test automation */
    driver.SwitchTo().ParentFrame();

    /* Frame Number | Frame Name        | Frame XPath */
    /* 0            | packageListFrame  | /html/frameset/frameset/frame[1] */
    /* 1            | packageFrame      | /html/frameset/frameset/frame[2] */
    /* 2            | classFrame        | /html/frameset/frame */

    /* Switching to a new frame by frame number. The new frame will be classFrame */
    driver.SwitchTo().Frame(driver.FindElement(By.XPath("/html/frameset/frame")));

    IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)driver;
    var currentFrame = jsExecutor.ExecuteScript("return self.name");
    Console.WriteLine(currentFrame);
}
Enter fullscreen mode Exit fullscreen mode

Every Selenium test automation case for handling iframe in Selenium for automated browser testing starts with switching to the Parent Frame.

/* Switch to the Parent frame before switching to any of the Child frames */
driver.SwitchTo().ParentFrame();
Enter fullscreen mode Exit fullscreen mode

Once we are in the Parent frame, we switch to the intended frame using its XPath property.

/* Switch to the Parent frame before switching to any of the Child frames */
driver.SwitchTo().Frame(driver.FindElement(By.XPath("/html/frameset/frame")));
Enter fullscreen mode Exit fullscreen mode

The three Selenium test automation scenarios pass with the SwitchTo() command successful in switching to the requested frame.

The examples mentioned in this Selenium C# tutorial can be useful in solving frequently encountered problems by Selenium automation testers. The solution to the problem witnessed in SwitchTo() Frame in Selenium with c# is available in the section Handling Nested Frames & iFrames in Selenium C#

In this XCUITest tutorial, learn about XCUITest framework and its benefits for mobile automation testing. Take a look at how XCUITest works and see how to use it to test your mobile applications.

Wrapping it Up

I hope you enjoyed this deep dive into handling frames and iFrames in Selenium C#. By now you should be able to switch between nested frames or iFrames in Selenium C#. In Selenium test automation, by using the SwitchTo() command, you can perform automated browser testing of websites (or web apps) that use pop-up windows, nested frames (or iFrames), and browser windows.

Still up for more learning? In the next article for this Selenium C# tutorial series, I’ll show you how to use Page Object Model in Selenium C#.‌

In case of any doubts, reach out to us in the comments section so that we can put our best foot forward to solve your test automation problems. Also, share the article with your peers seeking to learn about Selenium testing and handling frame and iframe in Selenium C#. Happy Testing!

Top comments (0)