2

I have been given two conditions based on which the webdriver needs to wait for either of the conditions to fulfill before moving ahead with execution. I am using Explicit wait along with ExpectedConditions.or for this purpose.

I tried using the below code:

new WebDriverWait(driver.getDriver(),30).until(
    ExpectedConditions.or(
        ExpectedConditions.jsReturnsValue("return document.ReadyState")).equals("complete"),    
        ExpectedConditions.visibilityOfElementLocated(driver.findElement(By.Id("name"))
    )
);

I am getting the Error:

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

Please note that I am using Guava 23.0 and its already added as a dependency in my pom.xml

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
abhishek pandey
  • 83
  • 1
  • 3
  • 13

3 Answers3

3

ExpectedConditions.or receives ExpectedConditions as parameters. When you compare the result of ExpectedConditions.jsReturnsValue to a string you are changing the all expression to boolean.

You can create custom ExpectedCondition to warp it

public static ExpectedCondition<Object> customeJsReturnsValue(final String javaScript) {
    return new ExpectedCondition<Object>() {
        @Override
        public Object apply(WebDriver driver) {
            return ExpectedConditions.jsReturnsValue("return Spotfire.Busy.idle()")).equals("true")
        }
    }
}

Uses:

new WebDriverWait(driver.getDriver(),30).until(
    ExpectedConditions.or(
        customeJsReturnsValue("return document.ReadyState")).equals("complete"),
        ExpectedConditions.visibilityOfElementLocated(driver.findElement(By.Id("name"))
    )
);
Guy
  • 46,488
  • 10
  • 44
  • 88
  • I tried the above code.However, I am still getting the Error on the below line: public static ExpectedCondition customeJsReturnsValue(final String javaScript) { return new ExpectedCondition() Error Message: Type mismatch: cannot convert from new ExpectedCondition(){} to String – abhishek pandey Sep 27 '19 at 04:33
  • Also, We have overriden ExpectedCondition method -> Would we have to override the ExpectedConditions.or method instead to return a boolean?? – abhishek pandey Sep 27 '19 at 06:04
0

jsReturnsValue()

The ExpectedConditions of jsReturnsValue() returns an Object and is defined as:

public static ExpectedCondition<java.lang.Object> jsReturnsValue(java.lang.String javaScript)

An expectation for String value from javascript

Parameters:
    javaScript - as executable js line

Returns:
    true once js return string

visibilityOfElementLocated()

The ExpectedConditions of visibilityOfElementLocated() returns the WebElement and is defined as:

public static ExpectedCondition<WebElement> visibilityOfElementLocated(By locator)

An expectation for checking that an element is present on the DOM of a page and visible. Visibility means that the element is not only displayed but also has a height and width that is greater than 0.

Parameters:
locator - used to find the element

Returns:
the WebElement once it is located and visible

This error message...

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

...implies that the until() is not appplicable for multiple return types boolean and WebElement.

In your usecase,

  • jsReturnsValue() returns an Object.
  • visibilityOfElementLocated() returns a WebElement.

Solution

If you your usecase is about the visibility of a certain WebElement you can safely ignore the concern for 'document.readyState' equal to "complete" as it would be an overhead. You can find a relevant discussion in Selenium IE WebDriver only works while debugging.

However, to use the until() for the visibilityOfElementLocated() for multiple element of similar type of data types you can follow the below example:

  • Waiting for either of the elements among By.xpath("//span[@id='id1']") or By.xpath("//span[@id='id2']") be like:

    new WebDriverWait(driver, 10).until(ExpectedConditions.or(
        ExpectedConditions.visibilityOfElementLocated(By.xpath("//span[@id='id1']")),
        ExpectedConditions.visibilityOfElementLocated(By.xpath("//span[@id='id2']"))
    ));
    

References

You can find a couple of relevant detailed discussions in


Outro

Do we have any generic function to check if page has completely loaded in Selenium

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • 1
    `jsReturnsValue()` returns the value from the JavaScript query as `Object`, not `boolean`. – Guy Sep 26 '19 at 12:46
0

Just add the selenium dependency in the pom.xml and the error is gone.

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