Akhil
Akhil

Reputation: 1

wait.until(ExpectedCondition) generating error

After upgrading to selenium Java 3.8.1 the wait.until(ExpectedCondition) has started giving error message.

For the following piece of code

WebElement framei = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(".//*[@id='ctl00_ContentPlaceHolder1_dlgModal_IFrame']")));       
    driver.switchTo().frame(framei);
    WebElement AcceptRadioButton=wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id='RblStatus']/tbody/tr[1]/td/label")));
    AcceptRadioButton.click();

The following error is given:

Type The method until(Function<? super WebDriver,V>) in the type FluentWait<WebDriver> is not applicable for the arguments (ExpectedCondition<WebElement>)

I tried to resolve the following issue by removing the Selenium java version 3.8.1 of

Upvotes: 0

Views: 2110

Answers (3)

Unitjarl
Unitjarl

Reputation: 11

Same problem as you but not so sure about Eugene S answer I search in sources of selenium-java 2.53.1 and 3.8.1 to see what was different between FluentWait class. Here are until fonctions of the different version:

2.53.1 :

  public void until(final Predicate<T> isTrue) {
    until(new Function<T, Boolean>() {
      public Boolean apply(T input) {
        return isTrue.apply(input);
      }

      public String toString() {
        return isTrue.toString();
      }
    });
  }

OR

  public <V> V until(Function<? super T, V> isTrue) {
    long end = clock.laterBy(timeout.in(MILLISECONDS));
    Throwable lastException = null;
    while (true) {
      try {
        V value = isTrue.apply(input);
        if (value != null && Boolean.class.equals(value.getClass())) {
          if (Boolean.TRUE.equals(value)) {
            return value;
          }
        } else if (value != null) {
          return value;
        }
      } catch (Throwable e) {
        lastException = propagateIfNotIgnored(e);
      }

  // Check the timeout after evaluating the function to ensure conditions
  // with a zero timeout can succeed.
      if (!clock.isNowBefore(end)) {
        String message = messageSupplier != null ?
            messageSupplier.get() : null;

        String toAppend = message == null ?
            " waiting for " + isTrue.toString() : ": " + message;

        String timeoutMessage = String.format("Timed out after %d seconds%s",
            timeout.in(SECONDS), toAppend);
        throw timeoutException(timeoutMessage, lastException);
      }

      try {
        sleeper.sleep(interval);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new WebDriverException(e);
      }
    }
  }

AND IN 3.8.1:

  public <V> V until(Function<? super T, V> isTrue) {
    long end = clock.laterBy(timeout.in(MILLISECONDS));
    Throwable lastException;
    while (true) {
      try {
        V value = isTrue.apply(input);
        if (value != null && (Boolean.class != value.getClass() || Boolean.TRUE.equals(value))) {
          return value;
        }

    // Clear the last exception; if another retry or timeout exception would
    // be caused by a false or null value, the last exception is not the
    // cause of the timeout.
        lastException = null;
      } catch (Throwable e) {
        lastException = propagateIfNotIgnored(e);
      }

  // Check the timeout after evaluating the function to ensure conditions
  // with a zero timeout can succeed.
      if (!clock.isNowBefore(end)) {
        String message = messageSupplier != null ?
            messageSupplier.get() : null;

        String timeoutMessage = String.format(
            "Expected condition failed: %s (tried for %d second(s) with %s interval)",
            message == null ? "waiting for " + isTrue : message,
            timeout.in(SECONDS), interval);
        throw timeoutException(timeoutMessage, lastException);
      }

      try {
        sleeper.sleep(interval);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new WebDriverException(e);
      }
    }
  }

I don't see any difference between the three functions arguments but the project I work on did not return me any error with 2.53.1 version but with 3.8.1 I have the same error than Akhil.

Upvotes: 1

undetected Selenium
undetected Selenium

Reputation: 193078

As per best practices we must try to switch to a <iframe> with proper WebDriverWait as follows :

new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//iframe[@id='ctl00_ContentPlaceHolder1_dlgModal_IFrame']")));

Upvotes: 0

Eugene S
Eugene S

Reputation: 6910

As it says in the error message:

FluentWait<WebDriver> is not applicable for the arguments (ExpectedCondition<WebElement>)

Starting from Selenium 3, until method declaration now looks like this:

public <V> V until(Function<? super T, V> isTrue) 

where Function is:

public interface Function<T, R>

So it has been converted to use Java 8 functional interface. You will need to rewrite your expected conditions accordingly.

Upvotes: 0

Related Questions