8

我知道我可以让 Selenium 2 的 webdriver 运行 JavaScript 并获取返回值,但是发生了太多异步的事情,我希望 JavaScript 与 Selenium 对话,而不是反过来。我做了一些搜索,但没有找到类似的东西。人们通常使用implicitly_wait吗?这似乎可能会失败,因为不可能为所有事情计时?完美的例子是让 Selenium 知道 XHR 何时完成或执行时间不确定的异步动画。

这可能吗?我们在 Saucelabs 上使用 Selenium 2 和 Python。

4

4 回答 4

8

您应该查看 execute_async_script() 方法(Java 中的 JavascriptExecutor.executeAsyncScript,.NET 中的 IJavaScriptExecutor.ExecuteAsyncScript()),它允许您等待回调函数。回调函数会自动附加到argumentsJavaScript 函数中的数组。因此,假设您的页面上已经有一个 JavaScript 函数等待您想要的条件,您可以执行以下操作(下面的 Java 代码,C# 和 Python 代码应该相似):

String script = "var callback = arguments[arguments.length - 1];"
    + "callback(myJavaScriptFunctionThatWaitsUntilReady());";

driver.manage().timeouts().setScriptTimeout(15, TimeUnit.SECONDS);
((JavascriptExecutor)driver).executeAsyncScript(script);

可能会更聪明,将回调函数直接传递给返回正确数据的事件。您可以在项目JavaDocs中找到有关 executeAsyncScript() 函数的更多信息,并且可以在项目源代码树中找到这方面的示例代码。在此文件中的测试中有一个很好的示例,即等待 XHR 完成。

如果这在可用于 SauceLabs 的 Python 绑定版本中尚不可用,我希望它很快就会可用。诚然,从某种意义上说,这是将测试用例中的“期望状态轮询”推送到 JavaScript 中,但它会使您的测试更具可读性。

于 2011-04-13T19:18:05.413 回答
3

理论上这是可能的,但我建议不要这样做。

该解决方案可能会在站点上运行一些 jQuery,当 JavaScript 处理完成时将变量设置为 true。

将 selenium 设置为循环通过 getEval 直到此变量变为 true,然后在 Selenium 中执行某些操作。

它会满足您的要求,但这是一个非常糟糕的主意。如果由于某种原因您的 jQuery 没有将触发器变量设置为 true(或您期望的任何状态),Selenium 将无限期地坐在那里。您可以对其设置很长的超时时间,但是让 Selenium 执行 getEval 并等待特定元素出现会有什么不同?

听起来你正试图过度设计你的解决方案,这将在未来给你带来更多的痛苦,而且几乎没有额外的好处。

于 2011-04-11T21:43:18.690 回答
2

不要过于直率,但如果您希望您的应用程序与您的测试运行程序对话,那么您做错了。

如果您需要等待 XHR 完成,您可以尝试显示微调器,然后测试微调器是否消失以指示请求成功。

关于动画,当动画完成时,它的回调可能会添加一个表示动画已经完成的类,然后您可以测试该类是否存在。

于 2011-04-08T20:03:52.457 回答
0

用 selenium 测试动画就是打开一罐蠕虫。测试可能非常脆弱并导致许多误报。

问题是调用是异步的,并且难以跟踪页面的行为和状态变化。

根据我的经验,异步调用可能非常快,以至于永远不会显示微调器,并且页面的状态可能会完全跳过一个状态(Selenium 可以检测到)。

等待页面状态转换可以使测试不那么脆弱,但是不能完全消除误报。

我建议对动画进行手动测试。

于 2013-04-16T23:25:54.773 回答