web-dev-qa-db-fra.com

Selenium WebDriver - Teste si l'élément est présent

existe-t-il un moyen de vérifier 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 que cela ne pose pas de problème, ce n'est pas un échec du test; une exception ne peut donc pas être la solution.

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

C'est 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);
    }
}
137
tester

Utilisez findElements au lieu de findElement.

findElements retournera une liste vide si aucun élément correspondant n'est trouvé à la place 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

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

236
el roso

Qu'en est-il 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;
}

Ce serait assez facile et fait le travail.

Edit: vous pouvez même aller plus loin et prendre un paramètre By elementLocator, ce qui élimine les problèmes si vous souhaitez rechercher l'élément autrement que par id.

49
Dennis

J'ai trouvé que cela fonctionne pour Java:

WebDriverWait waiter = new WebDriverWait(driver, 5000);
waiter.until( ExpectedConditions.presenceOfElementLocated(by) );
driver.FindElement(by);
14
Tango Ben
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);
}
7
RedDeckWins

J'ai eu le même problème. Pour moi, en fonction du niveau d'autorisation d'un utilisateur, certains liens, boutons et autres éléments ne s'afficheront pas sur la page. Une partie de ma suite testait que les éléments qui DEVRAIENT être manquants le sont. J'ai passé des heures à essayer de comprendre cela. J'ai enfin trouvé la solution parfaite. 

Cela indique au navigateur qu'il doit rechercher tous les éléments spécifiés. Si cela donne 0, cela signifie qu'aucun élément basé sur la spécification n'a été trouvé. Ensuite, j'ai le code exécuter une instruction if pour me faire savoir qu'il n'a pas été trouvé.

Ceci est en C#, les traductions doivent donc être effectuées en Java. Mais 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");
    }
}

Vous pouvez également suivre une autre voie 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, je demande au test d'exécuter un if. 

Si l'élément existe et est affiché sur la page, je dois console.write me le faire savoir et passer à autre chose. Si l'élément en question existe, je ne peux pas exécuter le test dont j'avais besoin, ce qui est le principal raisonnement derrière la nécessité de le configurer.

Si l'élément n'existe pas et n'est pas affiché sur la page. J'ai l'autre dans le if if 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 je suis un peu en retard sur la réponse au PO. Espérons que cela aide quelqu'un!

5
Tasha

Essayez ceci: Appelez cette méthode et passez 3 arguments:

  1. Variable WebDriver. // en supposant que driver_variable est le pilote.
  2. L'élément que vous allez vérifier. Devrait fournir Par méthode. // ex: By.id ("id")
  3. Limite de temps en secondes.

Exemple: waitForElementPresent (driver, By.id ("id"), 10);

public static WebElement waitForElementPresent(WebDriver driver, final By by, int timeOutInSeconds) {

        WebElement element; 

        try{
            driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait() 

            WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds); 
            element = wait.until(ExpectedConditions.presenceOfElementLocated(by));

            driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); //reset implicitlyWait
            return element; //return the element
        } catch (Exception e) {
            e.printStackTrace();
        } 
        return null; 
    }
5

Vous pouvez rendre le code plus rapide en raccourcissant le délai d'attente Selenium avant votre instruction try catch.

J'utilise le code suivant pour vérifier si un élément est présent.

protected boolean isElementPresent(By selector) {
    Selenium.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
    logger.debug("Is element present"+selector);
    boolean returnVal = true;
    try{
        Selenium.findElement(selector);
    } catch (NoSuchElementException e){
        returnVal = false;
    } finally {
        Selenium.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
    }
    return returnVal;
}
3
EsotericNonsense

Écrivez la fonction/méthode suivante en utilisant Java:

protected boolean isElementPresent(By by){
        try{
            driver.findElement(by);
            return true;
        }
        catch(NoSuchElementException e){
            return false;
        }
    }

Appelez la méthode avec le paramètre approprié lors de l'assertion.

3
Ripon Al Wasim

si vous utilisez rspec-Webdriver dans Ruby, vous pouvez utiliser ce script en supposant qu'un élément ne devrait vraiment pas être présent et qu'il s'agit d'un test réussi.

Commencez par écrire cette méthode à partir du fichier RB de votre classe.

class Test
 def element_present?
    begin
        browser.find_element(:name, "this_element_id".displayed?
        rescue Selenium::WebDriver::Error::NoSuchElementError
            puts "this element should not be present"
        end
 end

Ensuite, dans votre fichier de spécifications, appelez cette méthode.

  before(:all) do    
    @Test= Test.new(@browser)
  end

 @Test.element_present?.should == nil

Si votre élément n'est PAS présent, vos spécifications seront acceptées, mais si l'élément est présent, une erreur sera générée. Le test a échoué.

2
grayshell

Cela fonctionne pour moi:

 if(!driver.findElements(By.xpath("//*[@id='submit']")).isEmpty()){
    //THEN CLICK ON THE SUBMIT BUTTON
}else{
    //DO SOMETHING ELSE AS SUBMIT BUTTON IS NOT THERE
}
1
Amstel Bytes
public boolean isElementDisplayed() {
        return !driver.findElements(By.xpath("...")).isEmpty();
    }
0
Bogdan Shulga

Vous pouvez essayer l'attente implicite: 

WebDriver driver = new FirefoxDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
driver.Url = "http://somedomain/url_that_delays_loading";
IWebElement myDynamicElement = driver.FindElement(By.Id("someDynamicElement"));

`

Ou vous pouvez essayer explicitement attendre un:

IWebDriver driver = new FirefoxDriver();
driver.Url = "http://somedomain/url_that_delays_loading";
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
    {
        return d.FindElement(By.Id("someDynamicElement"));
    });

`

Explicit vérifiera si l'élément est présent avant une action. Une attente implicite peut être appelée à chaque endroit du code. Par exemple, après certaines actions AJAX.

Plus vous pouvez trouver à page SeleniumHQ

0
streser

Pour trouver un élément particulier, présent ou non, nous devons utiliser la méthode findElements () à la place de findElement () ..

int i=driver.findElements(By.xpath(".......")).size();
if(i=0)
System.out.println("Element is not present");
else
System.out.println("Element is present");

cela a fonctionné pour moi ... me suggère si je me trompe .. 

0
Subbarao Gaddam

Cela devrait le faire:

try {
    driver.findElement(By.id(id));
} catch (NoSuchElementException e) {
    //do what you need here if you were expecting
    //the element wouldn't exist
}
0
Scott Helme

Donner mon extrait de code. Ainsi, la méthode ci-dessous vérifie si un bouton d'élément Web «Créer une nouvelle application» aléatoire existe ou non sur une page. Notez que j'ai utilisé la période d'attente pendant 0 secondes.

public boolean isCreateNewApplicationButtonVisible(){
    WebDriverWait zeroWait = new WebDriverWait(driver, 0);
    ExpectedCondition<WebElement> c = ExpectedConditions.presenceOfElementLocated(By.xpath("//input[@value='Create New Application']"));
    try {
        zeroWait.until(c);
        logger.debug("Create New Application button is visible");
        return true;
    } catch (TimeoutException e) {
        logger.debug("Create New Application button is not visible");
        return false;
    }
}
0
Rambo7

Je voudrais utiliser quelque chose comme (avec Scala [le code dans le vieux "bon" Java 8 peut ressembler à ceci]):

object SeleniumFacade {

  def getElement(bySelector: By, maybeParent: Option[WebElement] = None, withIndex: Int = 0)(implicit driver: RemoteWebDriver): Option[WebElement] = {
    val elements = maybeParent match {
      case Some(parent) => parent.findElements(bySelector).asScala
      case None => driver.findElements(bySelector).asScala
    }
    if (elements.nonEmpty) {
      Try { Some(elements(withIndex)) } getOrElse None
    } else None
  }
  ...
}

donc alors,

val maybeHeaderLink = SeleniumFacade getElement(By.xpath(".//a"), Some(someParentElement))
0
ses

La manière la plus simple que j'ai trouvée en Java est:

List<WebElement> linkSearch=  driver.findElements(By.id("linkTag"));
int checkLink=linkSearch.size();
if(checkLink!=0){  //do something you want}
0
i_am_leo