Selenium WebDriver:等待加载带有 JavaScript 的复杂页面

新手上路,请多包涵

我有一个 Web 应用程序要使用 Selenium 进行测试。有很多 JavaScript 在页面加载时运行。

这段 JavaScript 代码写得不太好,但我无法更改任何内容。因此,使用 findElement() 方法等待元素出现在 DOM 中不是一种选择。

我想在 Java 中创建一个通用函数来等待页面加载,一个可能的解决方案是:

  • 从 WebDriver 运行 JavaScript 脚本并将 document.body.innerHTML 的结果存储在字符串变量 body 中。
  • body 变量与之前版本的 body 进行比较。如果它们相同,则设置递增计数器 notChangedCount 否则设置 notChangedCount 为零。
  • 稍等片刻(例如 50 毫秒)。
  • 如果页面在一段时间内(例如 500 毫秒)没有更改,那么 notChangedCount >= 10 然后退出循环,否则循环到第一步。

你认为这是一个有效的解决方案吗?

原文由 psadac 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 984
2 个回答

如果有人真的知道一个普遍且始终适用的答案,那么它早就在 各个地方 实施了,并且会让我们的生活变得更加轻松。

您可以做很多事情,但每件事都有一个问题:

  1. 正如 Ashwin Prabhu 所说,如果您非常了解脚本,则可以观察其行为并跟踪其在 windowdocument 等上的一些变量。但是,此解决方案并不适合所有人并且只能由您使用,并且只能在一组有限的页面上使用。

  2. 通过观察 HTML 代码以及它是否有一段时间未更改的解决方案还不错(还有 一种方法 可以直接通过 WebDriver 获取原始和未编辑的 HTML),但:

    • 实际断言页面需要很长时间,并且可能会显着延长测试时间。
    • 你永远不知道正确的间隔是多少。该脚本 可能 正在下载需要超过 500 毫秒的大文件。我们公司的内部页面有几个脚本,在IE中需要几秒。您的计算机可能暂时缺乏资源 - 假设杀毒软件将使您的 CPU 充分工作,那么即使对于不复杂的脚本,500 毫秒也可能太短了。
    • 有些脚本永远不会完成。他们以一些延迟调用自己 ( setTimeout() ) 并一次又一次地工作,并且可能在每次运行时更改 HTML。说真的,每个“Web 2.0”页面都这样做。甚至堆栈溢出。您可以覆盖最常用的方法并将使用它们的脚本视为已完成,但是……您不能确定。
    • 如果脚本除了更改 HTML 之外还做了其他事情怎么办?它可以做成千上万的事情,而不仅仅是一些 innerHTML 乐趣。
  3. 有一些工具可以帮助您解决这个问题。即 Progress Listeners 以及 nsIWebProgressListener 和其他一些。然而,浏览器对此的支持非常糟糕。 Firefox从FF4开始尝试支持(还在进化中),IE在IE9已经基本支持。

而且我想我很快就会想出另一个有缺陷的解决方案。事实是——对于什么时候说“现在页面已经完成”没有明确的答案,因为永久的脚本在做他们的工作。选择最适合你的,但要注意它的缺点。

原文由 Petr Janeček 发布,翻译遵循 CC BY-SA 3.0 许可协议

谢谢阿什温!

就我而言,我需要等待某个元素中的 jquery 插件执行。特别是“qtip”

根据您的提示,它对我来说非常有效:

 wait.until( new Predicate<WebDriver>() {
            public boolean apply(WebDriver driver) {
                return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
            }
        }
    );

注意:我使用的是 Webdriver 2

原文由 Eduardo Fabricio 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题