【问题标题】:Selenium async script in own thread blocks other scripts自己线程中的 Selenium 异步脚本会阻止其他脚本
【发布时间】:2016-08-31 08:55:08
【问题描述】:

我有这种情况:

必须在浏览器中执行不同的脚本。其中之一是将消息从一个浏览器发送到另一个浏览器(WebRTC)。我想测量每个操作的延迟,特别是发送消息。

为了实现这一点,我为每个执行脚本的 selenium 驱动程序创建了一个自己的线程。此外,我创建了 another 线程,该线程正在等待消息从其他浏览器到达观察到的浏览器。等待消息的线程执行如下异步脚本:

String message = (String) ((JavascriptExecutor) driver).executeAsyncScript(
 "window.receivedMessage = function(message_id){" +
                                  "arguments[arguments.length - 1](message_id);" +
                           "}");

如您所见,如果浏览器收到消息,我正在等待调用的回调。

不幸的是,这会阻止我在浏览器中注册此异步脚本后要执行的所有其他脚本(不管是 .executeScript() 还是 .executeAsyncScript() )。

是否有人知道如何不断等待消息到达并使用 webdriver 执行其他脚本?

编辑

顺便说一句:忙着等待不应该是解决办法。我更喜欢以某种方式通知 selenium 操作已完成的方法,而无需不断地从驱动程序轮询结果。

【问题讨论】:

  • 您是否有任何选项来验证浏览器 UI 上是否已收到消息?
  • @QVSJ 你的意思是我是否有权访问接收消息的浏览器?是的。我也可以修改浏览器的代码。
  • 你找到解决这个问题的方法了吗@firsti
  • @Seraph 抱歉回复晚了。我将设置更改为使用外部消息记录服务器。在程序结束时,我只收集发送时间戳和接收时间戳之间的差异。 Selenium 在浏览器中执行脚本时不支持多线程。

标签: javascript java multithreading selenium asynchronous


【解决方案1】:

一种方法是将消息存储在全局变量中,并在其他脚本执行后处理它们。这是一个例子:

JavascriptExecutor js = (JavascriptExecutor)driver;
driver.manage().timeouts().setScriptTimeout(20, TimeUnit.SECONDS);

// set a listener for the messages
js.executeScript(
    "window._asyncResult = [];                        " +
    "window.receivedMessage = function(message_id) {  " +
    "  window._asyncResult.push(message_id);          " +
    "};                                               " );

// send a message asynchroniously every second
js.executeScript(
    "window._asyncTimer = setInterval(function(){     " +
    "  window.receivedMessage(Math.random());         " +
    "}, 1000);                                        " );

// wait for 5 messages and return the list
List messages = (ArrayList)js.executeAsyncScript(
    "var callback = arguments[arguments.length - 1];  " +
    "(function fn(){                                  " +
    "  if(window._asyncResult.length > 5) {           " +
    "    clearInterval(window._asyncTimer);           " +
    "    return callback(window._asyncResult);        " +
    "  }                                              " +
    "  setTimeout(fn, 30);                            " +
    "})();                                            " );

【讨论】:

  • 感谢您的回答,但我认为这对我不起作用。我已经尝试过了,脚本仍然被 AsyncScript 阻止。问题主要是似乎两个脚本无法与驱动程序并行执行。即使其中一个是 AsyncScript 并且只是一个等待调用的函数。在执行以下脚本之前,驱动程序似乎仍在等待回调。
猜你喜欢
  • 1970-01-01
  • 2013-11-10
  • 1970-01-01
  • 2013-11-05
  • 2012-05-27
  • 2015-11-01
  • 2021-07-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多