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 ?

7voto

Ram Bharath Points 87
WebDriverWait wait = new WebDriverWait(dr, 30);
wait.until(ExpectedConditions.jsReturnsValue("return document.readyState==\"complete\";"));

4voto

S.Akruwala Points 506

Pour C# NUnit, vous devez convertir WebDriver en JSExecuter et ensuite exécuter le script pour vérifier si l'état document.ready est complet ou non. Vérifiez le code ci-dessous pour référence :

 public static void WaitForLoad(IWebDriver driver)
    {
        IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
        int timeoutSec = 15;
        WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSec));
        wait.Until(wd => js.ExecuteScript("return document.readyState").ToString() == "complete");
    }

Cela attendra que la condition soit satisfaite ou que le délai d'attente soit dépassé.

3voto

Roei Sabag Points 31

Pour le chargement initial de la page, j'ai remarqué que le fait de "maximiser" la fenêtre du navigateur attend pratiquement que le chargement de la page soit terminé (y compris les sources).

Remplacer :

AppDriver.Navigate().GoToUrl(url);

Avec :

public void OpenURL(IWebDriver AppDriver, string Url)
            {
                try
                {
                    AppDriver.Navigate().GoToUrl(Url);
                    AppDriver.Manage().Window.Maximize();
                    AppDriver.SwitchTo().ActiveElement();
                }
                catch (Exception e)
                {
                    Console.WriteLine("ERR: {0}; {1}", e.TargetSite, e.Message);
                    throw;
                }
            }

que l'utilisation :

OpenURL(myDriver, myUrl);

Cela chargera la page, attendra qu'elle soit terminée, la maximisera et se concentrera sur elle. Je ne sais pas pourquoi c'est comme ça mais ça marche.

Si vous voulez attendre le chargement de la page après avoir cliqué sur suivant ou tout autre déclencheur de navigation autre que "Navigate()", la réponse de Ben Dyer (dans ce fil de discussion) fera le travail.

2voto

sidanmor Points 2868

Dans Nodejs vous pouvez l'obtenir via des promesses ...

Si vous écrivez ce code, vous pouvez être sûr que la page est entièrement chargée lorsque vous arrivez à l'étape...

driver.get('www.sidanmor.com').then(()=> {
    // here the page is fully loaded!!!
    // do your stuff...
}).catch(console.log.bind(console));

Si vous écrivez ce code, vous allez naviguer, et selenium va attendre 3 secondes...

driver.get('www.sidanmor.com');
driver.sleep(3000);
// you can't be sure that the page is fully loaded!!!
// do your stuff... hope it will be OK...

Extrait de la documentation de Selenium :

this.get( url ) Thenable

Planifie une commande pour naviguer vers l'URL donnée.

Retourne une promesse qui sera résolue lorsque le document aura été modifié. chargement terminé .

Documentation Selenium (Nodejs)

1voto

qub1n Points 817

Jetez un coup d'œil à tapisserie web-framework. Vous pouvez télécharger le code source là.

L'idée est de signaler que la page est prête par l'attribut html de body. Vous pouvez utiliser cette idée pour ignorer les cas de sue compliqués.

<html>
<head>
</head>
<body data-page-initialized="false">
    <p>Write you page here</p>

    <script>
    $(document).ready(function () {
        $(document.body).attr('data-page-initialized', 'true');
    });
    </script>  
</body>
</html>

Et ensuite créer une extension de Selenium webdriver (selon le framework tapestry)

public static void WaitForPageToLoad(this IWebDriver driver, int timeout = 15000)
{
    //wait a bit for the page to start loading
    Thread.Sleep(100);

    //// In a limited number of cases, a "page" is an container error page or raw HTML content
    // that does not include the body element and data-page-initialized element. In those cases,
    // there will never be page initialization in the Tapestry sense and we return immediately.
    if (!driver.ElementIsDisplayed("/html/body[@data-page-initialized]"))
    {                
        return;
    }

    Stopwatch stopwatch = Stopwatch.StartNew();

    int sleepTime = 20;

    while(true)
    {
        if (driver.ElementIsDisplayed("/html/body[@data-page-initialized='true']"))
        {
            return;
        }

        if (stopwatch.ElapsedMilliseconds > 30000)
        {
            throw new Exception("Page did not finish initializing after 30 seconds.");
        }

        Thread.Sleep(sleepTime);
        sleepTime *= 2; // geometric row of sleep time
    }          
}

Utiliser l'extension ElementIsDisplayed écrit par Alister Scott .

public static bool ElementIsDisplayed(this IWebDriver driver, string xpath)
{
    try
    {
        return driver.FindElement(By.XPath(xpath)).Displayed;
    }
    catch(NoSuchElementException)
    {
        return false;
    }
}

Et enfin créer le test :

driver.Url = this.GetAbsoluteUrl("/Account/Login");            
driver.WaitForPageToLoad();

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