Recherche…


Types d'attentes dans Selenium WebDriver

Lors de l'exécution d'une application Web, il est nécessaire de prendre en compte le temps de chargement. Si votre code tente d'accéder à un élément qui n'est pas encore chargé, WebDriver lancera une exception et votre script s'arrêtera.

Il existe trois types de Waits -

  • Attentes implicites
  • Attentes explicites
  • Attentes Courantes

Les attentes implicites sont utilisées pour définir le temps d'attente tout au long du programme, tandis que les attentes explicites ne sont utilisées que sur des parties spécifiques.


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. Les attentes implicites sont essentiellement votre façon de dire à WebDriver la latence que vous souhaitez voir si l'élément Web spécifié n'est pas présent et que WebDriver recherche. 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'objet WebDriver. L'attente implicite est déclarée dans la partie instanciation du code à l'aide de l'extrait de code suivant.

Exemple en Java :

driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
// You need to import the following class - import java.util.concurrent.TimeUnit;

Exemple en C # :

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

Donc, dans ce cas, vous dites à WebDriver qu'il doit attendre 15 secondes dans le cas où l'élément spécifié n'est pas disponible sur l'interface utilisateur (DOM).


Attente explicite

Vous pouvez rencontrer des cas où un élément prend plus de temps à charger. Définir l'attente implicite pour de tels cas n'a pas de sens car le navigateur attendra inutilement le même temps pour chaque élément, augmentant ainsi le temps d'automatisation. L'attente explicite aide ici en contournant l'attente implicite pour certains éléments spécifiques.

Les attentes explicites sont des attentes intelligentes limitées à un élément Web particulier. En utilisant des attentes explicites, vous indiquez à WebDriver au maximum qu'il faut attendre X unités de temps avant d'abandonner.

Les attentes explicites sont effectuées à l'aide des classes WebDriverWait et ExpectedConditions. Dans l'exemple ci-dessous, nous allons attendre jusqu'à 10 secondes pour qu'un élément dont l'identifiant est un nom d'utilisateur soit visible avant de passer à la commande suivante. Voici les étapes.

Exemple en Java :

//Import these two packages:
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

//Declare a WebDriverWait variable. In this example, we will use myWaitVar as the name of the variable.
WebDriverWait myWaitVar = new WebDriverWait(driver, 30);

//Use myWaitVar with ExpectedConditions on portions where you need the explicit wait to occur. In this case, we will use explicit wait on the username input before we type the text tutorial onto it.
myWaitVar.until(ExpectedConditions.visibilityOfElementLocated(By.id(“username”)));
driver.findElement(By.id(“username”)).sendKeys(“tutorial”);

La classe ExpectedConditions a des conditions communes prédéfinies pour attendre un élément. Cliquez ici pour voir la liste de ces conditions dans la liaison Java.

Exemple en C # :

using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.PhantomJS;

// You can use any other WebDriver you want, such as ChromeDriver.
using (var driver = new PhantomJSDriver())
{
    driver.Navigate().GoToUrl("http://somedomain/url_that_delays_loading");

    // We aren't going to use it more than once, so no need to declare this a variable.
    new WebDriverWait(driver, TimeSpan.FromSeconds(10))
        .Until(ExpectedConditions.ElementIsVisible(By.Id("element-id")));

    // After the element is detected by the previous Wait, 
    // it will display the element's text
    Console.WriteLine(driver.FindElement(By.Id("element-id")).Text);
}

Dans cet exemple, le système attendra 10 secondes jusqu'à ce que l'élément soit visible. Si l'élément n'est pas visible après l'expiration du délai, le WebDriver lancera une WebDriverTimeoutException .

Remarque: Si l'élément est visible avant l'expiration du délai de 10 secondes, le système procédera immédiatement à un traitement ultérieur.


Attendez

Contrairement à l'attente implicite et explicite, l'attente fluide utilise deux paramètres. Valeur de temporisation et fréquence d'interrogation. Disons que nous avons une valeur de délai d'attente de 30 secondes et une fréquence d'interrogation de 2 secondes. WebDriver vérifie l'élément après toutes les 2 secondes jusqu'à la valeur du délai d'attente (30 secondes). Une fois que la valeur du délai d'expiration est dépassée sans aucun résultat, une exception est levée. Vous trouverez ci-dessous un exemple de code indiquant la mise en œuvre d'une attente fluide.

Exemple en Java :

Wait wait = new FluentWait(driver).withTimeout(30, SECONDS).pollingEvery(2, SECONDS).ignoring(NoSuchElementException.class);


WebElement testElement = wait.until(new Function() {
    public WebElement apply(WebDriver driver) {
        return driver.findElement(By.id("testId"));
    }
});

Un autre avantage d'utiliser l'attente fluide est que nous pouvons ignorer des types spécifiques d'exceptions (par ex. NoSuchElementExceptions) en attendant. En raison de toutes ces dispositions, l'attente fluide est utile dans les applications AJAX ainsi que dans les scénarios où le temps de chargement des éléments varie souvent. L'utilisation stratégique d'attentes fluides améliore considérablement les efforts d'automatisation.


Différents types de conditions d'attente explicites

En attente explicite, vous vous attendez à une condition. Par exemple, vous voulez attendre qu'un élément soit cliquable.

Voici une démonstration de quelques problèmes communs.

S'il vous plaît noter: Dans tous ces exemples , vous pouvez utiliser tout By un localisateur, comme classname , xpath , link text , tag name la cssSelector tag name ou cssSelector


Attendez que l'élément soit visible

Par exemple, si le chargement de votre site Web prend un certain temps, vous pouvez attendre que la page se charge complètement et que votre élément soit visible par le WebDriver.

C #

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.ElementIsVisible(By.Id("element-id")));

Java

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("element-id")));

Attendez que l'élément ne soit plus visible

Comme avant, mais inversé.

C #

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.InvisibilityOfElementLocated(By.Id("element-id")));

Java

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("element-id")));

Attendez que du texte soit présent dans l'élément spécifié

C #

IWebElement element = driver.FindElement(By.Id("element-id"));

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.TextToBePresentInElement(element, "text"));

Java

WebElement element = driver.findElement(By.id("element-id"));

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.textToBePresentInElement(element, "text"));

Si vous allez au lien ci-dessus, vous verrez toutes les conditions d'attente.

La différence entre l'utilisation de ces conditions d'attente réside dans leur paramètre d'entrée.

Cela signifie que vous devez passer WebElement si son paramètre d'entrée est WebElement, vous devez passer le localisateur d'élément s'il utilise le localisateur By comme paramètre d'entrée.

Choisissez judicieusement le type de condition d'attente que vous souhaitez utiliser.

En attente de demandes Ajax à remplir

C #

using OpenQA.Selenium
using OpenQA.Selenium.Chrome;
using System.Threading;

namespace WebDriver Tests
{
    class WebDriverWaits
    {
        static void Main()
        {
            IWebDriver driver = new ChromeDriver(@"C:\WebDriver");
            
            driver.Navigate().GoToUrl("page with ajax requests");
            CheckPageIsLoaded(driver);

            // Now the page is fully loaded, you can continue with further tests.
        }

        private void CheckPageIsLoaded(IWebDriver driver)
        {
            while (true)
            {
                bool ajaxIsComplete = (bool)(driver as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0");
                if (ajaxIsComplete)
                    return;
                Thread.Sleep(100);
            }
        }
    }
}

Cet exemple est utile pour les pages où des requêtes ajax sont faites, ici nous utilisons le IJavaScriptExecutor pour exécuter notre propre code JavaScript. Comme il est dans un while en boucle continue à fonctionner jusqu'à ce que ajaxIsComplete == true et ainsi l'instruction de retour est exécutée.

Nous vérifions que toutes les requêtes ajax sont complètes en confirmant que jQuery.active est égal à 0 . Cela fonctionne car chaque fois qu'une nouvelle requête ajax est faite, jQuery.active est incrémenté et chaque fois qu'une requête est complétée, il est décrémenté, de là on peut déduire que lorsque jQuery.active == 0 toutes les requêtes ajax doivent être complètes.

Fluent Wait

Fluent wait est une super-classe d'attente explicite ( WebDriverWait ) qui est plus configurable car elle peut accepter un argument pour la fonction wait. Je vais laisser une attente implicite , car il est préférable de l'éviter.

Utilisation (Java):

Wait wait = new FluentWait<>(this.driver)
        .withTimeout(driverTimeoutSeconds, TimeUnit.SECONDS)
        .pollingEvery(500, TimeUnit.MILLISECONDS)
        .ignoring(StaleElementReferenceException.class)
        .ignoring(NoSuchElementException.class)
        .ignoring(ElementNotVisibleException.class);

WebElement foo = wait.until(ExpectedConditions.presenceOfElementLocated(By.yourBy));

// or use your own predicate:
WebElement foo = wait.until(new Function() {
  public WebElement apply(WebDriver driver) {
    return element.getText().length() > 0;
  }
});

Lorsque vous utilisez l' attente explicite avec ses valeurs par défaut, il s'agit simplement d'un FluentWait<WebDriver> avec les valeurs par défaut suivantes: DEFAULT_SLEEP_TIMEOUT = 500; et en ignorant NotFoundException .

Attendez

Chaque instance de FluentWait définit la durée maximale d'attente d'une condition, ainsi que la fréquence à laquelle vérifier la condition. En outre, l'utilisateur peut configurer l'attente pour ignorer certains types d'exceptions en attente, telles que NoSuchElementExceptions lors de la recherche d'un élément sur la page. Il est associé au pilote.

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, SECONDS) //actuall wait for the element to pe present
.pollingEvery(5, SECONDS) //selenium will keep looking for the element after every 5seconds
.ignoring(NoSuchElementException.class); //while ignoring this condition
wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.id("username"));


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow