How to Handle IFrame in Selenium C#

In this tutorial, we will discuss “iframe”, what is iframe and how to handle it in Selenium C#.

What is iframe

The <iframe> tag represents an inline frame and it is used to embed the other HTML document into the current HTML document.

For performing the action on the element which is present inside the Iframe first we need to switch to that frame. Just like we switch the parent browser window to the child browser window to perform the action on the child browser window.

Switching of Frames with a method in Selenium C#

So in order to switch to the frame, we are going to use the method called “SwithTo().Frame()” and this is coming from the ITargetLocator interface.

So here if we go to the IWebDriver Interface we have a method called SwitchTo() which will return us the ITargetLocator interface type and here to switch to the frame we have three overloaded methods.

  • Frame(IWebElement frameElement); ~ this takes the IWebElement
  • Frame(string frameName); ~ this takes the frame name
  • Frame(int frameIndex); ~ this takes the frame index.

Here we have one more method that is ParentFrame(); its work is to switch to the parent frame and this is similar to our SwitchToParent() method.

So on this webpage if we click on this button

so it is going to launch the child browser window and if we analyze “Try it” this particular element so as we can see here this particular element is present inside the frame.

So if we try to click on this element without switching the frame then our script will fail.

Let’s understand this with an example-

In Visual Studio in our TestScript we will add one more method inside TestMultipleBrowserWindow.cs

[TestMethod]
public void TestFrame()
{
NavigationHelper.NavigateYoUrl("http://www.w3schools.com/js/js popup.asp");
ButtonHelper.ClickButton(By.XPath("//div[@id='main']/descendant::a[position ()=3"));
BrowserHelper.SwitchToWindow(1);
ButtonHelper.ClickButton(By.XPath("//button[Text()='Try it']"));
}

Explanation of code:

We have created a method called TestFrame() and we are copying here the first two lines of code where we were navigating to the required webpage from our last code of Handling Multiple Browser Window then we are using BrowserHelper.SwitchToWindow(1);  with its help, we are switching to the child window.

Then //button[text()='Try it']  this is the XPath of that button which we want to click so ButtonHelper.ClickButton(By.XPath("//button[Text()='Try it']"));

Now we will put a breakpoint over here and run the script in debug mode.

Output: so it has hit the breakpoint, this is the button and if we do a stepover as we can see there it is still trying to search that button and the reason is the same because this particular button is present inside that frame.

So first we need to switch to that frame before performing the action. Now our script will fail with “NoSuchElementException”.

Solution:

so before performing this action we need to switch to that frame so we will use ObjectRepository.Driver.SwitchTo().Frame() and if we analyze this particular button so the frame Id is ‘iframeResult’ and we will use this particular id for locating the frame.

public void TestFrame() 
{ 
NavigationHelper.NavigateYoUrl("http://www.w3schools.com/js/js popup.asp"); 
ButtonHelper.ClickButton(By.XPath("//div[@id='main']/descendant::a[position ()=3")); 
BrowserHelper.SwitchToWindow(1); 
ObjectRepository.Driver.SwitchTo().Frame(ObjectRepository.Driver.FindElement(By.Id("iframeResult")));
ButtonHelper.ClickButton(By.XPath("//button[Text()='Try it']")); 
}

So here we will write Frame(ObjectRepository.Driver.FindElement(By.Id("iframeResult"))); so as we know this particular statement will return us the IWebElement. Now again we will run this script in debug mode.

Output: so if we do a stepover it is going to switch to that frame and again if we do a stepover it will click on that button. So as we can see here it has just clicked on that particular button and the popup is appear

and now continue the execution of this script.

Another example:

Now let us suppose after this we want to click on this button whose XPath is ("//div[@class='textarea']/descendant::button") this and which is not present inside the frame.

public void TestFrame() 
{ 
NavigationHelper.NavigateYoUrl("http://www.w3schools.com/js/js popup.asp"); ButtonHelper.ClickButton(By.XPath("//div[@id='main']/descendant::a[position ()=3")); 
BrowserHelper.SwitchToWindow(1); ObjectRepository.Driver.SwitchTo().Frame(ObjectRepository.Driver.FindElement(By.Id("iframeResult"))); 
ButtonHelper.ClickButton(By.XPath("//button[Text()='Try it']")); 
ButtonHelper.ClickButton(By.XPath("//div[@class='textarea']/descendant::button"));
}

so again we will build our solution and run the script in debug mode.

Output: so it has hit the breakpoint if we do a stepover it is going to switch to that frame and perform the action that is the click action on this button.

And if we do a stepover again so now our WebDriver will wait for this element which means it is searching for this element inside this frame that is not present.

So again our script will fail with UnhandledAlertException and the reason is the same it is trying to search or find the element in the frame. So we are going to stop this script.

DefaultContent() method:

In such cases we were done dealing with our iframe we need to call SwitchTo().DefaulContent() method. So we can continue our execution with other web elements.

public void TestFrame() 
{ 
NavigationHelper.NavigateYoUrl("http://www.w3schools.com/js/js popup.asp");
 ButtonHelper.ClickButton(By.XPath("//div[@id='main']/descendant::a[position ()=3")); 
BrowserHelper.SwitchToWindow(1); 
ObjectRepository.Driver.SwitchTo().Frame(ObjectRepository.Driver.FindElement(By.Id("iframeResult"))); //ButtonHelper.ClickButton(By.XPath("//button[Text()='Try it']")); 
ObjectRepository.Driver.SwitchTo().DefaultContent();
ButtonHelper.ClickButton(By.XPath("//div[@class='textarea']/descendant::button"));
 }

Here in our code, we will comment on this line of code //ButtonHelper.ClickButton(By.XPath("//button[Text()='Try it']")); and then add this line of code which has a method ObjectRepository.Driver.SwitchTo().DefaultContent();

Now put the breakpoint on ObjectRepository.Driver.SwitchTo().Frame(ObjectRepository.Driver.FindElement(By.Id("iframeResult"))); this and again build our solution and run the script in debug mode.

Output: so it has hit the breakpoint if we do a stepover it is going to switch to that frame and perform the click action on the button as we can see here.

Now again it will call the DefaultContent() method, we will switch to the default content and as we can see here our script is going in the normal way in the previous case it was failing because it was not able to locate this element.

So once we are done dealing with the iframe we should call this DefaultContent() method, so we can perform our actions on the other web element.

So in this manner, we can handle the iframe with the help of a web driver in Selenium C#.