Scala 在Play框架规范中设置PhantomJSDriver上的Accept语言

Scala 在Play框架规范中设置PhantomJSDriver上的Accept语言,scala,selenium,playframework,phantomjs,playframework-2.2,Scala,Selenium,Playframework,Phantomjs,Playframework 2.2,在Play Framework 2.2规范中,如何使用特定的Accept Language标头配置PhantomJSDriver 鉴于此代码: import org.specs2.mutable._ import org.specs2.runner._ import org.junit.runner._ import play.api.i18n._ import play.api.test._ import play.api.test.Helpers._ import org.openqa.se

在Play Framework 2.2规范中,如何使用特定的Accept Language标头配置PhantomJSDriver

鉴于此代码:

import org.specs2.mutable._
import org.specs2.runner._
import org.junit.runner._
import play.api.i18n._
import play.api.test._
import play.api.test.Helpers._
import org.openqa.selenium.phantomjs.PhantomJSDriver

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

  "Application" should {

    "work from within a browser" in new WithBrowser(webDriver = classOf[PhantomJSDriver]) {
      browser.goTo("http://localhost:" + port)
      implicit val lang = Lang("pt-BR")
      val expected = Messages("home.index.featured_lead")
      browser.pageSource must contain(expected)
    }
  }
}
我如何确保由
goTO
生成的请求将使用特定的
接受语言
头发送,例如
pt BR

更新:问题的目标是能够在模拟浏览器(如PhantomJS)中运行测试,并将浏览器配置为特定语言。上面的代码示例只要求浏览器检测页面中是否有一些本地化文本,但是可以在模拟浏览器中运行的测试种类差别很大。例如,可以在运行时通过JavaScript设置文本。或者我可能想要截图,并将其与之前的参考截图进行比较,以测试布局。默认情况下,显然浏览器正在使用机器的区域设置,这会中断连续集成测试。因此,问题是如何从Play Framework测试中配置PhantomJS。

根据一期关于读取响应头的评论,WebDriver似乎没有用于设置请求头或检查响应头的API。该评论建议使用HTTP客户端(Play具有)来测试请求和响应头

根据这些信息,您可以使用WS-Library检查服务器是否使用与
接受语言
头相对应的语言进行响应,并且您所做的任何前端测试都可以假定头得到了正确遵守。

基于,这可以通过从预配置的驱动程序创建
TestBrowser
对象来实现

例如:

在带有phantomjs.scala的文件
中:

package com.myproject.website.tests

import org.openqa.selenium.remote.DesiredCapabilities
import org.openqa.selenium.phantomjs.PhantomJSDriver
import org.openqa.selenium.phantomjs.PhantomJSDriverService
import org.specs2.execute.AsResult
import org.specs2.execute.Result
import org.specs2.mutable.Around
import org.specs2.specification.Scope
import play.api.i18n.Lang
import play.api.test.Helpers._
import play.api.test.FakeApplication
import play.api.test.TestBrowser
import play.api.test.TestServer
import scala.collection.JavaConverters._

abstract class WithPhantomJS(val additionalOptions: Map[String, String] = Map()) extends Around with Scope {

  implicit def app = FakeApplication()

  implicit def port = play.api.test.Helpers.testServerPort

  lazy val browser: TestBrowser = {
    val defaultCapabilities = DesiredCapabilities.phantomjs
    val additionalCapabilities = new DesiredCapabilities(additionalOptions.asJava)
    val capabilities = new DesiredCapabilities(defaultCapabilities, additionalCapabilities)
    val driver = new PhantomJSDriver(capabilities)
    TestBrowser(driver, Some("http://localhost:" + port))
  }

  override def around[T: AsResult](body: => T): Result = {
    try {
      running(TestServer(port, app))(AsResult.effectively(body))
    } finally {
      browser.quit()
    }
  }
}
package com.myproject.website.tests

import com.myproject.common.helpers._
import org.junit.runner._
import org.specs2.runner._
import play.api.i18n._
import play.api.test._
import play.api.test.Helpers._
import org.specs2.mutable.Specification
import org.openqa.selenium.phantomjs.PhantomJSDriverService

/**
 * An integration test will fire up a whole play application in a real (or headless) browser.
 */
@RunWith(classOf[JUnitRunner])
class IntegrationSpec extends Specification {

  val enUSLangCode = "en-US"
  val ptBRLangCode = "pt-BR"

  val enUSOptions = getPhantomJSLanguageOption(enUSLangCode)
  val ptBROptions = getPhantomJSLanguageOption(ptBRLangCode)

  "Application" should {

    "work from within a browser with en-US language" in new WithPhantomJS(enUSOptions) {
      browser.goTo("http://localhost:" + port)
      implicit val lang = Lang(enUSLangCode)
      val expected = Messages("home.index.featured_lead")
      browser.pageSource must contain(expected)
    }

    "work from within a browser with pt-BR language" in new WithPhantomJS(ptBROptions) {
      browser.goTo("http://localhost:" + port)
      implicit val lang = Lang(ptBRLangCode)
      val expected = Messages("home.index.featured_lead")
      browser.pageSource must contain(expected)
    }

  }

  private def getPhantomJSLanguageOption(langCode: String) =
    Map(PhantomJSDriverService.PHANTOMJS_PAGE_CUSTOMHEADERS_PREFIX + "Accept-Language" -> langCode)

}
在文件
IntegrationSpec.scala
中:

package com.myproject.website.tests

import org.openqa.selenium.remote.DesiredCapabilities
import org.openqa.selenium.phantomjs.PhantomJSDriver
import org.openqa.selenium.phantomjs.PhantomJSDriverService
import org.specs2.execute.AsResult
import org.specs2.execute.Result
import org.specs2.mutable.Around
import org.specs2.specification.Scope
import play.api.i18n.Lang
import play.api.test.Helpers._
import play.api.test.FakeApplication
import play.api.test.TestBrowser
import play.api.test.TestServer
import scala.collection.JavaConverters._

abstract class WithPhantomJS(val additionalOptions: Map[String, String] = Map()) extends Around with Scope {

  implicit def app = FakeApplication()

  implicit def port = play.api.test.Helpers.testServerPort

  lazy val browser: TestBrowser = {
    val defaultCapabilities = DesiredCapabilities.phantomjs
    val additionalCapabilities = new DesiredCapabilities(additionalOptions.asJava)
    val capabilities = new DesiredCapabilities(defaultCapabilities, additionalCapabilities)
    val driver = new PhantomJSDriver(capabilities)
    TestBrowser(driver, Some("http://localhost:" + port))
  }

  override def around[T: AsResult](body: => T): Result = {
    try {
      running(TestServer(port, app))(AsResult.effectively(body))
    } finally {
      browser.quit()
    }
  }
}
package com.myproject.website.tests

import com.myproject.common.helpers._
import org.junit.runner._
import org.specs2.runner._
import play.api.i18n._
import play.api.test._
import play.api.test.Helpers._
import org.specs2.mutable.Specification
import org.openqa.selenium.phantomjs.PhantomJSDriverService

/**
 * An integration test will fire up a whole play application in a real (or headless) browser.
 */
@RunWith(classOf[JUnitRunner])
class IntegrationSpec extends Specification {

  val enUSLangCode = "en-US"
  val ptBRLangCode = "pt-BR"

  val enUSOptions = getPhantomJSLanguageOption(enUSLangCode)
  val ptBROptions = getPhantomJSLanguageOption(ptBRLangCode)

  "Application" should {

    "work from within a browser with en-US language" in new WithPhantomJS(enUSOptions) {
      browser.goTo("http://localhost:" + port)
      implicit val lang = Lang(enUSLangCode)
      val expected = Messages("home.index.featured_lead")
      browser.pageSource must contain(expected)
    }

    "work from within a browser with pt-BR language" in new WithPhantomJS(ptBROptions) {
      browser.goTo("http://localhost:" + port)
      implicit val lang = Lang(ptBRLangCode)
      val expected = Messages("home.index.featured_lead")
      browser.pageSource must contain(expected)
    }

  }

  private def getPhantomJSLanguageOption(langCode: String) =
    Map(PhantomJSDriverService.PHANTOMJS_PAGE_CUSTOMHEADERS_PREFIX + "Accept-Language" -> langCode)

}
另外,
build.sbt
中需要此依赖项:

libraryDependencies += "com.github.detro.ghostdriver" % "phantomjsdriver" % "1.0.4" % "test"

在Play Framework 2.3中,使用浏览器的
class a
WebDriver
实例直接运行。

谢谢您的回答。不过,建议的解决办法还不够。我知道我可以发送HTTP请求并获得HTTP响应,但这个问题是关于在模拟浏览器(在本例中为PhantomJS)中运行的测试的。我没有尝试检索Accept Language标头。我正在尝试了解如何配置模拟浏览器以使用特定语言运行。这允许进行WS-Library无法进行的各种测试,例如测试客户端上运行的JavaScript代码、比较屏幕截图等。PhantomJs肯定能够设置Accept Language标头。你能用javascript编写测试直接由phantomjs运行吗?您可能会丢失selenium附带的许多功能,但您可以完成所需的所有客户端验证。您甚至可以让scala测试用测试脚本执行phantomjs可执行文件。谢谢您提供的信息。如果没有使用Scala和Play框架的解决方案,我会记住这一点。不幸的是,在升级到Play 2.4(我假设顺便升级了specs2的版本)之后,这对我来说就不起作用了。