是的,如果您在使用 StaleElementReferenceException 时遇到问题,那是因为存在争用条件。请考虑以下情形:
WebElement element = driver.findElement(By.id("foo"));
// DOM changes - page is refreshed, or element is removed and re-added
element.click();
现在,在您单击元素时,元素引用不再有效。WebDriver几乎不可能对所有可能发生这种情况的情况做出很好的猜测 - 所以它举起手来并给你控制权,作为测试/应用程序作者,他们应该确切地知道可能发生或可能不会发生的事情。您要做的是明确地等待DOM处于您知道事情不会改变的状态。例如,使用 WebDriverWait 等待特定元素存在:
// times out after 5 seconds
WebDriverWait wait = new WebDriverWait(driver, 5);
// while the following loop runs, the DOM changes -
// page is refreshed, or element is removed and re-added
wait.until(presenceOfElementLocated(By.id("container-element")));
// now we're good - let's click the element
driver.findElement(By.id("foo")).click();
PresenceOfElementLocated() 方法将如下所示:
private static Function<WebDriver,WebElement> presenceOfElementLocated(final By locator) {
return new Function<WebDriver, WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
};
}
你对当前的Chrome驱动程序非常不稳定的说法是正确的,你会很高兴听到Selenium主干有一个重写的Chrome驱动程序,其中大部分实现都是由Chromium开发人员完成的,作为他们树的一部分。
或者,您可以启用隐式等待,而不是像上面示例中那样显式等待 - 这样WebDriver将始终循环,直到指定的超时等待元素出现:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS)
然而,根据我的经验,明确等待总是更可靠。