WebDriver 提供了方法来同步 / 异步执行 JavaScript 代码,这是因为 JavaScript 可以完成一些 WebDriver 本身所不能完成的功能,从而让 WebDriver 更加灵活和强大。
本文中所提到的都是 JAVA 代码。
1. 在 WebDriver 中如何执行 JavaScript 代码
JavaScript 代码总是以字符串的形式传递给 WebDriver ,不管你的 JavaScript 代码是一行还是多行, WebDriver 都可以用 executeScript方法来执行字符串中包含的所有 JavaScript代码。
WebDriver driver = new FirefoxDriver();
JavascriptExecutor driver_js=(JavascriptExecutor)driver;
String js = “alert(\”Hello World!\”);”;
driver_js.executeScript( js);
2. 同步执行 JavaScript 和异步执行 JavaScript 的区别
- 同步执行: driver_js.executeScript( js)
如果 JavaScript 代码的执行时间较短,可以选择同步执行,因为 Webdriver 会等待同步执行的结果,然后再运行其它的代码。
- 异步执行: driver_js.executeAsyncScript(js)
如果 JavaScript 代码的执行时间较长,可以选择异步执行,因为 Webdriver 不会等待其执行结果,而是直接执行下面的代码。
3. 用J avascript 实现等待页面加载的功能
public void waitForPageLoad() {
While(driver_js.executeScript(“return document.readyState” ).equals (“complete”)){
Thread.sleep(500);
}
}
这样做的缺点是,没有设定timeout时间,如果页面加载一直不能完成的话,那么代码也会一直等待。当然你也可以为while循环设定循环次数,或者直接采用下面的代码:
protected Function<WebDriver, Boolean> isPageLoaded() {
return new Function<WebDriver, Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor) driver).executeScript(“returndocument.readyState”).equals(“complete”);
}
};
}
public voidwaitForPageLoad() {
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(isPageLoaded());
}
需要指出的是单纯的 JavaScript 是很难实现等待功能的,因为 JavaScript 的执行是不阻塞主线程的,你可以为指定代码的执行设定等待时间,但是却无法达到为其它 WebDriver 代码设定等待时间的目的。有兴趣的同学可以研究一下。
4. Javascrpt 模拟点击操作,并触发相应事件
String js =”$(\”button.ui-multiselect.ui-widget\”).trigger(\”focus\”);”
+”$(\”button.ui-multiselect.ui-widget\”).click();”
+”$(\”button.ui-multiselect.ui-widget\”).trigger(\”open\”);”;
((JavascriptExecutor)driver).executeScript( js);
5. Javacript scrollbar 的操作
String js =”var obj = document.getElementsById(\“div_scroll\”);”
+”obj.scrollTop= obj.scrollHeight/2;”
((JavascriptExecutor)driver).executeScript(js);
6. Javascript 重写 confirm
String js =”window.confirm = function(msg){ return true;}”
((JavascriptExecutor)driver).executeScript( js);
通过执行上面的 js, 该页面上所有的 confirm 将都不再弹出。
7. 动态载入 jquery
并不是所有的网页都引入了 Jquery ,如果我们要在这些网页上执行 Jquery 代码,就必须动态加载 Jquery source文件
driver.get(“file:///C:/test.html”);
boolean flag =(boolean)(driver_js).executeScript(“return typeof jQuery ==’undefined'”);
if (flag)
{
driver_js.executeScript(“var jq =document.createElement(‘script’);”
+ “jq.type =’text/javascript’; ”
+”jq.src =’http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js’;”
+”document.getElementsByTagName(‘head’)[0].appendChild(jq);”);
Thread.sleep(3000);
}
waiter.waitForPageLoad();
driver_js.executeScript(“$(\”input#testid\”).val(\”test\”);”);
8. 判断元素是否存在
可以通过下面的办法来判断页面元素是否存在,但是缺点就是如果元素不存在,必须在抛出 exception后 才能知道,所以会消耗一定的时间(需要超时后才会抛出异常)。
boolean ElementExist(By Locator){
try{
driver.findElement(Locator);
return true;
}
catch(org.openqa.selenium.NoSuchElementException ex)
{
return false;
}
}
也许我们可以在 JavaScript 中判断页面元素是否存在,然后再将结果返回给 Webdriver 的 Java 代码。
- 页面元素
String js =” if(document.getElementById(“XXX”)){ return true; } else{ return false; }”
String result = ((JavascriptExecutor)driver).executeScript(js);
或者
- 表单元素
String js =” if(document.theForm.###){return true; } else{ return false; }”
String result = ((JavascriptExecutor)driver).executeScript(js);
9. 结尾
JavaScript 在 WebDriver 中还可以做很多事情,但这还不是全部。比如,我们是否可以编写代码来监视在整个 Webdrvier 测试代码运行过程是否产生过 JavaScriptError 呢,答案是肯定的,有兴趣的同学可以深入研究一下。