web-dev-qa-db-fra.com

Selenium WebDriver - Comment définir le délai de chargement de la page à l'aide de C #

J'utilise Selenium 2.20 WebDriver pour créer et gérer un navigateur Firefox avec C #. Pour visiter une page, j'utilise le code suivant, en définissant les délais d'expiration du pilote avant de visiter l'URL:

driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5)); // Set implicit wait timeouts to 5 secs
driver.Manage().Timeouts().SetScriptTimeout(new TimeSpan(0, 0, 0, 5));  // Set script timeouts to 5 secs
driver.Navigate().GoToUrl(myUrl);   // Goto page url

Le problème est que parfois les pages prennent une éternité à charger, et il semble que le délai par défaut pour une page à charger à l'aide de Selenium WebDriver est de 30 secondes, ce qui est trop long. Et je ne pense pas que les délais d'attente que je fixe s'appliquent au chargement d'une page à l'aide de la méthode GoToUrl ().

J'essaie donc de comprendre comment définir un délai d'attente pour une page à charger, cependant, je ne trouve aucune propriété ou méthode qui fonctionne réellement. Le délai d'expiration de 30 secondes par défaut semble également s'appliquer lorsque je clique sur un élément.

Existe-t-il un moyen de définir le délai de chargement de la page sur une valeur spécifique afin que lorsque j'appelle la méthode GoToUrl (), il n'attende que l'heure spécifiée avant de continuer?

35
KabanaSoft
driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(5);

Remarque: driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(5)) est désormais obsolète.

31
Josh

Dans le cas où cela aiderait quiconque cherche toujours la réponse à cela, l'API C # WebDriver contient désormais la méthode appropriée.

driver.Manage().Timeouts().SetPageLoadTimeout(timespan)
31
ktam33

Avec cela, vous devriez pouvoir déclarer explicitement une attente.

WebDriverWait wait = new WebDriverWait(browser, new TimeSpan(time in seconds));
wait.until(Your condition)

vous pouvez également modifier le temps d'attente implicite

driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));

Je pense que c'est la syntaxe en C #. (pas sûr)

En Ruby c'est

@driver.manage.timeouts.implicit_wait = 30
@wait = Selenium::WebDriver::Wait.new(:timeout => 30)
4
Amey

j'ai trouvé la solution à ce problème. Lors de la création d'un nouveau FirefoxDriver, il y a des surcharges dans le constructeur qui vous permettent de spécifier un délai d'expiration de commande qui est le temps maximum d'attente pour chaque commande, et il semble fonctionner lors de l'appel de la méthode GoToUrl ():

driver = new FirefoxDriver(new FirefoxBinary(), profile, new TimeSpan(0, 0, 0, timeoutSeconds));

lien vers la documentation du constructeur FirefoxDriver pour référence: http://Selenium.googlecode.com/svn/trunk/docs/api/dotnet/html/M_OpenQA_Selenium_Firefox_FirefoxDriver__ctor_2.htm

J'espère que cela aide quelqu'un d'autre qui rencontre ce problème.

4
KabanaSoft

À partir de 2018: En plus de ceux-ci:

driver.Manage().Timeouts().ImplicitWait.Add(System.TimeSpan.FromSeconds(5));      
driver.Manage().Timeouts().PageLoad.Add(System.TimeSpan.FromSeconds(5));
driver.Manage().Timeouts().AsynchronousJavaScript.Add(timespan));

attendez respectivement la recherche d'un élément, le chargement d'une page et l'attente d'un script. Il y a:

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
2
Ywapom

Nous, les Brésiliens, avons un mot pour des solutions de contournement "Gambiarra" ... Eh bien ... au moins, ils font le travail ... Voici le mien:

var url = "www.your.url.here"
try {
    DRIVER.Navigate().GoToUrl(url);
} catch {
    // Here you can freely use the Selenium's By class:
    WaitElement(By.Id("element_id_or_class_or_whatever_to_be_waited"), 60);
}
// rest of your application

Ce que ma WaitElement(By, int) fait:

/// <summary>
/// Waits until an element of the type <paramref name="element"/> to show in the screen.
/// </summary>
/// <param name="element">Element to be waited for.</param>
/// <param name="timeout">How long (in seconds) it should be waited for.</param>
/// <returns>
/// False: Never found the element. 
/// True: Element found.
/// </returns>
private bool WaitElement(By element, int timeout)
{
    try {
        Console.WriteLine($" - Waiting for the element {element.ToString()}");
        int timesToWait = timeout * 4; // Times to wait for 1/4 of a second.
        int waitedTimes = 0; // Times waited.
        // This setup timesout at 7 seconds. you can change the code to pass the 

        do {
            waitedTimes++;
            if (waitedTimes >= timesToWait) {
                Console.WriteLine($" -- Element not found within (" +
                $"{(timesToWait * 0.25)} seconds). Canceling section...");
                return false;
            }
            Thread.Sleep(250);
        } while (!ExistsElement(element));

        Console.WriteLine($" -- Element found. Continuing...");
    //  Thread.Sleep(1000); // may apply here
        return true;
    } catch { throw; }
}

Après cela, vous pouvez jouer avec timeout...

Faites By les choses que vous remarquez que les chargements durent dans la page (comme les éléments javascript et les captchas) en vous souvenant: cela commencera à travailler le // rest of your application Avant que la page ne se charge complètement, donc il peut être agréable de mettre un Thread.Sleep(1000) à la fin juste pour être sûr ...

Notez également que cette méthode sera appelée APRÈS le délai d'expiration standard de 60 secondes de la fonction DRIVER.Navigate().GoToUrl(url); de Selenium

Pas le meilleur, mais ... comme je l'ai dit: un bon gambiarra fait le travail ...

2
Marko Marchiori

Les délais d'attente de chargement de page ne sont pas encore implémentés dans les liaisons .NET. J'espère qu'ils le seront bientôt.

1
JimEvans

Pour tous ceux qui veulent l'effet inverse: définir un délai d'attente supérieur à 60s.

Vous devez utiliser les deux:

new FirefoxDriver(FirefoxDriverService.CreateDefaultService(), new FirefoxOptions(), TimeSpan.FromSeconds(120))

et

driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(120);

La new FirefoxDriver(binary, profile, timeSpan) est obsolète.

1
imba-tjd
driver.Manage().Timeouts().SetPageLoadTimeout(timespan) 

ne marche pas.

Cela marche. Utilisez une syntaxe de définition de propriété.

driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(15);
0
T. Muir