Selenium操作Frame中的页面元素
写在前面
在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操作方法出一篇文章,各位敬请期待...
文章评论(7)
自动化测试学习交流群:670250199
微信小程序评论
这条评论来自微信小程序
小程序测试留言
小程序测试留言功能
《Selenium操作Iframe中的页面元素》文章已出,见链接:https://www.testclass.cn/selenium_iframe.html