WebDriver executeAsyncScript vs executeScript

vis*_*art 34 javascript testing selenium qa webdriver

executeAsyncScript和executeScript有什么区别?我如何使用window.onload等事件?我试过这样的事

((JavascriptExecutor) driver).executeAsyncScript("window.onload = function() {alert('Hello')}"); 
Run Code Online (Sandbox Code Playgroud)

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

eug*_*kov 24

我用executeScript.示例提供:

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

关于警报的细节,已知问题.你可以在这里获得细节

根据文件的不同之处是:

executeScript

public java.lang.Object executeScript(java.lang.String script,
                             java.lang.Object... args)
Run Code Online (Sandbox Code Playgroud)

从界面复制的说明:JavascriptExecutor 在当前选定的框架或窗口的上下文中执行JavaScript.提供的脚本片段将作为匿名函数的主体执行.在脚本中,使用document来引用当前文档.请注意,一旦脚本执行完毕,局部变量将不可用,但全局变量将保持不变.如果脚本具有返回值(即,如果脚本包含return语句),则将执行以下步骤:

  • 对于HTML元素,此方法返回WebElement
  • 对于小数,返回Double
  • 对于非十进制数,返回Long
  • 对于布尔值,返回一个布尔值
  • 对于所有其他情况,返回String.
  • 对于数组,按照上述规则返回每个对象的List.我们支持嵌套列表.
  • 除非值为null或没有返回值,否则返回null

参数必须是数字,布尔值,字符串,WebElement或上述任意组合的列表.如果参数不符合这些条件,则抛出异常.参数将通过"arguments"魔术变量提供给JavaScript,就像通过"Function.apply"调用该函数一样

指定者:接口JavascriptExecutor中的executeScript参数:script - 要执行的JavaScript args - 脚本的参数.可能为空返回:Boolean,Long,String,List或WebElement之一.或者为null.

executeAsyncScript

public java.lang.Object executeAsyncScript(java.lang.String script,
                                  java.lang.Object... args)
Run Code Online (Sandbox Code Playgroud)

从接口复制的描述: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));  
Run Code Online (Sandbox Code Playgroud)

示例#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");
Run Code Online (Sandbox Code Playgroud)

示例#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"));
Run Code Online (Sandbox Code Playgroud)

脚本参数必须是数字,布尔值,字符串,WebElement或上述任意组合的列表.如果参数不符合这些条件,则抛出异常.参数将通过"arguments"变量提供给JavaScript.

指定者:接口JavascriptExecutor中的executeAsyncScript参数:script - 要执行的JavaScript.args - 脚本的参数.可能是空的.返回:Boolean,Long,String,List,WebElement或null之一.

详细文档在这里

  • 上面的"描述"(从界面文档中复制)和链接到的文档已过时."对象"列表将作为List <Map <String,Object >>返回.其中,每个键都是对象的属性.我不知道如何得到这方面的任何细节,但我读完之后就被烧了所以我以为我会做出贡献. (6认同)

use*_*740 24

(保持简单,正确.)

execteScript和之间的相关区别executeAsyncScript是:

调用的函数executeAsyncScript将'done callback'作为最后一个参数,必须调用该函数来表示脚本已完成执行.

这允许它与仅在使用回调时"完成"的代码一起使用 - 例如.setTimeout或异步XHR.如果未在超时限制内调用"完成回调",则将拒绝返回的承诺.

与使用#executeScript执行同步JavaScript不同,使用[#executeAsyncScript]执行的脚本必须通过调用提供的回调明确表示它们已完成.这个回调将始终作为最后一个参数注入到执行的函数中.

也就是说,两个函数都会阻止WebDriver控制流,直到它们完成为止 - 要么运行代码结束,executeScript要么在调用'完成回调'时executeAsyncScript:名称中的"async"表示使用的信号机制,并不意味着/暗示JavaScript代码实际上是相对于WebDriver异步执行的.


sph*_*air 8

这些之间的主要区别在于,使用async执行的脚本必须通过调用提供的回调明确表示它们已完成.此回调始终作为最后一个参数注入到执行的函数中.