Categories
java selenium-webdriver webdriver

WebDriver – wait for element using Java

84

I’m looking for something similar to waitForElementPresent to check whether element is displayed before I click it. I thought this can be done by implicitWait, so I used the following:

driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);

and then click by

driver.findElement(By.id(prop.getProperty(vName))).click();

Unfortunately, sometimes it waits for the element and sometimes not. I looked for a while and found this solution :

for (int second = 0;; second++) {
    Thread.sleep(sleepTime);
    if (second >= 10)
        fail("timeout : " + vName);
    try {
        if (driver.findElement(By.id(prop.getProperty(vName))).isDisplayed())
            break;
    } catch (Exception e) {
        writeToExcel("data.xls", e.toString(), parameters.currentTestRow, 46);
    }
}
driver.findElement(By.id(prop.getProperty(vName))).click();

And it waited all right, but before timing out it had to wait 10 times 5, 50 seconds. A bit much. So I set the implicitly wait to 1sec and all seemed fine until now. Because now some things wait 10s before timeout but some other things time out after 1s.

How do you cover the waiting for element present/visible in your code? Any hint is appreciable.

    166

    This is how I do it in my code.

    WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>));
    

    or

    wait.until(ExpectedConditions.elementToBeClickable(By.id<locator>));
    

    to be precise.

    See also:

    2

    • 2

      Thanks! If I only knew sooner about this class my life would be easier 🙂

      – tom

      Aug 2, 2012 at 8:53

    • How do I incorporate your code into this format ? @FindBy(how = How.ID, using = "signup-button") WebElement signUpButton; Moreover, I still get a NPE with your code. Looks like it is trying to get elementToBeClickable. How can we use this method when the element is not loaded ?

      Apr 21, 2016 at 0:38

    14

    You can use Explicit wait or Fluent Wait

    Example of Explicit Wait –

    WebDriverWait wait = new WebDriverWait(WebDriverRefrence,20);
    WebElement aboutMe;
    aboutMe= wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("about_me")));     
    

    Example of Fluent Wait –

    Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)                            
    .withTimeout(20, TimeUnit.SECONDS)          
    .pollingEvery(5, TimeUnit.SECONDS)          
    .ignoring(NoSuchElementException.class);    
    
      WebElement aboutMe= wait.until(new Function<WebDriver, WebElement>() {       
    public WebElement apply(WebDriver driver) { 
    return driver.findElement(By.id("about_me"));     
     }  
    });  
    

    Check this TUTORIAL for more details.

    1

    • 2

      This method is deprecated.

      – JGFMK

      Mar 16, 2020 at 19:50

    5

    We’re having a lot of race conditions with elementToBeClickable. See https://github.com/angular/protractor/issues/2313. Something along these lines worked reasonably well even if a little brute force

    Awaitility.await()
            .atMost(timeout)
            .ignoreException(NoSuchElementException.class)
            .ignoreExceptionsMatching(
                Matchers.allOf(
                    Matchers.instanceOf(WebDriverException.class),
                    Matchers.hasProperty(
                        "message",
                        Matchers.containsString("is not clickable at point")
                    )
                )
            ).until(
                () -> {
                    this.driver.findElement(locator).click();
                    return true;
                },
                Matchers.is(true)
            );