如何等待Selenium中的元素不再存在

时间:2015-03-16 17:10:08

标签: java selenium selenium-webdriver

我正在测试用户点击删除按钮的UI,表条目消失。因此,我希望能够检查表条目不再存在。

我尝试使用ExpectedConditions.not()来反转ExpectedConditions.presenceOfElementLocated(),希望它意味着“期望不存在指定的元素”。我的代码是这样的:

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

然而,我发现即使这样做,我也会得到一个由TimeoutExpcetion引起的NoSuchElementException,说“foo”元素不存在。当然,没有这样的元素是我想要的,但我不想抛出异常。

那么我怎么能等到一个元素不再存在?我更喜欢一个不依赖于捕获异常的示例(如我所知,异常应该抛出异常行为)。

6 个答案:

答案 0 :(得分:42)

您也可以使用 -

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

如果您查看其来源,则可以看到NoSuchElementExceptionstaleElementReferenceException都已得到处理。

/**
   * 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;
        }
      }

答案 1 :(得分:5)

解决方案仍然依赖于异常处理。这是非常好的,即使standard Expected Conditions依赖于findElement()抛出的异常。

我们的想法是创建一个自定义预期条件

  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;
      }
    };
  }

答案 2 :(得分:1)

为什么不简单地找到elements的大小。我们知道元素的集合&#39;如果元素不存在, size 0

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

答案 3 :(得分:0)

// 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)
    {
    }
}

因为findelement会在元素不可靠性上抛出异常。所以我使用findelements实现了。请随意纠正并根据您的需要使用它。

答案 4 :(得分:0)

我找到了一种解决方法,以高效的方式为我解决这个问题,使用C#代码来处理这个,你可以将它转换为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;
        }
    }

答案 5 :(得分:0)

我不知道为什么,但是ExpectedConditions.invisibilityOf(element)是我唯一的工作,而ExpectedConditions.invisibilityOfElementLocated(By)!ExpectedConditions.presenceOfElementLocated(By) ...不是。试试吧!

希望获得帮助!