web自动化测试第9步:切换页面frame

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/CCGGAAG/article/details/76284777

在实际的测试中,有时候我们会经常遇到找不到元素的问题,这也是自动化测试中经常会遇到的情况,我一般首先考虑的就是是否由于页面中嵌套了frame,从而导致定位不到元素,如果页面代码中没有iframe层,再根据报错信息来考虑原因是否是:元素被隐藏,定位路径不正确等情况。

一般下列情况中页面可能包含frame嵌套:后台管理系统中,页面中有一些独立的功能模块,特征是页面显示切换了模块,但是地址栏的URL并没有变化。或者是一些对接其他系统功能的模块,很可能会包含嵌套。下面我们来学习一下,如何通过切换frame来成功定位元素。

frame标签有frameset、frame、iframe三种,frameset跟其他普通标签没有区别,不会影响到正常的定位,
而frame与iframe对selenium定位而言是一样的,selenium有一组方法对frame进行操作。

一、关于页面frame的方法

备注:部分方法为老写法,官方已经不推荐使用;点击这篇文章查看切换frame的新写法。

切换到一个frame中

  • switch_to.frame(frame_reference):    切换到某一个frame,有多个frame要一层一层进,一层一层出

  • frame_reference:id、name、element(定位的某个元素)、索引   element相当driver(驱动).find_element_by_xpath()等方法找到的元素

  • driver.switch_to.parent_frame()      可以切换到上一层的frame,对于层层嵌套的frame很有用

切换到主界面

  • switch_to.default_content():

注:driver.switch_to.frame(None)等同于driver.switch_to.default_content()

 

二、关于frame的源码研究

webdriver.py


 
 
  1. def switch_to_frame(self, frame_reference):
  2. """ Deprecated use driver.switch_to.frame
  3. """
  4. warnings.warn( "use driver.switch_to.frame instead", DeprecationWarning)
  5. self._switch_to.frame(frame_reference)
  6. def switch_to_default_content(self):
  7. """ Deprecated use driver.switch_to.default_content
  8. """
  9. warnings.warn( "use driver.switch_to.default_content instead", DeprecationWarning)
  10. self._switch_to.default_content()

switch_to.py


 
 
  1. def default_content(self):
  2. """
  3. Switch focus to the default frame.
  4. :Usage:
  5. driver.switch_to.default_content()
  6. """
  7. self._driver.execute(Command.SWITCH_TO_FRAME, { 'id': None})
  8. def frame(self, frame_reference):
  9. """
  10. Switches focus to the specified frame, by index, name, or webelement.
  11. :Args:
  12. - frame_reference: The name of the window to switch to, an integer representing the index,
  13. or a webelement that is an (i)frame to switch to.
  14. :Usage:
  15. driver.switch_to.frame('frame_name')
  16. driver.switch_to.frame(1)
  17. driver.switch_to.frame(driver.find_elements_by_tag_name("iframe")[0])
  18. """
  19. if isinstance(frame_reference, basestring) and self._driver.w3c:
  20. try:
  21. frame_reference = self._driver.find_element(By.ID, frame_reference)
  22. except NoSuchElementException:
  23. try:
  24. frame_reference = self._driver.find_element(By.NAME, frame_reference)
  25. except NoSuchElementException:
  26. raise NoSuchFrameException(frame_reference)
  27. 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()

三、实例验证(1)w3c网站的frame切换

我们通过进入w3cschool网站的实验室例子来实验frame,这个层级关系是有一个父类的frame层级,里面有三个frame的子类层级

代码实例:


 
 
  1. from selenium import webdriver
  2. # 打开Chrome 进入示例页面
  3. driver = webdriver.Chrome()
  4. driver.get( "http://www.w3school.com.cn/tiy/t.asp?f=html_frame_cols")
  5. # 定位父类层级iframe
  6. ele_framest = driver.find_element_by_css_selector( "#result > iframe")
  7. # 切换到父类层级iframe-通过元素切换
  8. driver.switch_to_frame(ele_framest)
  9. print(driver.page_source)
  10. print( "----------------------------------------------------------------------------")
  11. # 切换到第二个子类frame-通过索引切换
  12. driver.switch_to_frame( 1)
  13. print(driver.page_source)
  14. print( "----------------------------------------------------------------------------")
  15. # 切换到最上层层级-等同于driver.switch_to_frame(None)
  16. driver.switch_to_default_content()
  17. print(driver.page_source)

 

四、实例验证(2)163邮箱首页登录

 

本来实例只有一个的,因为毕竟目前网站上用frame的不多,但是在一次别人问我的问题,163邮箱登录的问题,琢磨了一段时间,这里把问题展示一下:

163邮箱

我们如果直接定位输入框,会发现无法定位到元素,通过查看源代码发现,原来163把登陆的功能单独调过来,独立的作为一个模块,用frame来隔断了,所以说我们要做的就是先切换到对应的frame后,再去定位

代码演示:


 
 
  1. # 163邮箱登陆
  2. from selenium import webdriver
  3. from time import sleep
  4. driver=webdriver.Chrome()
  5. # 进入163邮箱首页
  6. driver.get( "http://mail.163.com/")
  7. sleep( 2)
  8. # 切换到包含登录框的frame下
  9. driver.switch_to_frame( 0)
  10. # 通过name定位输入框,并输入数据
  11. driver.find_element_by_xpath( "//input[@name='email']").send_keys( "4444")

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然,我可以为您提供一个用函数写出切换到iframe的示例代码。以下是一个基于Selenium的Python函数: ```python from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def switch_to_iframe(driver, iframe_locator): # 等待iframe加载完成并切换到iframe WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(iframe_locator)) ``` 这个函数名为`switch_to_iframe`,接受两个参数:`driver`(浏览器驱动对象)和`iframe_locator`(iframe的定位器)。 在函数内部,我们使用`WebDriverWait`和`EC.frame_to_be_available_and_switch_to_it()`等待iframe加载完成并切换到iframe。`frame_to_be_available_and_switch_to_it()`方法接受一个定位器作为参数,并等待该定位器指定的iframe可用,并切换到该iframe。 您可以在调用这个函数之前先实例化一个浏览器驱动对象(例如,`driver = webdriver.Chrome()`),然后将该驱动对象和合适的iframe定位器作为参数传递给`switch_to_iframe`函数。 以下是一个使用示例: ```python from selenium import webdriver from selenium.webdriver.common.by import By # 启动浏览器 driver = webdriver.Chrome() try: # 打开网页 driver.get("https://example.com") # 定位iframe元素 iframe_locator = (By.CSS_SELECTOR, "iframe[name='iframe_name']") # 切换到iframe switch_to_iframe(driver, iframe_locator) # 在iframe中执行操作 # ... # 切换回主页面 driver.switch_to.default_content() # 在主页面执行其他操作 # ... finally: # 关闭浏览器 driver.quit() ``` 在这个示例中,我们首先启动了Chrome浏览器。 然后,使用`driver.get()`方法打开了一个网页(示例中的URL为https://example.com)。 接下来,使用`(By.CSS_SELECTOR, "iframe[name='iframe_name']")`定位器定位要切换的iframe元素。在示例中,我们使用CSS选择器来定位iframe,您可以根据实际情况使用其他定位方式。 然后,调用`switch_to_iframe()`函数,将浏览器驱动对象和iframe定位器作为参数传递给它,切换到该iframe。 在切换到iframe后,您可以在其中执行需要的操作。 完成在iframe中的操作后,使用`driver.switch_to.default_content()`方法切换回主页面。 最后,在`finally`块中,我们使用`driver.quit()`关闭浏览器。 请注意,这只是一个简单的示例,实际的Web自动化测试可能涉及更多的操作和断言。您可以根据自己的需求修改和扩展这个函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值