/framework/src/play-test/src/main/scala/play/api/test/Selenium.scala

http://github.com/playframework/Play20 · Scala · 124 lines · 44 code · 16 blank · 64 comment · 0 complexity · 416ce403526045295efb26592063e31a MD5 · raw file

  1. /*
  2. * Copyright (C) 2009-2016 Lightbend Inc. <https://www.lightbend.com>
  3. */
  4. package play.api.test
  5. import org.openqa.selenium._
  6. import org.openqa.selenium.firefox._
  7. import org.openqa.selenium.htmlunit._
  8. import org.fluentlenium.core._
  9. import java.util.concurrent.TimeUnit
  10. import com.google.common.base.Function
  11. import org.openqa.selenium.support.ui.FluentWait
  12. /**
  13. * A test browser (Using Selenium WebDriver) with the FluentLenium API (https://github.com/Fluentlenium/FluentLenium).
  14. *
  15. * @param webDriver The WebDriver instance to use.
  16. */
  17. case class TestBrowser(webDriver: WebDriver, baseUrl: Option[String]) extends FluentAdapter(webDriver) {
  18. baseUrl.map(baseUrl => withDefaultUrl(baseUrl))
  19. /**
  20. * Submits a form with the given field values
  21. *
  22. * @example {{{
  23. * submit("#login", fields =
  24. * "email" -> email,
  25. * "password" -> password
  26. * )
  27. * }}}
  28. */
  29. def submit(selector: String, fields: (String, String)*): Fluent = {
  30. fields.foreach {
  31. case (fieldName, fieldValue) =>
  32. fill(s"${selector} *[name=${fieldName}]").`with`(fieldValue)
  33. }
  34. super.submit(selector)
  35. }
  36. /**
  37. * Repeatedly applies this instance's input value to the given block until one of the following occurs:
  38. * the function returns neither null nor false,
  39. * the function throws an unignored exception,
  40. * the timeout expires
  41. *
  42. * @param timeout
  43. * @param timeUnit duration
  44. * @param block code to be executed
  45. */
  46. def waitUntil[T](timeout: Int, timeUnit: TimeUnit)(block: => T): T = {
  47. val wait = new FluentWait[WebDriver](webDriver).withTimeout(timeout, timeUnit)
  48. val f = new Function[WebDriver, T]() {
  49. def apply(driver: WebDriver): T = {
  50. block
  51. }
  52. }
  53. wait.until(f)
  54. }
  55. /**
  56. * Repeatedly applies this instance's input value to the given block until one of the following occurs:
  57. * the function returns neither null nor false,
  58. * the function throws an unignored exception,
  59. * the default timeout expires
  60. *
  61. * @param block code to be executed
  62. */
  63. def waitUntil[T](block: => T): T = waitUntil(3000, TimeUnit.MILLISECONDS)(block)
  64. /**
  65. * retrieves the underlying option interface that can be used
  66. * to set cookies, manage timeouts among other things
  67. */
  68. def manage: WebDriver.Options = super.getDriver.manage
  69. }
  70. /**
  71. * Helper utilities to build TestBrowsers
  72. */
  73. object TestBrowser {
  74. /**
  75. * Creates an in-memory WebBrowser (using HtmlUnit)
  76. *
  77. * @param baseUrl The default base URL that will be used for relative URLs
  78. */
  79. def default(baseUrl: Option[String] = None) = of(classOf[HtmlUnitDriver], baseUrl)
  80. /**
  81. * Creates a firefox WebBrowser.
  82. *
  83. * @param baseUrl The default base URL that will be used for relative URLs
  84. */
  85. def firefox(baseUrl: Option[String] = None) = of(classOf[FirefoxDriver], baseUrl)
  86. /**
  87. * Creates a WebBrowser of the specified class name.
  88. *
  89. * @param baseUrl The default base URL that will be used for relative URLs
  90. */
  91. def of[WEBDRIVER <: WebDriver](webDriver: Class[WEBDRIVER], baseUrl: Option[String] = None) = TestBrowser(WebDriverFactory(webDriver), baseUrl)
  92. }
  93. object WebDriverFactory {
  94. /**
  95. * Creates a Selenium Web Driver and configures it
  96. * @param clazz Type of driver to create
  97. * @return The driver instance
  98. */
  99. def apply[D <: WebDriver](clazz: Class[D]): WebDriver = {
  100. val driver = clazz.newInstance
  101. // Driver-specific configuration
  102. driver match {
  103. case htmlunit: HtmlUnitDriver => htmlunit.setJavascriptEnabled(true)
  104. case _ =>
  105. }
  106. driver
  107. }
  108. }