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?
driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(5);
Remarque: driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(5))
est désormais obsolète.
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)
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)
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.
À 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));
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 ...
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.
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.
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);