Oui, si vous avez des problèmes avec les StaleElementReferenceExceptions, c'est parce qu'il y a 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();
Maintenant, au moment où vous cliquez sur l'élément, la référence de l'élément n'est plus valide. Il est pratiquement impossible pour WebDriver de deviner tous les cas où cela pourrait se produire - il se défausse donc et vous laisse le contrôle, vous qui, en tant qu'auteur du test ou de l'application, devriez savoir exactement ce qui peut ou ne peut pas se produire. Ce que vous voulez faire, c'est 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 de dire que le pilote Chrome actuel est assez instable, et vous serez heureux d'apprendre que le tronc Selenium comporte un pilote Chrome réécrit, où la plupart de l'implémentation a été faite par les développeurs de Chromium dans le cadre de leur arbre.
PS. 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 timeout spécifié en attendant que l'élément devienne présent :
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS)
Mais d'après mon expérience, l'attente explicite est toujours plus fiable.
27 votes
J'espère que les 17 000 vues indiquent que ce n'est pas seulement vous ;) Cela doit être l'exception Selenium la plus frustrante qui soit.
4 votes
48k maintenant ! J'ai le même problème...
3 votes
Je trouve que le Sélénium est une pure et complète poubelle. ....
4 votes
60k, toujours un problème :)
0 votes
Dans mon cas, c'est parce que je faisais
from selenium.common.exceptions import NoSuchElementException