• Selenium Video Tutorials

Selenium WebDriver - 处理 Ajax 调用



Selenium Webdriver 可用于处理 Ajax 调用。Ajax 也称为异步 JavaScript,主要由XMLJavaScript 组成。从 UI 的角度来看,会向服务器发出 JavaScript 调用,然后我们从服务器以 XML 格式接收响应。

什么是 Ajax?

Ajax 或异步 JavaScript 主要用于创建快速且响应灵敏的网页。让我们以一个网页为例,在这个网页中,用户信息会在点击按钮时更新。假设用户频繁更新其信息,因此每次都需要重新加载整个网页。但是,在基于 Ajax 构建的网页上,只需要更新用户修改的那部分用户信息,而无需重新加载整个页面。

Ajax 兼容 HTTP 请求、JavaScript、XML、HTMLCSS 等技术。Ajax 以异步方式发送和接收数据,无需重新加载页面。

在 Ajax 系统中,用户界面向 XML HTTP 请求回调方法发送 JavaScript 调用,然后将 HTTP 请求发送到 Web 服务器。接下来,Web 服务器根据请求与数据库交换信息,并以 JSON/XML 格式获取信息以反映在用户界面中。

Selenium 如何处理 Ajax 调用?

Selenium Webdriver 并不总是能够在 Ajax 调用后成功访问 Web 元素。这是因为在 Ajax Web 应用程序中,元素可用的等待时间并不统一。Selenium 测试会等待特定时间,之后我们可能会遇到失败。无法预测 Ajax 调用的时间是 Selenium 测试面临的挑战。

为了克服这个问题,Selenium 使用以下同步和等待机制:

Thread.sleep()

此命令会暂停执行,暂停时间由传递的参数决定。但是,这不是一个好的选择,因为等待时间是固定的,但是无法预测 Ajax 调用的时间。此外,此命令会将当前线程从运行队列移动到等待队列。

隐式等待

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

显式等待

这种类型的等待非常适合处理 Ajax 调用。一些显式等待的预期条件如下:

  • titleContains
  • alertIsPresent
  • invisibilityOfElementLocated
  • titleIs
  • invisibilityOfElementWithText
  • visibilityOf
  • textToBePresentInElement
  • visibilityOfElementLocated
  • visibilityOfAllElements
  • presenceOfAllElementsLocatedBy
  • presenceOfElementLocated
  • elementToBeClickable
  • stalenessOf
  • textToBePresentInElementValue
  • textToBePresentInElementLocated
  • elementSelectionStateToBe
  • elementToBeSelected
  • frameToBeAvaliableAndSwitchToIt

流畅等待

这是驱动程序等待特定元素条件为真的最长时间。它还确定驱动程序在定位元素或抛出异常之前验证的间隔(轮询间隔)。

使用显式等待处理 Ajax

让我们以以下页面为例,我们将在其中点击点击我

Selenium Handling Ajax Calls 1

点击点击我后,我们将借助显式等待并等待网页上出现文本您已执行动态点击

Selenium Handling Ajax Calls 2

示例

package org.example;

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.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import java.util.concurrent.TimeUnit;

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

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

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

      // launching a browser
      driver.get("https://tutorialspoint.com/selenium/practice/buttons.php");

      // identify button then click on it
      WebElement l = driver.findElement
         (By.xpath("/html/body/main/div/div/div[2]/button[1]"));
      l.click();

      // Identify text
      WebElement e = driver.findElement(By.xpath("//*[@id='welcomeDiv']"));

      // explicit wait to expected condition for presence of a text
      WebDriverWait wt = new WebDriverWait(driver, Duration.ofSeconds(2));
      wt.until(ExpectedConditions.presenceOfElementLocated
         (By.xpath("//*[@id='welcomeDiv']")));

      // get text
      System.out.println("Get text after clicking: " + e.getText());

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

输出

Get text after clicking: You have done a dynamic click

Process finished with exit code 0

在上述示例中,点击点击我按钮后出现的文本为您已执行动态点击

最后,收到消息进程已退出,退出代码为 0,表示代码已成功执行。

使用流畅等待处理 Ajax

让我们再以以下页面为例,我们将在其中点击颜色更改

Selenium Handling Ajax Calls 3

点击颜色更改后,我们将借助流畅等待并等待网页上出现文本为5 秒后可见的按钮。

Selenium Handling Ajax Calls 4

示例

package org.example;

import org.openqa.selenium.*;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import java.time.Duration;

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

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

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

      // identify button then click
      WebElement l = driver.findElement(By.xpath("//*[@id='colorChange']"));
      l.click();

      // fluent wait of 6 secs till other button appears
      Wait<WebDriver> w = new FluentWait<WebDriver>(driver)
         .withTimeout(Duration.ofSeconds(20))     .pollingEvery(Duration.ofSeconds(6))
         .ignoring(NoSuchElementException.class);

      WebElement m = w.until
         (ExpectedConditions.visibilityOfElementLocated
         (By.xpath("//*[@id='visibleAfter']")));

      // checking button presence
      System.out.println("Button appeared: " + m.isDisplayed());

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

输出

Button appeared: true

使用隐式等待处理 Ajax

让我们以以下页面为例,我们将在其中尝试使用错误的 xpath 值定位文本Selenium 自动化实践表单并使用隐式等待。在此期间,一旦超时时间过去,应该会抛出 NoSuchElementException。

此元素正确的xpath应该是:/html/body/div/header/div[2]/h1。但是,为了产生异常,我们在实现中将使用错误的xpath - /html/body/div/header/div[2]/u1

Selenium Handling Ajax Calls 5

示例

package org.example;

import org.openqa.selenium.*;
import org.openqa.selenium.edge.EdgeDriver;
import java.util.concurrent.TimeUnit;

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

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

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

      // launching a browser and open a URL
      driver.get("https://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();
   }
}

输出

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: edge=121.0.6167.160)
For documentation on this error, please visit: https://www.seleniumcn.cn/documentation/webdriver/troubleshooting/errors#no-such-element-exception

Process finished with exit code 1

在上面的例子中,由于使用了错误的xpath值来定位文本,我们得到了NoSuchElementException异常。当2秒的隐式等待时间过去后,我们得到了异常。

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

结论

这总结了我们关于Selenium Webdriver处理Ajax调用的教程的全面概述。我们从描述什么是Ajax,Selenium如何处理Ajax开始,并逐步介绍了如何使用显式、隐式和流畅等待来处理Ajax以及Selenium的示例。这使您具备了处理Ajax调用的深入知识。明智的做法是不断练习您学到的知识,并探索与Selenium相关的其他知识,以加深您的理解并扩展您的视野。

广告