Selenium 简明教程

Selenium Webdriver - Explicit/Implicit Wait

Selenium Webdriver 可以与显式和隐式结合使用以实现同步。等待主要用于测试中,以处理动态网页。

整个页面加载之前通常会存在一些延迟时间,并且 Web 元素在网页上完全可用。Selenium Webdriver 中的等待有助于阻止测试执行,直到元素以其正确状态出现在/消失在网页上。

让我们讨论 Selenium Webdriver 中的部分等待类型−

Implicit Wait

它是 Selenium 中可用的默认等待。它是一种适用于整个驱动程序会话的全局等待。默认等待时间为 0,这意味着如果找不到元素,将立即抛出错误。但是,如果设置了等待时间,那么一旦等待时间超过就会抛出错误。一旦识别出元素,其引用将被返回,并且执行将移至下一步。我们应该以最佳方式使用隐式等待,较长的等待时间会增加测试的执行时间。

Syntax

driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);

在上述示例中,将在 15 秒后抛出 NoSuchElementException。

Explicit Wait

它类似于添加到代码中的循环,这些循环轮询网页以确定特定场景在退出循环并移动到下一行代码之前是否为真。如果在规定的时间内情况未得到满足,将抛出超时异常。显式等待使用 ExpectedConditions 和 WebDriverWait 类应用于具有其条件的特定元素。显式等待的一些预期条件是 -

titleContains, alertIsPresent, invisibilityOfElementLocated(By locator),
titleIs(), invisibilityOfElementWithText(By locator, String s),
visibilityOf(), textToBePresentInElement(By locator, String s),
visibilityOfElementLocated(By locator), visibilityOfAllElements(),
presenceOfAllElementsLocatedBy(By locator),
presenceOfElementLocated(By locator),
elementToBeClickable(By locator), stalenessOf(WebElement e),
textToBePresentInElementValue(), textToBePresentInElementLocated(),
elementSelectionStateToBe(), elementToBeSelected(),
frameToBeAvaliableAndSwitchToIt().

在同一驱动程序会话中添加隐式和显式等待时,我们应该谨慎,例如,显式等待 15 秒和隐式等待 10 秒的组合会导致 20 秒后发生超时。

Syntax

WebDriverWait wt = new WebDriverWait(driver,5);
wt.until(ExpectedConditions.invisibilityOfElementLocated
   (By.xpath("//*[@class='mui−btn']")));

在上述示例中,如果元素不可见的预期条件未在此指定时间内得到满足,将在 5 秒后抛出 TimeOutException。

让我们举一个例子,我们将尝试使用错误的 xpath 值识别文本 Selenium - Automation Practice Form 并添加一个隐式等待。在这种情况下,一旦超时时间过去,我们将收到 NoSuchElementException。

此元素的正确 xpath 为: /html/body/div/header/div[2]/h1 。但是,我们将在实现中使用不正确的 xpath /html/body/div/header/div[2]/u1 以获取异常。

selenium explicit implicit 1

Example

Implicitwts.java 类文件上的代码实现。

package org.example;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;

public class Implicitwts {
   public static void main(String[] args) throws InterruptedException {

      // Initiate the Webdriver
      WebDriver driver = new ChromeDriver();

      // adding implicit wait of 10 secs
      driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

      // launching a browser and open a URL
      driver.get("https://www.tutorialspoint.com/selenium/practice/selenium_automation_practice.php");

      // identify element with incorrect xpath value
      WebElement l = driver.findElement(By.xpath("/html/body/div/header/div[2]/u1"));
      l.click();

      // get text
      System.out.println("Get text : " + l.getText());

      // Quitting browser
      driver.quit();
   }
}

Output

Exception in thread "main"
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element:
{"method":"xpath","selector":"/html/body/div/header/div[2]/u1"}
  (Session info: chrome=121.0.6167.160)
For documentation on this error, please visit:
https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception

Process finished with exit code 1

在上述示例中,我们收到了 NoSuchElementException,因为使用了不正确的 xpath 值来识别元素。一旦隐式等待时间 2 秒过去,就会抛出一个异常。

最后,收到消息 Process finished with exit code 1 ,表示代码执行不成功。

让我们再看另一个例子,在该例子中我们会看到在显式等待时间已过时会抛出 Timeout 异常。

Example

Explicitwt.java 类文件中的代码实现。

package org.example;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;

public class Explicitwt {
   public static void main(String[] args) throws InterruptedException {

      // Initiate the Webdriver
      WebDriver driver = new ChromeDriver();

      // launching a browser and open a URL
      driver.get("https://www.tutorialspoint.com/index.htm");

      // identify element with locator xpath
      WebElement l = driver.findElement
         (By.xpath("/html/body/header/nav/ul/li[2]/a"));

      // explicit wait 2 secs for presence of incorrect element
      WebDriverWait wt = new WebDriverWait(driver, Duration.ofSeconds(2));
      wt.until(ExpectedConditions.presenceOfElementLocated
         (By.xpath("/html/body/header/nav/ul/li[2]/li")));

      // get text after presence of element condition is met
      System.out.println("Get text : " + l.getText());

      // Quitting browser
      driver.quit();
   }
}

Output

Exception in thread "main" org.openqa.selenium.TimeoutException:
   Expected condition failed: waiting for presence of element located by:
   By.xpath: /html/body/header/nav/ul/li[2]/li (tried for 2 second(s)
   with 500 milliseconds interval)
   at org.openqa.selenium.support.ui.WebDriverWait.
      timeoutException(WebDriverWait.java:84)
   at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:230)
   at org.example.Explicitwt.main(Explicitwt.java:25)
Caused by: org.openqa.selenium.NoSuchElementException: no such element:
   Unable to locate element:
{"method":"xpath","selector":"/html/body/header/nav/ul/li[2]/li"}
  (Session info: chrome=121.0.6167.85)

在上述示例中,我们收到了 TimeOutException,因为在 2 秒的显式等待时间内未满足元素可见性的预期条件。超过 2 秒的显式等待时间后,会抛出异常。

最后,收到了消息 Process finished with exit code 1 ,表示代码执行失败。

在本教程中,我们讨论了如何使用 Selenium Webdriver 处理隐式和显式等待。