我知道我可以使用Selenium 2的webdriver来运行JavaScript并获得返回值,但是发生了很多异步事情我想让JavaScript与Selenium交谈,而不是相反。我做了一些搜索,但没有找到这样的东西。人们通常只使用implicitly_wait
吗?这似乎很可能失败,因为不可能计时一切?完美的例子是让Selenium知道XHR何时完成或者是一个执行时间不确定的异步动画。
这可能吗?我们在Saucelabs上使用Selenium 2和Python。
答案 0 :(得分:8)
您应该查看execute_async_script()方法(Java中的JavascriptExecutor.executeAsyncScript,.NET中的IJavaScriptExecutor.ExecuteAsyncScript()),它允许您等待回调函数。回调函数会自动附加到JavaScript函数中的arguments
数组中。因此,假设您已经在页面上有一个等待所需条件的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()函数的更多信息,并可以在项目源代码树中找到此示例代码。在this file的测试中等待XHR完成的一个很好的例子。
如果在可用于SauceLabs的Python绑定版本中尚未提供此功能,我希望它不久可用。不可否认,从某种意义上说,这是将测试用例中的“所需状态轮询”推向JavaScript,但它会使您的测试更具可读性。
答案 1 :(得分:3)
理论上它是可能的,但我会反对它。
该解决方案可能会在网站上运行一些jQuery,在JavaScript处理完成后将变量设置为true。
将selenium设置为循环遍历getEval,直到此变量变为true,然后在Selenium中执行某些操作。
它会满足您的要求,但这是一个非常糟糕的主意。如果由于某种原因你的jQuery没有将触发变量设置为true(或者你期望的任何状态),Selenium将会无限期地坐在那里。你可以在它上面放一个很长的超时,但是那么让Selenium做一个getEval并等待一个特定的元素出现会有什么不同呢?
听起来你正试图过度使用你的解决方案,它会让你在未来更加痛苦,只会带来额外的好处。
答案 2 :(得分:2)
不要过于直率,但如果你想让你的App与你的测试跑步者交谈,那么你做错了。
如果您需要等待XHR完成,您可以尝试显示微调器,然后测试微调器已消失以指示请求成功。
关于动画,当动画完成时,它的回调可能会添加一个表示动画已完成的类,然后你可以测试该类是否存在。
答案 3 :(得分:1)
使用selenium测试动画正在打开一堆蠕虫。测试可能非常脆弱并导致许多误报。
问题是这些调用是异步的,很难跟踪行为和页面状态的变化。
根据我的经验,异步调用可以非常快,以至于从不显示微调器,并且页面的状态可以完全跳过一个状态(Selenium可以检测到)。
等待页面状态转换可以使测试不那么脆弱,但是误报不能完全消除。
我建议手动测试动画。