Selenium 等待 Ajax 内容加载 - 通用方法

Selenium wait for Ajax content to load - universal approach

是否有让 Selenium 等待所有 ajax 内容加载完毕的通用方法? (不绑定到特定网站 - 因此它适用于每个 ajax 网站)

正如 Mark Collin 在他的书 "Mastering Selenium Webdriver" 中描述的那样,使用 JavascriptExecutor 可以让您确定使用 jQuery 的网站是否已完成 AJAX 调用

public class AdditionalConditions {

  public static ExpectedCondition<Boolean> jQueryAJAXCallsHaveCompleted() {
    return new ExpectedCondition<Boolean>() {

        @Override
        public Boolean apply(WebDriver driver) {
            return (Boolean) ((JavascriptExecutor) driver).executeScript("return (window.jQuery != null) && (jQuery.active === 0);");
        }
    };
  }
}

我不相信有开箱即用的通用方法。我通常会创建一个方法来执行 .waituntilrowcount(2)waituntilvisible() 来轮询一个元素。

您需要等待 Javascript 和 jQuery 完成加载。执行Javascript检查jQuery.active是否为0document.readyState是否为complete,即JS和jQuery加载完成

public boolean waitForJSandJQueryToLoad() {

    WebDriverWait wait = new WebDriverWait(driver, 30);

    // wait for jQuery to load
    ExpectedCondition<Boolean> jQueryLoad = new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        try {
          return ((Long)((JavascriptExecutor)getDriver()).executeScript("return jQuery.active") == 0);
        }
        catch (Exception e) {
          // no jQuery present
          return true;
        }
      }
    };

    // wait for Javascript to load
    ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        return ((JavascriptExecutor)getDriver()).executeScript("return document.readyState")
        .toString().equals("complete");
      }
    };

  return wait.until(jQueryLoad) && wait.until(jsLoad);
}

我一直在使用这个简单的 do while 来迭代,直到 AJAX 完成。 它一直对我有用。

public void waitForAjax() throws InterruptedException{
    while (true)
    {
        Boolean ajaxIsComplete = (Boolean) ((JavascriptExecutor)driver).executeScript("return jQuery.active == 0");
        if (ajaxIsComplete){
            info("Ajax Call completed. ");
            break;
        }
        Thread.sleep(150);
    }
}