Selenium WebDriverWait.until(invisiblityOfAllElements) returns timeout on NoSuchElementException

Sniper :

I have a code which waits for a time for element to disappear

new WebDriverWait(driver, 10).until(ExpectedConditions.invisibilityOfAllElements(elements));

Which internally calls Selenium's

isInvisible(WebElement element)

and isInvisible is defined as follows

try {
      return !element.isDisplayed();
    } catch (StaleElementReferenceException ignored) {
      // We can assume a stale element isn't displayed.
      return true;
    }

Note: It only catches StaleElementReferenceException

and in isDispalyed when the element is referenced, pagefactory package's ElementLocator class's findElement is called method which throwsNoSuchElementException

This exception propogates to FluentWait class Wherein

try {
        V value = isTrue.apply(input);
        if (value != null && (Boolean.class != value.getClass() || Boolean.TRUE.equals(value))) {
          return value;
        }

        // Clear the last exception; if another retry or timeout exception would
        // be caused by a false or null value, the last exception is not the
        // cause of the timeout.
        lastException = null;
      } catch (Throwable e) {
        lastException = propagateIfNotIgnored(e);
      }

The exception is caught by Throwable, and this causes the timeout and I am not able to check whether all elements have been disappeared from the screen

P.S. All my Elements are defined by @FindBy Example

@FindBy(css = ".myclass-name")
private WebElement myWorkspaceButton;

So cannot use ExpectedConditions method taking By as argument

Is there any other way to check if all the WebElements have disappeared from the screen? Or Is there a solution to this problem?

AndiCover :

You could write you own method for that in which you loop through all you elements and catch those exceptions.

public static ExpectedCondition<Boolean> invisibilityOfAllElements(
        final List<WebElement> elements) {
    return new ExpectedCondition<Boolean>() {

        @Override
        public Boolean apply(WebDriver webDriver) {
            for (WebElement element : elements) {
                try {
                    if (element.isDisplayed()) {
                        return false;
                    }
                } catch (StaleElementReferenceException | NoSuchElementException ex) {
                    // ignore
                }
            }
            return true;
        }

        @Override
        public String toString() {
            return "invisibility of all elements " + elements;
        }
    };
}

I am not sure but probably you need to catch org.openqa.selenium.TimeoutException as well.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=141621&siteId=1