您的位置:首页 > 其它

Selenium WebDriver的使用(二)

2016-03-16 13:07 316 查看
WebDriver的get()方法只会在当前窗口( current browser window)加载页面,并且会阻塞程序的运行,直至页面加载完毕(onload)或者超时,超时可以通过在初始化实例时进行设置:

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内部,再进行查找操作。

webDriver.switchTo().frame(0);//switch to a frame by index


frame()有三个重载形式,可传入frame的索引编号、frameElement、和name/handle字符串。如果需要切出,可以使用

webDriver.switchTo().defaultContent();




webDriver.switchTo().parentFrame();


两者的区别在于defaultContent()会切换到第一个frame或者是顶层页面;parentFrame()会切换到父一级的frame。

那么遍历iframe包括嵌套的iframe,可通过递归实现,如:

public static void getFrame(){
//do something
iLen = webDriver.findElements(By.cssSelector("body iframe")).size();
for (i=0;i<iLen;i++) {
webDriver.switchTo().frame(i);
getFrame();
webDriver.switchTo().parentFrame();
};
}


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的时候控制递归遍历深度,可以设置一个深度阀值,在递归过程中当达到该阀值时返回,如:

static int fDepth = 2;
public static void getFrame() {
//do something
if (fDepth>0) {
iLen = webDriver.findElements(By.cssSelector("body iframe")).size();
for (int i=0;i<iLen;i++) {
fDepth--;
webDriver.switchTo().frame(i);
getFrame();
fDepth++;
webDriver.switchTo().parentFrame();
};
};
};


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

待续!

原创文章,转载请标明出处。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: