【问题标题】:Set Accept-Language on PhantomJSDriver in a Play Framework Specification在 Play 框架规范中对 PhantomJSDriver 设置 Accept-Language
【发布时间】:2014-01-14 17:58:51
【问题描述】:

如何在 Play Framework 2.2 规范中为 PhantomJSDriver 配置特定的 Accept-Language 语言标头?

鉴于此代码:

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 生成的请求将使用特定的Accept-Language 标头发送,例如pt-BR?

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

【问题讨论】:

    标签: scala selenium playframework phantomjs playframework-2.2


    【解决方案1】:

    基于a forum message by Yasuki Okumura,这可以通过从预配置的驱动程序创建TestBrowser 对象来完成。

    例如:

    在文件WithPhantomJS.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()
        }
      }
    }
    

    在文件IntegrationSpec.scala

    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 中,WithBrowserwill accept 直接是 WebDriver 实例。

    【讨论】:

    • 不幸的是,在升级到 play 2.4 后,这对我不起作用(我假设顺便升级了 specs2 的版本)。
    【解决方案2】:

    根据this 在有关读取响应标头的问题中的评论,WebDriver 似乎没有用于设置请求标头或检查响应标头的 API。该评论建议使用 HTTP 客户端(Play 有 WS Library)来测试请求和响应标头。

    鉴于该信息,您可以使用 WS 库来检查服务器是否使用与 Accept-Language 标头对应的语言进行响应,并且您所做的任何前端测试都可以假定标头得到了正确的尊重。

    【讨论】:

    • 感谢您的回答。但是,建议的解决方法还不够。我知道我可以发送 HTTP 请求并获得 HTTP 响应,但这个问题是关于在模拟浏览器(在本例中为 PhantomJS)中运行的测试。我不是要检索 Accept-Language 语言标头。我试图找出如何配置模拟浏览器以使用特定语言运行。这允许进行 WS 库无法进行的各种测试,例如测试在客户端上运行的 JavaScript 代码、比较屏幕截图等。
    • PhantomJs 绝对有能力设置 Accept-Language 标头。你能用 javascript 编写测试以直接由 phantomjs 运行吗?你会失去很多 selenium 附带的功能,但你可以做你正在寻找的所有客户端验证。你甚至可以让你的 scala 测试只用测试脚本执行 phantomjs 可执行文件。
    • 感谢您提供的信息。如果没有使用 Scala 和 Play 框架的解决方案,我会记住这一点。
    猜你喜欢
    • 1970-01-01
    • 2010-10-13
    • 1970-01-01
    • 2014-01-01
    • 2014-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多