An iFrame is an embedded document that is inside another HTML document. You can normally see an iframe in the html tree under or in a <iframe> tag. Usually the first sign there is an iframe in your AUT is when selenium is not detecting a web element and you don’t know why. They are a bit tricky because you will need to instruct selenium to switch to it in order to access its web elements. Then you’ll need to switch back if you need to access elements outside of that iframe. There are some web applications that make matters worse when their iframes do not have id properties or generate a random one. But we’ll talk about that later. In Selenium C#, in order to handle these frames there are several methods we can use with IWebDriver.SwitchTo().
- SwitchTo().DefaultContent() – Selects either the first frame on the page or the main document when a page contains iFrames.
- SwitchTo().Frame(int frameIndex) – Select a frame by its (zero-based) index.
- SwitchTo().Frame(IWebElement frameElement) – Select a frame using its previously located OpenQA.Selenium.IWebElement.
- SwitchTo().Frame(string frameName) – Select a frame by its name or ID.
- SwitchTo().ParentFrame() – Select the parent frame of the currently selected frame.
More details can be found in the interface ITargetLocator of Selenium.
Switch to a frame by Index
Before we can learn to switch to an iframe by index, we first need to know how many and which iframe to switch to. This approach can also help you if the iframe id/name is not given or if they are auto generated values.
List<IWebElement> frames = new List<IWebElement>(driver.FindElements(By.TagName("iframe"))); Console.WriteLine("Number of Frames: " + frames.Count); for (int i = 0; i < frames.Count; i++) { Console.WriteLine("frame[" + i + "]: " + frames[i].GetAttribute("id").ToString()); }
Now that we know which iframe we want, we can then simply pass the index.
driver.SwitchTo().Frame(0);
Switch to a frame by IWebElement
IWebElement iframe = driver.FindElement(By.Id("iframe1")); driver.SwitchTo().Frame(iframe);
Alternately we can use the first or last syntax from the List we created above.
</pre> <pre>List<IWebElement> frames = new List<IWebElement>(driver.FindElements(By.TagName("iframe"))); driver.SwitchTo().Frame(frames.First()); driver.SwitchTo().Frame(frames.Last())
Switch to a frame by Name of ID
driver.SwitchTo().Frame(("iframe1");
Switch back to the default document or the parent frame
In order to access the elements in the default document you’ll need to switch back out if you are currently in an iframe.
driver.SwitchTo().DefaultContent();
If the AUT has nested iframes, you can switch back out to the parent frame.
driver.SwitchTo().ParentFrame();