Test Scala.JS, with DOM, without PhantomJS

607 views
Skip to first unread message

David Barri

unread,
Aug 25, 2015, 5:18:12 AM8/25/15
to Scala.js
I use PhantomJS for my Scala.JS unit tests.
PhantomJS has an ridiculous number of bugs that have been open for years and are not being fixed.
Today I've been bitten by another one and instead of spending days hacking my way around it, I'd rather spend days trying to setup some other kind of environment.

Does anyone have any ideas or experience using a different environment?
I've heard there might be some Node.js plugin for DOM or something?
Anyone got Java's Nashorn working withi DOM somehow?

Please help. :(

David Barri

unread,
Aug 25, 2015, 5:23:12 AM8/25/15
to Scala.js
Btw, this is what I was talking about https://github.com/tmpvar/jsdom
Has anyone used this with Node.js or io.js and Scala.JS?

Justin du coeur

unread,
Aug 25, 2015, 8:08:00 AM8/25/15
to David Barri, Scala.js
Yeah, at this point I'm exasperated enough to agree.  I've been using Phantom for my unit-tests ever since I started with Scala.JS -- or I did, until I switched my development from Windows to Linux.  To my astonishment, months later, there is *still* no stable release of PhantomJS for Ubuntu, and at this point I'm starting to become skeptical that there ever will be one.

So yeah -- if anybody has good alternatives for a "headless browser" for testing, I'd love to hear about it...

--
You received this message because you are subscribed to the Google Groups "Scala.js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-js+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/scala-js/34bf14fa-8ec2-441d-8ac4-0a760b521b7e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Chad Retz

unread,
Aug 25, 2015, 1:40:01 PM8/25/15
to Scala.js, japg...@gmail.com
The most common thing I've seen people do is use xvfb with selenium browser drivers.

Justin du coeur

unread,
Aug 25, 2015, 1:53:25 PM8/25/15
to Chad Retz, Scala.js, David Barri
Intriguing -- I'm new to developing on Linux (I'd been doing *nix development way back when, but have been Windows-centric for the past 15 years), so I didn't know about xvfb.  I'll ponder that; thanks!

Justin du coeur

unread,
Aug 25, 2015, 1:59:11 PM8/25/15
to Chad Retz, Scala.js, David Barri
Does raise the followup question, though: has anyone built whatever infrastructure is needed to launch xvfb from Scala.js unit tests, and feed the page content to it?  I assume it *can* be done, but I don't know if it *has* been done...

Haoyi Li

unread,
Aug 25, 2015, 3:25:23 PM8/25/15
to Justin du coeur, Chad Retz, Scala.js, David Barri
I assume it *can* be done, but I don't know if it *has* been done...

We do this at Dropbox: 100s of EC2 Ubuntu machines running 10000s of selenium tests a day in CI, in Firefox on XVFB using Selenium/Python. This includes tons of interaction between browser-code and test-server (running on the same box) and is the primary testing strategy for much of our Javascript code base.

It works great. I imagine it would be even easier without the whole server part which constantly causes headaches.

You could also just not bother with the XVFB thing, let the Firefox window pop up, and drag it to the corner of your screen if you don't want to see it executing.

Justin du coeur

unread,
Aug 25, 2015, 3:41:44 PM8/25/15
to Haoyi Li, Chad Retz, Scala.js, David Barri
Oh, I get that -- I'm specifically asking whether anyone has a recipe for launching xvfb from sbt, inside utest or some such.  That is, has somebody already written the glue?

Marius Kotsbak

unread,
Aug 26, 2015, 1:09:05 AM8/26/15
to Scala.js
Well, there are some Grunt plugins for sbt: https://github.com/guardian/sbt-grunt-plugin

And for Grunt there is a Testem plugin https://www.npmjs.com/package/grunt-testem

If you need xvfb: https://gist.github.com/nwinkler/f0928740e7ae0e7477dd

Not a complete solution though. Someone should write a sbt plugin.

If you only need xvfb in Jenkins: https://wiki.jenkins-ci.org/display/JENKINS/Xvfb+Plugin

Justin du coeur

unread,
Aug 26, 2015, 8:24:26 AM8/26/15
to Marius Kotsbak, Scala.js
I know nothing whatsoever of Grunt (my heavy JS work predates it), and I'd prefer not to add it to my toolchain if I can avoid it.  I'm specifically wondering about an sbt plugin, along the lines of the support we already have for Node and Phantom.  Sounds like it doesn't exist yet, which isn't surprising, but now I'm pondering what would be involved...

--
You received this message because you are subscribed to the Google Groups "Scala.js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-js+u...@googlegroups.com.

Marius Kotsbak

unread,
Aug 26, 2015, 8:36:42 AM8/26/15
to Justin du coeur, Scala.js
Look at what the Grunt plugin do and implement in an sbt plugin. Seems quite trivial.

Anton Kulaga

unread,
Aug 26, 2015, 4:46:46 PM8/26/15
to Scala.js
What about selenium testing?

Erik LaBianca

unread,
Aug 26, 2015, 11:11:12 PM8/26/15
to Scala.js
Take a look at Karma. http://karma-runner.github.io/0.13/index.html

It works with most browsers (including phantomjs and slimerjs) and does some nice tricks to keep them running and avoid reloading unnecessarily. It's the defacto solution for driving both web driver and unit tests in the js space and it's pretty good.

It should be possible to either harness it via sbt-js-engine or borrow some good ideas. I've not figured out the sbt/scalajs pipeline enough to be very helpful in knowing where to wire it in, unfortunately.

--erik

David Walend

unread,
Aug 26, 2015, 11:16:56 PM8/26/15
to Scala.js
I've had partial success with node.js, jsdom, and scala.js via the setup via 

  scalaJSStage in Global := FastOptStage

In my javascript code I'm able to use d3 and jsdom npm modules to produce sag segments, html, and to read and write files (!) .

However I have no experience or taste for javascript and would very much like to do as much work as possible in scala.js

I have gotten org.scalajs.core.tools.io.NodeVirtualTextFile (from scalajs-tools) and upickle working with node.js. No luck with scalajs-dom (which I'd hoped would "just work" with nom's jsdom). I can call the surface dom APIs, but plough into "TypeError: Cannot read property 'document' of undefined"s. Near as I can tell, the goggles d3 library wants a dom to talk to.

Caveats - I'm using sbt run, not sbt test, for this project. It's my first venture into scala.js and javascript. I haven't got a clue what I'm doing, and have been thrashing quite a bit. There's a good chance I simply have something horribly misconfigured.

I'm tempted to just write my data to a .scala source file (like the goggles examples) and try automatic reloads and some scripting in chrome, but I'm not that interested in hacking sbt. I think a scala-js overlay for the npm jdom would give me the breakthrough I want, and would let me stand on something more solid.

Thanks,

Dave

David Barri

unread,
Aug 27, 2015, 12:44:05 AM8/27/15
to Scala.js
Interesting, I'd never heard to SlimerJS. Reading a bit about it, they say that is isn't truly headless and that you'd need xvfb or similar.

Erik LaBianca

unread,
Aug 27, 2015, 11:04:15 AM8/27/15
to Scala.js
I've had mixed luck with slimerjs, it does open a window on the screen but it doesn't expect to do much with it so it's pretty friendly to xvfb. Otoh, xvfb works great with chrome and firefox as well if you have the right test runner.

If you didn't notice the paper buried in the Karma website, it's worth taking a gander at for background right here.

The basic way it works is it starts up a server that listens for the browser to connect, then fires up a browser pointing at that server. The first page loads a javascript client that has adapters for your test frameworks. I believe the adapters write HTML into the page with the pass/fail results. It then loads an iframe with the tests and runs them, with the javascript client relaying the pass/fail results back to the server via http.

It appears as if the testing stuff for scalajs is similar. Naively poking around in the sources, there's a jetty server and some web sockets code that runs inside the browser. I'm not entirely clear how the test results make it back from the runner to the browser, I'm assuming it involves the web socket but I have no idea how they are captured from the test framework. It *seems* like it ought to be possible to generalize this a bit, maybe taking a page from the karma playbook and/or borrowing some of the code, particularly the client side. 

In an ideal world, you'd be able to run a command like ~test-wait and it would spit back the url to paste into your browser. Hitting reload on the browser would re-run the tests. ~test would do the same thing, just launching the browser pointing at the page and exiting when done, keeping a nice headless / command line experience. That way you can test ANY browser, including remote and mobile browsers and avoiding being locked in to buggy stuff like phantomjs, while still being able to use them for cases where they work.

I can say that my karma tests with phantomjs 2.0 work remarkably well and are incredibly fast due to not needing to restart the engine between runs.

--erik

Haoyi Li

unread,
Aug 27, 2015, 12:52:05 PM8/27/15
to Erik LaBianca, Scala.js
IMHO we should support selenium/firefox or something similar. That's the least-setup-necessary (Chrome, Safari, IE etc. require special drivers installed/on-path, firefox does not) and I suspect many people won't mind the firefox window opening up. We could hide it with xvfb, but honestly it's no big deal to have something pop up and then disappear.

In fact, having a physical window is cool because if stuff breaks you can leave the window open and see what happened! If your tests were doing things to the DOM and they failed, you can actually *look at* the thing and see what's funny with it. Also, you can debug using the Firefox JS console! We do this a lot at Dropbox and it's way more fun than trying to debug PhantomJS's misbehaviors where you can't see anything and there's no way of interacting other than adding printlns and running again..

--
You received this message because you are subscribed to the Google Groups "Scala.js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-js+u...@googlegroups.com.

Erik LaBianca

unread,
Aug 27, 2015, 1:28:18 PM8/27/15
to Haoyi Li, Scala.js
Agreed, from my experience firefox is the most “user-friendly” target and I’ve had the same experience with having the browser window… it can be very handy.

—erik

Benjamin Jackman

unread,
Aug 27, 2015, 1:56:35 PM8/27/15
to Scala.js, japg...@gmail.com
I would suggest installing phantom-js via npm rather than using apt. I had similar problems until I made the switch now it runs better (still not perfect)


On Tuesday, August 25, 2015 at 7:08:00 AM UTC-5, Justin du coeur wrote:

Anton Kulaga

unread,
Aug 27, 2015, 4:34:38 PM8/27/15
to Haoyi Li, Erik LaBianca, Scala.js
I would rather prefer to use Selenium with Firefox driver. The only problem here is that current scalatest selenium API does not take into account scalajs, so I write tests in ScalaJVM and try to analyze DOM rendered with help of scalajs, I would be happy to have scalajs all the way down.
Reply all
Reply to author
Forward
0 new messages