179 votes

Tester si un élément est présent en utilisant Selenium WebDriver ?

Existe-t-il un moyen de tester si un élément est présent ? Toute méthode findElement se terminerait par une exception, mais ce n'est pas ce que je veux, car il se peut qu'un élément ne soit pas présent et ce n'est pas grave, ce n'est pas un échec du test, donc une exception ne peut pas être la solution.

J'ai trouvé ce poste : Selenium c# Webdriver : Attendre que l'élément soit présent Mais c'est pour C# et je ne suis pas très bon dans ce domaine. Quelqu'un peut-il traduire le code en Java ? Je suis désolé les gars, je l'ai essayé dans Eclipse mais je n'arrive pas à le traduire en code Java.

Voici le code :

public static class WebDriverExtensions{
    public static IWebElement FindElement(this IWebDriver driver, By by, int timeoutInSeconds){

        if (timeoutInSeconds > 0){
            var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
            return wait.Until(drv => drv.FindElement(by));
        }

        return driver.FindElement(by);
    }
}

0 votes

J'ai quelques méthodes qui fonctionnent très efficacement pour vérifier la présence d'un objet, mais cela dépend de ce que vous voulez en faire. Par exemple, voulez-vous chercher l'élément jusqu'à ce qu'il existe, jusqu'à ce qu'il n'existe plus ou voulez-vous simplement essayer de le trouver ?

1 votes

Java est très similaire à C#. Je pense que l'un des principaux problèmes que vous rencontrez ici est qu'en Java, on parle de WebElement au lieu de IWebElement.

0 votes

Connaissez-vous la méthode de l'attente implicite ? En configurant cette méthode au début du test, vous ne devez jamais vérifier l'existence d'un élément, car elle utilise la valeur d'attente implicite pour interroger, mais si elle dépasse cette valeur, elle lève une exception.

304voto

el roso Points 663

Utilisez findElements au lieu de findElement .

findElements retournera une liste vide si aucun élément correspondant n'est trouvé au lieu d'une exception.

Pour vérifier qu'un élément est présent, vous pouvez essayer ceci

Boolean isPresent = driver.findElements(By.yourLocator).size() > 0

Ceci retournera true si au moins un élément est trouvé et false s'il n'existe pas.

La documentation officielle recommande cette méthode :

findElement ne doit pas être utilisé pour rechercher des éléments non présents, utilisez plutôt findElements(By) et affirmez une réponse de longueur nulle.

36 votes

Cela augmentera considérablement le temps nécessaire à l'exécution de vos tests. Vous ne pouvez pas utiliser cette technique partout.

0 votes

Je comprends que ce n'est peut-être pas la meilleure solution pour tous les scénarios, mais elle fonctionne bien dans mon cas, où je dois utiliser une boucle do-while pour juger si un élément peut être localisé ou non à chaque fois.

10 votes

@Droogans - Je n'ajouterai pas de temps à vos tests. La raison pour laquelle il ne le fait pas est que l'attente implicite par défaut est toujours de 0. Si vous avez augmenté l'attente implicite par défaut, alors je suis d'accord que cela se produirait, mais cela ne semble pas être le cas ici.

59voto

Dennis Points 262

Que diriez-vous d'une méthode privée qui recherche simplement l'élément et détermine s'il est présent comme ceci :

private boolean existsElement(String id) {
    try {
        driver.findElement(By.id(id));
    } catch (NoSuchElementException e) {
        return false;
    }
    return true;
}

Cela serait assez facile et fait l'affaire.

Edit : vous pourriez même aller plus loin et prendre un By elementLocator comme paramètre, ce qui élimine les problèmes si vous voulez trouver l'élément par autre chose que id.

5 votes

Oui, c'est ce qu'il faut faire. Je ne comprends pas pourquoi les gens ignorent cette méthode et comptent les éléments correspondants pour voir si le résultat est 0.

47 votes

Eh bien, je dois dire que l'utilisation des exceptions pour réguler le flux du programme n'est pas la meilleure façon de procéder.

2 votes

Hein ? C'était votre suggestion ! C'est une bonne façon de procéder si votre test s'attend à ne pas trouver l'élément. Comme vous le montrez, il suffit de retourner null et assert.isnull ou isnotnull, ce qui est une façon significative de tester si une chose existe.

15voto

Tango Ben Points 39

J'ai constaté que cela fonctionne pour Java :

WebDriverWait waiter = new WebDriverWait(driver, 5000);
waiter.until( ExpectedConditions.presenceOfElementLocated(by) );
driver.FindElement(by);

19 votes

presenceOfElementLocated lèvera une exception si l'élément n'est pas trouvé lors d'une tentative particulière. Pour éviter cela, ajoutez un wait.ignoring(NoSuchElementException.class); entre la première et la deuxième ligne.

9voto

RedDeckWins Points 719
public static WebElement FindElement(WebDriver driver, By by, int timeoutInSeconds)
{
    WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds);
    wait.until( ExpectedConditions.presenceOfElementLocated(by) ); //throws a timeout exception if element not present after waiting <timeoutInSeconds> seconds
    return driver.findElement(by);
}

6voto

Tasha Points 33

J'ai eu le même problème. Pour moi, selon le niveau de permission de l'utilisateur, certains liens, boutons et autres éléments n'apparaissent pas sur la page. Une partie de ma suite consistait à tester que les éléments qui DEVRAIENT être absents, le sont. J'ai passé des heures à essayer de résoudre ce problème. J'ai finalement trouvé la solution parfaite.

Ce que cela fait, c'est dire au navigateur de rechercher tous les éléments spécifiés. Si le résultat est 0 cela signifie qu'aucun élément basé sur la spécification n'a été trouvé. Ensuite, j'ai demandé au code d'exécuter une instruction if pour me faire savoir qu'il n'a pas été trouvé.

Ceci est en C# Il faudrait donc traduire les documents suivants Java . Mais ça ne devrait pas être trop difficile.

public void verifyPermission(string link)
{
    IList<IWebElement> adminPermissions = driver.FindElements(By.CssSelector(link));
    if (adminPermissions.Count == 0)
    {
        Console.WriteLine("User's permission properly hidden");
    }
}

Il existe également une autre voie que vous pouvez emprunter en fonction de ce dont vous avez besoin pour votre test.

L'extrait suivant vérifie si un élément très spécifique existe sur la page. En fonction de l'existence de l'élément, le test exécute un if else.

Si l'élément existe et qu'il est affiché sur la page, j'ai console.write faites-le moi savoir et passez à autre chose. Si l'élément en question existe, je ne peux pas exécuter le test dont j'avais besoin, ce qui est la raison principale pour laquelle j'ai eu besoin de mettre cela en place.

Si l'élément n'existe pas, et n'est pas affiché sur la page. J'ai le else dans le if else pour exécuter le test.

IList<IWebElement> deviceNotFound = driver.FindElements(By.CssSelector("CSS LINK GOES HERE"));
//if the element specified above results in more than 0 elements and is displayed on page execute the following, otherwise execute whats in the else statement
if (deviceNotFound.Count > 0 && deviceNotFound[0].Displayed){
    //script to execute if element is found
} else {
    //Test script goes here.
}

Je sais que j'ai un peu de retard dans la réponse à l'OP. J'espère que cela aidera quelqu'un !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X