Wie kann ich Selenium dazu bringen, darauf zu warten, dass z. B. ein Kalender-Widget geladen wird? Im Moment mache ich nur eine Thread.sleep(2500)
nach dem Exportieren des Testfalls in ein Junit-Programm.
Antworten
Zu viele Anzeigen?Eine allgemeinere Lösung als das Warten auf ein Element wäre es, zu warten, bis alle Verbindungen zum Server geschlossen sind. Auf diese Weise können Sie warten, bis alle Ajax-Aufrufe beendet sind, auch wenn sie keinen Callback haben und somit keine Auswirkungen auf die Seite haben. Weitere Einzelheiten finden Sie unter aquí .
Mit C# und jQuery habe ich die folgende Methode erstellt, um zu warten, bis alle AJax-Aufrufe abgeschlossen sind (wenn jemand direktere Möglichkeiten des Zugriffs auf JS-Variablen von C# hat, bitte kommentieren):
internal void WaitForAjax(int timeOut = 15)
{
var value = "";
RepeatUntil(
() => value = GetJavascriptValue("jQuery.active"),
() => value == "0",
"Ajax calls did not complete before timeout"
);
}
internal void RepeatUntil(Action repeat, Func<bool> until, string errorMessage, int timeout = 15)
{
var end = DateTime.Now + TimeSpan.FromSeconds(timeout);
var complete = false;
while (DateTime.Now < end)
{
repeat();
try
{
if (until())
{
complete = true;
break;
}
}
catch (Exception)
{ }
Thread.Sleep(500);
}
if (!complete)
throw new TimeoutException(errorMessage);
}
internal string GetJavascriptValue(string variableName)
{
var id = Guid.NewGuid().ToString();
_selenium.RunScript(String.Format(@"window.$('body').append(""<input type='text' value='""+{0}+""' id='{1}'/>"");", variableName, id));
return _selenium.GetValue(id);
}
Wenn Sie Python verwenden, können Sie diese Funktion verwenden, die auf die Schaltfläche klickt und auf die DOM-Änderung wartet:
def click_n_wait(driver, button, timeout=5):
source = driver.page_source
button.click()
def compare_source(driver):
try:
return source != driver.page_source
except WebDriverException:
pass
WebDriverWait(driver, timeout).until(compare_source)
(CREDIT: basierend auf diese Stack-Overflow-Antwort )
Mit webdriver aka selenium2 können Sie die implizite Wartekonfiguration verwenden, wie sie unter https://www.selenium.dev/documentation/en/webdriver/waits/#implicit-wait
Java verwenden:
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));
Oder mit Python:
from selenium import webdriver
ff = webdriver.Firefox()
ff.implicitly_wait(10) # seconds
ff.get("http://somedomain/url_that_delays_loading")
myDynamicElement = ff.find_element_by_id("myDynamicElement")
Das funktioniert bei mir
public void waitForAjax(WebDriver driver) {
new WebDriverWait(driver, 180).until(new ExpectedCondition<Boolean>(){
public Boolean apply(WebDriver driver) {
JavascriptExecutor js = (JavascriptExecutor) driver;
return (Boolean) js.executeScript("return jQuery.active == 0");
}
});
}
- See previous answers
- Weitere Antworten anzeigen