I've been struggling with selenium to fix this issue:
java.lang.NoSuchMethodError: org.openqa.selenium.support.ui.Wait.until(Lcom/google/common/base/Function;)Ljava/lang/Object;
This is where I get this error:
Wait<WebDriver> wait = new FluentWait<>(getDriverInstance())
.withTimeout(timeout, TimeUnit.SECONDS)
.pollingEvery(frequency, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
wait.until(driver -> {
assert driver != null;
elt.click();
return true;
});
The most solutions on the internet suggest to use Guava 21
, but this is not working for me.
Running selenium locally works just fine, and I don't get this issue, the problem is we use a runner that will use the selenium-server-standalone-3.12.0
to run tests on multiple virtual machines, and in the classpath we define all the dependencies we use, where I declared Guava as well, I also tried other versions of Guava
from 19 to 23.
I tried multiple solutions and now I'm out of ideas, I don't know why I'm still getting this error even though I have declared Guava, and I can clearly see when I run tests locally, that Guava 23
works just fine.
I'm using java 1.8_71
.
When I checked the code source of selenium-server-standalone-3.12.0
the Wait interface looks like this:
import java.util.function.Function;
public interface Wait<F> {
<T> T until(Function<? super F, T> var1);
}
But in local it looks like this:
import com.google.common.base.Function;
public interface Wait<F> {
<T> T until(Function<? super F, T> var1);
}
But since com.google.common.base.Function
is extending com.google.common.base.Function
in Guava 23, this shouldn't be a problem, so why I'm still getting this error ?
Thanks in advance.
I have checked the content of the standalone jar, and it contains Guava
version 23.6-jre
, so I'm highly skeptical about the issue being from guava.
I also checked the Wait
interface and it's defined like this:
import java.util.function.Function;
public interface Wait<F> {
<T> T until(Function<? super F, T> var1);
}
I still don't understand why I'm getting until(Lcom/google/common/base/Function;)
in the exception when the used Function
interface is from java.util.function
and not com.google.common.base
I have somehow solved this issue by looking at how intellij executes my jar, so I added D:\..\target\test-classes
to the classpath and the exception disappeared for some reason, why this happened ? and how can I include the files in test-classes
to my final jar ?
Normally I have a bat file that runs my test:
@SETLOCAL
@ECHO OFF
@set JAVA_HOME="C:\Program Files\Java\jdk1.8.0_231"
@set PATH=%JAVA_HOME%\bin;D:\drivers;%PATH%
@set CLASSPATH=.;
@set CLASSPATH=%CLASSPATH%D:\sln\lib\*;
@set CLASSPATH=%CLASSPATH%D:\sln\selenium-server-standalone-3.12.0.jar;
echo %CLASSPATH%
"C:\Program Files\Java\jdk1.8.0_231\bin\java.exe" com.sln.Runner %*
which I use as following:
D:\sln\Run.bat -u localhost -f D:\sln\target\sln-1.0-SNAPSHOT-tests.jar -c com.sln.SeleniumTest ...
This won't work I'll get the NoSuchMethodError
exception unless I add this to the class path:
@set CLASSPATH=%CLASSPATH%D:\sln\target\test-classes;
This error message...
java.lang.NoSuchMethodError: org.openqa.selenium.support.ui.Wait.until(Lcom/google/common/base/Function;)Ljava/lang/Object;
...implies that the Guava version was incompatible.
As you are using selenium-server-standalone-3.12.0 as per the contents of selenium-java-3.12.0 client kits the supported guava version is:
guava-23.6-jre
An immediate solution would be to:
guava-23.6-jre.jar
In your first update as you have confirmed that Guava version is 23.6-jre
, the real issue seems to be constructor of FluentWait. The argument type for withTimeout
and pollingEvery
post Selenium v3.11.0, which was:
pollingEvery
: pollingEvery(long duration, java.util.concurrent.TimeUnit unit)
withTimeout
: withTimeout(long duration, java.util.concurrent.TimeUnit unit)
Are now Deprecated and the new type is java.time.Duration. So your effective code block will be:
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofMillis(500))
.ignoring(NoSuchElementException.class);
You can find a detailed discussion in The type FluentWait is not generic; it cannot be parameterized with arguments error for FluentWait Class through Selenium and Java
Additionally,
As per the best practices you need to:
Test
as a non-root user.driver.quit()
within tearDown(){}
method to close & destroy the WebDriver and Web Client instances gracefully.You can find a relevant detailed discussion in:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With