Selenium WebDriver 中的等待类型

在运行任何 Web 应用程序时,需要考虑加载时间。如果你的代码试图访问尚未加载的任何元素,WebDriver 将抛出异常并且你的脚本将停止。

等待有三种类型 -

  • 隐含等待
  • 明确的等待
  • 流利的等待

隐式等待用于设置整个程序的等待时间,而显式等待仅用于特定部分。

隐含的等待

隐式等待是告诉 WebDriver 在尝试查找一个或多个元素(如果它们不是立即可用)时轮询 DOM 一段时间。隐式等待基本上是告诉 WebDriver 如果 WebDriver 正在寻找的指定 web 元素不存在你想看到的延迟的方式。默认设置为 0.设置后,将为 WebDriver 对象实例的生命周期设置隐式等待。使用以下代码段在代码的实例化部分中声明隐式等待。

Java 中的示例 :

driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
// You need to import the following class - import java.util.concurrent.TimeUnit;

C#中的示例 :

driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(15));

所以在这种情况下,你告诉 WebDriver,如果在 UI(DOM) 上没有指定的元素,它应该等待 15 秒。

明确的等待

当某个元素需要更多时间加载时,你可能会遇到实例。设置隐式等待这种情况没有意义,因为浏览器会在每个元素的同一时间不必要地等待,从而增加了自动化时间。显式等待有助于通过绕过某些特定元素的隐式等待来完成。

显式等待是限于特定 Web 元素的智能等待。使用显式等待你基本上是告诉 WebDriver 它最多是在它放弃之前等待 X 个单位的时间。

显式等待使用 WebDriverWait 和 ExpectedConditions 类完成。在下面的示例中,对于 id 为 username 的元素,我们将等待最多 10 秒,然后再继续执行下一个命令。这是步骤。

Java 中的示例 :

//Import these two packages:
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

//Declare a WebDriverWait variable. In this example, we will use myWaitVar as the name of the variable.
WebDriverWait myWaitVar = new WebDriverWait(driver, 30);

//Use myWaitVar with ExpectedConditions on portions where you need the explicit wait to occur. In this case, we will use explicit wait on the username input before we type the text tutorial onto it.
myWaitVar.until(ExpectedConditions.visibilityOfElementLocated(By.id(`username`)));
driver.findElement(By.id(`username`)).sendKeys(`tutorial`);

ExpectedConditions 类具有一些等待元素的预定义公共条件。单击此处以查看 Java 绑定中的这些条件的列表。

C#中的示例 :

using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.PhantomJS;

// You can use any other WebDriver you want, such as ChromeDriver.
using (var driver = new PhantomJSDriver())
{
    driver.Navigate().GoToUrl("http://somedomain/url_that_delays_loading");

    // We aren't going to use it more than once, so no need to declare this a variable.
    new WebDriverWait(driver, TimeSpan.FromSeconds(10))
        .Until(ExpectedConditions.ElementIsVisible(By.Id("element-id")));

    // After the element is detected by the previous Wait, 
    // it will display the element's text
    Console.WriteLine(driver.FindElement(By.Id("element-id")).Text);
}

在此示例中,系统将等待 10 秒,直到元素可见。如果超时后元素不可见,WebDriver 将抛出一个 WebDriverTimeoutException

请注意:如果元素在 10 秒超时之前可见,系统将立即继续进行进一步处理。

流利的等待

与隐式和显式等待不同,流畅等待使用两个参数。超时值和轮询频率。假设我们将超时值设置为 30 秒,将轮询频率设置为 2 秒。WebDriver 将每 2 秒检查一次元素,直到超时值(30 秒)。超过超时值后没有任何结果,抛出异常。下面是一个示例代码,显示了流畅等待的实现。

Java 中的示例 :

Wait wait = new FluentWait(driver).withTimeout(30, SECONDS).pollingEvery(2, SECONDS).ignoring(NoSuchElementException.class);

WebElement testElement = wait.until(new Function() {
    public WebElement apply(WebDriver driver) {
        return driver.findElement(By.id("testId"));
    }
});

使用流畅等待的另一个好处是,我们可以在等待时忽略特定类型的异常(例如 NoSuchElementExceptions)。由于所有这些规定,流畅的等待有助于 AJAX 应用程序以及元素加载时间经常波动的情况。流畅等待的策略性使用显着改善了自动化工作。