Oui, si vous rencontrez des problèmes avec StaleElementReferenceExceptions, c'est parce que vos tests sont mal écrits. C'est une condition de course. Considérez le scénario suivant:
WebElement element = driver.findElement(By.id("foo"));
// DOM changes - page is refreshed, or element is removed and re-added
element.click();
Désormais, au moment où vous cliquez sur l'élément, la référence d'élément n'est plus valide. Il est presque impossible pour WebDriver de faire une bonne estimation de tous les cas où cela pourrait se produire - il lève donc les mains et vous donne le contrôle, qui en tant qu'auteur du test / de l'application devrait savoir exactement ce qui peut ou non se produire. Ce que vous voulez faire est d'attendre explicitement que le DOM soit dans un état où vous savez que les choses ne changeront pas. Par exemple, en utilisant un WebDriverWait pour attendre qu'un élément spécifique existe:
// 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();
La méthode presenceOfElementLocated () ressemblerait à ceci:
private static Function<WebDriver,WebElement> presenceOfElementLocated(final By locator) {
return new Function<WebDriver, WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
};
}
Vous avez tout à fait raison sur le fait que le pilote Chrome actuel est assez instable, et vous serez heureux d'apprendre que le tronc Selenium a un pilote Chrome réécrit, où la plupart de l'implémentation a été effectuée par les développeurs Chromium dans le cadre de leur arbre.
PS. Alternativement, au lieu d'attendre explicitement comme dans l'exemple ci-dessus, vous pouvez activer les attentes implicites - de cette façon, WebDriver bouclera toujours jusqu'au délai spécifié d'attente pour que l'élément devienne présent:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS)
D'après mon expérience, l'attente explicite est toujours plus fiable.