jck28 - 小柒 - selenium - L2 - 显式等待高级使用

一, 显式等待原理

  • 在代码中定义等待一定条件发生后再进一步执行代码
  • 最长等待时间循环执行结束条件的函数
  • 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());
    }