0

I am using Fluent wait. I want to return void instead of Web Element or Boolean. How can I do it? I have tried like this. Code snippet is below

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(Duration.ofSeconds(30))
                .pollingEvery(Duration.ofSeconds(3)).ignoring(NoSuchElementException.class)

    wait.until(new Function<WebDriver, Void>() {
            public void apply(WebDriver driver) {
            if( driver.findElement(By.id("foo")).isDisplayed())
                driver.findElement(By.id("foo")).click();
            }
        });
    }

However, it gives me error at void:

The return type is incompatible with Function<WebDriver,Void>.apply(WebDriver)

NOTE: I only want return void. Is that possible?

frianH
  • 7,295
  • 6
  • 20
  • 45
  • BTW, this part of your code, `.pollingEvery(Duration.ofSeconds(30))`, means that the condition is only checked once every 30s (polling time), which is surely not what you want. You probably want the default polling time of 500ms so that the code regularly checks to see if the condition is true and if so, moves on. If your timeout and polling time are both 30s, it's likely going to check once immediately and then either timeout after 30s or maybe check once at 30s. At that point, you might was well use a sleep, which is NOT a good practice. – JeffC Oct 10 '20 at 06:27
  • My bad, I have changed pollingEvery(Duration.ofSeconds(30) to pollingEvery(Duration.ofSeconds(3) – Nghia Huy Hoang Oct 10 '20 at 06:36

3 Answers3

1

The answer is no, I think.


We can find some useful info from api docs.

It explains the Returns like this:

The function's return value if the function returned something different from null or false before the timeout expired.

So, it is impossible for the function to handle void and null correctly at the same time.

Peter Quan
  • 788
  • 4
  • 9
1

I think you have misunderstood the use of the wait Function. It's supposed to return a Boolean or WebElement once a condition is met. You are trying to click inside of the method which is not the way it's intended to be used.

You don't really need FluentWait here. You can use a WebDriverWait to make this much simpler.

new WebDriverWait(driver, 30).until(ExpectedConditions.elementToBeClickable(By.id("foo"))).click();

This will wait for up to 30s for the element to be clickable and if it doesn't time out, the returned element will be clicked.


To your comment... in that case, I would write a separate method ElementExists that returns a WebElement. If the returned WebElement is not null, click it.

Helper method

public static WebElement ElementExists(By locator, int timeout)
{
    try
    {
        return new WebDriverWait(driver, timeout).until(ExpectedConditions.visibilityOfElementLocated(locator));
    } catch (TimeoutException e)
    {
        return null;
    }
}

Script code

WebElement ele = ElementExists(By.id("foo"), 30);
if (ele != null)
{
    ele.click();
}
JeffC
  • 22,180
  • 5
  • 32
  • 55
  • I want to check, if that element exist, then I will click it. If no, then do something else. That elements sometimes it appears, sometimes it doesn't . How can I solve that problem? – Nghia Huy Hoang Oct 10 '20 at 06:35
  • @NghiaHuyHoang I updated my answer with a solution to your question. – JeffC Oct 12 '20 at 14:29
0

You can use return this, it return the instance of the current class that is using the FluentWait and you can just ignore it.

ValorHeart
  • 35
  • 6