4

I know that in terms of waiting for web element that isn't in the DOM yet, the most efficient is a fluent wait. So my question is:

Is there a way to handle and catch the NoSuchElementException or any exception that fluent wait might throw because the element is not existing?

I need to have a boolean method wherein it will give me result whether the element is found or not.

This method is quite popular on the web.

public void waitForElement(WebDriver driver, final By locator){
    Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
            .withTimeout(60, TimeUnit.SECONDS)
            .pollingEvery(2, TimeUnit.SECONDS)
            .ignoring(NoSuchElementException.class);

   wait.until(new Function<WebDriver, WebElement>() {
        public WebElement apply(WebDriver driver) {
            return driver.findElement(locator);
        }
    });
}

What I need is, **.ignoring(NoSuchElementException.class);** will not be ignored. And once the exception is caught, it will return FALSE. On the other hand, when an element is found, it will return TRUE.

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
ohlori
  • 312
  • 1
  • 8
  • 22

4 Answers4

5

As an alternative as you have wanted to see the implementation of WebDriverWait with polling, here are the constructor details :

  • WebDriverWait(WebDriver driver, long timeOutInSeconds): Wait will ignore instances of NotFoundException that are encountered (thrown) by default in the 'until' condition, and immediately propagate all others.

    WebDriverWait wait1 = new WebDriverWait(driver, 10);
    
  • WebDriverWait(WebDriver driver, long timeOutInSeconds, long sleepInMillis): Wait will ignore instances of NotFoundException that are encountered (thrown) by default in the 'until' condition, and immediately propagate all others.

    WebDriverWait wait2 = new WebDriverWait(driver, 10, 500);
    

Update :

To answer to your comment, you need to define the WebDriverWait instance here. Next we have to implement the WebDriverWait instance i.e. wait1 / wait2 within your code through proper ExpectedConditions clauses.

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • 1
    Thank you so much for explain this. However, I have to catch the exception to know whether the element was not found. – ohlori Nov 30 '17 at 14:32
  • 1
    Sure. See we have just defined the `WebDriverWait` instance here. Next we have to implement it within our code through `ExpectedCondition` clauses. See the [**`ExpectedCondition`**](http://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedCondition.html) documentation here. – undetected Selenium Nov 30 '17 at 14:37
  • 1
    Got it. :) My answer is below. :D Thank you! Learned something too. Your answer is more worthy than it. :) Other readers might learn from it too. – ohlori Nov 30 '17 at 14:41
3

Here it is:

public boolean waitForElementBoolean(WebDriver driver, By object){
    try {
        WebDriverWait wait = new WebDriverWait(driver,60);
        wait.pollingEvery(2, TimeUnit.SECONDS);
        wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(object));
        return true;
    } catch (Exception e) {
        System.out.println(e.getMessage()); 
        return false;
    }
}

I integrated the fluent wait with the explicit wait. :D Thank you guys! :)

ohlori
  • 312
  • 1
  • 8
  • 22
2

You can use WebDriverWait with polling and ignoring

Example:

public boolean isElementPresentWithWait(WebDriver driver, WebElement element) {
    try {
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.pollingEvery(3, TimeUnit.SECONDS).ignoring(NoSuchElementException.class).until(ExpectedConditions.visibilityOf(element);
        return true;
    } catch (TimeoutException e) {
        return false;
    }
}

Methods ignoring and pollingEvery return instance of FluentWait<WebDriver>

Fenio
  • 3,528
  • 1
  • 13
  • 27
  • The thing is that, I need to handle the exception. So ignoring it won't help. :| – ohlori Nov 30 '17 at 14:34
  • You can handle it through `if(isElementPresentWithWait(element)) {} else {}` :) – Fenio Nov 30 '17 at 14:39
  • is this different if it is separated? `wait.pollingEvery(5, TimeUnit.SECONDS); wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(object));` – ohlori Nov 30 '17 at 17:00
  • No. It works the same way. It's called `method chaining`. You can even make 1 line of code with following `new WebDriverWait(driver, 10).pollingEvery(3,TimeUnit.SECONDS) .ignoring(NoSuchElementException.class) .until(ExpectedConditions.visibilityOf(element);` – Fenio Nov 30 '17 at 17:51
1

you can try with this below code snippet

    /*
 * wait until expected element is visible
 */
public boolean waitForElement(WebDriver driver, By expectedElement) {
    boolean isFound = true;
    try {
        WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds , 300);
        wait.until(ExpectedConditions.visibilityOfElementLocated(expectedElement));
        makeWait(1);
    } catch (Exception e) {
        //System.out.println(e.getMessage());
        isFound = false;
    }
    return isFound;
}
Mahmud Riad
  • 1,169
  • 1
  • 8
  • 19