Sí, si tiene problemas con StaleElementReferenceExceptions es porque sus pruebas están mal escritas. Es una condición de carrera. Considere el siguiente escenario:
WebElement element = driver.findElement(By.id("foo"));
// DOM changes - page is refreshed, or element is removed and re-added
element.click();
Ahora, en el punto donde hace clic en el elemento, la referencia del elemento ya no es válida. Es casi imposible para WebDriver hacer una buena suposición sobre todos los casos en que esto podría suceder, por lo que levanta las manos y le da el control a usted, que como autor de la prueba / aplicación debe saber exactamente qué puede o no suceder. Lo que desea hacer es esperar explícitamente hasta que el DOM esté en un estado en el que sepa que las cosas no cambiarán. Por ejemplo, usando un WebDriverWait para esperar a que exista un elemento específico:
// 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();
El método presenciaOfElementoLocalizado () se vería así:
private static Function<WebDriver,WebElement> presenceOfElementLocated(final By locator) {
return new Function<WebDriver, WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
};
}
Tiene toda la razón acerca de que el controlador Chrome actual es bastante inestable, y le alegrará saber que el tronco Selenium tiene un controlador Chrome reescrito, donde los desarrolladores de Chromium realizaron la mayor parte de la implementación como parte de su árbol.
PD. Alternativamente, en lugar de esperar explícitamente como en el ejemplo anterior, puede habilitar las esperas implícitas, de esta manera WebDriver siempre se repetirá hasta el tiempo de espera especificado esperando que el elemento esté presente:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS)
Sin embargo, en mi experiencia, esperar explícitamente siempre es más confiable.