在實際的測試中,有時候我們會經常遇到找不到元素的問題,這也是自動化測試中經常會遇到的情況,我一般首先考慮的就是是否由于頁面中嵌套了frame,進而導緻定位不到元素,如果頁面代碼中沒有iframe層,再根據報錯資訊來考慮原因是否是:元素被隐藏,定位路徑不正确等情況。
一般下列情況中頁面可能包含frame嵌套:背景管理系統中,頁面中有一些獨立的功能子產品,特征是頁面顯示切換了子產品,但是位址欄的URL并沒有變化。或者是一些對接其他系統功能的子產品,很可能會包含嵌套。下面我們來學習一下,如何通過切換frame來成功定位元素。
一、關于頁面frame的方法
備注:部分方法為老寫法,官方已經不推薦使用;點選這篇文章檢視切換frame的新寫法。
切換到一個frame中
switch_to_frame(frame_reference):
frame_reference:id、name、element(定位的某個元素)、索引
切換到主界面
switch_to_default_content():
注:driver.switch_to_frame(None)等同于driver.switch_to_default_content()
二、關于frame的源碼研究
webdriver.py.
def switch_to_frame(self, frame_reference):
""" Deprecated use driver.switch_to.frame
"""
warnings.warn("use driver.switch_to.frame instead", DeprecationWarning)
self._switch_to.frame(frame_reference)
def switch_to_default_content(self):
""" Deprecated use driver.switch_to.default_content
"""
warnings.warn("use driver.switch_to.default_content instead", DeprecationWarning)
switch_to.py.
def default_content(self):
"""
Switch focus to the default frame.
:Usage:
driver.switch_to.default_content()
"""
self._driver.execute(Command.SWITCH_TO_FRAME, {'id': None})
def frame(self, frame_reference):
"""
Switches focus to the specified frame, by index, name, or webelement.
:Args:
- frame_reference: The name of the window to switch to, an integer representing the index,
or a webelement that is an (i)frame to switch to.
:Usage:
driver.switch_to.frame('frame_name')
driver.switch_to.frame(1)
driver.switch_to.frame(driver.find_elements_by_tag_name("iframe")[0])
"""
if isinstance(frame_reference, basestring) and self._driver.w3c:
try:
frame_reference = self._driver.find_element(By.ID, frame_reference)
except NoSuchElementException:
try:
frame_reference = self._driver.find_element(By.NAME, frame_reference)
except NoSuchElementException:
raise NoSuchFrameException(frame_reference)
self._driver.execute(Command.SWITCH_TO_FRAME, {'id': frame_reference})
通過觀察源碼,發現切換frame時,是通過id、name、索引、元素這四種方法來實作switch_to_frame()方法,而default_content的方法預設值為None,是以說我們可以發現switch_to_frame(None)等同于switch_to_default_content()
執行個體:w3c網站的Frame切換
通過進入w3cschool網站的實驗室例子來實驗frame,這個層級關系是有一個父類的frame層級,裡面有三個frame的子類層級
代碼執行個體:
from selenium import webdriver
# 打開Chrome 進入示例頁面
driver = webdriver.Chrome()
driver.get("http://www.w3school.com.cn/tiy/t.asp?f=html_frame_cols")
# 定位父類層級iframe
ele_framest = driver.find_element_by_css_selector("#result > iframe")
# 切換到父類層級iframe-通過元素切換
driver.switch_to_frame(ele_framest)
print(driver.page_source)
print("----------------------------------------------------------------------------")
# 切換到第二個子類frame-通過索引切換
driver.switch_to_frame(1)
print(driver.page_source)
print("----------------------------------------------------------------------------")
# 切換到最上層層級-等同于driver.switch_to_frame(None)
driver.switch_to_default_content()
print(driver.page_source)