如何以及何时实现 Selenium WebDriver 的刷新(ExpectedCondition<T> 条件)?

How and when to implement refreshed(ExpectedCondition<T> condition) of Selenium WebDriver?

我正在研究 ExpectedCondtions class 的方法并找到了一种方法:refreshed

我可以理解,当你得到 StaleElementReferenceException 并且你想再次检索该元素时可以使用该方法,这样可以避免 StaleElementReferenceException

我上面的理解可能不正确,所以我想确认一下:

  1. 什么时候应该使用refreshed
  2. 以下代码的 something 部分的代码应该是什么:

wait.until(ExpectedConditions.refreshed(**something**));

有人可以举例说明吗?

根据消息来源:

Wrapper for a condition, which allows for elements to update by redrawing. This works around the problem of conditions which have two parts: find an element and then check for some condition on it. For these conditions it is possible that an element is located and then subsequently it is redrawn on the client. When this happens a {@link StaleElementReferenceException} is thrown when the second part of the condition is checked.

基本上,这是一个等待 DOM 操作完成对象的方法。

通常,当您执行 driver.findElement 时,该对象表示该对象是什么。

当 DOM 被操作时,并在单击按钮后说,向该元素添加一个 class。如果您尝试对所述元素执行操作,它将抛出 StaleElementReferenceException 因为现在返回的 WebElement 不代表更新的元素。

当您期望 DOM 操作发生时,您将使用 refreshed,并且您想等到它在 DOM 中完成操作。

示例:

<body>
  <button id="myBtn" class="" onmouseover="this.class = \"hovered\";" />
</body>

// pseudo-code
1. WebElement button = driver.findElement(By.id("myBtn")); // right now, if you read the Class, it will return ""
2. button.hoverOver(); // now the class will be "hovered"
3. wait.until(ExpectedConditions.refreshed(button));
4. button = driver.findElement(By.id("myBtn")); // by this point, the DOM manipulation should have finished since we used refreshed.
5. button.getClass();  // will now == "hovered"

请注意,如果您在第 3 行执行 button.click(),它将抛出 StaleReferenceException,因为此时已对 DOM 进行了操作。

在我使用 Selenium 的这些年里,我从来没有使用过这种情况,所以我相信这是一种“边缘情况”情况,您很可能甚至不必担心使用。希望这对您有所帮助!

refreshed 方法在尝试访问新刷新的搜索结果时对我很有帮助。试图通过 ExpectedConditions.elementToBeClickable(...) returns StaleElementReferenceException 等待搜索结果。为了解决这个问题,这是一个辅助方法,它会等待并重试最多 30 秒,以便刷新和可点击搜索元素。

public WebElement waitForElementToBeRefreshedAndClickable(WebDriver driver, By by) {
    return new WebDriverWait(driver, 30)
            .until(ExpectedConditions.refreshed(
                    ExpectedConditions.elementToBeClickable(by)));
}

然后点击搜索后的结果:

waitForElementToBeRefreshedAndClickable(driver, By.cssSelector("css_selector_to_search_result_link")).click();

希望这对其他人有所帮助。