web-dev-qa-db-fra.com

Comment attendre qu'un élément n'existe plus dans Selenium

Je teste une interface utilisateur dans laquelle l'utilisateur clique sur un bouton Supprimer et une entrée de tableau disparaît. En tant que tel, je veux pouvoir vérifier que l'entrée de table n'existe plus.

J'ai essayé d'utiliser ExpectedConditions.not() pour inverser ExpectedConditions.presenceOfElementLocated(), en espérant que cela signifierait "s'attendre à ce qu'il n'y ait pas de présence de l'élément spécifié". Mon code est comme ça:

browser.navigate().to("http://stackoverflow.com");
new WebDriverWait(browser, 1).until(
        ExpectedConditions.not(
                ExpectedConditions.presenceOfElementLocated(By.id("foo"))));

Cependant, j'ai trouvé que même en faisant cela, j'obtiens un TimeoutExpcetion provoqué par un NoSuchElementException disant que l'élément "foo" n'existe pas. Bien sûr, ne pas avoir un tel élément est ce que je veux, mais je ne veux pas qu'une exception soit levée.

Alors, comment puis-je attendre qu'un élément n'existe plus? Je préférerais un exemple qui ne repose pas sur la capture d'une exception si possible (si je comprends bien, des exceptions doivent être levées pour un comportement exceptionnel).

28
Thunderforge

Vous pouvez aussi utiliser -

new WebDriverWait(driver, 10).until(ExpectedConditions.invisibilityOfElementLocated(locator));

Si vous en parcourez la source, vous pouvez voir que NoSuchElementException et staleElementReferenceException sont traités.

/**
   * An expectation for checking that an element is either invisible or not
   * present on the DOM.
   *
   * @param locator used to find the element
   */
  public static ExpectedCondition<Boolean> invisibilityOfElementLocated(
      final By locator) {
    return new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        try {
          return !(findElement(locator, driver).isDisplayed());
        } catch (NoSuchElementException e) {
          // Returns true because the element is not present in DOM. The
          // try block checks if the element is present but is invisible.
          return true;
        } catch (StaleElementReferenceException e) {
          // Returns true because stale element reference implies that element
          // is no longer visible.
          return true;
        }
      }
45
Vivek Singh

La solution reposerait toujours sur la gestion des exceptions. Et c'est à peu près correct, même Conditions attendues standard reposent sur des exceptions levées par findElement().

L'idée est de créer une condition attendue personnalisée :

  public static ExpectedCondition<Boolean> absenceOfElementLocated(
      final By locator) {
    return new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        try {
          driver.findElement(locator);
          return false;
        } catch (NoSuchElementException e) {
          return true;
        } catch (StaleElementReferenceException e) {
          return true;
        }
      }

      @Override
      public String toString() {
        return "element to not being present: " + locator;
      }
    };
  }
5
alecxe

Pourquoi ne trouvez-vous pas simplement la taille de elements. Nous savons que la taille de la collection d'éléments serait si l'élément n'existe pas.

if(driver.findElements(By.id("foo").size() > 0 ){
    //It should fail
}else{
    //pass
}
1
Saifur

J'ai trouvé une solution de contournement pour résoudre ce problème pour moi de manière efficace, utilisé en suivant le code C # pour gérer cela, vous pouvez le convertir en Java

    public bool WaitForElementDisapper(By element)
    {
        try
        {
            while (true)
            {
                try
                {
                    if (driver.FindElement(element).Displayed)
                        Thread.Sleep(2000);
                }
                catch (NoSuchElementException)
                {
                    break;
                }
            }
            return true;
        }
        catch (Exception e)
        {
            logger.Error(e.Message);
            return false;
        }
    }
0
Abhinav Saxena
// pseudo code
public Fun<driver,webelement> ElemtDisappear(locator)
{
    webelement element=null;
    iList<webelement> elemt =null;
    return driver=>
    {
    try
    {
    elemt = driver.findelements(By.locator);
    if(elemt.count!=0)
    {
    element=driver.findelement(By.locator);
    }
    }
    catch(Exception e)
    {
    }
    return(elemnt==0)?element:null;
};

// call function
public void waitforelemDiappear(driver,locator)
{
    webdriverwaiter wait = new webdriverwaiter(driver,time);
    try
    {
    wait.until(ElemtDisappear(locator));
    }
    catch(Exception e)
    {
    }
}

Comme findelement lève une exception sur l'élément non-fiabilité, j'ai donc implémenté l'aide de findelements. n'hésitez pas à le corriger et à l'utiliser selon vos besoins.

0
Nagaraju