Так, якщо у вас проблеми зі StaleElementReferenceExceptions, це тому, що ваші тести погано написані. Це умова гонки. Розглянемо наступний сценарій:
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();
Метод присутностіOfElementLocated () виглядатиме приблизно так:
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 як частина свого дерева.
PS. Крім того, замість того, щоб чекати явно, як у наведеному вище прикладі, ви можете ввімкнути неявні очікування - таким чином WebDriver завжди буде циклічно закінчуватися до вказаного часу очікування очікування, коли елемент стане присутнім:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS)
На моєму досвіді, явно очікування завжди надійніше.