Selenium操作Frame中的页面元素

2019年1月29日 4.82k 次阅读 7 条评论 1 人点赞

写在前面

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

实践案例

Frame 对象代表一个 HTML 框架。 Frame就是一个子窗口,在里面可以加载网页 。嵌套多个Frame的页面,这种情况我们就需要一层层的跳转,从第一层跳转到要定位元素所在的那层框架。处理完业务如果需要跳转到其他层框架,首先需要跳转到最外层的页面,然后再逐一跳转Frame框架。 为了更直观的演示案例,制作了一个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.选择测试类型:安全测试。

详细测试代码如下:

#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 TimeoutException

driver=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.quit()

执行结果如下所示:

PS C:\Users\WangXiao\Desktop\python> cd 'c:\Users\WangXiao\Desktop\python'; ${env:PYTHONIOENCODING}='UTF-8'; ${env:PYTHONUNBUFFERED}='1'; & 'C:\Users\WangXiao\AppData\Local\Programs\Python\Python36\python.exe' 'c:\Users\WangXiao\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\ptvsd_launcher.py' '--default' '--client' '--host' 'localhost' '--port' '64186' 'c:\Users\WangXiao\Desktop\python\control_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()方法;

详细实现代码:

#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 TimeoutException

driver=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()

执行结果如下所示:

PS C:\Users\WangXiao\Desktop\python> cd 'c:\Users\WangXiao\Desktop\python'; ${env:PYTHONIOENCODING}='UTF-8'; ${env:PYTHONUNBUFFERED}='1'; & 'C:\Users\WangXiao\AppData\Local\Programs\Python\Python36\python.exe' 'c:\Users\WangXiao\.vscode\extensions\ms-python.python-2018.12.1\pythonFiles\ptvsd_launcher.py' '--default' '--client' '--host' 'localhost' '--port' '54867' 'c:\Users\WangXiao\Desktop\python\control_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操作方法出一篇文章,各位敬请期待...

温馨提示:欢迎点击加入软件测试学习交流QQ群:软件测试学习交流群

风里云里,我在这里等你!

文章评论(7)

  • 11

    自动化测试学习交流群:670250199

    2019年3月28日
  • 售后小刘_微拓互联

    微信小程序评论

    2019年2月1日
  • 售后小刘_微拓互联

    这条评论来自微信小程序

    2019年2月1日
  • 售后小刘_微拓互联

    小程序测试留言

    2019年2月1日
  • 售后小刘_微拓互联

    小程序测试留言功能

    2019年2月1日
  • Altumn

    《Selenium操作Iframe中的页面元素》文章已出,见链接:https://www.testclass.cn/selenium_iframe.html

    2019年1月29日