How can I debug scala.js unit tests?

1.3k Views Asked by At

I have some scala.js unit tests written in utest. They all run just fine from the sbt build, however I would like to be able to step through the unit tests in a debugger. Using my favorite IDE (intellij) to debug the tests won't work because it will try to run them on the JVM. Is there some way to step through the unit test execution similar to how you can step through the (javascript) application code in browsers like chrome?

2

There are 2 best solutions below

4
On BEST ANSWER

Currently, the only way to (step-by-step) debug Scala.js code I know of, is inside a browser. You can generate an HTML runner for your tests in sbt:

sbt> testHtmlFastOpt
// snip
[info] Wrote HTML test runner. Point your browser to .../test-suite-fastopt-test.html

This works starting Scala.js 0.6.10.

0
On

Yes, you can by passing the right environment flags to the JavaScript Environment.

It might look something like this:

lazy val jsEnvDebug = settingKey[Boolean]("Whether to debug the JS env.")

jsEnvDebug := sys.env.get("JSENV_DEBUG").contains("true")

Test / scalaJSLinkerConfig ~= {
  _.withModuleKind(ModuleKind.NoModule)
    .withModuleSplitStyle(ModuleSplitStyle.FewestModules)
}


Test / jsEnv := {
  val debugArgs = if ((Test / jsEnvDebug).value) List("--inspect-brk") else Nil
  new NodeJSEnv(
    NodeJSEnv
      .Config()
      .withArgs("--trace-warnings" :: debugArgs)
  )
}

Then you can run sbt with:

JSENV_DEBUG=true sbt

Or within an existing sbt shell using:

set Test/jsEnvDebug := true;test

That will start Node.js and output:

Debugger listening on ws://127.0.0.1:9229/822351a0-b519-4cfe-9e4b-f1e7121ecdc3
For help, see: https://nodejs.org/en/docs/inspector

You can then add a new "Attach to Node.js/Chrome" run configuration in IntelliJ.

If you need the DOM then switch the environment to use Node.js with jsdom.

Sometimes IntelliJ has a problem hitting the breakpoints for some reason. I find that enabling the "Reconnect automatically" helps even though it shouldn't be necessary.

The downside is that I haven't figured out how get IntelliJ to use the source maps so you have to put the breakpoint in the generated js file which is pretty annoying but better than nothing.