一, 显式等待原理
- 在代码中定义等待一定条件发生后再进一步执行代码
- 在最长等待时间内循环执行结束条件的函数
- WebDriverWait(driver 实例, 最长等待时间).until(结束条件函数)
二, 常见 expected_conditions
三, 显式等待-定制等待条件
- 官方的 ExpectedConditions 不可能覆盖所有场景
- 定制封装条件会更加灵活、可控
- 代码示例
package waitDemo;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
public class WaitByConditionsTest {
static WebDriver driver;
static WebDriverWait wait;
@BeforeAll
static void setupClass() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
//创建一个driver对象
driver = new ChromeDriver(options);
wait = new WebDriverWait(driver, Duration.ofSeconds(8));
}
@AfterAll
static void tearDownClass() throws InterruptedException {
Thread.sleep(5000);
driver.quit();
}
@Test
void testWaitByConditions() {
driver.get("https://vip.ceshiren.com/#/ui_study/frame");
WebElement primary_btn = wait.until(
ExpectedConditions.elementToBeClickable(By.id("primary_btn")));
primary_btn.click();
System.out.println(primary_btn.getText());
}
//自定义显示等待的执行逻辑与条件
@Test
void waitByLambda(){
driver.get("https://vip.ceshiren.com/#/ui_study/frame");
//点击两次才会出现弹框
WebElement element = wait.until(
(driver) -> {
//在等待过程中不停地执行点击按钮,直到对应的文本信息出来为止
driver.findElement(By.id("primary_btn")).click();
//使用lambda表达式,返回弹框的文本值
return driver.findElement(By.xpath("//*[text()='该弹框点击两次后才会弹出']"));
}
);
System.out.println(element.getText());
}
}
四, FluentWait等待
1, FluentWait简介
- 与显式等待近似
- 设定超时时间
- 设定轮询频率
- 忽略特定类型的异常
2, FluentWait使用场景
3, 示例代码
@Test
void fluentWait(){
FluentWait<WebDriver> fluentWait = new FluentWait<>(driver);
//设置等待评估条件为真的时间 ---超时值
fluentWait.withTimeout(Duration.ofSeconds(30))
//设置评估条件的频率 ---轮询频率
.pollingEvery(Duration.ofSeconds(5))
//忽略特定类型的异常
.ignoring(NoSuchElementException.class);
driver.get("https://vip.ceshiren.com/#/ui_study/frame");
WebElement primaryBtn = fluentWait.until(
(driver) -> {
driver.findElement(By.id("primary_btn")).click();
return driver.findElement(By.xpath("//*[text()='该弹框点击两次后才会弹出']"));
}
);
System.out.println(primaryBtn.getText());
}