WebDriver - wait for element using Java

JavaWebdriverSelenium Webdriver

Java Problem Overview


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.

Java Solutions


Solution 1 - Java

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:

Solution 2 - Java

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.

Solution 3 - Java

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

Solution 4 - Java

Above wait statement is a nice example of Explicit wait.

As Explicit waits are intelligent waits that are confined to a particular web element(as mentioned in above x-path).

By Using explicit waits you are basically telling WebDriver at the max it is to wait for X units(whatever you have given as timeoutInSeconds) of time before it gives up.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiontomView Question on Stackoverflow
Solution 1 - JavaAshwin PrabhuView Answer on Stackoverflow
Solution 2 - Javaanuja jainView Answer on Stackoverflow
Solution 3 - JavaandrejView Answer on Stackoverflow
Solution 4 - JavasatenderView Answer on Stackoverflow