0
votes

I've been trying to pass WebBrowser as implicit parameter in a Selenium ScalaTest Spec, but it fails. I have a base superclass for all the tests:

abstract class BaseSpec extends FunSpec with WebBrowser with ShouldMatchers {
  implicit val webDriver: WebDriver = new FirefoxDriver
}

Then I have a Page Object having a method with implict WebBrowser parameter:

object LoginPage extends Page {
  def login(username: String, password: String) (implicit browser : WebBrowser ) = {      
    //...
  }

And then I want to call the login method from the actual spec. As the spec class implements the WebBrowser trait via its BaseSpec superclass I expect the spec instance calling the method to be resolved as the implicit WebBrowser:

class LoginSpec extends BaseSpec {

  it("Should fail on invalid password") {
    LoginPage login("wrong username", "wrong password")
    assertIsOnLoginPage()
  }
}

But this fails with compilation error:

could not find implicit value for parameter browser: org.scalatest.selenium.WebBrowser

on line LoginPage login("wrong username", "wrong password")

Do I always need to explicitly provide this as the WebBrowser parameter value or is there a better way?

2

2 Answers

2
votes

As the spec class implements the WebBrowser trait via its BaseSpec superclass I expect the spec instance calling the method to be resolved as the implicit WebBrowser

this isn't available as an implicit automatically, but you can easily add it:

abstract class BaseSpec extends FunSpec with WebBrowser with ShouldMatchers {
  implicit def webBrowser: WebBrowser = this
  implicit val webDriver: WebDriver = new FirefoxDriver
}
1
votes

Create an implicit val inside class LoginSpec as in this code:

trait WebBrowser
class WebDriver
class FunSpec
trait ShouldMatchers
class FirefoxDriver extends WebDriver

abstract class BaseSpec extends FunSpec with WebBrowser with ShouldMatchers {
  implicit val webDriver: WebDriver = new FirefoxDriver
}

trait Page

object LoginPage extends Page {
  def login(username: String, password: String)(implicit browser: WebBrowser) = {
    println(username, password)
  }
}

class LoginSpec extends BaseSpec {
  implicit val browser: WebBrowser = this
  def fun = {
    LoginPage login("wrong username", "wrong password")
  }
}

object ImplicitThis {
  def main(args: Array[String]) {
    new LoginSpec().fun
  }
}

This compiles, and works just fine.