Selenium WebDriver: Fluent wait works as expected, but implicit wait does not

Viewed 50900

I am new to Selenium WebDriver and am trying to understand the correct way to 'wait' for elements to be present.

I am testing a page with a bunch of questions that have radio button answers. As you select answers, Javascript may enable/disable some of the questions on the page.

The problem seems to be that Selenium is 'clicking too fast' and not waiting for the Javascript to finish. I have tried solving this problem in two ways - explicit waits solved the problem. Specifically, this works, and solves my issue:

private static WebElement findElement(final WebDriver driver, final By locator, final int timeoutSeconds) {
    FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver)
            .withTimeout(timeoutSeconds, TimeUnit.SECONDS)
            .pollingEvery(500, TimeUnit.MILLISECONDS)
            .ignoring(NoSuchElementException.class);

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

However, I would prefer to use an implicit wait instead of this. I have my web driver configured like this:

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

This does not solve the problem and I get a NoSuchElementException. Additionally, I do not notice a 10 second pause - it just errors out immediately. I have verified this line in the code is being hit with a debugger. What am I doing wrong? Why does implicitlyWait not wait for the element to appear, but FluentWait does?

Note: As I mentioned I already have a work around, I really just want to know why Implicit wait isn't solving my issue. Thanks.

9 Answers
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;


FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver);
            wait.pollingEvery(250,  TimeUnit.MILLISECONDS);
            wait.withTimeout(20, TimeUnit.SECONDS);
            wait.ignoring(NoSuchElementException.class);

            Predicate<WebDriver> predicate  = new Predicate <WebDriver>()
                    {
                        public boolean apply(WebDriver arg0) {
                            WebElement element = arg0.findElement(By.id("colorVar"));
                            String color = element.getAttribute("color");
                            System.out.println("The color if the button is " + color);
                            if(color.equals("blue"))
                            {
                                return true;
                            }
                            return false;
                        }
                    };

            wait.until(predicate);
Related