32

So far I used 2.45.0 version of selenium and all my waits were done in this way:

WebDriverWait wait = new WebDriverWait(webKitUtility.getWebDriver(), 5);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("role")));

But I updated selenium to 3.1.0 and I am getting the error:

"The method until(Predicate) in the type FluentWait is not applicable for the arguments (ExpectedCondition)"

I see that from 2.45.0 to 3.1.0 some things are deprecated. I am trying to investigate what is the best way to do it now, but I am not sure. Most of the things I'm finding on google are old information explaining the same way I was using so far.

lijep dam
  • 596
  • 2
  • 8
  • 23

10 Answers10

53

I had the same issue.

I fixed it by using the not deprecated .until() method of WebDriverWait and by adding the following to my maven pom.xml:

<dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>21.0</version>
</dependency>

Other than that, my code looks exactly like before.

To be more specific there are now two .until() methods.

The old one (which is deprecated):
public void until(final Predicate<T> isTrue) {}

And the new one:
public <V> V until(Function<? super T, V> isTrue) {}

Robert G
  • 928
  • 7
  • 9
  • 1
    I went to official selenium chat room and guy told me to do the same thing you did. It works also for me. I come here to post an answer but you have already did it :). – lijep dam Feb 23 '17 at 17:27
  • 1
    Can someone tell me an example of how to use the new one. I mean real program. – Bala Jul 19 '18 at 10:14
  • 1
    For gradle: `compile group: 'com.google.guava', name:'guava', version:'21.0'` in your dependencies in `build.gradle`. [Info on dependencies](https://docs.gradle.org/current/userguide/dependency_management_for_java_projects.html). – Sean Breckenridge Dec 15 '18 at 05:41
  • 1
    This is very funny. My `wait.until` worked perfectly fine, until I update my IntelliJ to the newest version 2021.1 today, then I start to see this issue. Adding Guava dependency as explained by @Robert does solve the issue. Not sure what does the newest IntelliJ do that breaks my code. Moving forward, I am not keen to update my IntelliJ anymore :) – keylogger Apr 12 '21 at 03:18
9

Note if you are using Maven that order of the dependencies do matter.

For example:

public static void main(String[] args) {
    System.setProperty("webdriver.gecko.driver", "/Users/me/geckodriver");
    final WebDriver driver = new FirefoxDriver();
    driver.get("https://www.google.com");
    final WebDriverWait wait = new WebDriverWait(driver, 5);
    final By feelLuckyXpath = By.xpath("//div[@class='jsb']/center/input[@type='submit' and @name='btnI']");
    wait.until(ExpectedConditions.visibilityOfElementLocated(feelLuckyXpath)).click();
    driver.close();
}

this code works fine with the following maven dependencies:

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.8.1</version>
</dependency>

<dependency>
    <groupId>com.google.api-client</groupId>
    <artifactId>google-api-client</artifactId>
    <version>1.22.0</version>
</dependency>

but it may fail with reordered one:

<dependency>
    <groupId>com.google.api-client</groupId>
    <artifactId>google-api-client</artifactId>
    <version>1.22.0</version>
</dependency>

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.8.1</version>
</dependency>

In this case because the google-api-client contains:

<groupId>com.google.guava</groupId>
<artifactId>guava-jdk5</artifactId>

as dependency which shadows the guava lib in the selenium lib.

In this case the error is:

no instance(s) of type variable(s) V exist so that ExpectedCondition<> ...

method until in class org.openqa.selenium.support.ui.FluentWait cannot be applied to given types; required: java.util.function.Function found: org.openqa.selenium.support.ui.ExpectedCondition reason: cannot infer type-variable(s) V (argument mismatch; org.openqa.selenium.support.ui.ExpectedCondition cannot be converted to java.util.function.Function)

nyxz
  • 6,918
  • 9
  • 54
  • 67
8

You would need to add dependency:

<dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-support</artifactId>
        <version>3.0.1</version>
</dependency>

This is in order to make your code still work. Although ultimately the code would need to be rewritten not to use deprecated FluentWait.

Lukasz
  • 368
  • 4
  • 9
1

If you are using maven to manage your dependencies, check the dependency hierarchy and check the guava version in use. selenium-remote-driver JAR requires guava version 21. Add an exclusion to the artifact that uses the unwanted guava version. For example:

<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>1.5.1</version>
  <exclusions>
    <exclusion>
       <groupId>com.google.guava</groupId>
       <artifactId>guava</artifactId>
    </exclusion>
  </exclusions>
</dependency>
Ricardo
  • 11
  • 1
1

You can do something like this for the new FluentWait

    new WebDriverWait(driver, 60).until(new Function<WebDriver, Boolean>() {
    Boolean isWindowFound = Boolean.FALSE;
        @Override
        public Boolean apply(WebDriver driver) {
            try {
                driver.switchTo().window("Your Window Name");
                isWindowFound = Boolean.TRUE;
            } catch (NoSuchWindowException e) {
                System.out.println("Your Window Name not found");
                System.out.println(driver.getTitle());
                return isWindowFound;
            }
            return isWindowFound;
        }
    });
Damien-Amen
  • 7,232
  • 12
  • 46
  • 75
1

I got this compilation error when I changed from selenium 2 (org.seleniumhq.selenium:selenium-java:2.53.0) to selenium 3 (org.seleniumhq.selenium:selenium-java:3.4.0).

As mentioned above, I had to change from guava 18 (guava:com.google.guava:18.0) to guava 21 (guava:com.google.guava:21.0).

However, I also had to configure the build to use Java 8 because

ExpectedCondition<T> extends Function<WebDriver, T>
Function<F, T> extends java.util.function.Function<F, T>

where java.util.function.Function must come from Java 8 JDK.

For the command line, I changed my JAVA_HOME environment variable to JAVA_HOME: C:\Program Files\Java\jdk1.8.0_131

For Eclipse, Windows -> Preferences, Java/Installed JREs, Add Button, JRE home: C:\Program Files\Java\jdk1.8.0_131 and JRE name: jdk1.8.0_131.

Scott Izu
  • 2,229
  • 25
  • 12
1

If you are working with intellij.you want your code to work with latest version: -->undate intellij to latest version:2020.2.1 geckodriver:v0.27.0 selenium 3.12.0 also update guava to 28.0-jre and delete older versions of selenium and guava jar from jar folders

0

I was facing similar kind of problem related to java.util.function after making the above changes in guava version as 21 and changing the maven plugin configuration version to maven-compiler-plugin 3.11.81.8
I was still stucked with the same error and the build was failing. The solution for this to delete the maven repo .m2 folder and import the project from beginning and then try to make the following changes.Try to do a Maven update after making changes in POM selenium java and selenium server version and try to to a maven clean followed by maven install.Somehow the pom.xml was still using the older selenium version in my case. I changed the used jdk version to 1.8 after making the maven plugin changes and now it works perfectly fine for me

nikita
  • 1
0

i removed this error by adding guava 21 and removing guava 20.0 , when you are using selenium above 3.1.0 version

CodingGirl1
  • 21
  • 2
  • 5
0

this dependency works for me.

<dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-support</artifactId>
        <version>3.0.1</version>
</dependency>