151 votes

Selenium attend que le document soit prêt

Quelqu'un peut-il me dire comment faire en sorte que Selenium attende le chargement complet de la page ? Je veux quelque chose de générique, je sais que je peux configurer WebDriverWait et appeler quelque chose comme 'find' pour le faire attendre mais je ne veux pas aller aussi loin. J'ai juste besoin de tester que la page se charge avec succès et de passer à la page suivante à tester.

J'ai trouvé quelque chose en .net mais je n'ai pas réussi à le faire fonctionner en java ...

IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));
wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));

Quelqu'un a-t-il une idée ?

1voto

Hazel Troost Points 376

La réponse de Ben Dryer n'a pas compilé sur ma machine ( "The method until(Predicate<WebDriver>) is ambiguous for the type WebDriverWait" ).

Version de Java 8 fonctionnelle :

Predicate<WebDriver> pageLoaded = wd -> ((JavascriptExecutor) wd).executeScript(
        "return document.readyState").equals("complete");
new FluentWait<WebDriver>(driver).until(pageLoaded);

Version de Java 7 :

Predicate<WebDriver> pageLoaded = new Predicate<WebDriver>() {

        @Override
        public boolean apply(WebDriver input) {
            return ((JavascriptExecutor) input).executeScript("return document.readyState").equals("complete");
        }

};
new FluentWait<WebDriver>(driver).until(pageLoaded);

1voto

BlackHawkDesign Points 452

L'attente de l'événement document.ready n'est pas la seule solution à ce problème, car ce code est toujours dans une condition de course : Parfois, ce code est déclenché avant que l'événement click ne soit traité, ce qui entraîne un retour direct, puisque le navigateur n'a pas encore commencé à charger la nouvelle page.

Après quelques recherches, j'ai trouvé un article sur Obay la chèvre de test qui a une solution pour ce problème. Le code c# pour cette solution est quelque chose comme ceci :

 IWebElement page = null;
 ...
 public void WaitForPageLoad()
 {
    if (page != null)
    {
       var waitForCurrentPageToStale = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
       waitForCurrentPageToStale.Until(ExpectedConditions.StalenessOf(page));
    }

    var waitForDocumentReady = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    waitForDocumentReady.Until((wdriver) => (driver as IJavaScriptExecutor).ExecuteScript("return document.readyState").Equals("complete"));

    page = driver.FindElement(By.TagName("html"));

}

` Je lance cette méthode directement après la méthode driver.navigate.gotourl, pour qu'elle obtienne une référence de la page dès que possible. Amusez-vous bien avec !

1voto

elazzam Points 91

Normalement, lorsque le sélénium ouvre une nouvelle page à partir d'un clic, d'un submit ou d'une méthode get, il attend que la page soit chargée, mais le problème est que lorsque la page a un appel xhr (ajax), il n'attendra jamais que le xhr soit chargé, donc créer une nouvelle méthode pour surveiller un xhr et l'attendre sera la bonne.

public boolean waitForJSandJQueryToLoad() {
    WebDriverWait wait = new WebDriverWait(webDriver, 30);
    // wait for jQuery to load
    ExpectedCondition<Boolean> jQueryLoad = new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        try {
            Long r = (Long)((JavascriptExecutor)driver).executeScript("return $.active");
            return r == 0;
        } catch (Exception e) {
            LOG.info("no jquery present");
            return true;
        }
      }
    };

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

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

if $.active == 0 Il n'y a donc pas d'appel à xhrs actif (qui ne fonctionne qu'avec jQuery). pour l'appel javascript ajax vous devez créer une variable dans votre projet et la simuler.

0voto

Vaibhav Pandey Points 9

Vous pouvez écrire une logique pour gérer cela. J'ai écrit une méthode qui retournera le WebElement et cette méthode sera appelée trois fois ou vous pouvez augmenter le temps et ajouter une vérification de nullité pour WebElement Voici un exemple

public static void main(String[] args) {
        WebDriver driver = new FirefoxDriver();
        driver.get("https://www.crowdanalytix.com/#home");
        WebElement webElement = getWebElement(driver, "homekkkkkkkkkkkk");
        int i = 1;
        while (webElement == null && i < 4) {
            webElement = getWebElement(driver, "homessssssssssss");
            System.out.println("calling");
            i++;
        }
        System.out.println(webElement.getTagName());
        System.out.println("End");
        driver.close();
    }

    public static WebElement getWebElement(WebDriver driver, String id) {
        WebElement myDynamicElement = null;
        try {
            myDynamicElement = (new WebDriverWait(driver, 10))
                    .until(ExpectedConditions.presenceOfElementLocated(By
                            .id(id)));
            return myDynamicElement;
        } catch (TimeoutException ex) {
            return null;
        }
    }

0voto

bertanasco Points 91

J'ai exécuté un code javascript pour vérifier si le document est prêt. Cela m'a fait gagner beaucoup de temps dans le débogage des tests Selenium pour les sites qui ont un rendu côté client.

public static boolean waitUntilDOMIsReady(WebDriver driver) {
def maxSeconds = DEFAULT_WAIT_SECONDS * 10
for (count in 1..maxSeconds) {
    Thread.sleep(100)
    def ready = isDOMReady(driver);
    if (ready) {
        break;
    }
}

}

public static boolean isDOMReady(WebDriver driver){
    return driver.executeScript("return document.readyState");
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X