Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ language: scala
before_script:
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
- sleep 3 # give xvfb some time to start
- python -m SimpleHTTPServer 8080 &
script:
- sbt ++$TRAVIS_SCALA_VERSION seleniumJSEnv/scalastyle seleniumJSEnv/test:scalastyle seleniumJSEnvTest/scalastyle seleniumJSEnvTest/test:scalastyle
- sbt ++$TRAVIS_SCALA_VERSION seleniumJSEnv/scalastyle seleniumJSEnv/test:scalastyle seleniumJSEnvTest/scalastyle seleniumJSHttpEnvTest/test:scalastyle seleniumJSEnvTest/test:scalastyle
- sbt ++$TRAVIS_SCALA_VERSION seleniumJSEnvTest/run seleniumJSEnvTest/test 'set scalaJSStage in Global := FullOptStage' seleniumJSEnvTest/run seleniumJSEnvTest/test
- sbt ++$TRAVIS_SCALA_VERSION 'set inScope(ThisScope in seleniumJSEnvTest)(jsEnv := new org.scalajs.jsenv.selenium.SeleniumJSEnv(org.scalajs.jsenv.selenium.Firefox).withKeepAlive())' seleniumJSEnvTest/run seleniumJSEnvTest/test 'set scalaJSStage in Global := FullOptStage' seleniumJSEnvTest/run seleniumJSEnvTest/test
- sbt ++$TRAVIS_SCALA_VERSION 'set scalaJSStage in Global := FullOptStage' seleniumJSHttpEnvTest/test
scala:
- 2.10.6
- 2.11.7
Expand Down
27 changes: 20 additions & 7 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import sbt.Keys._

import org.scalajs.jsenv.selenium.SeleniumJSEnv
import org.scalajs.jsenv.selenium.Firefox
import org.scalajs.jsenv.selenium.CustomFileMaterializer

val commonSettings: Seq[Setting[_]] = Seq(
version := "0.1.2-SNAPSHOT",
Expand All @@ -18,6 +19,15 @@ val commonSettings: Seq[Setting[_]] = Seq(
Some("scm:git:[email protected]:scala-js/scala-js-env-selenium.git")))
)

val testSettings: Seq[Setting[_]] = commonSettings ++ Seq(
testOptions +=
Tests.Argument(TestFramework("com.novocode.junit.JUnitFramework"), "-v", "-a"),
jsDependencies ++= Seq(
RuntimeDOM % "test",
"org.webjars" % "jquery" % "1.10.2" / "jquery.js"
)
)

// We'll need the name scalajs-env-selenium for the `seleniumJSEnv` project
name := "root"

Expand Down Expand Up @@ -65,13 +75,16 @@ lazy val seleniumJSEnv: Project = project.
lazy val seleniumJSEnvTest: Project = project.
enablePlugins(ScalaJSPlugin).
enablePlugins(ScalaJSJUnitPlugin).
settings(commonSettings).
settings(testSettings).
settings(
testOptions +=
Tests.Argument(TestFramework("com.novocode.junit.JUnitFramework"), "-v", "-a"),
jsDependencies ++= Seq(
RuntimeDOM % "test",
"org.webjars" % "jquery" % "1.10.2" / "jquery.js"
),
jsEnv := new SeleniumJSEnv(Firefox)
)

lazy val seleniumJSHttpEnvTest: Project = project.
enablePlugins(ScalaJSPlugin).
enablePlugins(ScalaJSJUnitPlugin).
settings(testSettings).
settings(
jsEnv := new SeleniumJSEnv(Firefox).
withMaterializer(new CustomFileMaterializer("tmp", "http://localhost:8080/tmp"))
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package org.scalajs.jsenv.selenium
import org.scalajs.core.tools.io.{MemVirtualJSFile, VirtualJSFile}
import org.scalajs.core.tools.jsdep.ResolvedJSDependency
import org.scalajs.core.tools.logging.Logger
import org.scalajs.jsenv.{VirtualFileMaterializer, JSConsole}
import org.scalajs.jsenv.JSConsole

abstract class AbstractSeleniumJSRunner(browserProvider: SeleniumBrowser,
libs: Seq[ResolvedJSDependency], code: VirtualJSFile) {
libs: Seq[ResolvedJSDependency], code: VirtualJSFile, materializer: FileMaterializer) {

protected val browser = browserProvider.newDriver

Expand All @@ -22,30 +22,23 @@ abstract class AbstractSeleniumJSRunner(browserProvider: SeleniumBrowser,
_console = console
}

protected[this] val libCache = new VirtualFileMaterializer(true)

protected def initFiles(): Seq[VirtualJSFile] =
browserProvider.initFiles() ++ runtimeEnv()

protected def runAllScripts(): Unit = {
val inits = initFiles()
val cacheDir = libCache.cacheDir.getAbsolutePath
def absolutePath(fileName: String): String =
"file://" + cacheDir + "/" + fileName

val jsFiles = {
inits.map(file => absolutePath(file.path)) ++
libs.map(dep => absolutePath(dep.info.relPath.split('/').last)) :+
inits.map(materializer.materialize(_).toString) ++
libs.map(dep => materializer.materialize(dep.lib).toString) :+
code.path
}
val page = htmlPage(jsFiles)

inits.foreach(libCache.materialize)
libs.foreach(dep => libCache.materialize(dep.lib))
libCache.materialize(code)
libCache.materialize(page)
materializer.materialize(code)
val pageURL = materializer.materialize(page)

browser.getWebDriver.get("file://" + cacheDir + "/" + page.path)
browser.getWebDriver.get(pageURL.toString)
browser.processConsoleLogs(console)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.scalajs.jsenv.selenium

import java.io.File
import java.net.URL

import org.scalajs.core.tools.io.{IO, VirtualTextFile, WritableFileVirtualTextFile}

/** Materializes files on the filesystem and specifies a custom url to access stored files.
* This can be used to bypass cross origin access policies as shown below.
*
* @param fsRoot Location on the filesystem where to store the generated files
* @param webRoot Corresponding url to access the files
*
* @example
*
* The following illustrates how to configure a project such that the browser fetches
* files by http:// instead of file://.
* This example assumes a local webserver is running and serving the ".tmp"
* directory at http://localhost:8080
*
* <pre>
* jsSettings(
* // ...
* jsEnv := new SeleniumJSEnv(org.scalajs.jsenv.selenium.Firefox)
* .withMaterializer(new SpecificFileMaterializer(".tmp", "http://localhost:8080"))
* )
* </pre>
*/
class CustomFileMaterializer(val fsRoot: String, val webRoot: String) extends FileMaterializer {

val storageDir = createStorageDir()

/** Create a target file to write/copy to. Will also call
* deleteOnExit on the file.
*/
private def trgFile(name: String): File = {
val f = new File(storageDir, name)
f.deleteOnExit()
f
}

/** Creates the storage directory if it does not exist. */
private def createStorageDir(): File = {
val storageDir = new File(fsRoot)
storageDir.mkdir()
storageDir
}

override def materialize(vf: VirtualTextFile): URL = {
val trg = trgFile(vf.name)
IO.copyTo(vf, WritableFileVirtualTextFile(trg))
new URL(webRoot + "/" + vf.name)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.scalajs.jsenv.selenium

import org.scalajs.core.tools.io.VirtualTextFile
import org.scalajs.jsenv.VirtualFileMaterializer
import java.net.URL

/** Materializes virtual files in a temporary directory and links to them
* via file://
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment should be formatted as follows.

/** Materializes virtual files in a temporary directory and links to them
 *  via file://
 */

*/
object DefaultFileMaterializer extends FileMaterializer {

private val materializer = new VirtualFileMaterializer(true)

override def materialize(vf: VirtualTextFile): URL = {
materializer.materialize(vf).toURI.toURL
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.scalajs.jsenv.selenium

import java.net.URL

import org.scalajs.core.tools.io.VirtualTextFile

trait FileMaterializer {
def materialize(vf: VirtualTextFile): URL
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import scala.concurrent.{Future, Promise}
import scala.util.Try

class SeleniumAsyncJSRunner(browserProvider: SeleniumBrowser,
libs: Seq[ResolvedJSDependency], code: VirtualJSFile, keepAlive: Boolean)
extends AbstractSeleniumJSRunner(browserProvider, libs, code)
libs: Seq[ResolvedJSDependency], code: VirtualJSFile, keepAlive: Boolean, materializer: FileMaterializer)
extends AbstractSeleniumJSRunner(browserProvider, libs, code, materializer)
with AsyncJSRunner {

private[this] var promise = Promise[Unit]()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import scala.concurrent.duration.Duration
import scala.util.Try

class SeleniumComJSRunner(browserProvider: SeleniumBrowser,
libs: Seq[ResolvedJSDependency], code: VirtualJSFile, keepAlive: Boolean)
extends SeleniumAsyncJSRunner(browserProvider, libs, code, keepAlive)
libs: Seq[ResolvedJSDependency], code: VirtualJSFile, keepAlive: Boolean, materializer: FileMaterializer)
extends SeleniumAsyncJSRunner(browserProvider, libs, code, keepAlive, materializer)
with ComJSRunner {

protected def envName: String =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,32 @@ import org.scalajs.core.tools.jsdep.ResolvedJSDependency
import org.scalajs.jsenv.{AsyncJSEnv, ComJSEnv}
import org.scalajs.jsenv.{JSRunner, AsyncJSRunner, ComJSRunner}

class SeleniumJSEnv private (browser: SeleniumBrowser, keepAlive: Boolean)
class SeleniumJSEnv private (browser: SeleniumBrowser, keepAlive: Boolean, materializer: FileMaterializer)
extends AsyncJSEnv with ComJSEnv {

def this(browser: SeleniumBrowser) =
this(browser, keepAlive = false)
this(browser, keepAlive = false, materializer = DefaultFileMaterializer)

def withMaterializer(materializer: FileMaterializer): SeleniumJSEnv =
new SeleniumJSEnv(browser, keepAlive, materializer)

def withKeepAlive(): SeleniumJSEnv =
new SeleniumJSEnv(browser, keepAlive = true)
new SeleniumJSEnv(browser, keepAlive = true, materializer)

def browserName: String = browser.name

def name: String = "SeleniumJSEnv for " + browserName

def jsRunner(libs: Seq[ResolvedJSDependency], code: VirtualJSFile): JSRunner =
new SeleniumRunner(browser, libs, code, keepAlive)
new SeleniumRunner(browser, libs, code, keepAlive, materializer)

def asyncRunner(libs: Seq[ResolvedJSDependency],
code: VirtualJSFile): AsyncJSRunner = {
new SeleniumAsyncJSRunner(browser, libs, code, keepAlive)
new SeleniumAsyncJSRunner(browser, libs, code, keepAlive, materializer)
}

def comRunner(libs: Seq[ResolvedJSDependency],
code: VirtualJSFile): ComJSRunner = {
new SeleniumComJSRunner(browser, libs, code, keepAlive)
new SeleniumComJSRunner(browser, libs, code, keepAlive, materializer)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import org.scalajs.core.tools.logging.Logger
import org.scalajs.jsenv.{JSConsole, JSRunner}

class SeleniumRunner(browserProvider: SeleniumBrowser,
libs: Seq[ResolvedJSDependency], code: VirtualJSFile, keepAlive: Boolean)
extends AbstractSeleniumJSRunner(browserProvider, libs, code) with JSRunner {
libs: Seq[ResolvedJSDependency], code: VirtualJSFile, keepAlive: Boolean, materializer: FileMaterializer)
extends AbstractSeleniumJSRunner(browserProvider, libs, code, materializer) with JSRunner {

def run(logger: Logger, console: JSConsole): Unit = {
setupLoggerAndConsole(logger, console)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.scalajs.jsenv.selenium

import org.junit.Assert._
import org.junit.Test

import scala.scalajs.js.Dynamic.global

class LocationTest {

@Test def LocationTest(): Unit = {
assertEquals("http:", global.window.location.protocol.toString())
assertEquals("localhost:8080", global.window.location.host.toString())
}
}