executeAsyncScript和executeScript有什么区别?我如何使用window.onload等事件?我试过这样的事情
((JavascriptExecutor) driver).executeAsyncScript("window.onload = function() {alert('Hello')}");
但当然它不起作用...... 所以如果有人知道它是如何工作的,请写一个例子
答案 0 :(得分:24)
我使用executeScript
。提供的示例:
String cssSelector="...blablabla...";
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("document.getElementById(\'"+cssSelector +"\').click();");
js.executeScript(stringBuilder.toString());
关于警报的详细信息,已知问题。您可以获得详细信息here
根据文件的不同之处是:
<强> executeScript 强>
public java.lang.Object executeScript(java.lang.String script, java.lang.Object... args)
从界面复制的说明:JavascriptExecutor 在当前选定的框架或窗口的上下文中执行JavaScript。提供的脚本片段将作为主体执行 一个匿名函数。在脚本中,使用文档来引用 目前的文件。请注意,局部变量不可用一次 脚本已完成执行,但全局变量将执行 坚持。如果脚本具有返回值(即脚本包含的话) 返回声明),然后将采取以下步骤:
- 对于HTML元素,此方法返回WebElement
- 对于小数,返回Double
- 对于非十进制数字,返回Long
- 对于布尔值,返回布尔值
- 对于所有其他情况,返回一个String。
- 对于数组,按照上述规则返回包含每个对象的List。我们支持嵌套列表。
- 除非值为null或没有返回值,否则返回null
参数必须是数字,布尔值,字符串,WebElement或List 以上的任何组合。如果是,将抛出异常 参数不符合这些标准。这些论点将被提出 通过“arguments”魔术变量可以使用JavaScript,就好像 该函数通过“Function.apply”
调用指定者:接口JavascriptExecutor中的executeScript 参数:script - 要执行args的JavaScript - 要执行的参数 剧本。可能为空返回:Boolean,Long,String,List之一 或WebElement。或者null。
<强> executeAsyncScript 强>
public java.lang.Object executeAsyncScript(java.lang.String script, java.lang.Object... args)
从界面复制的说明:JavascriptExecutor 在当前选定的框架或窗口的上下文中执行异步JavaScript。与执行同步不同 JavaScript,使用此方法执行的脚本必须明确发出信号 它们是通过调用提供的回调来完成的。这个回调是 总是将执行函数作为最后一个参数注入。 传递给回调函数的第一个参数将被用作 脚本的结果。该值的处理方式与 同步案例。
示例#1:在被测浏览器中执行睡眠。
long start = System.currentTimeMillis(); ((JavascriptExecutor) driver).executeAsyncScript( "window.setTimeout(arguments[arguments.length - 1], 500);"); System.out.println( "Elapsed time: " + (System.currentTimeMillis() - start));
示例#2:将测试与AJAX应用程序同步:
WebElement composeButton = driver.findElement(By.id("compose-button")); composeButton.click(); ((JavascriptExecutor) driver).executeAsyncScript( "var callback = arguments[arguments.length - 1];" + "mailClient.getComposeWindowWidget().onload(callback);"); driver.switchTo().frame("composeWidget"); driver.findElement(By.id("to")).sendKeys("bog@example.com");
示例#3:注入XMLHttpRequest并等待结果:
Object response = ((JavascriptExecutor) driver).executeAsyncScript( "var callback = arguments[arguments.length - 1];" + "var xhr = new XMLHttpRequest();" + "xhr.open('GET', '/resource/data.json', true);" + "xhr.onreadystatechange = function() {" + " if (xhr.readyState == 4) {" + " callback(xhr.responseText);" + " }" + "}" + "xhr.send();"); JSONObject json = new JSONObject((String) response); assertEquals("cheese", json.getString("food"));
脚本参数必须是数字,布尔值,字符串,WebElement, 或上述任何组合的清单。将抛出异常 如果参数不符合这些标准。争论将是 通过“arguments”变量提供给JavaScript。
指定者:接口JavascriptExecutor中的executeAsyncScript 参数:script - 要执行的JavaScript。 args - 论点 到脚本。可能是空的。返回:Boolean,Long,String之一, List,WebElement或null。
详细文档为here
答案 1 :(得分:22)
(保持简单,更正。)
execteScript
和executeAsyncScript
之间的相关区别是:
使用executeAsyncScript
调用的函数需要完成回调&#39;作为最后一个参数,必须被调用以表示脚本已完成执行。
这使得它可以用于仅完成&#39;的代码。当使用回调时 - 例如setTimeout或异步XHR。如果完成回调&#39;在超时限制内未调用返回的承诺将被拒绝。
与使用#executeScript执行同步JavaScript不同,使用[#executeAsyncScript] 执行的脚本必须通过调用提供的回调明确表示它们已完成。这个回调将始终作为最后一个参数注入到执行的函数中。
也就是说, 这两个函数都会阻止WebDriver控制流 ,直到它们完成 - 运行executeScript
的代码末尾或调用& #39;完成回调&#39;与executeAsyncScript
:&#34; async&#34;在名称中表示使用的信号机制,并不表示/暗示JavaScript代码实际上是相对于WebDriver异步执行的。
答案 2 :(得分:8)
这些之间的主要区别在于,使用async执行的脚本必须通过调用提供的回调明确表示它们已完成。这个回调总是作为最后一个参数注入到执行的函数中。
答案 3 :(得分:2)
((JavascriptExecutor) driver).executeScript("alert('Hello');");
将显示警告:
((JavascriptExecutor)驱动程序)当JS花费时间执行例如Web服务调用时,使用.executeAsyncScript()。
window.onload
确保在页面完全加载时执行JS。
答案 4 :(得分:2)
我花了很多时间来完成这个功能,最后我得到了它。以下代码将有很多帮助:
/**
* executeAsyncScript document mentioned callback is a browser intrinsic function for returning deferred value (e.g 123 in example) from
* js environment to Java environment
*
*/
@Test
public void testAsyncScript() {
webDriver.manage().timeouts().setScriptTimeout(1, TimeUnit.SECONDS);
Integer a = 23;
TestUtil.elapse("first", () -> {
Object value = getJsExecutor().executeAsyncScript("window.setTimeout(arguments[arguments.length - 1](123), 500);", a);
// following code should be executed after 500ms timeout
System.out.println("a is " + a); // a has nothing to do with the documented "callback"
assertEquals(123, value);
});
}
答案 5 :(得分:0)
这个简单的Async脚本侦听在DOM上单击的元素,并通过回调解析 executeAsyncScript
var clicked_element = await driver.executeAsyncScript('var callback=arguments[arguments.length - 1]; window.document.addEventListener("click", function(e){ var element = event.srcElement ||event.target; callback(element); });');