如何从Selenium Webdriver获取异步Javascript响应

use*_*517 7 javascript python selenium asynchronous webdriver

我们在我们的网站上添加了一个异步的javascript调用.我正试图让Selenium Webdriver等待来电的响应.

听众看起来像这样:

$(document).on("application:subapp:rendered", function(){console.log("foo");});
Run Code Online (Sandbox Code Playgroud)

我的webdriver代码(python):

driver.set_script_timeout(30)
response =  driver.execute_async_script("$(document).on(\"application:subapp:rendered\", function(){return \"foo\";});"
Run Code Online (Sandbox Code Playgroud)

接下来我执行页面应该让"foo"返回

不过这是我的回答......

TimeoutException:消息:异步脚本超时:结果未在30秒内接收(会话信息:chrome = 41.0.2272.118)(驱动程序信息:chromedriver = 2.11.298604(75ea2fdb5c87f133a8e1b8da16f6091fb7d532 1e),platform = Windows NT 6.1 SP1 x86_64)

Lou*_*uis 9

当你调用时execute_async_script,Selenium作为JavaScript代码的最后一个参数传递你必须调用的回调,表明异步代码已经完成执行,如果你在调用脚本后没有传递参数execute_async_script,那么这将arguments[0]在JavaScript的.无论你传递给这个回调的价值是什么,你execute_async_script将返回如此:

response = driver.execute_async_script("""
    var done = arguments[0];
    $(document).one("application:subapp:rendered", 
        function(){
           done("foo");
    });
""")
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我将回调分配给done.这就是我喜欢的方式.注意如何response通过调用设置要设置的值done("foo").

还要注意我使用.one()而不是.on().我发现Selenium(至少高达2.45)并不认为创建的旧回调execute_async_script是"过时的"所以如果你的JavaScript在上面的JavaScript完成执行后有可能再次发生,那么它将会再次呼叫回叫,Selenium将再次接听电话.如果你碰巧execute_async_script在那个时候正在运行另一个,那么这个虚假的调用将终止你的另一个 execute_async_script调用,返回值为"foo".我在我的一个测试套件中发生过这种情况.这导致了非常奇怪的失败.


ale*_*cxe 2

用作arguments[0]回调:

driver.execute_async_script("""
    $(document).on('application:subapp:rendered', arguments[0]);
""")
Run Code Online (Sandbox Code Playgroud)

另请参阅(应该有助于理解):