C# Selenium WebDriver - 等待未完成的 HTTP 请求的解决方案

问题描述

背景

在编写前端测试时,我们通常需要等到 Web 应用程序完成获取数据和更新 DOM 之后,才能与页面进行交互。使用 Selenium C#,这意味着对针对特定场景定制的页面状态进行大量显式等待(可能等待加载指示器或特定元素出现)。然而,大多数情况下,这个视觉指示器只是一个像 HTTP 请求这样的异步任务的代理。其他解决方案如 ProtractorCypress 有等待 HTTP 请求的简单解决方案(这是 Protractor 中的认设置)。

问题

我维护的一个框架是用 C# 编写的,我试图找到一种解决方案来轻松等待任何未完成的 HTTP 请求,而不是针对 DOM 编写自定义的显式等待。有解决方案吗?如果需要,我愿意使用其他开源解决方案。

我假设我可能需要设置一个代理,以便我可以操作和连接到 HTTP 请求。我查看了 BrowserUpBrowserMobProxy 项目的延续,似乎不再维护),但无法从文档中判断此类用例是否可能或有意。

解决方法

我记得几年前试图用 Ruby 解决这个问题。我们决定采用 JavaScript 和 Ruby 混合解决方案。每次发送 Ajax 请求时,我们都会将全局 JavaScript 变量设置为 true。当所有待处理的请求完成后,我们将其设置为 false。我们仍然有不稳定的测试。即使在幕后进行了一些 JavaScript 体操,它们也很脆弱且不一致。

即使 Ajax(或后台 HTTP 请求)可能已经完成,JavaScript 仍然需要额外的处理时间来处理响应。这只是几毫秒,但请记住,Selenium 和您的浏览器在不同的线程中运行——一切都是竞争条件。由于 HTTP 请求已完成,我们不断收到间歇性测试失败,但当 Selenium 尝试与请求完成后应该出现在屏幕上的元素进行交互时,浏览器仍在评估 element.innerHTML = response.responseText。我们仍然必须使用显式等待。

基本上,为了实现稳定的测试,您不得不使用显式等待。多年来,我已经跳过了很多 圈子以使事情以任何其他方式工作。我发现的唯一可取之处是 Page Object Model Pattern,它至少将这些丑陋的代码集中在任何特定用例的一个地方。

所以,是的。代码很丑。您需要使用显式等待。事实证明,测试代码需要与其测试的应用程序代码一样有针对性地构建。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...