I am trying to convert Java code to scala

189 Views Asked by At

I want to use fluent wait with selenium in scala. However I am not able to convert the below code into Scala. Please help me out.

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
        .withTimeout(30, SECONDS)
        .pollingEvery(5, SECONDS)
        .ignoring(NoSuchElementException.class);

WebElement foo = wait.until(new Function<WebDriver, WebElement>() 
{
  public WebElement apply(WebDriver driver) {
  return driver.findElement(By.id("foo"));
}
});

When I use it in Scala, I get

@BrianMcCutchon - Hi. When I use this code in Scala, it gets converted to the following,

val wait = new FluentWait[WebDriver](driver).withTimeout(30, SECONDS).pollingEvery(5, SECONDS).ignoring(classOf[Nothing])

  val foo = wait.until(new Nothing() {
    def apply(driver: WebDriver): WebElement = driver.findElement(By.id("foo"))
  })

In this code, val wait is not resolved. Moreover, Nothing seems meaningless

3

There are 3 best solutions below

0
On

I'm not talking about that Selenium's FluentWait here. For a generic fluent api in Java, it should have a default value, shouldn't it? In that case, the named parameter in Scala looks better to me. For example,

new FluentWait(timeout = 30.seconds, polling = 5.seconds)

the ignoring argument is ignored and will get the default value of classOf[NoSuchElementException].

2
On

This code should be written with lambdas in both Java (8 and later) and Scala (2.12 to interoperate with Java interface Function) unless you have a specific reason not to.

Java:

WebElement foo = wait.until(driver -> driver.findElement(By.id("foo")));

Scala:

val foo = wait.until(_.findElement(By.id("foo")))

or

val foo = wait.until(driver => driver.findElement(By.id("foo")))

Also, wait should have ignoring(classOf[NoSuchElementException]), not Nothing.

0
On

Here's the conversion:

Converting "wait"

The Java and Scala are pretty similiar here. Just note that:

  1. Scala uses [] for generics instead of Java's <>.
  2. Scala's version of SomeClass.class is classOf[SomeClass].

Java:

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
    .withTimeout(30, SECONDS)
    .pollingEvery(5, SECONDS)
    .ignoring(NoSuchElementException.class);

Scala:

val wait = new FluentWait[WebDriver](driver)
    .withTimeout(30, SECONDS)
    .pollingEvery(5, SECONDS)
    .ignoring(classOf[NoSuchElementException])

Converting "foo"

This is a good place to illustrate the similarity between functional-style Java and Scala I'm translating your example to a functional-style in Java and using var which was introduced in Java 10. The Scala version is very, very similar to this style.

Your Java:

WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
  public WebElement apply(WebDriver driver) {
    return driver.findElement(By.id("foo"));
  }
});

Function-style Java w/ local type inference (JDK 10+):

var foo = wait.until(driver -> driver.findElement(By.id("foo")));

Scala:

val foo = wait.until(driver => driver.findElement(By.id("foo")))

In Scala _ can be used instead of an explicit parameter name in the function call. This is a style-choice, but you could also write the above Scala code as:

val foo = wait.until(_.findElement(By.id("foo")))