Drive Mocha-PhantomJS with CoffeeScript

JavaScript, CoffeeScript, PhantomJS, Testing

PhantomJS opened up to me in a major way once I discovered I was able to drive it with Mocha. I still, however, find creating HTML pages for tests very cumbersome, and far from DRY. And I want to write my tests in CoffeeScript, dammit!


You can accomplish this fairly easily with a framework like Brunch that concatenates and compiles CoffeeScript by design. But I was knee deep (neck deep?) in a project with a completely custom build process that I needed to work in harmony with.

Drop-in ready

I have a pretty lightweight solution using an Eco-templated PhantomJS HTML harness generated dynamically from one or more CoffeeScript test runners. This allows me to just add new CoffeeScript tests at will.

If you want to skip directly to the code here is the gist

The system basically runs all of your tests from a make target that uses mocha-phantomjs:

test: build
    for HTML_FILE in $(shell ls ${BUILD_DIR}html) ; do \
        ${NODE_MODULES_DIR}.bin/mocha-phantomjs \
            ${BUILD_DIR}html/$$HTML_FILE ; \

Where the BUILD_DIR contents is in turn generated by some CoffeeScript in


Configuration happens in the template file

Protip: One of the most useful things about mocha configuration is globals, e.g.:

    '$',         // jquery
    'jQuery',    // jquery
    'jQuery*'    // jquery JSONP

You get a great warning of global variable leaks in your scripts under test and can suppress any specific ones here.

Run a complete example

As long as you have node.js, NPM, and make installed:

  1. Download the gist
  2. (from the unzipped directory)

     npm install

    followed by


This should actually run a headless test and give you a successful output to the console. You can also open the generated HTML in any browser and run the same test.

open ./build/html/addtwonumbersasync_spec.html 

It's probably best to move the different types of files into different directories but everything is currently flattened so it works as a gist.