webdriver的executeAsyncScript VS executeScript(WebD

2019-07-03 23:23发布

是什么executeAsyncScript和executeScript之间的区别? 如何使用事件,例如在window.onload? 我想是这样的

((JavascriptExecutor) driver).executeAsyncScript("window.onload = function() {alert('Hello')}"); 

当然,它没有工作。所以,如果有人知道它是如何工作的,请写一个例子

Answer 1:

I use executeScript. Example provided:

String cssSelector="...blablabla...";
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("document.getElementById(\'"+cssSelector +"\').click();");
js.executeScript(stringBuilder.toString());

Concerning details on alerts there is known issue. you can get details here

In accordance with documentation difference is:

executeScript

public java.lang.Object executeScript(java.lang.String script,
                             java.lang.Object... args)

Description copied from interface: JavascriptExecutor Executes JavaScript in the context of the currently selected frame or window. The script fragment provided will be executed as the body of an anonymous function. Within the script, use document to refer to the current document. Note that local variables will not be available once the script has finished executing, though global variables will persist. If the script has a return value (i.e. if the script contains a return statement), then the following steps will be taken:

  • For an HTML element, this method returns a WebElement
  • For a decimal, a Double is returned
  • For a non-decimal number, a Long is returned
  • For a boolean, a Boolean is returned
  • For all other cases, a String is returned.
  • For an array, return a List with each object following the rules above. We support nested lists.
  • Unless the value is null or there is no return value, in which null is returned

Arguments must be a number, a boolean, a String, WebElement, or a List of any combination of the above. An exception will be thrown if the arguments do not meet these criteria. The arguments will be made available to the JavaScript via the "arguments" magic variable, as if the function were called via "Function.apply"

Specified by: executeScript in interface JavascriptExecutor Parameters: script - The JavaScript to execute args - The arguments to the script. May be empty Returns: One of Boolean, Long, String, List or WebElement. Or null.

executeAsyncScript

public java.lang.Object executeAsyncScript(java.lang.String script,
                                  java.lang.Object... args)

Description copied from interface: JavascriptExecutor Execute an asynchronous piece of JavaScript in the context of the currently selected frame or window. Unlike executing synchronous JavaScript, scripts executed with this method must explicitly signal they are finished by invoking the provided callback. This callback is always injected into the executed function as the last argument. The first argument passed to the callback function will be used as the script's result. This value will be handled in the same way as the synchronous case.

Example #1: Performing a sleep in the browser under test.

 long start = System.currentTimeMillis();
   ((JavascriptExecutor) driver).executeAsyncScript(
       "window.setTimeout(arguments[arguments.length - 1], 500);");
   System.out.println(
       "Elapsed time: " + (System.currentTimeMillis() - start));  

Example #2: Synchronizing a test with an AJAX application:

 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");

Example #3: Injecting a XMLHttpRequest and waiting for the result:

 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"));

Script arguments must be a number, a boolean, a String, WebElement, or a List of any combination of the above. An exception will be thrown if the arguments do not meet these criteria. The arguments will be made available to the JavaScript via the "arguments" variable.

Specified by: executeAsyncScript in interface JavascriptExecutor Parameters: script - The JavaScript to execute. args - The arguments to the script. May be empty. Returns: One of Boolean, Long, String, List, WebElement, or null.

详细文档这里



Answer 2:

(保持简单 ,和正确的 。)

之间的相关差异execteScriptexecuteAsyncScript是这样的:

与调用的函数executeAsyncScript需要“做回调”作为最后一个参数, 必须调用以指示脚本执行完毕。

这使得它与代码中使用,当使用一个回调只是“完成” - 如。 的setTimeout或异步XHR。 如果“做回调”不叫内超时限制返回的承诺将被拒绝。

不像#executeScript执行同步的JavaScript,与[#executeAsyncScript]执行的脚本必须显式地发信号他们通过调用提供的回调结束 。 这个回调将永远被注入到执行的函数作为最后一个参数..

也就是说,直到他们完成两个功能阻止webdriver的控制流程 -无论是运行关闭代码的最后executeScript或打电话时的“完成回调” executeAsyncScript :在名为“异步”表示使用的信号机制,并不意味着/暗示的JavaScript代码实际上是相对于所述的webdriver异步地执行。



Answer 3:

那些之间的主要区别是用异步执行的脚本必须明确的信号,他们是通过调用提供的回调完成。 此回调总是注入执行功能作为最后一个参数。



Answer 4:

((JavascriptExecutor) driver).executeScript("alert('Hello');"); 

将显示警告:

((JavascriptExecutor)驱动程序).executeAsyncScript()时使用JS需要时间来执行egin Web服务调用。

window.onload确保了JS的当页面完全加载执行。



Answer 5:

我用了大量的时间来undertand这个功能终于我知道了。 follwing代码将有很大的帮助:

/**
 * 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);
    });

}


文章来源: WebDriver executeAsyncScript vs executeScript