Selenium WebDriver的使用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Selenium WebDriver的使用相关的知识,希望对你有一定的参考价值。
WebDriver的get()方法只会在当前窗口( current browser window)加载页面,并且会阻塞程序的运行,直至页面加载完毕(onload)或者超时,超时可以通过在初始化实例时进行设置:
1 webDriver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);//设置为10秒的超时
如果需要用一个WebDriver实例同时操作多个浏览器窗口,需要留意该特性造成的影响。默认一个WebDriver实例只会打开一个浏览器窗口,但可以使用中转页面或通过javascript:伪协议,popup出多个浏览器窗口。
对于并发测试需求,由于get的阻塞和javascript单线程执行特性,应该采用多线程来实现。
于get()方式类似的还有WebDriver.Navigation接口的to()方法,WebDriver.Navigation还有back()、forward()、refresh()方法来实现浏览器的历史导航(back()、forward()实现的是单步历史导航,不接收步长参数)
Selenium WebDriver也可以通过Selenium Standalone Server实现跨服务器的浏览器调用,具体实现参考官方文档。
WebDriver.Timeouts接口还有另外两个方法,setScriptTimeout()和implicitlyWait():
使用setScriptTimeout()方式可以设置等待一个异步脚本在抛出错误之前执行的时长。
使用implicitlyWait()方式可以设置查找元素时在抛出NoSuchElementException错误之前的等待时长,这是一个隐性的或称为全局的设置。与之对应的是Explicit Waits,具体可参考http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp#explicit-and-implicit-waits。
Timeout值的设置需要根据实际需求合理设置并调优,设置了过短,在程序运行过程中将会抛出大量超时错误,过长又会降低程序效率。
另外Timeout不恰当的设置,将会在程序运行过程中,产生不可预期的等待效果,比如同时设置了显性和隐性超时时长,那么查找元素的超时时长将不确定。
当页面中含有frame,如果需要查找frame内部的元素,需要先使用webDriver.switchTo().frame();切换到iframe内部,再进行查找操作。
1 webDriver.switchTo().frame(0);//switch to a frame by index
frame()有三个重载形式,可传入frame的索引编号、frameElement、和name/handle字符串。如果需要切出,可以使用
1 webDriver.switchTo().defaultContent();
或
1 webDriver.switchTo().parentFrame();
两者的区别在于defaultContent()会切换到第一个frame或者是顶层页面;parentFrame()会切换到父一级的frame。
那么遍历iframe包括嵌套的iframe,可通过递归实现,如:
1 public static void getFrame(){ 2 //do something 3 iLen = webDriver.findElements(By.cssSelector("body iframe")).size(); 4 for (i=0;i<iLen;i++) { 5 webDriver.switchTo().frame(i); 6 getFrame(); 7 webDriver.switchTo().parentFrame(); 8 }; 9 }
iframe可以嵌入自己所在的页面吗?答案是可以的,但不会无限制嵌入下去,只会嵌入3层,之后在内部第三层的frame就不会再嵌入了。
有些网站会用自动跳转的方法处理404错误,当有页面通过frame被嵌入到跳转目标页,如果该页面不存在,就产生了页面嵌套自身的情况,在使用Selenium WebDriver对这类iframe内容查找时,如果遍历frame的策略不当,会产生frame遍历的死循环或者导致程序抛出NoSuchFrameException异常。
2.21版本chromedriver,使用webDriver.getCurrentUrl()获取页面的url时,跟旧版本不同,在switchTo()到一个frame后,不会返回该frame的url,永远只会返回顶层页面的url。通过获取frame的src属性来识别frame页面也不是100%可靠,因为frame的页面内容是可以动态写入的。
如果需要在遍历frame的时候控制递归遍历深度,可以设置一个深度阀值,在递归过程中当达到该阀值时返回,如:
1 static int fDepth = 2; 2 public static void getFrame() { 3 //do something 4 if (fDepth>0) { 5 iLen = webDriver.findElements(By.cssSelector("body iframe")).size(); 6 for (int i=0;i<iLen;i++) { 7 fDepth--; 8 webDriver.switchTo().frame(i); 9 getFrame(); 10 fDepth++; 11 webDriver.switchTo().parentFrame(); 12 }; 13 }; 14 };
Selenium WebDriver在实际使用过程中,执行速度很慢,怎么办?
待续!
原创文章,转载请标明出处。
以上是关于Selenium WebDriver的使用的主要内容,如果未能解决你的问题,请参考以下文章
使用 Java 的 Selenium WebDriver (Selenium 2) 中 selenium.refresh() 的等效代码
如何使用 Selenium WebDriver 获取 Inspect Element 代码
一行js代码识别Selenium+Webdriver及其应对方案
如何使用 Selenium WebDriver 启动 InternetExplorerDriver