Dieser Thread ist etwas älter, dachte aber, ich würde posten, was ich gerade mache (in Arbeit).
Obwohl ich immer noch auf Situationen stoße, in denen das System stark ausgelastet ist und wenn ich auf eine Senden-Schaltfläche (z. B. login.jsp) klicke, kehren alle drei Bedingungen (siehe unten) zurück, true
aber die nächste Seite (z. B. home.jsp) ist nicht vorhanden. Ich habe noch nicht mit dem Laden begonnen.
Dies ist eine generische Wartemethode, die eine Liste von ExpectedConditions erstellt.
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;
}
Ich habe verschiedene wiederverwendbare ExpectedConditions definiert (drei davon sind unten aufgeführt). In diesem Beispiel umfassen die drei erwarteten Bedingungen document.readyState = 'complete', kein "wait_dialog" und keine 'spinners' (Elemente, die angeben, dass asynchrone Daten angefordert werden).
Nur die erste kann generisch auf alle Webseiten angewendet werden.
/**
* 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;
}
};
Abhängig von der Seite kann ich eine oder alle verwenden:
waitForPageLoad(timeoutInSec,
EXPECT_DOC_READY_STATE,
EXPECT_NOT_WAITING,
EXPECT_NO_SPINNERS
);
Es gibt auch vordefinierte ExpectedConditions in der folgenden Klasse: org.openqa.selenium.support.ui.ExpectedConditions