web-dev-qa-db-fra.com

Selenium attend le chargement du contenu Ajax - approche universelle

Existe-t-il une approche universelle permettant à Selenium d'attendre que tout le contenu ajax soit chargé? (non lié à un site Web spécifique - cela fonctionne donc pour tous les sites Web ajax)

16
Fabian Lurz

Vous devez attendre que Javascript et jQuery soient chargés pour terminer le chargement. Exécutez Javascript pour vérifier si jQuery.active est 0 et document.readyState est complete, ce qui signifie que la charge de JS et jQuery est terminée.

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);
}
23
LINGS

Comme Mark Collin l'a décrit dans son livre "Mastering Selenium Webdriver", utilisez JavascriptExecutor pour déterminer si un site Web utilisant jQuery a fini de passer des appels 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);");
        }
    };
  }
}
2
Slav Kurochkin

J'utilise cette simple opération en itérant jusqu'à ce qu'un AJAX soit terminé. Cela fonctionne toujours pour moi. 

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);
    }
}
0
Aniket Wadkar

Je ne crois pas qu'il existe une approche universelle hors de la boîte. Je crée généralement une méthode qui effectue une .waituntilrowcount(2) ou une waituntilvisible() qui interroge un élément.

0
eagle12