Search code examples
javaseleniumselenium-webdriverwaitpredicate

How to make Selenium wait until an element is present?


I'm trying to make Selenium wait for an element that is dynamically added to the DOM after page load. I tried this:

fluentWait.until(ExpectedConditions.presenceOfElement(By.id("elementId"));

In case it helps, here is fluentWait:

FluentWait fluentWait = new FluentWait<>(webDriver) {
    .withTimeout(30, TimeUnit.SECONDS)
    .pollingEvery(200, TimeUnit.MILLISECONDS);
}

But it throws a NoSuchElementException. It looks like presenceOfElement expects the element to be there, so this is flawed. This must be bread and butter to Selenium, and I don't want to reinvent the wheel... Is there an alternative, ideally without rolling my own Predicate?


Solution

  • You need to call ignoring with an exception to ignore while the WebDriver will wait.

    FluentWait<WebDriver> fluentWait = new FluentWait<>(driver)
            .withTimeout(30, TimeUnit.SECONDS)
            .pollingEvery(200, TimeUnit.MILLISECONDS)
            .ignoring(NoSuchElementException.class);
    

    See the documentation of FluentWait for more information. But beware that this condition is already implemented in ExpectedConditions, so you should use:

    WebElement element = (new WebDriverWait(driver, 10))
       .until(ExpectedConditions.elementToBeClickable(By.id("someid")));
    

    *Fewer versions of Selenium:

    withTimeout(long, TimeUnit) has become withTimeout(Duration)
    pollingEvery(long, TimeUnit) has become pollingEvery(Duration)
    

    So the code will look as such:

    FluentWait<WebDriver> fluentWait = new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(30)
            .pollingEvery(Duration.ofMillis(200)
            .ignoring(NoSuchElementException.class);
    

    A basic tutorial for waiting can be found here.