How to handle Frames/Iframes using Selenium Web Driver


An iframe or inline frame is used to display external objects including other web pages within a web page. An iframe pretty much acts like a mini web browser within a web browser. Also, the content inside an iframe exists entirely independent from the surrounding elements, and its content can be changed without reloading the whole webpage.
A website can have multiple frames on a single page. And a frame can also have inner frames (Frame in side a Frame).

An iframe within a web page can be identified in the browser if the option named ‘View frame soirce’ is displayed on the right click options as shown below.
 


Alternatively, we can also validate if a web page has any iframes by looking at the source code and searching for the tag <iframe> within the source code.
In Selenium to work with iFrames/Frames, we have different ways to handle depends on the need.
1)   Index
2)   ID or name
3)   Web Element

driver.switch_to.frame(index):
Select a frame by its index. If a page has multiple frames (more than 1), the first frame would be at index "0", the second at index "1" and so on.
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.

Syntax:
 driver.switch_to.frame(index number) 
  Ex: driver.swithc_to.frame(0)

Scenario:
Invoke Google Chrome browser.
Open URL: http://www.londonfreelance.org/courses/frames/index.html
Switch to the frame by using Frame index.
Print the text “Title bar (top.html)”
Script: 
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
import time
chromePath=
"C:\\BrowserDrivers\\chromedriver.exe"
driver=webdriver.Chrome(executable_path=chromePath)
driver.get(
"http://www.londonfreelance.org/courses/frames/index.html")
# Switch to frame by using index as it is 3rd frame so its index is 2.
driver.switch_to.frame(2)
# Printing the “Title bar (top.html)” message
Txtmsg=driver.find_element_by_xpath("//body[@background='top.gif']/h2").text
print(Txtmsg)

driver.switch_to.frame(ID or name):
Select a frame by its name or ID. Frames located by matching name attributes are always given precedence over those matched by ID.
Syntax:
 driver.switch_to.frame(ID or name) 
 Ex: driver.swithc_to.frame(“main”)

Scenario:
Invoke Google Chrome browser.
Open URL: http://www.londonfreelance.org/courses/frames/index.html
Switch to the frame by using frame name.
Print the text “Title bar (top.html)”
Script:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
import time
chromePath=
"C:\\BrowserDrivers\\chromedriver.exe"
driver=webdriver.Chrome(executable_path=chromePath)
driver.get("http://www.londonfreelance.org/courses/frames/index.html") 
# Switch to frame by using name, this frame’s name is “main”
driver.switch_to.frame("main") 
# Printing the “Title bar (top.html)” message
Txtnsg=driver.find_element_by_xpath(
"//body[@background='top.gif']/h2").text
print(Txtnsg)

driver.switch_to.frame(Web Element):
Select a frame by Web Element. Frames located by matching Web element.
Syntax:
 driver.switch_to.frame(Web Element) 
Ex: driver.swithc_to.frame(driver.find_element_by_xpath(“//frame[@src='top.html']))

Scenario:
Invoke Google Chrome browser.
Open URL: http://www.londonfreelance.org/courses/frames/index.html
Switch to the frame by using Web Element.
Print the text “Title bar (top.html)”
Script:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
import time
chromePath="C:\\BrowserDrivers\\chromedriver.exe"
driver=webdriver.Chrome(executable_path=chromePath)
driver.get(
"http://www.londonfreelance.org/courses/frames/index.html") 
# Switch to frame by using Web Element
driver.switch_to.frame(driver.find_element_by_xpath(
"//frame[@src='top.html']"))
Txtnsg=driver.find_element_by_xpath("//body[@background='top.gif']/h2").text
print(Txtnsg)

How to switch back to the Main Frame.
After working with the frames/iframes, important thing is to come back to the web page. if we don't switch back to the default page, driver will throw an exception.
To move back to the parent frame, you can use below methods based on your need.
1)   driver.switch_to.default_content()
2)   driver.switch_to_parent_frame()

What is the difference between default_content() and parent_frame()?

driver.switch_to.default_content(): Switches the control to the main web page regardless of the number of frames within the web page. 
driver.switch_to_parent_frame(): Switches the control to the parent frame of the current frame.

Ex:
When there are multiple frames and some of them are nested.
Main Body:
     iframeMain:
           iframeParent:
                  iframechild:

Assume you are in ifrmaechild :

When you use driver.switchTo().parentFrame() you will go to iframeParent .
But when you use driver.switchTo().defaultContent() you will go to main HTML of page means Main Body.
Note that in this case you will not go to iframeMain .

Scenario 1:
Invoke Google Chrome browser.
Open URL: http://www.londonfreelance.org/courses/frames/index.html
Switch to the frame by using Web Element.
Print the text “Title bar (top.html)”
Switch to main page(using default_content)
Print the title of the main page.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
import time
chromePath=
"C:\\BrowserDrivers\\chromedriver.exe"
driver=webdriver.Chrome(executable_path=chromePath)
driver.get(
"http://www.londonfreelance.org/courses/frames/index.html")
# Switch to frame by using Web Element
driver.switch_to.frame(driver.find_element_by_xpath("//frame[@src='top.html']"))
Txtnsg=driver.find_element_by_xpath("//body[@background='top.gif']/h2").text
print(Txtnsg)
# control switch to main page.
driver.switch_to.default_content()
titlemsg=driver.title
print("Main page Title is :",titlemsg)

Scenario 2:
Invoke Google Chrome browser.
Open URL: http://www.londonfreelance.org/courses/frames/index.html
Switch to the frame by using Web Element.
Print the text “Title bar (top.html)”
Switch to main page(using parent_frame)
Print the title of the main page.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
import time
chromePath=
"C:\\BrowserDrivers\\chromedriver.exe"
driver=webdriver.Chrome(executable_path=chromePath)
driver.get(
"http://www.londonfreelance.org/courses/frames/index.html")
# Switch to frame by using Web Element
driver.switch_to.frame(driver.find_element_by_xpath("//frame[@src='top.html']"))
Txtnsg=driver.find_element_by_xpath("//body[@background='top.gif']/h2").text
print(Txtnsg)
# control switch to main page.
driver.switch_to.parent_frame()
titlemsg=driver.title
print("Main page Title is :",titlemsg)

Note:
1) It will throw NoSuchFrameException when the required frame is not found on the current web page.
2) It will throw NoSuchElementException when you are trying to access web elements without switch over to frame.

Comments