0

I am trying to use phantomjs as installed via npm to perform my unit tests for ScalaJS.

When I run the tests I am getting the following error:

/usr/bin/env: node: No such file or directory

I believe that is because of how phatomjs when installed with npm loads node:

Here is the first line from phantomjs:

#!/usr/bin/env node

If I change that first line to hardcode to the node executable (this involves modifying a file installed by npm so it's only a temporary solution at best):

#!/home/bjackman/cgta/opt/node/default/bin/node

Everything works.

I am using phantom.js btw because moment.js doesn't work in the NodeJSEnv.

Work Around:

After looking through the plugin source is here the workaround:

I am forwarding the environment from sbt to the PhantomJSEnv:

import scala.scalajs.sbtplugin.ScalaJSPlugin._
import scala.scalajs.sbtplugin.env.nodejs.NodeJSEnv
import scala.scalajs.sbtplugin.env.phantomjs.PhantomJSEnv
import scala.collection.JavaConverters._
val env = System.getenv().asScala.toList.map{case (k,v)=>s"$k=$v"}

olibCross.sjs.settings(
  ScalaJSKeys.requiresDOM := true,
  libraryDependencies += "org.webjars" % "momentjs" % "2.7.0",
  ScalaJSKeys.jsDependencies += "org.webjars" % "momentjs" % "2.7.0" / "moment.js",
  ScalaJSKeys.postLinkJSEnv := {
    if (ScalaJSKeys.requiresDOM.value) new PhantomJSEnv(None, env)
    else new NodeJSEnv
  }
)

With this I am able to use moment.js in my unit tests.

BenjaminJackman
  • 1,439
  • 1
  • 10
  • 18
  • Just as a comment aside: `jsDependencies` automatically adds the Module to `libraryDependencies`, so no need to do it twice. – gzm0 Jul 11 '14 at 09:46
  • Looks more like a bug report than a question. Would you mind filing this (and the workaround) on GitHub, please? https://github.com/scala-js/scala-js/issues Thanks. – sjrd Jul 13 '14 at 08:32

1 Answers1

2

UPDATE: The relevant bug in Scala.js (#865) has been fixed. This should work without a workaround.

This is indeed a bug in Scala.js (issue #865). For future reference; if you would like to modify the environment of a jsEnv, you have two options (this applies to Node.js and PhantomJS equally):

  1. Pass in additional environment variables as argument (just like in @KingCub's example):

    new PhantomJSEnv(None, env)
    // env: Map[String, String]
    

    Passed-in values will take precedence over default values.

  2. Override getVMEnv:

     protected def getVMEnv(args: RunJSArgs): Map[String, String] =
       sys.env ++ additionalEnv // this is the default
    

    This will allow you to:

    1. Read/Modify the environment provided by super.getVMEnv
    2. Make your environment depend on the arguments to the runJS method.

The same applies for arguments that are passed to the executable.

gzm0
  • 14,752
  • 1
  • 36
  • 64