疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

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

  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

  7 fDepth--;

  8 webDriver.switchTo().frame(i);

  9 getFrame();

  10 fDepth++;

  11 webDriver.switchTo().parentFrame();

  12 };

  13 };

  14 };

  复制代码

  Selenium WebDriver在实际使用过程中,执行速度很慢,怎么办?