Selenium 中与 WebElement 交互的最佳等待策略是什么
What is the best wait strategy in Selenium for interacting with a WebElement
我刚开始为新的 WebApplication 实施一些 UI 测试,我注意到有时在等待元素存在时测试会失败,而在等待元素可见时相同的测试会成功。
所以我的问题是,网络元素变成 "existing"、"clickable"、"visible"、"displayed" 等是否有固定的顺序,或者这完全取决于关于开发人员如何实现网页或用于实现应用程序的 JS 框架?
这完全取决于页面的编写方式。
Web 元素不会从一种状态演变为另一种状态。它可能会更改,但由于某些动态内容、在页面上执行的操作等。
这些状态告诉我们什么:
- 现有 - 当元素在页面中时 DOM。它不一定必须是可见的或可交互的。这是基本状态,因为元素不能有其他状态,没有存在。使用
driver.FindElement(By.Xpath(".//*"))
将找到页面上的所有元素。
- 显示 - 当元素存在时它可能是可见的。使用
IWebElement.Displayed
(C# 语法)检查元素是否显示。
- 可点击 - 有时当您尝试点击该元素时,可能会抛出异常,表示点击其他内容。要处理这些问题,请参阅 this answer。
如何判断元素是否存在?如果你只是在搜索元素,当找不到元素时,它会抛出异常。我建议使用 WebDriverWait 来查找元素,在一定时间段内处理加载:
Wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSecond));
Wait.Until(d => d.FindElement(by));
准确地说, can deal with 3 distinct states of a WebElement with in the HTML DOM:
- 元素存在,即存在。
- 元素可见。
- 元素是互动/可点击。
老实说,您不必跟踪网络元素变为 existing、clickable、[=36 的顺序=]可见、显示等
如果您的用例是验证任何元素的存在,您需要引入WebDriverWait setting the ExpectedConditions as ElementExists()
这是检查元素是否存在的期望出现在页面的 DOM 上。这并不一定意味着该元素是可见的。所以有效的代码行将是:
IWebElement element = new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.ElementExists(By.CssSelector("element_cssSelector")));
如果您的用例是提取任何元素的任何属性,您需要引入WebDriverWait setting the ExpectedConditions as ElementIsVisible(locator)
,这是检查元素是否存在的期望出现在页面的 DOM 上并且可见。可见性意味着该元素不仅被显示而且具有大于 0 的高度和宽度。因此在您的用例中有效的代码行将是:
IWebElement element = new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.ElementIsVisible(By.ClassName("element_classname")));
如果您的用例要在任何需要引入 WebDriverWait setting the ExpectedConditions as ElementToBeClickable()
的元素上调用 click()
,这是检查的期望一个元素可见并启用,以便您可以单击它。因此,在您的用例中,有效的代码行将是:
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("element_xpath"))).Click();
我刚开始为新的 WebApplication 实施一些 UI 测试,我注意到有时在等待元素存在时测试会失败,而在等待元素可见时相同的测试会成功。
所以我的问题是,网络元素变成 "existing"、"clickable"、"visible"、"displayed" 等是否有固定的顺序,或者这完全取决于关于开发人员如何实现网页或用于实现应用程序的 JS 框架?
这完全取决于页面的编写方式。 Web 元素不会从一种状态演变为另一种状态。它可能会更改,但由于某些动态内容、在页面上执行的操作等。
这些状态告诉我们什么:
- 现有 - 当元素在页面中时 DOM。它不一定必须是可见的或可交互的。这是基本状态,因为元素不能有其他状态,没有存在。使用
driver.FindElement(By.Xpath(".//*"))
将找到页面上的所有元素。 - 显示 - 当元素存在时它可能是可见的。使用
IWebElement.Displayed
(C# 语法)检查元素是否显示。 - 可点击 - 有时当您尝试点击该元素时,可能会抛出异常,表示点击其他内容。要处理这些问题,请参阅 this answer。
如何判断元素是否存在?如果你只是在搜索元素,当找不到元素时,它会抛出异常。我建议使用 WebDriverWait 来查找元素,在一定时间段内处理加载:
Wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSecond));
Wait.Until(d => d.FindElement(by));
准确地说,
- 元素存在,即存在。
- 元素可见。
- 元素是互动/可点击。
老实说,您不必跟踪网络元素变为 existing、clickable、[=36 的顺序=]可见、显示等
如果您的用例是验证任何元素的存在,您需要引入WebDriverWait setting the ExpectedConditions as
ElementExists()
这是检查元素是否存在的期望出现在页面的 DOM 上。这并不一定意味着该元素是可见的。所以有效的代码行将是:IWebElement element = new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.ElementExists(By.CssSelector("element_cssSelector")));
如果您的用例是提取任何元素的任何属性,您需要引入WebDriverWait setting the ExpectedConditions as
ElementIsVisible(locator)
,这是检查元素是否存在的期望出现在页面的 DOM 上并且可见。可见性意味着该元素不仅被显示而且具有大于 0 的高度和宽度。因此在您的用例中有效的代码行将是:IWebElement element = new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.ElementIsVisible(By.ClassName("element_classname")));
如果您的用例要在任何需要引入 WebDriverWait setting the ExpectedConditions as
ElementToBeClickable()
的元素上调用click()
,这是检查的期望一个元素可见并启用,以便您可以单击它。因此,在您的用例中,有效的代码行将是:new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("element_xpath"))).Click();