java - presence_of_element_located - wait until expected conditions selenium
Temporalmente evitando esperas implĂcitas con WebDriver (6)
Dado que Selenium no parece ofrecer lo que quiero directamente (en base a lo que dijeron Mike Kwan y Slanec), este método simple de ayuda es lo que hice por ahora:
protected boolean isElementHiddenNow(String id) {
turnOffImplicitWaits();
boolean result = ExpectedConditions.invisibilityOfElementLocated(By.id(id)).apply(driver);
turnOnImplicitWaits();
return result;
}
private void turnOffImplicitWaits() {
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
}
private void turnOnImplicitWaits() {
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
Si el elemento está oculto o no está presente, el método devuelve verdadero; si es visible, devuelve falso. De cualquier manera, el control se realiza al instante.
El uso de lo anterior es, al menos, mucho más turnOffImplicitWaits()
que turnOffImplicitWaits()
los casos de prueba con llamadas a turnOffImplicitWaits()
y turnOnImplicitWaits()
.
Ver también estas respuestas para versiones afinadas del mismo enfoque:
- Usar try-finally para volver a activar las esperas implícitas
- Uso del localizador como parámetro
Cuando utilizo esperas implícitas, como se aconseja aquí , todavía a veces quiero afirmar la invisibilidad inmediata o la inexistencia de elementos.
En otras palabras, sé que algunos elementos deben estar ocultos, y quiero que mis pruebas hagan que esa afirmación sea rápida , sin pasar varios segundos debido a la espera implícita (de lo contrario útil).
Una cosa que probé fue un método de ayuda como este:
// NB: doesn''t seem to do what I want
private boolean isElementHiddenNow(String id) {
WebDriverWait zeroWait = new WebDriverWait(driver, 0);
ExpectedCondition<Boolean> c = invisibilityOfElementLocated(By.id(id));
try {
zeroWait.until(c);
return true;
} catch (TimeoutException e) {
return false;
}
}
Pero en el código anterior, la llamada a until()
solo regresa después de que ha pasado el tiempo de espera implícito , es decir, no hace lo que yo quería.
Esta es la única forma que he encontrado hasta ahora que funciona:
@Test
public void checkThatSomethingIsNotVisible() {
turnOffImplicitWaits();
// ... the actual test
turnOnImplicitWaits();
}
... donde, por ejemplo, turnOffImplicitWaits()
es un ayudante en la superclase de selenio común:
protected void turnOffImplicitWaits() {
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
}
Pero eso no es muy elegante, creo. ¿Hay alguna manera más limpia de evitar la espera implícita ocasionalmente?
En un código existente que depende mucho de la manera de pensar de espera implícita, y sin CSS al rescate, encontré una salida para ese tipo de cosas, complementándolo con Jsoup, y continuando con Jsoup:
# this is straightforward Scala... put the types and it is Java.
val innerHtml = seleniumWebElementFatherInstance.getAttribute("innerHTML")
val jsoupElements = Jsoup.parse(innerHtml).select("div.your.css.selector")
Mi enfoque fue eludir totalmente la espera implícita y findElements()
con la adición de un control de visibilidad, etc.) en mis propios findElement()
y findElements()
que ahora uso de forma predeterminada. De esta forma, cuando quiero verificar algo al instante, puedo llamar al método original de WebDriver, que no espera, por supuesto.
Mi implementación:
using (driver.NoImplicitWait())
{
....
}
Con el método de extensión:
public static NoImplicitWait NoImplicitWait(this IWebDriver driver)
{
return new NoImplicitWait(driver);
}
Y clase:
public sealed class NoImplicitWait : IDisposable
{
private readonly IWebDriver _driver;
public NoImplicitWait(IWebDriver driver)
{
_driver = driver;
_driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(0));
}
public void Dispose()
{
_driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(30));
}
}
También sugiero cambiar el parámetro a un localizador "Por" para obtener más flexibilidad al buscar el elemento.
protected boolean isElementHiddenNow(By locator) {
turnOffImplicitWaits();
boolean result = false;
try {
result = ExpectedConditions.invisibilityOfElementLocated(locator).apply(driver);
}
finally {
turnOnImplicitWaits();
}
return result;
}
De esta forma, puede buscar por css si es necesario en lugar de simplemente id:
By PartLinkLocator = By.cssSelector("div.search-result div.row a");
''Por supuesto, su localizador probablemente debería diseñarse para devolver solo un elemento (a diferencia del ejemplo'' Por ''que agarré rápidamente, que devuelve todos los enlaces de parte en una tabla de filas css ...) Entonces, un ejemplo de'' id ''se vería
By usernameLocator = By.id("inputEmail");
myResult = isElementHiddenNow(usernameLocator);
share me ayudó, sin embargo, share una try { } finally { }
y llamé a turnOnImplicitWaits()
en el bloque finally
para asegurarme de que siempre se vuelva a encender.
protected boolean isElementHiddenNow(String id) {
turnOffImplicitWaits();
boolean result = false;
try {
result = ExpectedConditions.invisibilityOfElementLocated(By.id(id)).apply(driver);
}
finally {
turnOnImplicitWaits();
}
return result;
}