J'utilise:
driver.manage().timeouts().implicitlyWait(180, TimeUnit.SECONDS);
Mais il échoue toujours pour l'élément ci-dessous
driver.findElement(By.id("name")).clear();
driver.findElement(By.id("name")).sendKeys("Create_title_01");
J'ai ajouté le code d'attente:
for (int second = 0;; second++) {
if (second >= 120) fail("timeout");
try { if (isElementPresent(By.id("name"))) break; } catch (Exception e) {}
Thread.sleep(1000);
}
L'attente implicite ne devrait-elle pas prendre soin d'attendre jusqu'à ce qu'un élément soit trouvé? Serait-il également préférable d'utiliser l'attente explicite au lieu du code que j'ai ajouté et qui contient Thread.sleep()
?
TL; DR: Toujours utiliser l'attente explicite. Oubliez que l'attente implicite existe.
Voici un rapide aperçu des différences entre attente explicite et implicite:
Attente explicite:
Attente implicite:
Voyons la différence entre attente explicite et attente implicite dans le code source actuel de Selenium. J'ai copié le code de la liaison python de Selenium car python est "facile à lire".
Le code de WebDriverWait.until()
(attente explicite):
def until(self, method, message=''):
end_time = time.time() + self._timeout
while(True):
try:
value = method(self._driver)
if value:
return value
except self._ignored_exceptions:
pass
time.sleep(self._poll)
if(time.time() > end_time):
break
raise TimeoutException(message)
En langage humain, l'attente explicite attend une méthode qui renvoie une valeur True si elle aboutit. Il exécute ensuite à plusieurs reprises la méthode donnée avec un délai entre les deux. Les erreurs attendues de la méthode donnée sont supprimées. Si la méthode donnée renvoie une valeur réelle, l'attente explicite renverra cette valeur. Si le délai est écoulé, une exception de délai d'attente est déclenchée.
Comparez au code de WebDriver.implicitly_wait()
(commentaires supprimés par souci de brièveté):
def implicitly_wait(self, time_to_wait):
self.execute(Command.IMPLICIT_WAIT, {'ms': float(time_to_wait) * 1000})
self.execute()
est WebDriver.execute()
qui appelle RemoteConnection.execute()
qui, à mon avis, constitue un RPC situé du côté éloigné de Selenium.
En langage humain: l'attente implicite envoie un message au "côté distant" du WebDriver Selenium. Le côté distant du sélecteur de sites Web Selenium est la partie de Selenium qui contrôle actuellement le navigateur. Que fait le côté distant avec le message? "Ça dépend". Cela dépend du système d'exploitation, du navigateur et de la version de Selenium. Autant que je sache, rien ne garantit le comportement réel d'une implémentation spécifique.
Les implémentations possibles sont:
Notez que l'attente implicite ne prend effet que sur les méthodes de recherche d'élément (s).
Je n'ai pas cherché le code source des côtés distants de Selenium. Les informations sont recueillies en lisant les commentaires dans les rapports de bugs sur l’attente implicite et explicite dans Selenium :
Ma conclusion: l'attente implicite est mauvaise. Les capacités sont limitées. Le comportement est non documenté et dépend de la mise en œuvre.
L'attente explicite peut faire tout ce qui est implicite, voire plus. Le seul inconvénient de l'attente explicite est un peu plus important à cause des appels multiples de procédures distantes. En outre, l'attente explicite est un peu plus détaillée. Mais cette verbosité rend le code explicite. Et explicite vaut mieux qu'implicite. Droite?
Lectures complémentaires:
Attente implicite - C'est paramètre global applicable pour tous les éléments. Si l'élément apparaît avant l'heure spécifiée, le script commencera à s'exécuter, sinon le script lancera NoSuchElementException
. Meilleure façon d'utiliser la méthode d'installation. N'affectez que By.findelement()
.
Thread.sleep()
- Il sera temps de dormir pour le script, pas le bon moyen à utiliser dans le script car il est en veille sans condition. Et si 2 secondes ne suffisaient pas dans 5% des cas?
Attente explicite : Attendre spécifier contenir/attribut changer. Plus utilisé lorsque l’application donneAJAXun appel au système et obtient des données dynamiques et un rendu sur l’interface utilisateur. Dans ce cas, WebDriverWait
convient.
Avez-vous essayé fluentWait? Une implémentation de l'interface Wait dont le délai d'attente et l'interrogation peut être configuré à la volée . Chaque instance de FluentWait définit le délai d'attente maximal d'une condition, ainsi que la fréquence. avec lequel vérifier l'état. De plus, l'utilisateur peut configurer l'attente pour ignorer des types d'exceptions spécifiques pendant l'attente, tels que NoSuchElementExceptions lors de la recherche d'un élément sur la page.
voir ce lien description d'attente courante
En particulier, j'ai utilisé l'attente courante de cette manière:
public WebElement fluentWait(final By locator){
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(
new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
}
);
return foo; } ;
Comme vous avez remarqué, les éléments d’attente trouvés sont renvoyés. Donc, vous passez simplement le localisateur avec Par type et vous pouvez ensuite effectuer toutes les actions sur l'élément Web trouvé.
fluentWait(By.id("name")).clear();
J'espère que cela vous aide)
Avez-vous essayé d'utiliser ' WebDriverWait '? J'imagine que vous voulez, c'est ceci:
WebDriverWait _wait = new WebDriverWait(driver, new TimeSpan(0, 0, 2)); //waits 2 secs max
_wait.Until(d => d.FindElement(By.Id("name")));
//do your business on the element here :)
À ma connaissance, cela fera à peu près ce que votre code actuel est. Il essaiera constamment la méthode (en ignorant les exceptions non trouvées) jusqu'à ce que le délai d'expiration de la période écoulée soit atteint et qu'un troisième paramètre puisse être entré pour spécifier le sommeil en millisecondes . Désolé si c'est ce que vous attend implicitement aussi!
Edit: J’ai lu un peu aujourd’hui et je comprends mieux votre question et je réalise que cela correspond exactement à ce que votre réglage d’attente implicite devrait faire. Je le laisserai ici au cas où le code lui-même pourrait aider quelqu'un d'autre.
ImplicitWait:
1. Static Wait
2. UnConditional Wait. ( No Conditions were given)
3. Applicable throughout the program
Déclarer l'attente implicite en Java - Selenium:
driver.manage().timeout().implicitWait(20, TimeUnit.Seconds());
Attente explicite:
Déclaration de l'attente explicite dans Java Selenium.
WebDriverWait wait=new WebDriverWait(driver, 20); wait.until(somecondition);
Les attentes implicites sont utilisées pour fournir un temps d'attente (par exemple, 30 secondes) entre chaque étape de test consécutive sur l'ensemble du script ou du programme de test. La prochaine étape n'est exécutée qu'après l'exécution de l'étape précédente (ou quel que soit le temps imparti)
Syntaxe:
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
Les attentes explicites sont utilisées pour arrêter l'exécution jusqu'à ce qu'une condition particulière soit remplie ou que le temps maximum défini soit écoulé. Une attente implicite s’est appliquée entre chaque étape de test consécutive sur l’ensemble du script ou des programmes de test, tandis que les attentes explicites ne sont appliquées que pour une instance particulière.
Syntaxe:
WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver,30);