How to wait until an element no longer exists in Selenium

I don't know why but ExpectedConditions.invisibilityOf(element) is the only work for me while ExpectedConditions.invisibilityOfElementLocated(By), !ExpectedConditions.presenceOfElementLocated(By) ... not. Try it!

Hope this help!


Why don't you simply find the size of elements. We know the the collection of elements' size would be 0 if element does not exist.

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

You can also use -

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

If you go through the source of it you can see that both NoSuchElementException and staleElementReferenceException are handled.

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

The solution would still rely on exception-handling. And this is pretty much ok, even standard Expected Conditions rely on exceptions being thrown by findElement().

The idea is to create a custom Expected Condition:

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