做web应用的自动化测试时,定位元素是必不可少的,这个过程经常会碰到定位不到元素的情况(报selenium.common.exceptions.NoSuchElementException),一般可以从以下几个方面着手解决:
1、定位表达式错误或者定位到多个
试了好几种定位方式了,怎么看这个元素就是这个属性,没错啊!这应该是我们最常遇到了情况。这个时候怎么办呢?很简单。检验你的定位方式到底有没有找到元素
1、打开chrom浏览器
2、F12打开调试模式
3、选择元素右键检查
4、按住ctrl+F键,调试框下方出现一个输入框
5、输入自己的元素定位表达式
- 黄色加亮为定位到的元素,2的标识处为定位到的元素个数,如果有唯一元素,说明定位表达式正确
- 如果有多个元素,需要优化定位表达式直至唯一或用下标精准定位到你要找的元素。
也可以把定位到的多个元素属性及下标打印出来,对应你要定位到的原元素
- 如果没有定位到元素,说明元素表达式错误
2、Frame/Iframe原因定位不到元素:
这个是最常见的原因,首先要理解下frame的实质,frame中实际上是嵌入了另一个页面,而webdriver每次只能在一个页面识别,因此需要先定位到相应的frame,对那个页面里的元素进行定位。
解决方案:
如果iframe有name或id的话,直接使用switch_to_frame("name值")或switch_to_frame("id值")。如下:
如果没有可用的id和name属性,可以先定位到frame/iframe,再将定位对象传给switch_to.frame(对象)方法。如下:
如果完成操作后,可以通过switch_to.parent_content()方法跳出当前iframe,或者还可以通过switch_to.default_content()方法跳回最外层的页面。
3.页面还没有加载出来,就对页面上的元素进行的操作:
这种情况一般说来,可以设置等待,等待页面或者元素加载完毕后再进行操作
可用的有三种等待方式:
- WebDriverWait() 显性等待
- driver.implicitly_wait(秒) 全局隐式等待
- sleep(秒) 线程等待,休眠固定的时间
具体用法参看另外一篇文章 :Selenium:元素定位的各种方法
4、页面元素失去焦点导致脚本运行不稳定
解决方法:driver.switch_to.active_element 遇到脚本不稳定,有时会失去焦点导致测试失败的情况下,可以先切到焦点元素再进行操作。注意.active_element后面不带括号()。
5、元素被遮挡,不可用,不可见
5.1窗口最大化
driver.maximize_window() 由于窗口大小改变引起的页面元素布局发生变化,被测元素被遮挡,可以先将窗口最大化,再进行元素定位。
5.2页面有滚动条,元素需要操作滚动条后才可见
5.3不可用
对于有些WebDriver没有提供的方法或者无法实现的功能,WebDriver提供了driver.execute_script()方法来执行JavaScript代码。
假设一个输入框可以通过id='text'将其定位,却不能通过send_keys()输入文本内容,可以借助JavaScript代码来实现
假如某个元素属性display:none方法是设置元素不可见(display='block'将显示元素),导致通过定位页面元素无法定位。’
对于这种问题,可以通过JavaScript修改页面元素属性来将元素置位可见,然后通过id、classname等方法去定位,示例代码如下
当我们想在输入框 是日期类型,并send_keys 的时候发现不能输入,输入框被禁用readonly,处理方式如下
6、页面跳转到新的标签页,或者弹出的警告框等
在页面操作过程中有时候点击某个链接会弹出新窗口,这时就需要切换焦点到新窗口上进行操作。
窗口切换:
driver.switch_to.window(window_handle)切换到新窗口。
首先获取当前窗口的句柄driver.current_window_handle,接着打开弹出新窗口,获得当前打开的所有窗口的句柄driver.window_handles。通过for循环遍历handle,如果不等于第一次打开窗口的句柄,那么一定是新窗口的句柄,因为执行过程只打开了两个窗口;改变条件,如果等于第一次打开窗口的句柄,那么可以切换回第一次打开的窗口。
警告框:
对于JavaScript生成的alert、confirm以及prompt,无法使用前端工具对弹出窗口进行定位的,使用driver.switch_to.alert方法定位弹出框。alert的方法有: