Selenium WebDriver 是一个用于自动化 web 应用程序测试的工具,它提供了多种等待机制来确保页面元素在交互前已经完全加载和可用。在动态网页中(使用 AJAX、jQuery 或动画效果),等待页面完全加载尤为重要。
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
wait.until(ExpectedConditions.jsReturnsValue("return document.readyState == 'complete'"));
// 等待 jQuery 活动完成
wait.until(d -> (Boolean)((JavascriptExecutor)d).executeScript("return jQuery.active == 0"));
// 等待 AJAX 请求完成
wait.until(d -> (Boolean)((JavascriptExecutor)d).executeScript("return window.jQuery != undefined && jQuery.active == 0"));
wait.until(d -> ((JavascriptExecutor)d).executeScript("return document.readyState").equals("complete"));
// 等待页面加载完成
browser.waitUntil(() => {
return browser.execute(() => document.readyState === 'complete');
}, {
timeout: 10000,
timeoutMsg: '页面没有在10秒内完成加载'
});
// 等待 jQuery 活动完成
browser.waitUntil(() => {
return browser.execute(() => {
return window.jQuery === undefined || jQuery.active === 0;
});
}, {
timeout: 10000,
timeoutMsg: 'jQuery 活动没有在10秒内完成'
});
原因: 元素尚未加载完成或仍在动画中 解决: 使用显式等待结合 ExpectedConditions
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("elementId")));
原因: AJAX 请求未完成 解决: 检查 jQuery.active 或自定义 AJAX 计数器
wait.until(d -> (Boolean)((JavascriptExecutor)d).executeScript("return window.allAjaxRequestsFinished === true"));
原因: 元素被动画遮挡或仍在移动 解决: 等待动画完成后再操作
wait.until(ExpectedConditions.elementToBeClickable(By.id("buttonId")));
wait.until(driver -> {
WebElement element = driver.findElement(By.id("dynamicElement"));
String text = element.getText();
return text != null && !text.isEmpty();
});
ExpectedCondition<Boolean> jQueryLoad = d -> (Boolean)((JavascriptExecutor)d).executeScript("return window.jQuery != undefined && jQuery.active == 0");
ExpectedCondition<Boolean> jsLoad = d -> ((JavascriptExecutor)d).executeScript("return document.readyState").equals("complete");
wait.until(jQueryLoad) && wait.until(jsLoad);
通过合理使用这些等待策略,可以确保 Selenium WebDriver 测试在各种动态内容加载场景下的稳定性和可靠性。