Este hilo es un poco más antiguo, pero pensé en publicar lo que hago actualmente (trabajo en progreso).
Aunque todavía estoy en situaciones en las que el sistema está bajo una gran carga y cuando hago clic en un botón de envío (por ejemplo, login.jsp), las tres condiciones (ver más abajo) regresan, true
pero la página siguiente (por ejemplo, home.jsp) no aparece. t comenzó a cargar todavía.
Este es un método de espera genérico que toma una lista de condiciones esperadas.
public boolean waitForPageLoad(int waitTimeInSec, ExpectedCondition<Boolean>... conditions) {
boolean isLoaded = false;
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(waitTimeInSec, TimeUnit.SECONDS)
.ignoring(StaleElementReferenceException.class)
.pollingEvery(2, TimeUnit.SECONDS);
for (ExpectedCondition<Boolean> condition : conditions) {
isLoaded = wait.until(condition);
if (isLoaded == false) {
//Stop checking on first condition returning false.
break;
}
}
return isLoaded;
}
He definido varias condiciones esperadas reutilizables (tres están a continuación). En este ejemplo, las tres condiciones esperadas incluyen document.readyState = 'complete', sin "wait_dialog" presente y sin 'spinners' (elementos que indican que se están solicitando datos asíncronos).
Solo el primero se puede aplicar genéricamente a todas las páginas web.
/**
* Returns 'true' if the value of the 'window.document.readyState' via
* JavaScript is 'complete'
*/
public static final ExpectedCondition<Boolean> EXPECT_DOC_READY_STATE = new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
String script = "if (typeof window != 'undefined' && window.document) { return window.document.readyState; } else { return 'notready'; }";
Boolean result;
try {
result = ((JavascriptExecutor) driver).executeScript(script).equals("complete");
} catch (Exception ex) {
result = Boolean.FALSE;
}
return result;
}
};
/**
* Returns 'true' if there is no 'wait_dialog' element present on the page.
*/
public static final ExpectedCondition<Boolean> EXPECT_NOT_WAITING = new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
Boolean loaded = true;
try {
WebElement wait = driver.findElement(By.id("F"));
if (wait.isDisplayed()) {
loaded = false;
}
} catch (StaleElementReferenceException serex) {
loaded = false;
} catch (NoSuchElementException nseex) {
loaded = true;
} catch (Exception ex) {
loaded = false;
System.out.println("EXPECTED_NOT_WAITING: UNEXPECTED EXCEPTION: " + ex.getMessage());
}
return loaded;
}
};
/**
* Returns true if there are no elements with the 'spinner' class name.
*/
public static final ExpectedCondition<Boolean> EXPECT_NO_SPINNERS = new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
Boolean loaded = true;
try {
List<WebElement> spinners = driver.findElements(By.className("spinner"));
for (WebElement spinner : spinners) {
if (spinner.isDisplayed()) {
loaded = false;
break;
}
}
}catch (Exception ex) {
loaded = false;
}
return loaded;
}
};
Dependiendo de la página, puedo usar uno o todos:
waitForPageLoad(timeoutInSec,
EXPECT_DOC_READY_STATE,
EXPECT_NOT_WAITING,
EXPECT_NO_SPINNERS
);
También hay condiciones esperadas predefinidas en la siguiente clase: org.openqa.selenium.support.ui.ExpectedConditions