[2.2.1] Integration testing with PhantomJS

445 views
Skip to first unread message

paulabr...@gmail.com

unread,
Jan 18, 2014, 6:51:57 PM1/18/14
to play-fr...@googlegroups.com
Hi all,

**** play 2.2.1 built with Scala 2.10.2 (running Java 1.7.0_40) ****

I'm trying to do some integration testing on the application I'm working on.  I created the skeleton application using Typesafe Activator, ran the tests and all was fine.

However, as I'm starting to add content (specifically JavaScript files), the integration tests are failing with errors similar to:

org.openqa.selenium.WebDriverException: com.gargoylesoftware.htmlunit.ScriptException: TypeError: Cannot find function addEventListener in object [object HTMLDocument]. (http://localhost:19001/assets/js/jquery.js#834)
Build info: version: '2.35.0', revision: '8df0c6bedf70ff9f22c647788f9fe9c8d22210e2', time: '2013-08-17 12:46:41'
System info: os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.7.0_25'
Driver info: driver.version: HtmlUnitDriver
at org.openqa.selenium.htmlunit.HtmlUnitDriver.get(HtmlUnitDriver.java:376)
at org.openqa.selenium.htmlunit.HtmlUnitDriver.get(HtmlUnitDriver.java:355)
at org.fluentlenium.core.Fluent.goTo(Fluent.java:228)
at IntegrationSpec$$anonfun$1$$anonfun$apply$1$$anon$1$delayedInit$body.apply(IntegrationSpec.scala:30)
at play.api.test.WithBrowser$$anonfun$around$3.apply(Specs.scala:57)
at play.api.test.WithBrowser$$anonfun$around$3.apply(Specs.scala:57)

Following some Googling, it seems that perhaps HtmlUnit isn't the best to use when there are JavaScript files involved, so I'm trying PhantomJS to see if that solves the problem.

My integration test looks like this (taking the code from [https://groups.google.com/forum/#!topic/scalatest-users/Kpvf-712cq4]):

@RunWith(classOf[JUnitRunner])
class IntegrationSpec extends Specification {

  implicit val webDriver: WebDriver = {
    val capabilities = new DesiredCapabilities
    capabilities.setJavascriptEnabled(false)
    capabilities.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, "C:/phantomjs.exe")
    new PhantomJSDriver(capabilities)
  }

  "Application" should {
    "work from within a browser" in new WithBrowser {
      browser.goTo("http://localhost:" + port)
      browser.pageSource must contain("Hello Play Framework")
    }
  }

}


Now the test starts the PhantomJS part, but it still runs HtmlUnit and the test fails.

Any ideas what I am doing wrong?

Thanks.

Paul Abraham.

Yasuki Okumura

unread,
Jan 19, 2014, 5:12:23 AM1/19/14
to play-fr...@googlegroups.com
You need to implement another WithBrowser for PhantomJS like this:
trait WithPhantomjs extends Around with Scope {

  val TEST_PORT = 11111
  val fakeApp   = FakeApplication

  // for phantomjs
  lazy val browser: TestBrowser = {
    val sCaps = new DesiredCapabilities()
    val phantomjsPath = {
      if(null != System.getenv("PHANTOMJS_PATH")){
        System.getenv("PHANTOMJS_PATH")
      } else {
        System.getProperty("PHANTOMJS_PATH")
      }
    }

    sCaps.setJavascriptEnabled(true);
    sCaps.setCapability("takesScreenshot", true);
    sCaps.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, phantomjsPath)

    // Disable "web-security", enable all possible "ssl-protocols" and "ignore-ssl-errors" for PhantomJSDriver
    sCaps.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS, Array(
      "--web-security=false",
      "--ssl-protocol=any",
      "--ignore-ssl-errors=true"
    ))


    val driver = new PhantomJSDriver(sCaps)
    // set timeout
    driver.manage().timeouts().implicitlyWait(10L, java.util.concurrent.TimeUnit.SECONDS)
    driver.manage().timeouts().pageLoadTimeout(30L, java.util.concurrent.TimeUnit.SECONDS)
    driver.manage().timeouts().setScriptTimeout(30L, java.util.concurrent.TimeUnit.SECONDS)
    TestBrowser(driver)
  }


  def around[A <% Result](f: => A) = running(TestServer(TEST_PORT, fakeApp)) {
    try {
      f
    } finally {
      browser.quit()
    }
  }
}

Then you can use it like this:
  "Application" should {
    "work from within a browser" in new WithPhantomjs{

      browser.goTo("http://localhost:" + port)
      browser.pageSource must contain("Hello Play Framework")
    }
  }

WithPhantomjs works in play2.0.4 but I am not sure it works in play2.2.1. I think you need to change it little bit.

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Fernando Correia

unread,
Jan 20, 2014, 1:44:54 PM1/20/14
to play-fr...@googlegroups.com
Thank you for this example, Yasuki. It helped me find out a good way to configure PhantomJS in my tests.

This answer contains an example of the code that worked for me with Play 2.2.1:

http://stackoverflow.com/a/21241686/376366
 
Reply all
Reply to author
Forward
0 new messages