mushroom
mushroom

Reputation: 6289

Play integration test with browser that supports WebSocket

I am trying to do some simple integration tests with my WebSocket code using WithBrowser:

  class ApplicationControllerSpec extends Specification{
    "Application Controller" should {
      "do something" in new WithBrowser{
        browser.goTo("http://localhost:3333")
        browser.pageSource must contain("Hello")
      }
    }
  }

When I do this I get a very long error but part of it says:

WebDriverException: com.gargoylesoftware.htmlunit.ScriptException: ReferenceError: "WebSocket" is not defined.

Is there an alternative WebDriver that does have WebSocket implemented? Alternatively, is there a way to have it actually open up firefox or chrome?

I would also appreciate any advice on how to test WebSocket code, but it looks like there is another unanswered question about that here.

I am using Play 2.1.3.

Upvotes: 2

Views: 1100

Answers (2)

Schleichardt
Schleichardt

Reputation: 7552

I test WebSockets with Firefox:

https://github.com/schleichardt/stackoverflow-answers/commit/13d5876791ef409e092e4a097f54247d851e17dc#L8R14

WithBrowser supports as first argument the Browser, see Doc.

So it could look like

 class ApplicationControllerSpec extends Specification{
    "Application Controller" should {
      "do something" in new WithBrowser(play.api.test.Helpers.FIREFOX){
        browser.goTo("http://localhost:3333")
        browser.pageSource must contain("Hello")
      }
    }
  }

If you use firefox, it is a good idea to load the most recent selenium driver for it.

Upvotes: 2

Christian
Christian

Reputation: 4593

I'm not sure why you are using WithBrowser to test your websocket, but this is how I'm doing it:

class ApplicationSpec extends Specification {

  "Application" should {
    "work" in {
      running(TestServer(9000)) {
        val client = new WebSocketClient(URI.create("ws://localhost:9000/test"),
          new Draft_17(), Map("HeaderKey1" -> "HeaderValue1"), 0) {

          def onError(p1: Exception) {
            println("onError")
          }

          def onMessage(message: String) {
            println("onMessage, message = " + message)
          }

          def onClose(code: Int, reason: String, remote: Boolean) {
            println("onClose")
          }

          def onOpen(handshakedata: ServerHandshake) {
            println("onOpen")
          }
        }
        client.connectBlocking()
        client.send("message")

        Thread.sleep(1000)
        success
      }
    }
  }
}

I'm using Java-WebSocket to call the websocket. This library can even send custom http headers during the handshake.

Note that I don't do any assertions, so I have to return success at the end of the test. I need a Thread.sleep, otherwise a RuntimeException ("There is no started application") can happen because the test finishes before the websocket communication is complete.

Upvotes: 2

Related Questions