Selenium操作Frame中的页面元素

2019-10-21 17:12:45 浏览数 (1)

横眉冷对千夫指,俯首甘为孺子牛。

-------鲁迅

写在前面




在Web应用中经常会遇到网页中嵌套多个Frame框架的情况。这种情况下,如果直接去定位嵌套在Frame页面中的元素就会抛出NoSuchElementException异常。所以在操作嵌套在Frame框架上页面元素前,需要将页面焦点切换到Frame中。Selenium提供的switch_to.frame()方法可以实现Frame之间的跳转。

实践案例




Frame 对象代表一个 HTML 框架。 Frame就是一个子窗口,在里面可以加载网页 。嵌套多个Frame的页面,这种情况我们就需要一层层的跳转,从第一层跳转到要定位元素所在的那层框架。处理完业务如果需要跳转到其他层框架,首先需要跳转到最外层的页面,然后再逐一跳转Frame框架。 为了更直观的演示案例,制作了一个html。以下链接复制到浏览器打开:

https://www.testclass.cn/test_html/frame/frameset.html

前端界面显示如下:

html代码显示如下:

测试案例操作步骤:

一、定位页面最左侧的Frame:

1.首先定位页面最左边的Frame;

2.获取最左侧Frame中内容;

3.通过条件判断获取的内容是否复核预期结果;

4.点击界面按钮,弹出Alert,获取Alert,并且接受Alert;

二、定位页面最中间的Frame:

1.从最左侧的Frame中跳转到最外层的页面;

2.定位页面中间的Frame;

3.获取页面中间Frame中的内容;

4.通过条件判断获取的内容是否复核预期结果;

5.在中间页面input框中输入内容;

6.点击提交,弹出Alert,获取Alert,并且接受Alert;

三、定位页面最右边的Frame:

1.从中间的Frame中跳转到最外层的页面;

2.定位到页面最右边的Frame;

3.获取页面最右边Frame中的内容;

4.通过条件判断获取的内容是否复核预期结果;

5.选择测试类型:安全测试。

详细测试代码如下:

代码语言:javascript复制
#control_frame.py
#www.testclass.cn
#Altumn
import time
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutExceptiondriver=webdriver.Chrome()
url="https://www.testclass.cn/test_html/frame/frameset.html"
driver.get(url)
driver.maximize_window()
driver.implicitly_wait(10)
#一、定位最左侧的frame;
#通过driver.switch_to.frame("id")跳转frame;
driver.switch_to.frame("leftframe")
leftframe = driver.find_element_by_xpath("//p")
text=leftframe.text
print("最左侧frame内容为:",text)
correct_text = "来了老弟!欢迎来到www.testclass.cn"
#判断一下是否和预期的内容correct_text相符合;
if text == correct_text:
   print("最左侧frame内容核对成功!")
else:
   print("最左侧frame内容核对失败!")
#点击左边frame上面的button;
driver.find_element_by_tag_name("input").click()
#等待alert出现,并且获取弹出框的内容;
try:
   alert=WebDriverWait(driver,10).until(EC.alert_is_present())
   print(alert.text)    
    #等待一下,为了演示效果。该等待在实际应用中可以去掉。
   time.sleep(2)
   alert=driver.switch_to.alert
   alert.accept()
except TimeoutException as e:
   print(e)
#二、定位中间的frame;
#由于上面的代码跳转到了最左侧的frame,如果需要定位其他frame,需要先跳转到界面最外层。
#使用方法driver.switch_to.default_content()跳转到界面最外层;
driver.switch_to.default_content()
#通过driver.switch_to.frame("id")跳转frame;
driver.switch_to.frame("middleframe")
middleframe = driver.find_element_by_xpath("//p")
text=middleframe.text
print("中间frame内容为:",text)
correct_text = "这只是用来演示测试效果的html网页"
#判断一下是否和预期的内容correct_text相符合;
if text == correct_text:
   print("中间的frame内容核对成功!")
else:
   print("中间的frame内容核对失败!")
#清除输入框中的内容“www.testclass.cn”;

driver.find_element_by_id("text").clear()
#编辑框内重新输入内容;
driver.find_element_by_id("text").send_keys("亲爱哒博主你好帅啊!")
#点击submit按钮;
driver.find_element_by_id("button").click()
#等待alert出现,并且获取弹出框的内容;
try:
   alert=WebDriverWait(driver,10).until(EC.alert_is_present())
   print(alert.text)    
    #等待一下,为了演示效果。该等待在实际应用中可以去掉。
   time.sleep(2)
   alert=driver.switch_to.alert
   alert.accept()
except TimeoutException as e:
   print(e)
#三、定位最右侧的frame;
#由于上面的代码跳转到了中间的frame,如果需要定位其他frame,需要先跳转到界面最外层。
#使用方法driver.switch_to.default_content()跳转到界面最外层;
driver.switch_to.default_content()
#通过driver.switch_to.frame("id")跳转frame;
driver.switch_to.frame("rightframe")
rightframe = driver.find_element_by_xpath("//p")
text=rightframe.text
print("最右边的frame内容为:",text)
correct_text = "你喜欢做什么类型的软件测试?"
#判断一下是否和预期的内容correct_text相符合;
if text == correct_text:
   print("最右边的frame内容核对成功!")
else:
   print("最右边的frame内容核对失败!")
#选择安全测试类型;
driver.find_element_by_id("security_test").click()
#等待一下,演示效果;
time.sleep(3)
driver.qu

执行结果如下所示:

代码语言:javascript复制
PS C:UsersWangXiaoDesktoppython> cd 'c:UsersWangXiaoDesktoppython'; ${env:PYTHONIOENCODING}='UTF-8'; ${env:PYTHONUNBUFFERED}='1'; & 'C:UsersWangXiaoAppDataLocalProgramsPythonPython36python.exe' 'c:UsersWangXiao.vscodeextensionsms-python.python-2018.12.1pythonFilesptvsd_launcher.py' '--default' '--client' '--host' 'localhost' '--port' '64186' 'c:UsersWangXiaoDesktoppythoncontrol_frame.py'DevTools listening on ws://127.0.0.1:12322/devtools/browser/4b400637-f554-4557-b586-dce015368441
最左侧frame内容为: 来了老弟!欢迎来到www.testclass.cn
最左侧frame内容核对成功!
Follow your own course,and let people talk!-----www.testclass.cn
中间frame内容为: 这只是用来演示测试效果的html网页
中间的frame内容核对成功!
哈哈,不好意思.逗你玩儿呢!----www.testclass.cn
最右边的frame内容为: 你喜欢做什么类型的软件测试?
最右边的frame内容核对成功!

如上所示,在进入多级Frame的情况下,可以通过switch_to.default_content()跳回最外层的页面。

switch_to.frame()默认可以直接取Frame的id或name属性。 如果Frame没有可用的id和name属性,则可以通过下面的方式进行定位。

实现思路:

1.先通过id/name/xpath等元素定位方式正确定位到frame;

2.然后将定位对象传给switch_to.frame()方法;

详细实现代码:

代码语言:javascript复制
#control_frame.py
#www.testclass.cn
#Altumn
import time
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutExceptiondriver=webdriver.Chrome()
url="https://www.testclass.cn/test_html/frame/frameset.html"
driver.get(url)
driver.maximize_window()
driver.implicitly_wait(10)
#一、定位最左侧的frame;
#先通过id定位到frame;
frame=driver.find_element_by_id("leftframe")
#再将定位对象传给switch_to.frame()方法;
driver.switch_to.frame(frame)
leftframe = driver.find_element_by_xpath("//p")
text=leftframe.text
print("最左侧frame内容为:",text)
#点击左边frame上面的button;
driver.find_element_by_tag_name("input").click()
#等待alert出现,并且获取弹出框的内容;
try:
   alert=WebDriverWait(driver,10).until(EC.alert_is_present())
   print(alert.text)    
#等待一下,为了演示效果。该等待在实际应用中可以去掉。
   time.sleep(2)
   alert=driver.switch_to.alert
   alert.accept()
except TimeoutException as e:
   print(e)
#二、定位中间的frame;
#由于上面的代码跳转到了最左侧的frame,如果需要定位其他frame,需要先跳转到界面最外层。
driver.switch_to.default_content()
#先通过id定位到frame;
frame=driver.find_element_by_id("middleframe")
#再将定位对象传给switch_to.frame()方法;
driver.switch_to.frame(frame)
middleframe = driver.find_element_by_xpath("//p")
text=middleframe.text
print("最左侧frame内容为:",text)
#清除输入框中的内容“www.testclass.cn”;
driver.find_element_by_id("text").clear()
#编辑框内重新输入内容;
driver.find_element_by_id("text").send_keys("亲爱哒博主你好帅啊!")
#点击submit按钮;
driver.find_element_by_id("button").click()
#等待alert出现,并且获取弹出框的内容;
try:
   alert=WebDriverWait(driver,10).until(EC.alert_is_present())
   print(alert.text)    
    #等待一下,为了演示效果。该等待在实际应用中可以去掉。
   time.sleep(2)
   alert=driver.switch_to.alert
   alert.accept()
except TimeoutException as e:
   print(e)
#三、定位最右侧的frame;
#由于上面的代码跳转到了中间的frame,如果需要定位其他frame,需要先跳转到界面最外层。
driver.switch_to.default_content()
#先通过id定位到frame;
frame=driver.find_element_by_id("rightframe")
#再将定位对象传给switch_to.frame()方法;
driver.switch_to.frame(frame)
rightframe = driver.find_element_by_xpath("//p")
text=rightframe.text
print("最右边的frame内容为:",text)
#选择安全测试类型;
driver.find_element_by_id("security_test").click()
#等待一下,演示效果;
time.sleep(3)
driver.quit()

执行结果如下所示:

代码语言:javascript复制
PS C:UsersWangXiaoDesktoppython> cd 'c:UsersWangXiaoDesktoppython'; ${env:PYTHONIOENCODING}='UTF-8'; ${env:PYTHONUNBUFFERED}='1'; & 'C:UsersWangXiaoAppDataLocalProgramsPythonPython36python.exe' 'c:UsersWangXiao.vscodeextensionsms-python.python-2018.12.1pythonFilesptvsd_launcher.py' '--default' '--client' '--host' 'localhost' '--port' '54867' 'c:UsersWangXiaoDesktoppythoncontrol_frame_test.py'DevTools listening on ws://127.0.0.1:12925/devtools/browser/c3854147-4c14-4fe8-864f-7277113755fe
最左侧frame内容为: 来了老弟!欢迎来到www.testclass.cn
Follow your own course,and let people talk!-----www.testclass.cn
最左侧frame内容为: 这只是用来演示测试效果的html网页
哈哈,不好意思.逗你玩儿呢!----www.testclass.cn
最右边的frame内容为: 你喜欢做什么类型的软件测试?

总结一下



在日常的自动化测试中经常会遇到alert、frame和新的window出现,所以针对这几种情况,上文中所使用的方法switch_to的相关方法非常好用。在这里特此总结一下经常用到的方法:

switch_to_alert()

切换到alert弹窗 ;

switch_to_window(window_name)

切换到某个浏览器window_name窗口 ;

switch_to.frame()

跳转到对应id/name属性的frame ;

switch_to.active_element()

返回当前焦点(光标的位置) ;

switch_to.default_content()

返回文档主页,从其他Frame/Iframe中返回到最外一层;

switch_to.parent_frame()

切换到父frame,可以切换到上一层的frame,对于层层嵌套的frame很有用 ;

注意:在低版本的selenium中,提供的方法是:

switch_to_frame() switch_to_default_content()

在此作者使用的selenium版本为:3.12.0。

该版本目前已推荐使用switch_to.frame()和switch_to.default_content()方法,同时也是兼容老版本的。

上面主要介绍了关于多Frame框架页面中元素Selenium的操作方法,IFrame和Frame的处理方法类似,但是html页面有所不同。接下来也会针对Iframe中的页面元素Selenium操作方法出一篇文章,各位敬请期待...

0 人点赞