You can use either new Predicate<WebElement>() or new Function<WebElement, Boolean>(). The Predicate will return a boolean. The Function can return a boolean which will get promoted to a Boolean. They are, for the most part the same in this situation.
With a FluentWait you give it the element you want to pass to the apply() method. In this case the FluentWait<WebElement> will need a WebElement. So I can say that the countdown variable is a WebElement. The rest of the initialization is for 10 second, check every 100 milliseconds to see if the until Function/Predicate returns true. If the Function/Predicate returns true the FluentWait stops waiting. Otherwise it will wait for 10 seconds then throw an exception.
The Function has two parameters. The first is the input and the second is the return type of the apply() method. The Predicate takes one parameter which is the input. There is no second parameter because its apply() always returns boolean.
So every 100 millisecond, for a maximum of 10 seconds this code will check the WebElement countdown (element also refers to the same WebElement) to see if countdown.getText().endsWith("04") is true. If you want to break this out to be a little more obvious you could write:
public boolean apply(WebElement element) {
String text = element.getText();
boolean flag = text.endsWith("04");
return flag;
}
Exact same thing but a lot more typing. You could also do things like:
public void waitForButtonToBeVisible() {
new FluentWait<WebDriver>(driver).
withTimeout(3, TimeUnit.SECONDS).
pollingEvery(50, TimeUnit.MILLISECONDS).
ignoring(NoSuchElementException.class).
until(new Predicate<WebDriver>() {
public boolean apply(WebDriver d) {
WebElement w = d.findElement(By.cssSelector("#editor1"));
return w.isDisplayed();
}
}
}
This will takes as input a WebDriver. It will try for 3 seconds, checking every 50 milliseconds to see if the WebElement is displayed. It will also ignore NoSuchElementException. So it might check for the element, it does not exist, the apply function ignores the NoSuchElementException. It keeps check every 50 milliseconds. At some point the element exists in the DOM but it is not visible. So the apply method returns false (rather than a NoSuchElementException). It keeps checking every 50 milliseconds so long as the timer is not at 3 seconds. If the element becomes visible within 3 seconds, the apply function returns true and the FluentWait stops checking. If the element never exists or it is never visible then the method will throw a TimeoutException.
Darrell