Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[🐛 Bug]: wait.until is not usable #10606

Closed
Clairwai opened this issue May 4, 2022 · 22 comments · Fixed by #10695
Closed

[🐛 Bug]: wait.until is not usable #10606

Clairwai opened this issue May 4, 2022 · 22 comments · Fixed by #10695

Comments

@Clairwai
Copy link

Clairwai commented May 4, 2022

What happened?

My "wait.until" function worked fine yesterday, but all a sudden now is not runnable.

Error message: reason: no instance(s) of type variable(s) V exist so that ExpectedCondition conforms to Function<? super WebDriver, V>

I have looked it up online, and people said it is related to the inconsistent versions of Guava and Selenium. However, I have already checked my project structure, and there are no other extra versions of Guava and Selenium.

How can we reproduce the issue?

I am not sure how to reproduce since I don't know what's wrong.
The only thing I can provide is what I am using. Sorry and thanks.

Please see my pom.xml below:

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

  <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>31.1-jre</version>
     </dependency>

The code I have run:

public void visibilityOfElementLocatedByXpath(String xpath){
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(xpath)));
    }

In addition, I am using JAVA 17, maven project with IntelliJ IDEA with MacBook Air (M1,2020).

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

Operating System

MacBook Air (M1,2020) - macOS Monterey 12.2.1

Selenium version

4.1.3

What are the browser(s) and version(s) where you see this issue?

Not-related

What are the browser driver(s) and version(s) where you see this issue?

Not-related

Are you using Selenium Grid?

No

@github-actions
Copy link

github-actions bot commented May 4, 2022

@Clairwai, thank you for creating this issue. We will troubleshoot it as soon as we can.


Info for maintainers

Triage this issue by using labels.

If information is missing, add a helpful comment and then I-issue-template label.

If the issue is a question, add the I-question label.

If the issue is valid but there is no time to troubleshoot it, consider adding the help wanted label.

If the issue requires changes or fixes from an external project (e.g., ChromeDriver, GeckoDriver, MSEdgeDriver, W3C), add the applicable G-* label, and it will provide the correct link and auto-close the issue.

After troubleshooting the issue, please add the R-awaiting answer label.

Thank you!

@Clairwai
Copy link
Author

Clairwai commented May 4, 2022

FYI, I can run the same project in my window computer and Mac with Intel CPU. Thanks.

@diemol diemol added I-issue-template Applied to issues not following the template, or missing information. and removed needs-triaging labels May 4, 2022
@github-actions
Copy link

github-actions bot commented May 4, 2022

Hi, @Clairwai.
Please follow the issue template, we need more information to reproduce the issue.

Either a complete code snippet and URL/HTML (if more than one file is needed, provide a GitHub repo and instructions to run the code), the specific versions used, or a more detailed description to help us understand the issue.

Note: If you cannot share your code and URL/HTML, any complete code snippet and URL/HTML that reproduces the issue is good enough.

Reply to this issue when all information is provided, thank you.

@diemol
Copy link
Member

diemol commented May 4, 2022

Can you please provide a GitHub repository with a sample project we can clone to reproduce the issue?

@titusfortner
Copy link
Member

ExpectedCondition used to extend Guava, but no longer does, so those fixes are old.

I suspect that you have a dependency issue on the machine that is having the problem. Please investigate: https://www.javaadvent.com/2020/12/how-to-debug-dependency-conflicts-in-maven-and-gradle.html

My preferred recommendation is to switch to using the lambdas directly, especially if you are wrapping them in methods like this:

public void visibilityOfElementLocatedByXpath(String xpath){
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

        wait.withMessage("waiting for visibility of element located with By.xpath: " + xpath)
                .until(d -> d.findElement(By.xpath(xpath)).isDisplayed());
    }

@titusfortner titusfortner added R-awaiting answer and removed I-issue-template Applied to issues not following the template, or missing information. labels May 4, 2022
@diemol
Copy link
Member

diemol commented May 22, 2022

Closing as we did not get more information.

@diemol diemol closed this as completed May 22, 2022
@ammmze
Copy link
Contributor

ammmze commented May 24, 2022

To reproduce this, it depends on the guava version you are using. I just ran across this in a project that has guava 25.1-android. The ExpectedConditions extends only the guava com.google.common.base.Function. And in my version of guava, that interface looks like this (note that it does NOT extend java.util.function.Function:

package com.google.common.base;

public interface Function<F, T> {
    T apply(@NullableDecl F input);
}

But compare that to the non-android version which looks like this:

package com.google.common.base;

public interface Function<F, T> extends java.util.function.Function<F, T> {
    T apply(@NullableDecl F input);
}

To work around it, you can wrap your expected conditions in a custom method defined as:

public static <T> Function<? super WebDriver, T> toFunc(ExpectedCondition<T> expectedCondition) {
    return expectedCondition::apply;
}

And usage would then need to be something like:

new FluentWait<>(driver)
    .withTimeout(Duration.ofSeconds(2))
    .until(toFunc(visibilityOf(menuOptions)))

Or use a different version of guava.

Ideally, the ExpectedCondition class should have been updated to extend java.util.function.Function...either alternative or addition to guava.

@titusfortner
Copy link
Member

@ammmze what version of Selenium is this? We shouldn't be depending on Guava any longer.

@ammmze
Copy link
Contributor

ammmze commented May 24, 2022

We started seeing this when I just did an upgrade from 3.x to 4.1.4. The dependency is here.

@ammmze
Copy link
Contributor

ammmze commented May 24, 2022

But FWIW, I still see lots of stuff pulling in guava stuff.

@titusfortner
Copy link
Member

Welp, I either misread a while back or missed entirely the note on that page for why Selenium uses the Guava Function instead of the Java one. I still have a lot to learn about our Java code. :) Thanks for the explanation.

@ammmze
Copy link
Contributor

ammmze commented May 25, 2022

No worries! I think we should be able to resolve this issue as well as keep the guava functionality if we just update the ExpectedCondition interface from being:

public interface ExpectedCondition<T> extends Function<WebDriver, T> {}

to be:

public interface ExpectedCondition<T> extends Function<WebDriver, T>, java.util.function.Function<WebDriver, T> {}

This should allow it to work with the versions of guava that don't extend the java native Function and allowing it to be compatible with the wait until method change in the v4 release.

@titusfortner titusfortner reopened this May 25, 2022
@titusfortner
Copy link
Member

@ammmze would you mind making a PR with the proposed fix? Not sure how easy it'll be to test.

@ammmze
Copy link
Contributor

ammmze commented May 26, 2022

@titusfortner I'm not sure there is a feasible way to test it 🤷🏻‍♂️ but here's that pr.

@diemol
Copy link
Member

diemol commented May 26, 2022

Reading the comments in ExpectedCondition, I see:

// NB: this originally extended Guava's Function interface since Java didn't have one. To avoid code
// such as "com.google.common.base.Function condition = ExpectedConditions.elementFound(By);"
// breaking at compile time, we continue to extend Guava's Function interface.

I wonder how much users' code we would break if we switch to the Java Function one.

@titusfortner
Copy link
Member

yeah, i don't know enough how Java inheritance works to know what that does and/or breaks, so @diemol / @pujagani get to decide on it.
But also, seems like it should be possible to require a specific guava implementation that includes it? Or is Java just weird?

@ammmze
Copy link
Contributor

ammmze commented May 27, 2022

I wonder how much users' code we would break if we switch to the Java Function one.

Yea...if this was for the 4.0.0 release, I think it would have been fine to entirely swap to the java native one as that would have been a breaking change in that regard.

The effect of just simply adding the java native Function to interface (which technically, the signature of the required method is identical to the guava one) should not break anything. It just allows ExpectedCondition objects to be assign to java native Function as well as guava Function. So both of these should be valid (the latter one is required to work in order to be used the new wait until functions, however does NOT work when using some versions of guava...which is this whole bug):

com.google.common.base.Function condition = ExpectedConditions.elementFound(By);
java.util.function.Function condition = ExpectedConditions.elementFound(By);

@diemol
Copy link
Member

diemol commented Jun 8, 2022

@ammmze do you know if the exception below happens at compile time or at run time?

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

@ammmze
Copy link
Contributor

ammmze commented Jun 8, 2022

@ammmze do you know if the exception below happens at compile time or at run time?

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

Hmm...I'm not 100% sure. I would guess compile time. Most type issues with java are caught at compile time. Did you trigger this error somewhere?

@diemol
Copy link
Member

diemol commented Jun 8, 2022

It is in the original comment.

@ammmze
Copy link
Contributor

ammmze commented Jun 8, 2022

It is in the original comment.

Oh right...yea...the issue we were seeing here was compile time. So before this was fixed we couldn't compile successfully.

elgatov pushed a commit to elgatov/selenium that referenced this issue Jun 27, 2022
@github-actions
Copy link

github-actions bot commented Jul 9, 2022

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked and limited conversation to collaborators Jul 9, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants