Equivalent de waitForVisible / waitForElementPresent dans les tests Selenium WebDriver utilisant Java?

Avec les tests Selenium “HTML” (créés avec Selenium IDE ou manuellement), vous pouvez utiliser des commandes très pratiques comme WaitForElementPresent ou WaitForVisible .

  waitForElementPresent id=saveButton   

Lors du codage des tests Selenium en Java (Webdriver / Selenium RC – je ne suis pas sûr de la terminologie utilisée ici), y a-t-il quelque chose de similaire intégré ?

Par exemple, pour vérifier qu’une boîte de dialog (qui prend du temps à s’ouvrir) est visible …

 WebElement dialog = driver.findElement(By.id("reportDialog")); assertTrue(dialog.isDisplayed()); // often fails as it isn't visible *yet* 

Quelle est la méthode la plus propre et la plus efficace pour coder cette vérification?

Ajouter des Thread.sleep() partout serait moche et fragile, et rouler vos propres boucles semble trop maladroit aussi …

Attentes implicites et explicites

Attente implicite

Une attente implicite consiste à demander à WebDriver d’interroger le DOM pendant un certain temps lorsqu’il tente de trouver un élément ou des éléments s’ils ne sont pas immédiatement disponibles. Le paramètre par défaut est 0. Une fois définie, l’attente implicite est définie pour la durée de vie de l’instance de l’object WebDriver.

 driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); 

Attente explicite + Conditions attendues

Une attente explicite est un code que vous définissez pour attendre qu’une certaine condition se produise avant de continuer dans le code. Le cas le plus défavorable est Thread.sleep (), qui définit la condition sur une période exacte à attendre. Il existe des méthodes pratiques qui vous aident à écrire du code qui attendra aussi longtemps que nécessaire. WebDriverWait en combinaison avec ExpectedCondition est une solution possible.

 WebDriverWait wait = new WebDriverWait(driver, 10); WebElement element = wait.until( ExpectedConditions.visibilityOfElementLocated(By.id("someid"))); 
 WebElement myDynamicElement = (new WebDriverWait(driver, 10)) .until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement"))); 

Cela attend jusqu’à 10 secondes avant de lancer une TimeoutException ou si l’élément détecte que l’élément le renverra dans 0 – 10 secondes. WebDriverWait appelle par défaut le ExpectedCondition toutes les 500 millisecondes jusqu’à ce qu’il retourne avec succès. Un retour réussi est pour le type ExpectedCondition si Boolean renvoie la valeur de retour true ou not null pour tous les autres types ExpectedCondition.


 WebDriverWait wait = new WebDriverWait(driver, 10); WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid"))); 

L’élément est cliquable – il est affiché et activé.

De WebDriver docs: Attentes explicites et implicites

Eh bien, le fait est que vous ne voulez probablement pas que le test se déroule indéfiniment. Vous voulez simplement attendre plus longtemps avant que la bibliothèque décide que l’élément n’existe pas. Dans ce cas, la solution la plus élégante consiste à utiliser l’attente implicite, conçue uniquement pour cela:

 driver.manage().timeouts().implicitlyWait( ... ) 

Pour les éléments individuels, le code ci-dessous pourrait être utilisé:

 private boolean isElementPresent(By by) { try { driver.findElement(by); return true; } catch (NoSuchElementException e) { return false; } } for (int second = 0;; second++) { if (second >= 60){ fail("timeout"); } try { if (isElementPresent(By.id("someid"))){ break; } } catch (Exception e) { } Thread.sleep(1000); }