+ All Categories
Home > Documents > Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does...

Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does...

Date post: 27-Sep-2020
Category:
Upload: others
View: 12 times
Download: 0 times
Share this document with a friend
186
Buster.JS Documentation Release 0.7 Christian Johansen and August Lilleaas April 08, 2016
Transcript
Page 1: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS DocumentationRelease 0.7

Christian Johansen and August Lilleaas

April 08, 2016

Page 2: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static
Page 3: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Contents

1 User’s guide 31.1 Talks and video tutorials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2 Buster.JS overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.3 Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191.4 Browser testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231.5 Node.js testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281.6 Hybrid testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291.7 Manually starting test run . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

2 Reference documentation 332.1 Core modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332.2 Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138

3 Project resources 1453.1 Download . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1453.2 Community . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1453.3 Contributors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1463.4 Developers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1473.5 Roadmap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1633.6 Changelog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1653.7 Licenses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178

i

Page 4: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

ii

Page 5: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

In beta. Many things are unstable at this point in time. Check out the roadmap.

A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnitstyle static HTML page testing, testing in headless browsers (PhantomJS, jsdom), and more. Take a look at theoverview!

A Node.js testing toolkit. You get the same test case library, assertion library, etc. This is also great for hybridbrowser and Node.js code. Write your test case with Buster.JS and run it both in Node.js and in a real browser.

Flexible. There’s a public API for almost everything. You can write reporters for customizing the output of bustertest (we already have xUnit XML, traditional dots, specification, tap, TeamCity and more), write extensions thatwrap other testing frameworks (we already have buster-jstestdriver), add your own testing syntax (we ship with xUnitand BDD), and much more. Again, the overview lists many of these things.

Written by you. We believe in open development, and already have a dozen or so contributors beyond the core authorsof Buster.JS, August Lilleaas and Christian Johansen. All development happens in public in the issue tracker and thebusterjs-dev mailing list. We welcome your opinion.

A set of reusable libraries. For example, ramp is our generic browser automation library that lets you successivelyload webpages into browsers and send data to and from them. It is completely reusable and has no knowledge ofBuster.JS tests, or tests at all for that matter.

Take Buster.JS for a spin and judge for yourself! Be warned, it’s still in beta, so it has some rough edges.

Contents 1

Page 6: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

2 Contents

Page 7: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

CHAPTER 1

User’s guide

These are articles, howtos, and guides to help get started with Buster.JS.

1.1 Talks and video tutorials

Here you can find talks and video tutorials about Buster.JS.

1.1.1 Hands-on unit testing with Buster.JS

Here’s a talk about Buster.JS by Christian Johansen from Frontend Conference Zürich in September 2011. You canfind alternative versions for download at Ustream.

1.1.2 Buster.JS Academy

Learn about Buster.JS through a series of short to-the-point screencasts, brought to you by screencast extraordinaireMagnar Sveen (of ZombieTDD and Emacs Rocks fame).

Getting started

Buster.JS is a JavaScript test framework for node and browsers. Get up and running in 3 minutes with this introscreencast.

1.2 Buster.JS overview

Buster.JS is a JavaScript test framework for node and browsers.

1.2.1 Installation

See getting started.

3

Page 8: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

1.2.2 The config file

Buster.JS needs a config file, both for Node.js tests and browser tests. Name the config file buster.js and put it ineither test/ or spec/ in your project:

var config = module.exports;

config["My tests"] = {environment: "browser", // or "node"rootPath: "../",sources: [

"lib/mylib.js", // Paths are relative to config file"lib/**/*.js" // Glob patterns supported

],tests: [

"test/*-test.js"]

};

// Add more configuration groups as needed

Run tests for your config file with:

buster-test// Assumes test/buster.js or spec/buster.js

buster-test --config anywhere/buster.js// Can also specify config file

For more, see buster-configuration.

1.2.3 Test cases

Typically, you have one test case per file. Here’s an example, in test/my-thing-test.js. Since the file nameends with -test.js, the config file above will load the test.

var assert = buster.assert;

buster.testCase("My thing", {"has the foo and bar": function () {

assert.equals("foo", "bar");},

"states the obvious": function () {assert(true);

}})

Note that you are free to name your test cases whatever you want. They don’t have to start with "test ..." or"should ...".

For more, see Test case.

1.2.4 Examples

Buster.JS has pluggable “front-ends” to specifying examples/tests/whatever. Here’s the other bundled way of doing it:

4 Chapter 1. User’s guide

Page 9: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

// Expose describe and it functions globallybuster.spec.expose();

describe("My thing", function () {it("has the foo and bar", function () {

expect("foo").toEqual("bar");});

it("states the obvious", function () {expect(true).toBe(true);;

});});

For more, see Test spec.

1.2.5 Browser testing

Buster.JS can automate browsers, JsTestDriver style. First, start the server.

Open the browsers you want to run tests in and click the capture button.

1.2. Buster.JS overview 5

Page 10: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Buster.JS automatically runs the tests in all the captured browsers.

For more, see Browser testing.

1.2.6 Static HTML based browser testing

Buster.JS also has a static browser runner that runs tests by opening a web page in a browser. This is similar to QUnit,Mocha, etc.

6 Chapter 1. User’s guide

Page 11: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

For more, see buster-static.

1.2.7 Node testing

Works just like browser tests, but you need to require Buster.JS in your tests:

1.2. Buster.JS overview 7

Page 12: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

var buster = require("buster");var assert = buster.referee.assert;var myLib = require("../lib/my-lib");

buster.testCase("A test case", {"test it": function () {

assert(myLib.doIt());}

});

You can now run the file simply by doing node my-test.js, or you can create a configuration file withenvironment: "node" that will run all tests in your project.

Use buster-test in a terminal to initiate the test run. Here’s the test output for posix-argv-parser:

For more, see Node.js testing.

1.2.8 Assertions

Buster.JS comes packed with assertions, and a simple DSL to add app-specific custom assertions:

assert(true);assert.same(two, objects);assert.equals(two, objects);assert.defined(something);assert.exception(function () { ... });assert.isNull();// .. and many more

Note the lack of assert.notEquals, assert.notDefined etc. Instead, Buster.JS provides a more symmetricAPI:

// This assertion does not exist!assert.notEquals(foo, bar);

// Instead:

8 Chapter 1. User’s guide

Page 13: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

refute.equals(two, objects);

// And so onrefute(false);refute.same(two, objects);refute.defined(something);

So instead of changing the function name, replace assert with refute.

assert.match is neat. All the assertions below will pass:

// Partial property matchingvar largeObject = {foo: "bar", baz: {test: "it"}};assert.match(largeObject, {foo: "bar"});

// Fancy string matchingassert.match("Yeah!", { toString: function () { return "yeah"; } });

// Regexp matchingassert.match("Give me something", /^[a-z\s]$/i);

// Lazy typesassert.match("123", 123);

// DOM elementsvar el = document.getElementById("myEl");

assert.match(el, {tagName: "h2",className: "item",innerHTML: "Howdy"

});

Adding your own custom assertions is easy. The DSL produces both an assert and refute. If you provide anexpectation name, an expectation is created, too:

buster.referee.add("inRange", {assert: function (num, lower, upper) {

return num >= lower && num <= upper;}

});

For more, see Assertions and refutations and Expectations.

1.2.9 BDD syntax

Buster.JS is pluggable so you can write your own front-ends. Buster.JS also ships with two built-in front-ends; thexUnit style test cases we saw previously, and BDD style specs/examples:

buster.spec.expose(); // Make spec functions global

var spec = describe("Bowling kata", function () {before(function () {

this.game = new BowlingGame();

this.rollMany = function (rolls, pins) {for (var i = 0; i < rolls; ++i) {

this.game.roll(pins);

1.2. Buster.JS overview 9

Page 14: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

}};

});

it("yield 0 in score for gutter game", function () {this.rollMany(20, 0);buster.assert.equals(0, this.game.score());

});

it("yield score of 20 for 1 pin on each roll", function () {this.rollMany(20, 1);buster.assert.equals(20, this.game.score());

});});

For more, see Test spec.

1.2.10 Reporters

There are a number of reporters built into Buster.JS. There is also a simple API for building your own reporters.

The default reporter is brief:

Other reporters:

10 Chapter 1. User’s guide

Page 15: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

1.2. Buster.JS overview 11

Page 16: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

All human-consumable reporters (i.e. not XML and tap output) can use no colors, bright colors, or dim colors.

For more, see Test reporters.

1.2.11 Focus rocket

If you want to run exactly one test, test case or subset of tests and you don’t want to pass the corresponding name asa command line argument to buster-test, you can use the focus rocket. Prepend the string => to the name of thetest, test case or subset of tests, you want to execute:

"=>test assert": function () {assert(true);

}

From now on, only that test, test case or subset of tests is executed by Buster.JS:

Focus rockets are undesirable in source control and continuous integration. Disable the behavior by runningbuster-test with --fail-on-focus to make the whole suite will fail with an error.

1.2.12 Deferred/pending tests

Commenting out an entire test case is bad. It will leave the test case out of the loop entirely, and you might forget tocomment it back in again before pushing your code.

To remedy this, Buster.JS supports deferring a test so it doesn’t actually run, but you get notified that there’s a deferredtests every time you run your test suite.

12 Chapter 1. User’s guide

Page 17: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

To defer a test, add // to the start of the test name:

buster.testCase("My tests", {"// bla bla bla test case": function () {

// This function will not be called},

"this one is not deferred and will run": function () {assert(true);

},

"// exhibits feature A": "A simple place-holder, we need to detail this test"});

For more, see Deferred tests for xUnit style and Deferred specs for BDD style.

1.2.13 Mocking and stubbing

Buster.JS ships with Sinon.JS. Every test in a test case has a sandbox associated with it, making it easy to mock andstub without worrying about side-effects beyond the scope of the test. assert also comes with lots of Sinon.JS-awareassertions.

buster.testCase("My tests", {"demonstrates stubbing": function () {

this.stub(myLib.thingie, "aMethod"); // Will be automatically reverted// after the test completes

doSomething();assert.calledOnce(myLib.thingie.aMethod);

}});

See full docs at buster-sinon.

1.2. Buster.JS overview 13

Page 18: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

1.2.14 Asynchronous tests

Asynchronous tests are tests that aren’t finished running when the test method has finished executing. To tag a test asasync, have the test function take one argument, done:

buster.testCase("My thing", {"test not asynchronous": function () {

assert(true);},

"test asynchronous": function (done) {myLibrary.doAjaxRequest("/foo", done(function (response) {

assert.equals(response.statusCode, 200);}));

}});

The done argument is a function. Call it to tell Buster.JS that the asynchronous test has finished running. If you don’tcall done, the test will eventually time out and fail. You can also have the test function return a thenable promise tomake it asynchronous.

setUp and tearDown can also be asynchronous. The procedure is identical to that of tests:

buster.testCase("My thing", {setUp: function (done) {

this.httpServer = http.createServer(function (req, res) {res.writeHead(418);res.end();

});this.httpServer.listen(17171, function () { done(); });this.myThing = new MyThing();this.myThing.attach(this.httpServer);

},

tearDown: function (done) {this.httpServer.on("close", function () { done(); });this.httpServer.close();

},

// ... tests});

For more, see Asynchronous tests for xUnit style and Asynchronous specs for BDD style.

1.2.15 Test case contexts

A test case can have nested contexts, as deep as you want. Pass an object instead of a function to create a context.Nested contexts can have their own setUp and tearDown methods:

buster.testCase("My thing", {setUp: function () {

this.myThing = new MyThing();},

"simple test": function () {assert(true);

},

14 Chapter 1. User’s guide

Page 19: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

"on steroids": {setUp: function () {

this.myThing.onSteroids = true;},

// ... tests

"with cowbell": {setUp: function () {

this.myThing.cobwell = true;},

// ... tests}

}});

setUp is called top-down, so when a test in the context "with cowbell" is called, the root setUp is called, thenthe one in "on steroids", then lastly the one in "with cowbell". The this is the same in all contexts.

See Nested setup and teardown or Nested before and after for extended examples.

1.2.16 Proxying to HTTP servers

In your browser tests you might want to perform HTTP request to a server, such as your application server. This can bedifficult since your tests run via the Buster.JS server, and you can’t access your application server due to cross domainorigin policies in browsers.

To remedy this, Buster.JS lets you set up a proxy server in your config file:

var config = module.exports;

config["My tests"] = {environment: "browser",sources: ["../lib/**/*.js"],tests: ["*-test.js"],resources: [{

path: "/app",backend: "http://192.168.1.200:3030"

}]};

A request to /app/foo will be proxied to http://192.168.1.200:3030/foo.

If you’re talking to an app server with state, you probably want to reset it before every test to avoid leaks from testcase to test case. You’re responsible for doing that yourself. Here’s an example using an asynchronous setUp thatwon’t run the test until the request to reset the app server has ended:

buster.testCase("My tests", {setUp: function (done) {

myHttpLib("/app/reset", {success: function () { done(); }

});},

// ... tests here ...});

1.2. Buster.JS overview 15

Page 20: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

1.2.17 Running a subset of tests

To run a single test, pass it’s full name as an operand to buster- test:

buster-test "My tests should run this particular test"

The operand is treated as a JavaScript regular expression so you can do partial matching and regex stuff in it as well:

buster-test "delete user"

If you don’t quote the operand, it will be treated as a series of OR’d filters.

To run a single file, do this:

buster-test --tests test/mytest.js

This assumes the presence of a config file, and just like plain buster- test it tries to find a config file auto-matically, if you don’t specify one with --config. Buster needs the config file to load your proxies, library code,dependencies, and so on.

See Test options for a complete overview of buster- test command line options.

1.2.18 Testing AJAX

Buster.JS comes with Sinon.JS. This makes mocking out the entire XHR stack in a browser trivial. You will find anexample in the buster-sinon module description.

1.2.19 Feature detection

You can tell Buster.JS to not run certain test cases in certain situations. This is useful if you want to run the same testsuite for a program that works in IE6, so you want to run most of your tests in IE6, but also has features that will crashwhen called in IE6:

buster.testCase("My thing", {requiresSupportFor: {

"touch events": typeof(document.body.ontouchstart) != "object","XHR": typeof(XMLHttpRequest) != "undefined"

},

"should receive touch events": function () {// ..

},

// ...});

You can also apply the feature detection filter to nested contexts to only filter out a subset of the test case.

1.2.20 Custom test beds

For browser tests, you can specify the HTML document the tests will run in. Buster.JS defaults to a plain HTML5document. But you might want to run the tests in a HTML4 strict environment, and what not:

var config = module.exports;

config["My tests"] = {

16 Chapter 1. User’s guide

Page 21: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

environment: "browser",sources: ["../lib/**/*.js"],tests: ["*-test.js"],testbed: "my-file.html"

};

Script tags for your tests will be added automatically at the ending body tag, or at the end of the document if no endingbody tag is present.

1.2.21 Logging

Logging with buster.log will group the log messages in the reporter output with the test that was logged from.When logging objects of various sorts, the logger uses a (pluggable) formatter for pretty output.

In Node.js, when running tests, buster.log is available globally by default, for convenience. So you canbuster.log in your implementations without requiring buster first.

1.2.22 Modularity

Buster.JS consists of many stand-alone modules with a documented API that can be re-used for various purposes.

The referee package can easily be used in other testing frameworks. If you use JsTestDriver, follow these steps (hint:it’s pretty easy).

If you write your own testing framework, you may find many of our modules useful. referee is one such module,and is completely reusable. You can also use ramp if you want browser automation in your test framework, withoutimplementing the actual browser automation part yourself.

Another example of usage of Buster.JS modules in other projects is Slidebuster (note: proof of concept). The rampmodule is not test runner specific, it is a generic browser automation framework. Slidebuster uses it so that if you“capture” a normal browser and a touch device, you can swipe left and right on the touch device to change the slideson the normal browser.

See Architecture overview for an overview of all Buster.JS modules and extensions.

1.2. Buster.JS overview 17

Page 22: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

1.2.23 AMD Support

If your project uses AMD (Asynchronous Module Definition) and a loader such as require.js or curl.js, you can usethe buster-amd extension to ensure modules load properly and that you can adapt your AMD configuration for testing.

Check the buster-amd for more information.

1.2.24 Control when tests start running

Some applications use a module loader, such as an AMD based loader. So the default strategy of Buster.JS to startrunning tests on window.onload may not work for you. You can disable auto running and tell Buster.JS when tostart running tests.

Add { autoRun: false } to your config file and call buster.run() to start the test run. That gives you fullcontrol over when the test run starts.

If you use the buster-amd extension, it will do this automatically for you and you do not need to set { autoRun:false } or call buster.run().

For more, see Manually starting test run and the buster-amd documentation.

1.2.25 Global variables

By default, Buster.JS exposes four global variables: buster, expect, assert, and refute. The two latter arealso available as properties on the buster object (buster.assert, buster.refute). If you’re a purist likeus, you’ll want to disable these additional globals and only have it expose the buster global variable (in browsers,on Node.js you’ll have to require the things you want to use).

Note: In the beta, there’s not yet a setting for disabling the exposure of these global variables.

1.2.26 Editor integration

TextMate

Magnar Sveen maintains TextMate bundle. It includes snippets, running tests with command + R, and more.

Emacs

Christian Johansen maintains buster-mode.el.

Magnar Sveen has written a set of yasnippet snippets for Buster.JS.

1.2.27 Buster.JS Academy

Short, to-the-point screencasts about Buster.JS and unit testing in JavaScript. Watch.

18 Chapter 1. User’s guide

Page 23: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

1.3 Getting started

This guide walks you through installation and very basic setup of tests in a project. If you’re only interested in simplebrowser tests embedded in a web page, see the browser testing page.

1.3.1 Installing

Buster.JS on the command-line requires Node.js 0.6.3 or newer and npm. Node.js 0.6.3 and newer comes with npmbundled on most platforms.

OS X

1. Get the latest Node installer from nodejs.org. You need Node 0.6.3 or newer.

2. npm install -g buster

Note: Installing npm packages with sudo causes multiple problems, and is not recommended. If you cannot usenpm without sudo after using the installer, try changing ownership of the node installation to your user.

Linux

1. Install Node 0.6.3 or later with your favorite package manager. If you don’t have one, follow these simple buildinstructions.

2. npm install -g buster

Windows

1. Get the latest Node installer from nodejs.org. You need Node 0.6.3 or newer.

2. npm install -g buster

1.3.2 Create config file

Add a config file to your project. Call it test/buster.js or spec/buster.js. This way you don’t have to tellBuster.JS about it with --config every time you run tests. ./buster.js will also be recognized.

var config = module.exports;

config["My tests"] = {rootPath: "../",environment: "browser", // or "node"sources: [

"lib/mylib.js","lib/**/*.js"

],tests: [

"test/*-test.js"]

}

1.3. Getting started 19

Page 24: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

// Add more configuration groups as needed

For browser tests, list all your source files in sources and test files in tests. For Node.js tests, you don’t need tospecify sources as you typically require your source files directly in the test files.

Read the full configuration documentation for details.

Note that you may not “dot out” in sources, tests, etc. Paths are resolved relative to the directory where theconfiguration file lives. If your sources live outside this directory, adjust the root directory using the rootPathproperty (which is also resolved against the config file location, unless absolute).

1.3.3 Write tests

Given the config file above, all files named <something>-test.js in the same folder as the config file itself willbe loaded. You can of course change the glob pattern to better suit your needs. **/*-test.js would for examplerecursively load all <something>-test.js in the same folder the config file is in, and all its sub folders.

A test case looks like this:

// Browser tests

buster.testCase("A module", {"states the obvious": function () {

assert(true);}

});

The BDD inclined might prefer this alternate syntax:

buster.spec.expose(); // Make some functions global

describe("A module", function () {it("states the obvious", function () {

expect(true).toEqual(true);});

});

If your test is a Node.js test, you also need to require Buster.JS:

// Node.js testsvar buster = require("buster");var myLib = require("../lib/my-lib");

buster.testCase("A module", {"states the obvious": function () {

assert(true);}

});

See the full Test case docs and referee docs for details. There are also mocks and stubs and more, via the buster-sinonmodule.

20 Chapter 1. User’s guide

Page 25: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

1.3.4 Run tests

Node.js tests

For testing on Node.js we recommend to install Buster.JS locally. If you have installed it globally (-g flag in npminstall -g buster) you have to ensure it can be found by Node.js. One option is to set NODE_PATH to theglobal installed modules, which is done during the installation of Node.js on linux automatically, but unfortunately noton windows. Another option is to create a link to Buster.JS with the command npm link buster executed in theroot of the project.

Node.js tests can be run by simply typing node test/some-test.js. Doing this requires nothing more than afile with tests (i.e. you don’t need the above configuration).

While node test/my-test.js is nice and convenient, you want to use the buster-test binary to get at thefull power of Buster.JS. Open a terminal, cd to your project, and type in buster-test. Here’s the output from thetest run of posix-argv-parser:

See the Node.js testing documentation for more.

Browser tests

First, start a server. Open a terminal and type in buster-server.

1.3. Getting started 21

Page 26: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Capture some browsers to run the tests in by visiting the URL. Click the grey capture button to actually perform thecapture.

Then you’re ready to run the tests with buster-test.

22 Chapter 1. User’s guide

Page 27: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

See the browser testing documentation for more.

Hybrid tests

If your project has both Node.js and browser tests, and your config file specifies multiple groups for the differentenvironments, running buster test will automatically run all the groups, both Node.js and browser. This requiresthat you already have a buster-server up and running.

If you only want to run tests for one environment, use buster test --environment browser or bustertest -e node.

You have to manually make sure your test cases and source files are able to run in both browsers and Node.js. Here’san example:

if (typeof require != "undefined") {var buster = require("buster");var myLib = require("../lib/my-lib");

}

buster.testCase("A test case", {"test it": function () {

assert(true);}

});

See the hybrid testing documentation for more.

1.4 Browser testing

Buster.JS offers multiple ways of running your tests in browsers. This document describes three ways, ranging fromsimple setup to most useful (if that’s a scale).

1.4. Browser testing 23

Page 28: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

1.4.1 Running with buster-server

Inspired by JsTestDriver, Buster.JS can automate browsers seamlessly and provide feedback anywhere you want,making running your tests in actual browsers easy and painless. Hell, it even makes it fun.

First, start a server:

Then, capture how many browsers you want:

And simultaneously run tests on all the captured browsers:

24 Chapter 1. User’s guide

Page 29: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

1.4.2 Running with buster-static

In the cases where you need a simpler method for running tests, but don’t care for the manual HTML scaffold (seenext section), Buster.JS can serve the scaffold for you based on your configuration.

Start the server:

Open the page in the browser and watch the tests run immediately:

1.4. Browser testing 25

Page 30: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

1.4.3 Write to disk with buster-static

If you specifiy a directory when executing buster-static, no sever will be started. Instead the files needed forthe test run are written into this directory. All you have to do to run the tests is to open the index.html file in abrowser.

26 Chapter 1. User’s guide

Page 31: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

1.4.4 Using an HTML scaffold

Warning: This is still an experimental feature, but should work fine.

The simplest way to try Buster.JS is to copy the following code, save it to a file and run it in a browser:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">

<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><title>strftime</title>

</head><body><script type="text/javascript" src="http://cdn.busterjs.org/releases/latest/buster-test.js"></script><script type="text/javascript" src="http://cdn.busterjs.org/examples/strftime/strftime.js"></script><script type="text/javascript" src="http://cdn.busterjs.org/examples/strftime/strftime-test.js"></script>

</body></html>

Go ahead, try it.

If you use Git, you can clone this example to your machine:

git clone git://gist.github.com/1904218.git gist-1904218

Note: If you opt for downloading the script locally, remember to get the CSS file too. When using the pre-builtlibrary, there’s no installation, but you also miss out on much of the automation sweetness.

1.4.5 Running headless with PhantomJS

You can run browser tests headless with PhantomJS very easy by starting the server with option -c.

1.4. Browser testing 27

Page 32: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

You must have installed PhantomJS on your system of course.

1.4.6 Continues Integration

You can run the buster server, capture browsers, on the local or remote machine, run tests, close the browsers andshutdown the server with only one command: buster-ci.

1.4.7 Examples

Check the demos repository for example projects.

1.5 Node.js testing

Warning: This document is work in progress.

1.5.1 Getting started

To set up Node.JS testing, specify "node" as the environment in your config file:

var config = module.exports;

config["My tests"] = {environment: "node",tests: [

"**/*-test.js"]

};

This config file will load all <something>-test.js in the same folder as the config file and all sub folders. Unlikebrowser tests, you don’t need to specify your source files with "sources". In fact, doing so will only make the testsslower, as the config file takes longer time to load. Instead, you do what you always do in Node.JS: require() themodules you use in the files where you need to use them:

var buster = require("buster");var myLib = require("../lib/my-lib");

buster.testCase("A test case", {"test it": function () {

assert(true);}

});

As we can see, we also need to require Buster.JS itself. The buster module provides all the core functionality suchas test cases, assertions, and more.

1.5.2 Running tests

To run the tests, simply type:

28 Chapter 1. User’s guide

Page 33: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

buster test

Here’s the test output for the posix-argv-parser module:

See buster test –help for more information about the options you can pass to buster test.

1.5.3 Tips and tricks

Testing the HTTP module

TODO Write section

1.6 Hybrid testing

Warning: This document is work in progress

1.6.1 Writing hybrid tests

Running tests in both browsers and Node requires a small feature test to determine whether or not to load Buster inyour tests. The code under test obviously also needs to check for module, require etc. The following exampleshows a typical test that runs both in browsers and on node:

if (typeof module == "object" && typeof require == "function") {var buster = require("buster");

}

buster.testCase("Multi-environment", {"runs in all environments": function () {

assert(true);},

1.6. Hybrid testing 29

Page 34: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

"sub context": {requiresSupportFor: { "DOM": typeof document != "undefined" },

"only runs in browser-like environments": function () {// ...

}}

});

1.6.2 Running tests

The simplest way to run multi-environment tests is to use a configuration file and the buster test binary:

var config = module.exports;

config["Tests"] = {tests: ["test/**/*.js"]

};

config["Browser tests"] = {extends: "Tests",environment: "browser",sources: ["lib**/*.js"]

};

config["Node tests"] = {extends: "Tests",environment: "node"

};

Given this config, you can run for Node.js using:

buster test --node

and for browsers:

buster test --browser

1.7 Manually starting test run

When you use AMD (Asynchronous Module Loading) systems, or otherwise need to manually specify when yoursystem is ready to run tests, you can easily disable auto running of tests and manually start the test run. Normally,Buster.JS starts running tests when the browser has finished loading the page. Since AMD is a manual module loaderthat Buster.JS can’t automatically be aware of, you are required to manually tell Buster.JS when you’re good to go.

Add autoRun: false to your config file:

var config = module.exports;

config["My tests"] = {autoRun: false,sources: ["../lib/**/*.js"],tests: ["**/*-test.js", "run.js"]

}

30 Chapter 1. User’s guide

Page 35: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

we added the file run.js to the tests group. In this file, call buster.run() to start the test run:

// App specific notification of when your app is ready to be testedmyApp.onReady = function () {

buster.run();};

You’re of course free to call buster.run() anywhere you want, the only important thing is that it gets called whenyou load your tests, and when it gets called your application is ready to get tested.

If you use the buster-amd extension, it will do this automatically for you and you do not need to set { autoRun:false } or call buster.run().

1.7. Manually starting test run 31

Page 36: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

32 Chapter 1. User’s guide

Page 37: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

CHAPTER 2

Reference documentation

These are guides and API documentation for the individual Buster.JS core modules and extensions. See the genindexif you are looking for the docs for a particular part of the API.

2.1 Core modules

2.1.1 ramp

Version: 0.5 (2012-xx-xx)

Module: var captureServerModule = require("ramp");

The capture server captures browsers as slaves, and offers a completely generic API for carrying out work across thoseslaves. A workload is known as a “session”, and a test run is typically a session. Other uses include for instancesynced-across-devices slide shows (for which a POC has been built).

In general, the server knows nothing specifically of testing. It knows how to accept and serve web pages (in the formof resource sets), capture and command browser slaves, and coordinate every piece using messaging (Bayeux on theHTTP level, or websockets if available).

The server

The server is the central hub for all work in ramp. It needs to be manually attached to an existing node HTTP server.

captureServerModule.createServer()

var server = captureServerModule.createServer();

Creates a server instance.

server.attach()

server.attach(httpServer);

Attaches the ramp to a Node.js HTTP server. All HTTP requests that ramp handles is “consumed”, and won’ttrigger any “request” event listeners on the Node.js HTTP server.

33

Page 38: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Server client

To interact with a server, you always use a server client. This has the benefit of making the API for interacting withthe server identical whether the server runs in the same process as your own code, or the server is in another process(or even on another computer).

captureServerModule.createServerClient()

var serverClient = captureServerModule.createServerClient(opts);

Creates a new server client.

Options

host (required): The hostname where the http server is running.

port (required): The port the http server listens on

serverClient.createSession()

var promise = serverClient.createSession(opts);

Creates and queues a new session.

The promise resolves with the session object, and rejects with an error object.

Options

resourceSet: The resource set containing the full web page of the session. The resource with the path "/"is assumed to be a html page and is loaded into the captured browsers.

cache: Boolean specifying whether or not caching should be performed. Defaults to false.

joinable: Boolean specifying whether the session is joinable, meaning whether browsers captured after thesession has started will get the session loaded into them. Defaults to true.

staticResourcesPath: Boolean specifying whether the same path should be used for all sessions. Whenfalse, each session will get a new path. The actual value is unspecified, but it might be something like"/sessions/123-long-id-here/resources". This is useful to force browsers to reload all theresources as the path will be different for each session. When true, each session will be loaded with thesame path. This is useful for debugging, buster test uses this so that breakpoints can be set in browserdebuggers and apply across test runs. Defaults to false

serverClient.connect()

serverClient.connect();

Connects the server client to the server. Needs to be called manually, typically immediately after the serverclient is created.

serverClient.disconnect()

serverClient.disconnect();

Disconnecting is not mandatory, it’s only provided as a convenience if you want to clean up the connections.You can also just kill the process without disconnecting first, the server will be fine.

34 Chapter 2. Reference documentation

Page 39: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Session client

A session client is created for each session you want to interact with. It provides lifecycle events, and user specificpubsub events to send data to and from the slaves.

captureServerModule.createSessionClient()

var sessionClient = captureServerModule.createSessionClient(opts);

Creates a new session client.

Options

session (required): The session object to create a client for. This is the same object that is emitted from theserver client promise when you create a new session.

host (required): The hostname where the http server is running.

port (required): The port the http server listens on.

sessionClient.connect()

sessionClient.connect();

Connects the session client. Needs to be called manually for every session client create, typically immediatelyafter the session client is created.

sessionClient.disconnect()

sessionClient.disconnect();

Disconnecting is not mandatory, it’s only provided as a convenience if you want to clean up the connections.You can also just kill the process without disconnecting first, the server will be fine.

sessionClient.emit()

sessionClient.emit(event[, data]);

Emit an event to all slaves.

The event is a string. Examples: "goto", "slide:next", "testcase:state:timeout".

The data is optional, and will be JSON serialized in the form of {data: /* <your data here> */},so it can be an array, and object, a string, or a number.

sessionClient.emit("slide:goto", 5);sessionClient.emit("slide:next");

sessionClient.on()

sessionClient.on(event, handler);

Listens to events from all slaves.

The event string is identical in format to the one in sessionClient.emit().

The handler is a function, taking one argument which is the data that was emitted.

2.1. Core modules 35

Page 40: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

sessionClient.on("test:success", function (testInfo) {reporter.reportSuccess(testInfo);

});sessionClient.on("test:failure", function (testInfo) {

reporter.reportFailure(testInfop);});

sessionClient.end()

sessionClient.end();

Ends the session.

Lifecycle events

Promises are used for lifecycle events. These events only trigger once per session.

Note: TODO

We also need events for slave join and leave.

sessionClient.started: The session is now at the top of the session queue and is about to get loaded into thecaptured browsers.

sessionClient.loaded: The session is now fully loaded into all the slaves.

sessionClient.ended: The session is about to end.

sessionClient.unloaded: The session is now fully unloaded from all slaves and the next session in the queue(if any) will now be loaded.

var sessionClient = bCapServ.createSessionClient({host: "0.0.0.0",port: 8080,session: aSession

});sessionClient.connect();

// Emit an event to slaves when all slaves have loaded the session.sessionClient.loaded.then(function () {

sessionClient.emit("some:event", 123);});

Browser (or slave) environment

The slave environment for your sessions is a frame in a frameset. APIs are made available so you can send messagesto and from the slave and the session client.

buster.env.idThe ID of the current slave.

buster.env.contextPathThe context path to where the session resource set resources are available. If you have a resource with the path"/foo/bar.js", you can dynamically create a script tag for it like so:

36 Chapter 2. Reference documentation

Page 41: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

var scriptTag = document.createElement("script");scriptTag.src(buster.env.contextPath + "/foo/bar.js");document.body.appendChild(scriptTag);

Note that a relative path would also work:

var scriptTag = document.createElement("script");scriptTag.src("foo/bar.js");document.body.appendChild(scriptTag);

buster.emit()

buster.emit(event, [data]);

Emits the event to session client and all slaves, including itself.

buster.emit("slide:goto", 1);window.addEventListener("keyup", function (e) {

if (e.keyCode == 37) buster.emit("slide:prev");if (e.keyCode == 39) buster.emit("slide:next");

});

buster.on()

buster.on(event, handler);

Listens to the event.

buster.on("slide:goto", function (num) {currentSlide = num;loadCurrentSlide();

});buster.on("slide:next", function () {

++currentSlide;loadCurrentSlide();

});

2.1.2 buster-configuration

Module: require("buster-configuration");

In the browser: N/A (Node only)

The Buster configuration file (typically named buster.js) helps Buster to understand how to automate your testruns. You can run tests on Node without the configuration file (i.e. with node my-test.js), but it is requiredwhen using buster-test to run tests.

A configuration file can contain one or more test run configurations, called “groups”. A group specifies which teststo run, in which environment (Node or browser) to run them, and can provide certain configuration options to the testrunner.

The configuration file is focused on how to automate test runs. It is designed specifically for project-specific settingsonly. User-specific settings, like whether or not to use colors, what reporter to use and so on, is not part of thisconfiguration.

2.1. Core modules 37

Page 42: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

A simple configuration file

At its very simplest, a configuration file merely specifies the environment and which resources to load. For browsertests, this includes libraries and sources, while for Node you only need to specify tests (as typically they requiretheir own sources).

var config = module.exports;

config["Browser tests"] = {environment: "browser",libs: ["lib/**/*.js"],sources: ["src/core.js", "src/**/*.js"],tests: ["test/**/*.js", "!test/**/*integration-test.js"]

};

The configuration file is a JavaScript file. In fact, it is a Node module, as you might have guessed from the first line.The first line is pure vanity by the way. We think “config” reads better throughout the file than “exports”.

This configuration specifies a browser run (as seen from the environment property). It will cause all files inlib to be loaded first (using script tags), then all files in src, then all files in tests. Note how we specifiedsrc/core.js separately. Buster resolves these duplications, and you typically want to specify some files manuallyif ordering is important. To exclude files you just need to prepend a ! as you can see in the second pattern of thetests property. In the example that pattern prevents the integration tests to be run.

Configuration properties

To avoid wasting your time on typos and misunderstandings, Buster will fiercefully throw errors if you feed it config-uration properties it does not recognize. The following is a list of all the properties Buster recognizes.

tests: The test files to load and run. Value is an array of file names and/or glob patterns. Files are loaded in theorder provided. Like the libs and sources properties, it may include duplicates. However, it is highlyrecommended that your tests are not order dependent. Test helpers and similar utilities should be loaded withthe testHelpers property (or just require them on Node).

specs: Alias for tests

environment: browser or node. The browser environment allows you to run tests from the command-line andhave them executed in one or more browsers through the server component of Buster.JS. Refer to the browsertesting page.

env: Alias for environment.

rootPath: By default, Buster will resolve file paths in the configuration file relative to the directory in which theconfiguration file is found. Setting a rootPath allows you to change the base of path lookups. Note thatrootPath itself is also resolved relative to the directory where the configuration file is found.

The following properties only apply to the browser environment.

testHelpers: Library files to load in script tags in the browser. This setting should normally not beused for Node runs. If it is, files will be require‘d. Value is an array of file names and/or glob pat-terns. Files are loaded in the order provided. It may include duplicates, e.g. ["test/lib/core.js","test/lib/**/*.js"], files will only be loaded once. testHelpers are loaded after libraries andsources, but before tests.

specHelpers: Alias for testHelpers

libs: Library files to load in script tags in the browser. This setting should normally not be used for Node runs.If it is, files will be require‘d. Value is an array of file names and/or glob patterns. Files are loaded in the

38 Chapter 2. Reference documentation

Page 43: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

order provided. It may include duplicates, e.g. ["lib/core.js", "lib/**/*.js"], files will only beloaded once. Libraries are loaded before anything else.

deps: Alias for libs

sources: Source files to load in script tags in the browser. This setting should normally not be used for Noderuns. If it is, files will be require‘d. Value is an array of file names and/or glob patterns. Files are loaded inthe order provided. It may include duplicates, e.g. ["src/core.js", "src/**/*.js"], files will onlybe loaded once. Sources are loaded after libraries and before test libraries and tests.

src: Alias for sources

resources: Additional resources that will be made available for test runs, but not explicitly loaded. Valueis an array of resources. Resources are served from a context path on the server. To request a re-source in your test runs, you need to scope resource paths with buster.env.contextPath. Theresource /some/cookies.json can be requested as jQuery.get(buster.env.contextPath +"/some/cookies.json");

A resource can be a string, i.e. a glob pattern/file name, or an object. Objects may specify resources that areinlined content to be served as a file, a combination of other resources (optionally minified) or a proxy to anotherweb server. See resource.

autoRun: Only applies to browser runs. When set to false, Buster will not run tests immediately after loading allfiles. Refer to Manually starting test run for more information.

extends: Takes a group name, and loads all the configuration from that group as the basis for this group. Contentin libs, sources, tests and resources will be appended to the content from the original group. Otheroptions will default to the value from the referenced group unless the group itself specifies a value.

var config = module.exports;

config["Shared tests"] = {tests: ["test/shared/**/*.js"]

};

config["Browser defaults"] = {extends: "Shared tests",environment: "browser",libs: ["lib/**.js"],extensions: ["buster-amd"]

};

config["Node tests"] = {extends: "Shared tests",tests: ["test/server/**.js"]

};

config["Browser unit tests"] = {extends: "Browser defaults",tests: ["test/browser/unit/**.js"]

};

config["Browser integration tests"] = {extends: "Browser defaults",tests: ["test/browser/integration/**.js"]

};

As you can see, the extends property makes it possible to greatly reduce the duplication in configuration filesif you use multiple groups. It also encourages the use of multiple groups for multiple test profiles.

extensions:

2.1. Core modules 39

Page 44: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Extensions to load at runtime. The value is an array of extension objects which will be pinged when theconfiguration is loaded. If you are interested in developing extensions, check out the extensions page(which also lists known extensions).

To configure an extension, add settings under the name of the extension:

config["Browser integration tests"] = {extensions: [require("buster-jstestdriver"), require("buster-coverage")],"buster-coverage": {

"outputDirectory": "coverage"}

};

The Configuration API

The following is only relevant if you plan on working with the Buster.JS configuration file programatically.

Configuration

The configuration object allows you to work with a collection of groups, possibly read from a file.

/tmp/buster.js:

var config = exports;

exports["Browser tests"] = {environment: "browser",sources: ["client/src/*.js"],tests: ["client/test/*.js"]

};

exports["Server tests"] = {environment: "node",tests: ["server/test/*.js"]

};

Example:

var configuration = require("buster-configuration");

var config = configuration.create();config.loadFile("/tmp/buster.js");config.filterEnv("browser");config.filterGroup(/browser/);

config.resolveGroups(function (err, groups) {// groups[0].resourceSet.load ==// ["/client/src/todo-list.js", "/client/test/todo-list-test.js"]

});

config.groupsAn array consisting of all the Configuration group.

config.resolveGroups()

config.resolveGroups(function (err, groups) {});

40 Chapter 2. Reference documentation

Page 45: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Resolves all of the groups. See configGroup.resolve().

config.addGroup()

config.addGroup(name, groupData);

Adds a new group.

config.filterEnv()

config.filterEnv(envName);

Permanently removes all groups that aren’t of envName‘s environment. The available environments are"browser" and "node".

config.filterGroup()

config.filterGroup(regex);

Permanently filters out groups which name doesn’t match the regex. If the name provided is a string, it will beconverted to a regular expression through the RegExp constructor.

Configuration group

The individual object in the configuration’s list of groups.

configGroup.resourceSetA ramp-resources resource set, containing resources for all the objects in the config group.

This property is undefined until configGroup.resolve() is called.

configGroup.resolve()

var promise = configGroup.resolve();

Creates the resource set by performing all globs and file system operations neccesary to build up the full resourceset for the config group. The group is pretty much useless until this method is called. It won’t even have aresourceSet property defined.

The promise is resolved with the resourceSet object when the group has been fully loaded.

configGroup.setupFrameworkResources()

configGroup.setupFrameworkResources();

Adds all the framework resources such as :ref:`referee`,:ref:`buster-test` and Sinon to the resource set for the group. Theseresources are prepended so they appear before the files of the configgroup, so that everything is loaded beforehand.

.. note::This method is going away in favor of generic hooks. Buster will loadits "framework resources" as extensions using these hooks (work inprogress).

Example:

2.1. Core modules 41

Page 46: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

grp.resolve().then(function () {// Load custom-thing before the files in the config group.grp.resourceSet.addResource("/custom-thing", {...});grp.resourceSet.prependToLoad("/custom-thing");

// Load framework files, will be prepended so it loads before// the stuff added abovegrp.setupFrameworkResources();

// If you wish, you can load stuff before the framework resources.// You probably don't need to do that though.grp.resourceSet.addResource("/something-else", {...});grp.prependToLoad("/something-else");

});

Resource

A “resource” is something exposed on the server when you run browser tests using buster-server andbuster test. Exposing the resource /something.json allows you to request it in your tests using e.g.jQuery.ajax({ url: "something.json" });.

Content/file resources

etag: The etag is used by Buster to cache resources on the server. If the etag has not changed since the lasttime the resource was uploaded on the server, it will use the cached version. This improves the performance,especially if only one or two out of potentially tens or hundreds of files changed since the last run.

combine: Takes an array of resources to combine into one. Useful to run tests against a combined build of yourproject:

config["Browser build tests"] = {environment: "browser",libs: ["lib/**.js"],resources: [

"src/**.js",{ path: "/mylib.min.js",combine: ["src/base.js", "src/dom.js"] }

],sources: ["/mylib.min.js"],tests: ["test/**.js"]

};

The above configuration will run tests against a combined and minified bundle of your application. Note thatthe combine property unfortunately does not understand globs (yet).

When combine is set, you can not set content or file.

headers: Custom headers to serve the resource with. Content is an object where the property name is the headername, and the value is the header value.

content: Contents to serve as a string or a Buffer. When content is set, you can not set combine or file.

file: File to serve. When file is set, you can not set combine or content.

Proxy resources

backend: Another HTTP server that will handle the requests for path.

42 Chapter 2. Reference documentation

Page 47: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

config["Browser integration tests"] = {resources: [

{ path: "/todo-items", backend: "http://localhost:8000/todo/todo-items" }]

};

With this configuration, a request to buster.env.contextPath + "/todo-items/2"would be prox-yed to "http://localhost:8000/todo/todo-items/2"

2.1.3 buster-core

Version: 0.4.0 (2011-08-26)

Module: require("buster-core");

In browsers: buster;

A collection of utilities commonly used across Buster.JS projects. The module is stable and can be freely used whenextending Buster, or for any other projects should you wish to do so.

Methods

buster.bind()

buster.bind(object, methodOrString);

Binds a function to an object, such that its this value is fixed regardless ofhow it’s called. The function works much like ‘Function.prototype.bind<https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind>‘_. It is providedhere to work in environments that do not support Function.prototype.bind.

var homer = {name: "Homer",

burp: function () {return this.name + " goes buuuuuurp";

}};

var func = buster.bind(homer, homer.burp);func(); // "Homer goes buuuuuurp"

var func2 = buster.bind(homer, "burp");func2(); // "Homer goes buuuuuurp"

buster.create()

buster.create(object);

Cross-browser implementation of Object.create.

buster.create only supports creating a new object with the specified object as its prototype. It does notsupport property descriptors.

buster.extend()

2.1. Core modules 43

Page 48: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

buster.extend(target[, source1[, source2[, ...]]]);

Extends the target object by copying all the properties of all the sources onto it. Sources as processed in order.The method also returns the target object.

var target = { id: 42, num: 0 };

target = buster.extend(target,{ id: 13, name: "One" },{ name: "Two", prop: "erty" });

//=> { id: 13, num: 0, name: "Two", prop: "erty" }

buster.nextTick()

buster.nextTick(callback);

Calls the callback on the next tick of the event loop. On Node.js this method simply dele-gates to process.nextTick. In the browser, nextTick is emulated by passing the callback tosetTimeout(callback, 0).

buster.functionName()

buster.functionName(func);

Returns the name of the function, or an empty string if the function is a falsy value. The method tries threeapproaches, returning an empty string if all approaches fail:

1.Return func.displayName

2.Return func.name

3.Attempt to infer the name through func.toString()

Event emitter

A standalone Node.js and browser compatible event emitter API.

eventEmitter.create()

var emitter = buster.eventEmitter.create();

Creates a new event emitter object.

eventEmitter.addListener()

emitter.addListener(event, listener[, thisObject])

Adds the listener function to the named event. The optional thisObject will be the this of the listenerwhen called.

emitter.addListener("myevent", function () {// ...

});

eventEmitter.on()

44 Chapter 2. Reference documentation

Page 49: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

emitter.on(event, listener[, thisObject]);

Alias to addListener.

eventEmitter.once()

emitter.once(event, listener[, thisObject]);

Like addListener, but is removed after one emission.

emitter.once("myevent", function () {console.log("hello");

});emitter.emit("myevent"); // Logs "hello"emitter.emit("myevent"); // Nothing happens

eventEmitter.emit()

emitter.emit(event[, arg1, arg2, ...]);

Emits the event, triggering all the listeners with the given arguments.

emitter.addListener("myevent", function (a, b, c) {console.log(a, b, c);

});emitter.emit("myevent"); // undefined, undefined, undefinedemitter.emit("myevent", {}, "foo"); // {}, "foo", undefined

eventEmitter.removeListener()

emitter.removeListener(event, listener);

Removes the listener for that event.

var mylistener = function () {};emitter.addListener("myevent", mylistener);emitter.removeListener("myevent", mylistener);emitter.emit("myevent"); // Does not call 'mylistener'

eventEmitter.hasListener()

emitter.hasListener(event, listener[, thisObject]);

Tests if the event emitter has the given listener for that event, optionally a listener for the given thisObject.

var func1 = function () {};var func2 = function () {};var thisObj = {};

emitter.addListener("foo", func1);emitter.addListener("bar", func2, thisObj);

emitter.hasListener("foo", func1); // trueemitter.hasListener("foo", func2); // false

emitter.hasListener("bar", func1); // falseemitter.hasListener("bar", func2); // true

2.1. Core modules 45

Page 50: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

emitter.hasListener("bar", func2, {}); // falseemitter.hasListener("bar", func2, thisObj); // true

2.1.4 buster-format

Version: 0.4.0 (2011-08-10)

Module: var format = require("buster-format");

In browsers: var format = buster.format;

Utility functions with helpers for pretty formatting of arbitrary JavaScript values. Currently only supports asciiformatting, suitable for command-line utilities. Like JSON.stringify, it formats objects recursively, but unlikeJSON.stringify, it can handle regular expressions, functions and more.

Methods

format.ascii(object)format.ascii() can take any JavaScript object, including DOM elements, and format it nicely as plain text.It uses the helper functions described below to format different types of objects.

Simple object

var format = require("buster-format");

var object = {name: "Christian"

};

console.log(format.ascii(object));

// Outputs:// { name: "Christian" }

Complex object

var format = require("buster-format");

var developer = {name: "Christian",interests: ["Programming", "Guitar", "TV"],

location: {language: "Norway",city: "Oslo",

getLatLon: function getLatLon(callback) {// ...

},

distanceTo: function distanceTo(location) {}

},

speak: function () {return "Oh hi!";

}

46 Chapter 2. Reference documentation

Page 51: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

};

console.log(format.ascii(developer));

// Outputs:// {// interests: ["Programming", "Guitar", "TV"],// location: {// city: "Oslo",// distanceTo: function distanceTo() {},// getLatLon: function getLatLon() {},// language: "Norway"// },// name: "Christian",// speak: function () {}// }

Custom constructor

If the object to format is not a generic Object object, buster-format displays the type of object (i.e. name ofconstructor). Set the format.excludeConstructors property to control what constructors to include informatted output.

var format = require("buster-format");

function Person(name) {this.name = name;

}

var dude = new Person("Dude");console.log(format.ascii(dude));

// Outputs:// [Person] { name: "Dude" }

DOM elements

DOM elements are formatted as abbreviated HTML source. 20 characters of innerHTML is included, and ifthe content is longer, it is truncated with "[...]". Future editions will add the possibility to format nestedmarkup structures.

var p = document.createElement("p");p.id = "sample";p.className = "notice";p.setAttribute("data-custom", "42");p.innerHTML = "Hey there, here's some text for ya there buddy";

console.log(buster.format.ascii(p));

// Outputs// <p id="sample" class="notice" data-custom="42">Hey there, here's so[...]</p>

format.ascii.functionName(func)Guesses a function’s name. If the function defines the displayName property (used by some debugging tools)it is preferred. If it is not found, the name property is tried. If no name can be found this way, an attempt ismade to find the function name by looking at the function’s toString() representation.

format.ascii.func(func)Formats a function like "function [name]() {}". The name is retrieved from

2.1. Core modules 47

Page 52: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

format.ascii.functionName().

format.ascii.array(array)Formats an array as "[item1, item2, item3]" where each item is formatted with format.ascii().Circular references are represented in the resulting string as "[Circular]".

format.ascii.object(object)Formats all properties of the object with format.ascii(). If the object can be fully represented in 80characters, it’s formatted in one line. Otherwise, it’s nicely indented over as many lines as necessary. Circularreferences are represented by "[Circular]".

Objects created with custom constructors will be formatted as "[ConstructorName] { ... }". Setthe format.excludeConstructors property to control what constructors are included in the output likethis.

format.ascii.element(element)Formats a DOM element as HTML source. The tag name is represented in lower-case and all attributes and theirvalues are included. The element’s content is included, up to 20 characters. If the length exceeds 20 characters,it’s truncated with a "[...]".

format.ascii.constructorName(object)Attempts to guess the name of the constructor that created the object. It does so by getting thename of object.constructor using format.ascii.functionName(). If a name is found,format.excludeConstructors is consulted. If the constructor name matches any of these elements,an empty string is returned, otherwise the name is returned.

Properties

format.quoteStringsDefault: true

Whether or not to quote simple strings. When set to false, simple strings are not quoted. Strings in arrays andobjects will still be quoted, but ascii("Some string") will not gain additional quotes.

format.excludeConstructorsDefault: ["Object", /^.$/]

An array of strings and/or regular expressions naming constructors that should be stripped from the formattedoutput. The default value skips objects created by Object and constructors that have one character names(which are typically used in Object.create shims).

While you can set this property directly on format.ascii, it is recommended to create an instance offormat.ascii and override the property on that object.

Strings represent constructor names that should not be represented in the formatted output. Regular expres-sions are tested against constructor names when formatting. If the expression is a match, the constructor nameis not included in the formatted output.

function Person(name) {this.name = name;

}

var person = new Person("Chris");

console.log(buster.format.ascii(person));

// Outputs// [Person] { name: "Chris" }

48 Chapter 2. Reference documentation

Page 53: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

var formatter = Object.create(buster.format);formatter.excludeConstructors = ["Object", /^.$/, "Person"];console.log(formatter.ascii(person));

// Outputs// { name: "Chris" }

// Global overwrite, generally not recommendedbuster.format.excludeConstructors = ["Object", /^.$/, "Person"];console.log(buster.format.ascii(person));

// Outputs// { name: "Chris" }

2.1.5 ramp-resources

Version: 0.2 (2012-01-15)

Module: var resources = require("ramp-resources");

Manages virtual file systems that can be easily transported over network. Buster.JS uses resource collections to shipyour source files and tests to ramp, but they can also be used for other purposes, like mixing files on disk and “virtual”files for build scripts and whatnot.

The central data types is the resource–which can be a file on disk, an in-memory “file” or an http proxy–and theresource set. A resource set is a collection of resources that allows the creation of e.g. combined resources, and canbe serialized as a whole and transported over the network. Resource sets can be cached and served over http usingobjects in this module.

Resource middleware

var resourceMiddleware = require("ramp-resources").resourceMiddleware;

The resource middleware can serve resource sets over HTTP. In its simplest form, you spin up an instance, designatea context path to it, mount a resource set (only one can be served at any given time), and allow it to handle requestsentirely on its own:

var http = require("http");var rs = require("ramp-resources");

var middleware = rs.resourceMiddleware.create("/resources");

var set = rs.resourceSet.create();set.addResource({ path: "/buster.js", content: "Booyah!" });middleware.mount(set);

http.createServer(function (req, res) {if (middleware.respond(req, res)) { return; }res.writeHead(404);res.end();

}).listen(9988);

// Test ithttp.request({

host: "localhost",port: 9988,

2.1. Core modules 49

Page 54: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

path: "/resources/buster.js"}, function (res) {

res.setEncoding("utf8");res.on("data", function (chunk) {

console.log(chunk);});

}).end();

resourceMiddleware.create(contextPath)

var middleware = resourceMiddleware.create(contextPath);

Create a new instance to serve resource sets. The middleware will only respond to requests within the contextpath. The context path is also stripped from the URL before finding resources.

resourceMiddleware.setContextPath(contextPath)Change the context path.

resourceMiddleware.mount(resourceSet)Serve contents of resource set. If another resource set is mounted, it will be dismounted.

resourceMiddleware.respons(req, res)

var willRespond = middleware.respond(req, res);

Responds to an HTTP request, if the request is for a path within the middleware’s context path. If the middle-ware intends to handle the request, this method returns true (even if the request may not have been handledsynchronously). Otherwise, it returns false.

If the request is within the middleware’s context path, but does not match any resources, the middleware willgive a 404 response.

Typical usage:

var http = require("http");var resourceMiddleware = require("ramp-resources").resourceMiddleware;var middleware = resourceMiddleware.create("/resources");

// Mount sets

http.createServer(function (req, res) {if (middleware.respond(req, res)) { return; }

// Handle requests not handled by the middleware}).listen(8000);

Resource cache

var resourceSetCache = require("ramp-resources").resourceSetCache;

Cache content across resource sets. The resource set cache works as a central repository that you pass resource sets byto have their contents cached, and their missing contents replenished from the cache.

resourceSetCache.create(ttl)

50 Chapter 2. Reference documentation

Page 55: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

var cache = resourceSetCache.create(ttl);

Creates a new cache. ttl decides for how many milliseconds individual resources are cached. The default timeto live for resources is one hour. Note that the ttl only determines how long resources stay in the internalcache. Once you’ve inflated (using cache.inflate()) a resource set with a cached resource, it will stickaround in that resource set until you remove it on your own.

resourceSetCache.inflate(resourceSet)

var promise = cache.inflate(resourceSet);

Inflating a resource set achieves two things:

1.Any resource in the set that has an etag and content will be cached.

2.Any resource in the set that has an etag and whose content is empty, will be replaced with a cached copy,if one exists.

Note that the resource cache caches entire resources, not only content. To avoid having certain resources cached,simply make sure they don’t have an etag set.

Serving resource sets with a cache:

var http = require("http");var rs = require("ramp-resources");

var middleware = rs.resourceMiddleware.create("/resources");var cache = rs.resourceSetCache.create(60 * 60 * 1000);

// Assume 'set' is a resourceSet instancecache.inflate(set).then(function (inflatedSet) {

middleware.mount(inflatedSet);});

resourceSetCache.resourceVersions(resourceSet)

var result = cache.resourceVersions(resourceSet);

Returns an object with information about all path/etag combinations contained in the cache:

set.addResource({ path: "/buster.js", etag: "123", content: "OK" });set2.addResource({ path: "/buster.js", etag: "abc", content: "Newer" });

when.all([cache.inflate(set1), cache.inflate(set2)], function () {cache.resourceVersions() === {

"/buster.js": ["abc", "123"]};

});

Resource sets

var resourceSet = require("ramp-resources").resourceSet

A resource set lets you represent a set of files associated with paths. It lets you create bundles of multiple resources,proxy certain paths to other HTTP servers, preprocess resources (for example convert CoffeeScript into JavaScript),and more.

2.1. Core modules 51

Page 56: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

resourceSet.deserialize(data)

var promise = resourceSet.deserialize(data);

Deserialize a resource set. The data should be a JavaScript object, the kind thatresourceSet.serialize() produces. The method returns a promise that resolves with the fullyinflated resource set.

Typically, when receiving resource sets over HTTP, they will be JSON encoded, bring it back to life like so:

var resourceSet = require("buster-resource").resourceSet;

// Assume 'data' holds a JSON encoded resource set serializationresourceSet.deserialize(JSON.parse(data)).then(function (set) {

// Serve set over HTTP or similar});

resourceSet.create(rootPath)

var set = resourceSet.create(rootPath);

Creates a new resource set. The rootPath is used to resolve globs and direct file paths. If not provided, itdefaults to the current working directory. You can not add files to a resource set if they live outside the resourceset root directory.

resourceSet.lengthThe length of the resource set is the number of resources in it. Resource sets expose resources through anarray-like interface with length and numeric properties.

resourceSet.addResources(resources)

var promise = resourceSet.addResources(resources);

Adds multiple resources. Argument is an array of resources as accepted byresourceSet.addResource(). The method returns a promise that resolves with an array of re-sources.

resourceSet.addResource(resource)

var promise = resourceSet.addResource(resource);

Adds a resource. The argument can be either a proper resource() instance, a string (either a file path or aglob, see resourceSet.addGlobResource()) or an object with properties describing a resource. Themethod returns a promise that resolves with a single resource.

resourceSet.addGlobResource(path)

var promise = resourceSet.addGlobResource(path);

Add all files matching the glob as resources. Returns a promise that resolves with an array of resources. Theglob is resolved relatively to the resource set rootPath.

resourceSet.addFileResources(paths, options)

52 Chapter 2. Reference documentation

Page 57: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

var promise = resourceSet.addFileResources(paths, options);

Add multiple files as resources with common meta data options. Each path will be passed along withoptions to resourceSet.addFileResource(). Returns a promise that resolves with an array ofresources.

resourceSet.addFileResource(path, options)

var promise = resourceSet.addFileResource(path, options);

Adds a file as resource. The path is resolved against the resource set rootPath. You can provide the pathto serve the resource through as part of the options object. Returns a promise that resolves with a singleresource.

resourceSet.addCombinedResource(sources, options)

var promise = resourceSet.addCombinedResource(sources, options);

Add a resource whos content is the combination of other resources in the set. sources is an array of paths toother pre-existing resources. Returns a promise that resolves with a single resource.

resourceSet.get(path)

var resource = resourceSet.get(path);

Returns the resource at path. The path will be normalized before lookup:

resourceSet.get("buster.js") === resourceSet.get("/buster.js");

resourceSet.remove(path)Removes a resource with the given path. Will also remove it from loadPath if present.

resourceSet.serialize()

var promise = resourceSet.serialize();

Serializes the resource set. The serialization format is a plain JavaScript object with two properties:resources and load, both of which are arrays. The serialized object can safely be JSON encoded forwire transfer. The serialization will also have all resource contents loaded in a flat structure.

resourceSet.concat(rs2, rs3, ...)

var newRs = rs1.concat(rs2, rs3, ...);

Create a new resource set by combining this one with one or more other resource sets. Does not mutate any ofthe existing resource sets.

resourceSet.appendLoad(paths)Append paths to the load path. Paths may be glob patterns. Any path does not match an existing resource inthe resource set will be added from disk before added to the load path. This is different from calling appenddirectly on the loadPath, where a missing resource causes an error.

resourceSet.prependLoad(paths)Like resourceSet.appendLoad(), only prepend to the load path in place of append.

resourceSet.loadPathAn object that allows you to control what resources should be loaded when the resource set is loaded.

2.1. Core modules 53

Page 58: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Resource set load path

The following methods are available on the resourceSet.loadPath object.

loadPath.append(paths)Append paths to the end of the load path.

loadPath.prepend(paths)Prepend paths to the beginning of the load path.

loadPath.remove(path)Remove path from load path.

loadPath.clear()Remove all paths from load path.

loadPath.paths()

var paths = loadPath.paths();

Returns an array of paths on the load path. This array is just a copy, and can not be used to mutate the load path.

Resource set payload

Warning: Old and outdated

The resource set payload is an object that consists of a set of resources, and optionally a list of resources to automati-cally load in the root resource.

TODO: Write about root resource and auto injection.

resources.createResourceSet({resources: {

"/path": {...},"/other-path": {...},

...},load: [resourcePath, ...]

});

resourceSetPayload.resourcesAn object where the key is the path and the value is the resource payload. The equivalent of callingresourceSet.addResource().

resourceSetPayload.loadList of paths to “load”. The path must exist as a resource.

In ramp, the resources in load will be automatically injected as script tags before the closing </body> tag. Aresource set does not in itself know what it means to load something.

Resource payload

This section describes the object that is passed to resource creation, such asresourceSet.addResource("/path", payload) and resourceSet.addFile("/path/to/file",payload).

54 Chapter 2. Reference documentation

Page 59: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

String as content

{content: "a string"}

Sets the content of the resource to the value of the string.</p>

Buffer as content

{content: new Buffer(...)}

Sets the content of the resource to the value of the buffer.</p>

Function as content

{content: function (promise) {}}

Function will be called when needed and allows for asynchronous fetching of content via a promise. This is whatresourceSet.addFile() uses under the hood.

It is imperative that you either resolve or reject the promise. There’s no internal time out, so if you do networking orsomething else that could time out, you should create your own timeout and reject the promise when the timeout fires.You also need to make sure you don’t accept the promise after you already rejected it, and vice versa.

resourceSet.addResource("/foo", {content: function (promise) {

// We don't do anything asynchronous here so we might as well// have used a string directly instead of a function.promise.resolve("This is the content");

}});

resourceSet.addResource("/foo", {content: function (promise) {

fs.readFile("/foo", function (err, data) {if (err) {

promise.reject(err);} else {

promise.resolve(data);}

});}

});

resourceSet.addResource("/foo", {content: function (promise) {

http.request({host: "myserver.com", port: 80, path: "/test"},function (res) {

var data = "";res.on("data", function (chunk) { data += chunk; });res.on("end", function () { promise.resolve(data); });

}).end();

}});

2.1. Core modules 55

Page 60: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Headers

{headers:{"Header": "Value"}}

Set custom headers. A Content-Type header will be added automatically if not present, via the node-mime project.

Etag

{etag:"value"}

The etag is used in combination with the name of the resource to determine wether the ramp already has this resource.

How the etag is calculated is entirely up to you. By convention, the only expectation is that if the file for which theresource points to has changed, the etag should change as well. Internally in buster, we calculate the etag by applyingSHA1 to the mtime and the absolute path to the file.

TODO: write more about how to practically perform caching against ramp.

Backend

{backend: "url"}

A full URL to a http server that will be requested when the resource in question is requested.

The URLs will be rewritten based on the path to the resource itself. For:

resourceSet.addResource("/foo", {backend: "http://example.com"});

a call to:

resourceSet.getResource("/foo/test", cb);

will perform a request to http://example.com/test.

Combine

{combine: ["/foo.js", "/bar.js"]}

Combines existing reseources into one resource. The resources passed have to exist before you create a combinedresource for them.

2.1.6 buster-server-cli

Version: 0.1.0 (2012-05-14)

Module: require("buster-server-cli");

In browsers: N/A

Command-line interface API for running ramp instances with a simple interface that allows capturing and viewing alist of connected browsers.

In Buster, this module is the implementation of the buster-server command. It does not define the binaryhowever, as it is intended to be generic enough to be reused outside of Buster.

56 Chapter 2. Reference documentation

Page 61: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Possible use cases

The capture server is the central piece in Buster’s multiple browser automation capabilities. This module can be usedas is to run tests for any framework, as it does not know anything about tests at all. However, if you’re shipping acapture server for your own framework, you may want to brand your server a little.

The following example shows how to create a custom capture server for the fictional checkit test framework.

The binary

// checkit/bin/checkit-servervar path = require("path");var serverCli = require("buster-server-cli");

serverCli.create(process.stdout, process.stderr, {missionStatement: "Checkit crazy multi-browser test runner server",description: "checkit-server [options]",templateRoot: path.join(__dirname, "..", "views"),documentRoot: path.join(__dirname, "..", "public")

}).run(process.argv.slice(2));

The index template

You need to define two templates for the server to work correctly. The first one is index.ejs, which is an ejstemplate for the index page of the server.

Buster’s index template renders a list of captured browsers and a link to /capture, which is the URL that causes thebrowser to become a captured slave.

The index.ejs template is rendered with one piece of data — slaves — which is an array of slave objects:

slave.browserA string, i.e. “Firefox”

slave.platformA string, i.e. “Linux”

slave.versionA string, i.e. “12.0”

slave.osA string, contains a richer OS/platform description

slave.userAgentThe original user agent

The header template

The second template is the header.ejs template. It is used in the top frame in the frameset that is displayed incaptured slaves. Currently this is just a static template, but future versions will expose an API to communicate withthe server here to display progress etc.

See Buster’s header template for a reference implementation.

2.1. Core modules 57

Page 62: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

2.1.7 buster-sinon

Sinon.JS integration.

Warning: This documentation is incomplete.

Sinon specific assertions are documented at referee.

Refer to the Sinon.JS documentation and do some guesswork for the other functionality.

Quick cheat sheet

buster.testCase("Foo", {"test a stub": function () {

// Overrides "aMethod" and restores when test finishes runningthis.stub(myLib, "aMethod");myLib.otherThing();assert.calledOnce(myLib.aMethod);

},

"test a spy": function () {// Wraps "aMethod". The original method is called, and you can also// do stub like assertions with it.this.spy(myLib, "aMethod");myLib.otherThing();assert.calledOnce(myLib.aMethod);

}});

Testing AJAX

Sinon.JS mocks out the underlying XMLHttpRequest (or ActiveXObject) object, so your HTTP libraries don’tneed any modification to be testable in this way - even when using jQuery or another 3rd party library for your HTTPconnections.

var assert = buster.assert;

buster.testCase("My tests", {setUp: function () {

this.server = this.useFakeServer();},

"should POST to /todo-items": function () {myThing.createTodoItem("Some item");

assert.equals(this.server.requests.length, 1);assert.match(this.server.requests[0], {

method: "POST",url: "/todo-items"

});},

"should yield list item to callback on success": function () {this.server.respondWith(

"POST",

58 Chapter 2. Reference documentation

Page 63: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

"/todo-items",[200, {"content-type": "application/json"},'{"text":"Fetch eggs","done":false,"id":1}']);

var callback = this.spy();// Assuming implementation calls the callback with a JSON.parsed// response body when the request endsmyThing.createTodoItem("Fetch eggs", callback);

// Cause the request to respond, based on respondsWith above.this.server.respond();

// Sinon.JS replaces the entire XHR stack and synchronously handles// the request.assert.calledOnce(callback);assert.equals(callback.getCall(0).args[0], {

text: "Fetch eggs", done: false, id: 1});

}});

Minimal implementation for myThing to pass the tests:

var myThing = {createTodoItem: function (str, cb) {

var http = new XMLHttpRequest();var url = "/todo-items";http.open("POST", url, true);

http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

http.onreadystatechange = function () {if(http.readyState == 4 && http.status == 200) {

if (cb) {cb(JSON.parse(http.responseText));

}}

}http.send();

}}

2.1.8 buster-static

TODO Document

2.1. Core modules 59

Page 64: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

2.1.9 buster-test

Version: 0.1.0 (2011-03-23)

60 Chapter 2. Reference documentation

Page 65: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Test reporters

Version: See buster-test

Module: require("buster-test").reporters;

In browsers: buster.reporters;

Reporters listen to test runner events and visualize progress and results of test runs. Buster ships with several alterna-tives, and it is easy to make your own.

dots reporter

Prints a single character for each test as the tests are running. When the test run completes, it prints a list of errors anda summary. The characters printed while running are:

.: Test passed (green)

F: Test failed (red)

E: Uncaught error (yellow)

A: Asynchronous test (purple)

T: Timeout (red)

The A indicating an asynchronous test is replaced by one of the others when the test completes, or a T if it times out(using ANSI escape characters).

In order to help you find the source of errors faster, the reporter filters the stack trace using buster.stackFilter.

dotsReporter.create()

var reporter = dotsReporter.create(options)l

Create an instance. For options, see Console reporter options.

dotsReporter.listen()

reporter.listen(testRunner);

Bind the reporter to a test runner.

Example:

var testRunner = require("buster-test").testRunner;var dotsReporter = require("buster-test").reporters.dots;

var reporter = dotsReporter.create({ color: false });var runner = testRunner.create();reporter.listen(runner);

runner.runSuite(...);

2.1. Core modules 61

Page 66: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Sample output

specification reporter

Reporter inspired by those found in vows.js, nodeunit, and others. The reporter gives you all information it has as soonas it can. With longer-running test cases, this reporter will give you the meat of your errors faster.

In order to help you find the source of errors faster, the reporter filters the stack trace using buster.stackFilter.

specificationReporter.create()

62 Chapter 2. Reference documentation

Page 67: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

var reporter = specificationReporter.create(options);

Create an instance. For options, see Console reporter options.

specificationReporter.listen()

reporter.listen(testRunner);

Bind the reporter to a test runner.

Example:

var testRunner = require("buster-test").testRunner;var specificationReporter = require("buster-test").reporters.specification;

var reporter = specificationReporter.create({ color: false });var runner = testRunner.create();reporter.listen(runner);

runner.runSuite(...);

2.1. Core modules 63

Page 68: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Sample output

quiet reporter

The quiet reporter simply prints the ending stats only.

quietReporter.create()

var reporter = quietReporter.create(options);

Create an instance. For options, see Console reporter options.

quietReporter.listen()

64 Chapter 2. Reference documentation

Page 69: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

reporter.listen(testRunner);

Bind the reporter to a test runner.

Example:

var testRunner = require("buster-test").testRunner;var quietReporter = require("buster-test").reporters.quiet;

var reporter = quietReporter.create({ color: false });var runner = testRunner.create();reporter.listen(runner);

runner.runSuite(...);

Sample output

xml reporter

Generates JUnit/Ant compatible XML output for use in continuous integration servers. The reporter prints XML tostdout, so you have to pipe it to a file manually if needed. The XML output is compatible with CI servers such asJenkins (formerly Hudson).

xmlReporter.create()

var reporter = xmlReporter.create(options);

Create an instance. For options, see Console reporter options.

xmlReporter.listen()

reporter.listen(testRunner);

Bind the reporter to a test runner.

Example:

var testRunner = require("buster-test").testRunner;var xmlReporter = require("buster-test").reporters.xml;

var reporter = xmlReporter.create({ color: false });var runner = testRunner.create();reporter.listen(runner);

runner.runSuite(...);

2.1. Core modules 65

Page 70: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Sample output

html reporter

The reporter mimics the specification reporter. It can use an entire web page to render a nice test report, orembed itself as a console, making it useful for in-app integration testing. You can also use it on the command line togenerate an HTML report of your test run.

In order to help you find the source of errors faster, the reporter filters the stack trace using buster.stackFilter.

htmlReporter.create()

66 Chapter 2. Reference documentation

Page 71: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

var reporter = htmlReporter.create(htmlOptions);

Create an instance. For options, see HTML reporter options.

htmlReporter.listen()

reporter.listen(testRunner);

Bind the reporter to a test runner.

Example:

var reporter = buster.reporters.html.create({root: document.body // Full webpage mode

});

var runner = buster.testRunner.create();reporter.listen(runner);

runner.runSuite(...);

2.1. Core modules 67

Page 72: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Sample output

68 Chapter 2. Reference documentation

Page 73: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

jsonProxy reporter

Not intended for human consumption. The jsonProxy reporter proxies all events from the Test runner, but strips anynon-JSON safe value (such as functions). Buster uses this when emitting test results from a browser to the server.

jsonProxyReporter.create()

var reporter = jsonProxyReporter.create(emitter);

Create an instance. You can optionally provide an event emitter to emit events with. Buster uses this option toprovide a messaging client that will emit events directly over the wire.

jsonProxyReporter.listen()

reporter.listen(testRunner);

Bind the reporter to a test runner.

The jsonProxy reporter is to be used in place of the test runner when using a reporter that needs pure JSON-friendlyobjects. The example below uses the XML reporter - it works fine directly with the test runner as well, it is only usedto illustrate how jsonProxy works:

var proxy = buster.reporters.jsonProxy.create();var runner = buster.testRunner.create();proxy.listen(runner);

var reporter = buster.reporters.xml.create();reporter.listen(proxy);

Implementing a reporter

Buster reporters consume events from a buster.testRunner instance and should conform to the simple API describedbelow. For the reporter to be usable with Buster’s auto-wiring mechanism, you also need to make the reporter availableas a Node module. The auto-wiring mechanism is what is in use when you have not instantiated a runner on your ownand you do this:

BUSTER_REPORTER=myReporter node mytest.js

(Or use buster test -r myReporter)

1. Include the reporter in buster.reporters

In browsers, you must expose the reporter in the correct object:

buster.reporters.myReporter = { /*...*/ };

2. Implement create(options)

This method should return a new instance. It will be passed an options object.

3. Implement listen(testRunner)

This method allows you to listen to events of interest on the test runner. The built-in reporters typically usebuster.bind(), but you are completely free to implement this the way you feel best. See Events for availableevents.

4. Include your reporter on the load path

2.1. Core modules 69

Page 74: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

In browsers, this means add a script tag loading your reporter after loading Buster and before loading your tests.On node, you must make the reporter available to Buster. This is usually accomplished by coding the reporteras a Node module and doing npm link in the reporter project.

5. Run it:

BUSTER_REPORTER=myReporter node mytest.js

Example The following example shows how to implement a reporter that prints test contexts and test names as anested tree.

1. Create a directory for our reporter:

mkdir /tmp/spec-treecd /tmp/spec-tree

2. First, let’s just create a blank reporter and a sample project to test it with. We’ll have the reporter print somethingso we can verify that it works.

// /tmp/spec-tree/index.jsmodule.exports = {

create: function (options) {return Object.create(this);

},

listen: function (runner) {runner.on("test:start", function (test) {

console.log("Test started");});

}};

Console reporter options

Options when creating console reporters. All properties are optional.

color: When true, print report in colors. Default is true.

bright: When true, print report in bright colors (requires color: true). Default is true.

cwd: The current working directory. Passed to buster.stackFilter.

io: The stream to print to. The default value is to use the sys module. The io object is required to implement twomethods: print, which prints a string and puts, which prints a string and a line-break.

Default values{

color: true,bright: true,cwd: null,io: require("sys")

}

HTML reporter options

Options when creating HTML reporters.

70 Chapter 2. Reference documentation

Page 75: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

root: The root element to render test results in. Required.

Test spec

Version: See buster-test

Module: require("buster-test").spec;

In browsers: buster.spec;

BDD-style specifications. Buster’s spec tests supports the same features as the xUnit-style test cases but with a syntaxcloser to BDD-style frameworks such as RSpec, Jasmine and others.

buster.spec.describe() produces test context objects that can be run using the Test runner.

Unboxing the namespace

One of Buster’s core principles is to not pollute the global environment. For this reason we only add one singleglobal object – buster. However, in some cases, like this one, the namespaces seriously desugars your code.For this reason, the spec module has a buster.spec.expose() method that allows you to use describe,it, itEventually, before, beforeAll, beforeEach, after and afterAll, afterEach without thebuster.spec prefix:

buster.spec.expose();

describe("Namespace-less functions for ya", function () {// ...

});

Describe

spec.describe(name, callback)Creates a specification. The name should be a string, and the callback can be used to further describe yourspecification.

Example: Bowling kata The following example shows some specs from the bowling kata, using a beforemethod.

buster.spec.expose(); // Make functions global

var spec = describe("Bowling kata", function () {before(function () {

this.game = new BowlingGame();

this.rollMany = function (rolls, pins) {for (var i = 0; i < rolls; ++i) {

this.game.roll(pins);}

};});

it("yield 0 in score for gutter game", function () {this.rollMany(20, 0);buster.assert.equals(0, this.game.score());

});

2.1. Core modules 71

Page 76: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

it("yield score of 20 for 1 pin on each roll", function () {this.rollMany(20, 1);buster.assert.equals(20, this.game.score());

});});

Example: controller specs The following (slightly more involved) example shows some specs from a todo appli-cation’s form controller. Nested describes are used to separate both controller actions as well as successful and failedattempts at posting the form. Note the use of nested setup methods – both before callbacks will be run (the outer first,then the inner) for each requirement in the “adding items” specification.

buster.spec.expose();

var spec = describe("Form controller", function () {before(function () {

this.form = document.createElement("form");this.form.innerHTML = "<fieldset>" +

"<input type='text' name='item' id='item'>" +"</fieldset>";

this.input = this.form.getElementsByTagName("input")[0];this.backend = { add: sinon.spy() };this.controller = todoList.formController.create(this.form, this.backend);this.callback = sinon.spy();this.controller.on('item', this.callback);

});

describe("adding items", function () {before(function () {

this.input.value = "It puts the lotion in the basket";});

describe( "successfully", function () {it("emit onItem on success", function () {

var item = { text: "It puts the lotion in the basket" };sinon.stub(this.backend, "add").yields(item);

this.controller.addItem();

sinon.assert.calledOnce(this.callback);sinon.assert.calledWith(this.callback, item);

});

it("clear form on success", function () {this.input.value = "It puts the lotion in the basket";this.backend.add = sinon.stub().yields({});

this.controller.addItem();

buster.assert.equals("", this.input.value);});

});

describe("unsuccessfully", function () {it("render error on failure", function () {

sinon.stub(this.backend, "add").yields(null);

72 Chapter 2. Reference documentation

Page 77: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

this.controller.addItem();var err = this.form.firstChild;

buster.assert.match(err, {tagName: "p",className: "error",innerHTML: "An error prevented the item from being saved"

});});

});});

});

Nested describes Calls to describe can be arbitrarily nested. See the explanation of Nested before and after foran example of using nested describes.

Asynchronous specs

To create asynchronous specs (i.e. ones that the runner will wait for), the spec function can either explicitly accept asingle argument, which is a function, or return a thenable promise.

Explicitly accepting an argument The argument passed to the spec is a function. When the function is called, theasynchronous spec is deemed done. The idiomatic way of creating asynchronous specs using this arguments looks likethe following:

buster.spec.expose();

describe("Buster async specs", function () {it("be asynchronous", function (done) {

setTimeout(function () {buster.assert(true);done();

}, 100);});

});

This assumes that the assertion framework can fail without throwing an error (as an error would be intercepted asuncaught in the above example, if intercepted at all). If this is not the case, you can make your assertions in a callbackto the done function:

buster.spec.expose();

describe("Buster async specs", function () {it("be asynchronous", function (done) {

setTimeout(function () {done(function () {

buster.assert(true);});

}, 100);});

});

Returning a promise Specs can be made asynchronous by way of returning a promise. The spec runner considersany object with a then method a promise:

2.1. Core modules 73

Page 78: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

buster.spec.expose();

describe("Buster async/promise specs", function () {it("be asynchronous", function () {

var promise = {then: function (callback) {

this.callbacks = this.callbacks || [];this.callbacks.push(callback);

}};

setTimeout(function () {buster.assert(true);var callbacks = promise.callbacks || [];

for (var i = 0, l = callbacks.length; i < l; ++i) {callbacks[i]();

}}, 100);

return promise;});

});

Note that this does not work entirely as expected unless your assertion framework of choice is able to notify the runnerof failure without throwing an exception. If the assertion fails (and throws an exception), the promise will never beresolved, thus the runner will fail the spec with a timeout, not an assertion error.

The above example is very verbose, simply to illustrate the duck-typed nature of promises. You can do better by usinge.g. when.js:

describe("Buster async/promise specs", function () {it("be asynchronous", function () {

var deferred = when.defer();

setTimeout(function () {buster.assert(true);deferred.resolver.resolve();

}, 100);

return deferred.promise;});

});

Before and after callbacks can use the same mechanism to be asynchronous.

Before and after

Specs can use before and after callbacks. before callbacks are called before every spec, and is a suitable placeto put shared setup code:

buster.spec.expose();

var spec = describe("Spec with before", function () {before(function () {

this.object = { id: 42 };});

74 Chapter 2. Reference documentation

Page 79: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

it("override id": function () {this.object.id = 43;buster.assert.equals(this.object.id, 43);

});

it("not have id equal 43": function () {// The object is recreated in setUp for each specbuster.assert.notEquals(this.object.id, 43);

});});

Similarly, after callbacks can be used to clean up after each spec. Keep in mind though, that the spec’s this objectis discarded and recreated for each spec. If your specs are properly isolated you rarely need clean up.

buster.spec.expose();

var spec = describe("Spec with teardown", function () {after(function () {

if (jQuery.ajax.restore) {jQuery.ajax.restore();

}});

it("make http request": function () {twitter.timeline("cjno", function () {});

buster.assert(jQuery.ajax.calledOnce);});

});

Using beforeAll() and afterAll() Buster.js supports beforeAll() and afterAll() functions much like theones in Rspec. For example, if you want to run a setup function once and then make the specs evaluate the result, youcan do as follows:

function magicDoubler(number) {return number * 2;

}

buster.spec.expose();

var spec = describe("The magic doubler", function () {beforeAll(function() {

//magicDoubler is called only once.this.result; = magicDoubler(7);

});

it("should yield a defined result", function () {expect(this.result).toBeDefined();

});

it("should yield a number divisible by 2", function () {expect(this.result % 2 === 0).toBeTrue();

});});

Similarly, you can use afterAll() to call a single teardown function that runs after all specs have been executed.This is useful for cleaning up after a test that alters a model.

2.1. Core modules 75

Page 80: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Nested before and after When nesting describes, you can add before and after callbacks to some or all ofyour specs. All applicable before and after callbacks are called before each spec function. before callbacksare called starting from the outermost describe, while after callbacks are called starting from the spec’s localdescribe. Let’s illustrate by way of an example:

buster.spec.expose();

var spec = describe("Nested before and after call order", function () {before(function () {

console.log("Before #1");});

after(function () {console.log("After #1");

});

it("do #1", function () {console.log("Spec #1");

});

describe("context", function () {before(function () {

console.log("Before #2");});

it("do #2", function () {console.log("Spec #2");

});

describe("context", function () {before(function () {

console.log("Before #3");});

after(function () {console.log("After #3");

});

it("do #3": function () {console.log("Spec #3");

});}

}});

Will print:

Before #1Spec #1After #1Before #1Before #2Spec #2After #1Before #1Before #2Before #3Spec #3After #3

76 Chapter 2. Reference documentation

Page 81: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

After #1

Asynchronous before and after Before and after callbacks are treated as asynchronous by the test runner if theyeither return a thenable promise or if they explicitly accept an argument. See Asynchronous specs.

Deferred specs

If you have written a spec that for some reason is impossible to pass in the near future, you may grow tired of seeingit fail while working on other parts of the system. Because the spec may represent an important goal/requirement(perhaps the goal of a longer refactoring session) it is undesirable to delete it. Simply commenting out the spec maycause you to forget it and commit commented out code, which isn’t very nice.

Buster recognizes the valid use of deferred specs and provides a simple way to defer a spec – simply change it to theaptly named itEventually:

buster.spec.expose();

var spec = describe("Bowling kata", function () {before(function () {

this.game = new BowlingGame();

this.rollMany = function (rolls, pins) {for (var i = 0; i < rolls; ++i) {

this.game.roll(pins);}

};});

it("yield 0 in score for gutter game", function () {this.rollMany(20, 0);buster.assert.equals(0, this.game.score());

});

itEventually("yield score of 20 for 1 pin on each roll", function () {this.rollMany(20, 1);buster.assert.equals(20, this.game.score());

});});

In this example, the second spec will not run, but the reporter will include it and explicitly mark it as deferred,helping you avoid forgetting about it.

Stack filter

Version: See buster-test

Module: require("buster-test").stackFilter;

In browsers: buster.stackFilter;

Stack traces contain some interesting information and (often) lots of noise. The stack filter helps reduce the noise tohelp you find errors faster. It can do so by:

1. stripping the current working directory from paths, and

2. removing lines from inside buster (or other libraries not of your interest).

2.1. Core modules 77

Page 82: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Methods

stackFilter()

var lines = buster.stackFilter(stack[, cwd]);

Trims a stack trace by removing lines that match stackFilter.filters. stack is a string containingthe entire stack trace. The optional cwd argument is a string containing the current working directory. Whenprovided, it is stripped from all lines in the resulting stack trace.

The function returns an array of stack trace lines. Given the following stack trace:

var stack = 'AssertionError: [assert.equals] Expected "Something" to be equal to "Other"' +'at Function.fail (/home/christian/buster/node_modules/buster-assert/lib/buster-assert.js:147:25)' +'at fail (/home/christian/buster/node_modules/buster-assert/lib/buster-assert.js:61:16)' +'at Function.equals (/home/christian/buster/node_modules/buster-assert/lib/buster-assert.js:237:13)' +'at Object.<anonymous> (/home/christian/buster/doc/samples/test-case.js:101:23)' +'at asyncFunction (/home/christian/buster/node_modules/buster-test/lib/buster-test/runner.js:79:21)' +'at Object.runTestFunction (/home/christian/buster/node_modules/buster-test/lib/buster-test/runner.js:312:26)' +'at /home/christian/buster/node_modules/buster-core/lib/buster-core.js:45:31' +'at EventEmitter._tickCallback (node.js:108:26)';

stackFilter() would reduce it like so:

var lines = buster.stackFilter(stack, "/home/christian/buster");

// lines:// ['AssertionError: [assert.equals] Expected "Something" to be equal to "Other"',// 'at Object.<anonymous> (doc/samples/test-case.js:101:23)',// 'at runOne (node_modules/buster-promise/lib/buster-promise.js:89:35',// 'at Array.0 (node_modules/buster-promise/lib/buster-promise.js:75:47']

stackFilter.match()

var isMatch = buster.stackFilter.match(line);

Helper function used by stackFilter(). Returns true if line matches any ofstackFilter.filters.

Properties

stackFilter.filtersThe stackFilter.filters property is an array of strings to match against lines in a stack trace. Any stacktrace line that match one of these filters will be stripped. The default value is an array of core buster modules. Ifyou are developing add-ons to Buster, and don’t want long traces from inside these libraries in test reports, addentries to this array.

The buster-sinon module adds the core Sinon.JS libraries to the array to avoid them getting in the way of findingwhere in your test and implementation a failure originated. (Note that the added entry filters out lines from bothSinon.JS and the buster-sinon adapter.)

buster.stackFilter.filters.push("lib/sinon");

If you want the full traces, you can simply wipe the filters array in your tests:

78 Chapter 2. Reference documentation

Page 83: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

delete buster.stackFilter.filters;

Test case

Version: See buster-test

Module: require("buster-test").testCase;

In browsers: buster.testCase;

xUnit test case sprinkled with some BDD idioms. buster.testCase supports setup and teardown, asynchronoustests, nested test cases, deferred tests, and more.

buster.testCase produces test context objects that can be run using the Test runner.

testCase

buster.testCase(name, tests)name is an arbitrary string. The tests object can contain test functions, nested test cases, setup and teardown.

Example: Bowling kata The following example shows some tests from the bowling kata, using a setup method:

var testCase = buster.testCase("Bowling kata tests", {setUp: function () {

this.game = new BowlingGame();

this.rollMany = function (rolls, pins) {for (var i = 0; i < rolls; ++i) {

this.game.roll(pins);}

};},

"gutter game yields 0 in score": function () {this.rollMany(20, 0);

buster.assert.equals(0, this.game.score());},

"1 pin on each roll should yield score of 20": function () {this.rollMany(20, 1);

buster.assert.equals(20, this.game.score());}

});

Example: controller tests The following (slightly more involved) example shows some tests from a todo applica-tion’s form controller. Nested contexts are used to separate both controller actions as well as successful and failedattempts at posting the form. Note the use of nested setup methods – both setups will be run (the outer first, then theinner) for each test in the “adding items” test case).

var testCase = buster.testCase("Form controller", {setUp: function () {

this.form = document.createElement("form");this.form.innerHTML = "<fieldset>" +

2.1. Core modules 79

Page 84: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

"<input type='text' name='item' id='item'>" +"</fieldset>";

this.input = this.form.getElementsByTagName("input")[0];this.backend = { add: sinon.spy() };this.controller = todoList.formController.create(this.form, this.backend);this.callback = sinon.spy();this.controller.on('item', this.callback);

},

"adding items": {setUp: function () {

this.input.value = "It puts the lotion in the basket";},

"successfully": {"should emit onItem on success": function () {

var item = { text: "It puts the lotion in the basket" };sinon.stub(this.backend, "add").yields(item);

this.controller.addItem();

sinon.assert.calledOnce(this.callback);sinon.assert.calledWith(this.callback, item);

},

"should clear form on success": function () {this.input.value = "It puts the lotion in the basket";this.backend.add = sinon.stub().yields({});

this.controller.addItem();

buster.assert.equals("", this.input.value);}

},

"unsuccessfully": {"should render error on failure": function () {

sinon.stub(this.backend, "add").yields(null);

this.controller.addItem();var err = this.form.firstChild;

buster.assert.match(err, {tagName: "p",className: "error",innerHTML: "An error prevented the item from being saved"

});}

}}

});

Nested test cases Test cases can be arbitrarily nested. Simply add a property whose value is an object with optionalsetup and teardown, tests and even more test cases. See the explanation of Nested setup and teardown for an exampleof using nested test cases.

80 Chapter 2. Reference documentation

Page 85: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Asynchronous tests

To create asynchronous tests (i.e. ones that the runner will wait for), the test function can either explicitly accept asingle argument, which is a function, or return a thenable promise.

Explicitly accepting an argument The argument passed to the test is a function. When the function is called, theasynchronous test is deemed done. The idiomatic way of creating asynchronous tests using this arguments looks likethe following:

function someAsyncTestFunction(done) {setTimeout(function () {

buster.assert(true);done();

}, 100);}

This assumes that the assertion framework can fail without throwing an error (as an error would be intercepted asuncaught in the above example, if intercepted at all). If this is not the case, you can make your assertions in a callbackto the done function:

function someAsyncTestFunction(done) {setTimeout(done(function () {

buster.assert(true);}), 100);

}

Returning a promise Tests can be made asynchronous by way of returning a promise. The test runner considersany object with a then method a promise:

function someAsyncTestFunction() {var promise = {

then: function (callback) {this.callbacks = this.callbacks || [];this.callbacks.push(callback);

}};

setTimeout(function () {buster.assert(true);var callbacks = promise.callbacks || [];

for (var i = 0, l = callbacks.length; i < l; ++i) {callbacks[i]();

}}, 100);

return promise;}

Note that this does not work entirely as expected unless your assertion framework of choice is able to notify the runnerof failure without throwing an exception. If the assertion fails (and throws an exception), the promise will never beresolved, thus the runner will fail the test with a timeout, not an assertion error.

The above example is very verbose, simply to illustrate the duck-typed nature of promises. You can do better by usinge.g. when.js:

2.1. Core modules 81

Page 86: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

function someAsyncTestFunction() {var deferred = when.defer();

setTimeout(function () {buster.assert(true);deferred.resolver.resolve();

}, 100);

return deferred.promise;}

Setup and teardown functions can use the same mechanism to be asynchronous.

Setup and teardown

Test cases can have setup and teardown functions. Setup functions are called before every test, and is a suitable placeto put shared setup code:

var testCase = buster.testCase("Test with setup", {setUp: function () {

this.object = { id: 42 };},

"should override id": function () {this.object.id = 43;buster.assert.equals(this.object.id, 43);

},

"id should not equal 43": function () {// The object is recreated in setUp for each testbuster.assert.notEquals(this.object.id, 43);

}});

Similarly, teardown functions can be used to clean up after each test. Keep in mind though, that the test’s this objectis discarded and recreated for each test. If your unit tests are properly isolated you rarely need clean up.

var testCase = buster.testCase("Test with teardown", {tearDown: function () {

if (jQuery.ajax.restore) {jQuery.ajax.restore();

}},

"should make http request": function () {twitter.timeline("cjno", function () {});

buster.assert(jQuery.ajax.calledOnce);}

});

Nested setup and teardown When nesting test cases, you can add setup and teardown methods to some or all ofyour test cases. All applicable setup and teardown methods are called before each test function. Setups are calledstarting from the outermost test case, while tear downs are called starting from the test’s local context. Let’s illustrateby way of an example:

82 Chapter 2. Reference documentation

Page 87: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

var testCase = buster.testCase("Nested setup and teardown call order", {setUp: function () {

console.log("Setup #1");},

tearDown: function () {console.log("Teardown #1");

},

"test #1": function () {console.log("Test #1");

},

"context": {setUp: function () {

console.log("Setup #2");},

"test #2": function () {console.log("Test #2");

},

"context": {setUp: function () {

console.log("Setup #3");},

tearDown: function () {console.log("Teardown #3");

},

"test #3": function () {console.log("Test #3");

}}

}});

Will print:

Setup #1Test #1Teardown #1Setup #1Setup #2Test #2Teardown #1Setup #1Setup #2Setup #3Test #3Teardown #3Teardown #1

Asynchronous setup and teardown Setup and teardown methods are treated as asynchronous by the test runner ifthey either return a thenable promise or if they explicitly accept an argument. See Asynchronous tests.

2.1. Core modules 83

Page 88: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Deferred tests

If you have written a test that for some reason is impossible to pass in the near future, you may grow tired of seeing itfail while working on other parts of the system. Because the test may represent an important goal/requirement (perhapsthe goal of a longer refactoring session) it is undesirable to delete it. Simply commenting out the test may cause youto forget it and commit commented out code, which isn’t very nice.

Buster recognizes the valid use of deferred tests and provides a simple way to defer a test – simply “comment out” itsname, i.e., prefix the name with a pair of //:

var testCase = buster.testCase("Bowling kata tests", {setUp: function () {

this.game = new BowlingGame();

this.rollMany = function (rolls, pins) {for (var i = 0; i < rolls; ++i) {

this.game.roll(pins);}

};},

"gutter game yields 0 in score": function () {this.rollMany(20, 0);

buster.assert.equals(0, this.game.score());},

"// 1 pin on each roll should yield score of 20": function () {this.rollMany(20, 1);

buster.assert.equals(20, this.game.score());}

});

In this example, the second test will not run, but the reporter will include it and explicitly mark it as deferred, helpingyou avoid forgetting about it.

Test contexts

Version: See buster-test

A test context is Buster’s internal test case/specification data format. Specifically, a test context is the kind of objectthat the test runner knows how to run. This document describes the data format in detail - what features it and therunner supports as well as how to create test contexts from external front-ends.

The idea behind test contexts is to separate the syntax you use to write a test case/specification (the front-end) from thetools that run and visualize results of these tests. Test contexts have enabled Buster to ship with two rather differentways of writing tests for the same runner; buster.testCase and buster.spec. They also enable us to provide adapters forother test frameworks, such as in buster-jstestdriver.

If you are looking to run tests written for another testing library with Buster, you have come to the right place. Sup-porting other test frameworks front-ends is a simple matter of converting the objects/functions created by the libraryto a testContext object. For inspiration, see the implementation of the aforementioned buster.testCase, buster.spec andref:buster-jstestdriver.

Note: Test contexts are not intended to be hand-written, rather they represent the data test specification DSLs should

84 Chapter 2. Reference documentation

Page 89: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

produce in order to use the Buster test runner.

testContext object

Represents a test case (xUnit terminology) or a specification (BDD terminology). Contains a set of tests to run,optional setup and teardown methods as well as optional nested contexts. Refer to the example for more informationon how this can be used in practice.

Setup and teardown methods can be asynchronous, see the section on asynchronous tests.

testContext.nameThe test context name/description as a string

testContext.setUpOptional. A function that will run before each test. If using nested contexts, the setup function will also beexecuted before each test (and their local setup, if any) in nested contexts.

testContext.tearDownOptional. A function that will run after each test. If using nested contexts, the teardown function will also beexecuted after each test (and their local teardown, if any) in nested contexts.

testContext.testsAn array of test object.

testContext.contextsAn array of testContext object. In other words, the test context data format (and thus, the Test runner) supportsarbitrarily nested contexts.

testContext.parentThe parent testContext object, if any.

testContext.testCaseOptional. Prototype object used for this when running tests. This object may define helper methods andproperties to use in tests. The test runner creates a new instance from this object with buster.create() foreach test. The created object is shared as this in all setup and teardown methods as well as in the test. If thisobject is not provided, an “empty” object is created and used as this when running tests.

test object

Represents a test function.

test.nameThe test function name, as a string.

test.funcThe test function. See the section on asynchronous tests for how to mark it as - well, asynchronous.

test.contextOptional. The context to which the test belongs.

test.deferredOptional. If this property is set to true, the test will not be run, but the test runner will emit an event for it,allowing reporters to communicate tests that should eventually run (and hopefully pass).

2.1. Core modules 85

Page 90: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Asynchronous tests

There is no flag to mark tests as asynchronous even though the Test runner supports both synchronous and asyn-chronous tests. The reason is that it cannot be determined up-front if a test is asynchronous or not.

To create asynchronous tests (i.e. ones that the runner will wait for), the test function can either explicitly accept asingle argument, which is a function, or return a thenable promise.

The argument passed to the test is a function. When the function is called, the asynchronous test is deemed done. Theidiomatic way of creating asynchronous tests using this arguments looks like the following:

function someAsyncTestFunction(done) {setTimeout(function () {

buster.assert(true);done();

}, 100);}

This assumes that the assertion framework can fail without throwing an error (as an error would be intercepted asuncaught in the above example, if intercepted at all). If this is not the case, you can make your assertions in a callbackto the done function:

function someAsyncTestFunction(done) {setTimeout(function () {

done(function () {buster.assert(true);

});}, 100);

}

Tests can also be made asynchronous by way of returning a promise. The test runner considers any object with a thenmethod a promise:

function someAsyncTestFunction() {var promise = {

then: function (callback) {this.callbacks = this.callbacks || [];this.callbacks.push(callback);

}};

setTimeout(function () {buster.assert(true);var callbacks = promise.callbacks || [];

for (var i = 0, l = callbacks.length; i < l; ++i) {callbacks[i]();

}}, 100);

return promise;}

Note that this does not work entirely as expected unless your assertion framework of choice is able to notify the runnerof failure without throwing an exception. If the assertion fails (and throws an exception), the promise will never beresolved, thus the runner will fail the test with a timeout, not an assertion error.

The above example is very verbose, simply to illustrate the duck-typed nature of promises. You can do better by usinge.g. when.js:

86 Chapter 2. Reference documentation

Page 91: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

function someAsyncTestFunction() {var deferred = when.defer();

setTimeout(function () {buster.assert(true);deferred.resolver.resolve();

}, 100);

return deferred.promise;}

Setup and teardown functions can use the same mechanism to be asynchronous.

Example

Say you have a test case like the following (warning: fictional front-end, this is just to explain what goes where in thegenerated context):

testCase("Circle tests", {createCircle: function (radius) {

return {diameter: function () {

return radius * 2;}

};},

"diameter should equal twice the radius": function () {var circle = this.createCircle(6);

buster.assert.equals(circle.diameter(), 12);}

});

The test case has a single test and a helper method defined on the same object (thus accessed through this in thetest). This simple test case can be represented as a Buster runnable context the following way:

var simpleContext = {name: "Circle tests",

testCase: {createCircle: function (radius) {

return {diameter: function () {

return radius * 2;}

};}

},

tests: [{name: "diameter should equal twice the radius",func: function () {

var circle = this.createCircle(6);

buster.assert.equals(circle.diameter(), 12);}

2.1. Core modules 87

Page 92: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

}]};

The following example is reproduced from the official QUnit docs and shows a fairly typical QUnit test:

test("a basic test example", function () {ok(true, "this test is fine");var value = "hello";equals("hello", value, "We expect value to be hello");

});

module("Module A");

test("first test within module", function () {ok(true, "all pass");

});

test("second test within module", function () {ok(true, "all pass");

});

module("Module B");

test("some other test", function() {expect(2);equals(true, false, "failing test");equals(true, true, "passing test");

});

The corresponding test context would look like:

var qunitContext = {name: "" // Top level module was nameless

tests: [{name: "a basic test example",func: function () {

ok(true, "this test is fine");var value = "hello";equals("hello", value, "We expect value to be hello");

}}],

contexts: [{name: "Module A",

tests: [{name: "first test within module",func: function () {

ok(true, "all pass");}

}, {name: "second test within module",func: function () {

ok(true, "all pass");}

}]}, {

name: "Module B",

88 Chapter 2. Reference documentation

Page 93: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

tests: [{name: "some other test",func: function() {

expect(2);equals(true, false, "failing test");equals(true, true, "passing test");

}}]

}]};

Test runner

Version: See buster-test

Module: require("buster-test").testRunner;

In browsers: buster.testRunner;

Evented test runner for both synchronous and asynchronous tests. The runner itself always executes asynchronously,making it very good at visualizing ongoing progress and helps avoid long running script warnings in browsers.

var testRunner = require("buster-test").testRunner;var xUnitConsoleReporter = require("buster-test").xUnitConsoleReporter;

var runner = testRunner.create();var reporter = xUnitConsoleReporter.create({ color: true });reporter.listen(runner);

runner.runSuite([context, context2, ...]);

Events

suite:start event Signature:

"suite:start", function () {}

Emitted once, as the runner starts running a test suite (typically when testRunner.runSuite() is called).

suite:end event Signature:

"suite:end", function (results) {}

Emitted once, when all contexts are run (typically when testRunner.runSuite() completes).

context:start event Signature:

"context:start", function (context) {}

Emitted every time a testContext object is entered.

context:end event Signature:

2.1. Core modules 89

Page 94: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

"context:end", function (context) {}

Emitted every time a testContext object is completed.

context:unsupported event Signature:

"context:unsupported", function (unsupported) {}

Emitted every time a context fails its requirements (when that happens, neither context:start or context:endare emitted).

test:setUp event Signature:

"test:setUp", function (context) {}

Emitted once per test before the setup method(s) for a test is called.

test:start event Signature:

"test:start", function (context) {}

Emitted after running the test’s setup(s), but before the test itself runs.

test:async event Signature:

"test:async", function (test) {}

Emitted when a test has been found to be asynchronous (usually means that the test function was called and hasreturned).

test:tearDown event Signature:

"test:tearDown", function (test) {}

Emitted once per test before the tear down method(s) for a test is called.

test:failure event Signature:

"test:failure", function (error) {}

Emitted when the test throws (or otherwise flags) an AssertionFailure(). Only emitted once per test.

test:error event Signature:

"test:error", function (error) {}

Emitted when the test throws any error that is not an AssertionFailure(). Only emitted once per test.

test:success event Signature:

"test:success", function (test) {}

Emitted if the test passes.

90 Chapter 2. Reference documentation

Page 95: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

test:timeout event Signature:

"test:timeout", function (test) {}

Emitted if the test runner forcefully aborts the test. This happens when the test is asynchronous and does not resolvewithin the timeout configured by testRunnerOptions.timeout.

test:deferred event Signature:

"test:deferred", function (test) {}

Emitted when a test is marked as deferred. The test is not run.

uncaughtException event Signature:

"uncaughtException", function (exception) {}

Uncaught errors are errors that the test runner is unable to associate with the test that threw it. They occur in twosituations:

• A synchronous test spawns an asynchronous task that results in an error. For instance, calling setTimeout()with a callback that throws an error in a synchronous test.

• An aborted asynchronous test throws (for instance, by failing an assertion).

The "uncaughtException" event will only be emitted when the environment supports it and thehandleUncaughtExceptions property is set to true. Browsers that do not support window.onerror are un-able to support this feature.

Methods

testRunner.create()

var runner = buster.testRunner.create([opts]);

Creates a new test runner instance.

testRunner.onCreate()

buster.testRunner.onCreate(function (runner) {});

Register a callback which is called everytime a runner is created with testRunner.create().

testRunner.runSuite()

runner.runSuite([context, context2, ...]);

Run an array of testContext object as a test suite.

testRunner.run()

runner.run(context);

Run a single testContext object. Note that this method does not trigger the suite:start event, and using it insteadof testRunner.runSuite() may cause unintended behavior in Test reporters.

2.1. Core modules 91

Page 96: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

testRunner.assertionCount()

var count = runner.assertionCount();

The default implementation of this method is a no-op function. This method is called by the runner after eachtest to determine the number of assertions used in the test. It should not accumulate the assertion count.

Because the runner itself has no knowledge of the assertion library, this method is intended to be overridden bythe assertion library in use. For instance, this is the integration necessary to count assertions with referee:

var assertions = 0;

buster.assert.on("pass", function () {assertions += 1;

});

buster.testRunner.onCreate(function (runner) {runner.on("test:start", function () {

assertions = 0;});

});

buster.testRunner.assertionCount = function () {return assertions;

};

testRunner.assertionFailure()

runner.assertionFailure(exception);

Can be called from assertion libraries that do not throw an exception on assertion failure. For assertion failuresto be picked up no matter what in asynchronous tests, this method needs to be called, as some exceptions arenot possible for the runner to catch.

Properties

Test runner properties can be set when creating an instance, or simply by assigning to the property on an existingrunner:

var runner = buster.testRunner.create({timeout: 500

});

// Or:

var runner = buster.testRunner.create();runner.timeout = 500;

testRunnerOptions.failOnNoAssertions:Default: true

When true, a test with no assertions is considered a failure. The number of assertions are measured withtestRunner.assertionCount().

testRunnerOptions.timeoutDefault: 250

92 Chapter 2. Reference documentation

Page 97: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

When an asynchronous test runs for more than timeout ms, the runner will abort it and emit a test:timeoutevent.

testRunnerOptions.handleUncaughtExceptionsDefault: true

When true, the runner will attempt to handle uncaught exceptions, by registering a listener on process for“uncaughtException” (Node.js) and assigning a callback to window.onerror (browsers).

Supporting objects

context object See testContext object.

test object See test object.

results object A high-level numeric report. Emitted with suite:end event:

{contexts: 0,tests: 0,errors: 0,failures: 0,assertions: 0,timeouts: 0,deferred: 0

}

error object An object representing a test failure (or error), emitted with test:failure event and test:error event:

{name: "Name of test",error: {

name: "Type of exception",message: "Exception message",stack: "Stack trace as string"

}}

exception object An exception-like object, emitted with uncaughtException event. In browsers, this object doesnot have a stack trace:

{name: "Type of exception",message: "Exception message",stack: "Stack trace as string"

}

unsupported object Information about an unsupported context. Emitted with context:unsupported event. Con-tains an array of names of failed requirements and a context object:

{context: context,unsupported: ["label1", "label2"]

}

2.1. Core modules 93

Page 98: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Test options

Version: See buster-test

The command buster test accepts the following options:

-h, --helpShow usage help. See also --help reporters.

-l, --log-levelSet logging level. One of error, warn, log, info, debug.

-v, --verboseIncrease verbosity level. Include one (log level info) or two times (e.g. -vv, for log level debug).

-c, --configTest configuration file.

-g, --config-groupTest configuration group(s) to load.

-t, --testsTest files (within active configuration) to run.

-e, --environmentTest configuration environment to load.

-r, --reporterTest output reporter Default is dots.

-C, --colorOutput color scheme. One of dim, bright, none. Default is bright.

-s, --serverHostname and port to a running buster-server instance (for browser tests). Default ishttp://localhost:1111.

-R, --resetDon’t use cached resources on the server.

-W, --warningsWarnings to print. One of fatal, error, warning, all, none. Default is all.

-F, --fail-onFail on warnings at this level. One of fatal, error, warning. Default is fatal.

-L, --log-allLog all messages, including for passed tests.

-o, --release-consoleBy default, Buster captures log messages from console.log() and friends. It does so by replacing theglobal console object with the buster.console object. This option skips this hijacking.

-p, --static-pathsServe files over a static URL on the server. Reusing paths across test runs makes it possible to use breakpoints,but increases the risk of stale resources due to due to the browser caching too eagerly.

2.1.10 evented-logger

Version: 0.2.0 (2011-03-14)

Module: require("evented-logger");

94 Chapter 2. Reference documentation

Page 99: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

In browsers: eventedLogger; / buster.eventedLogger;

A simple evented console logger. In contrast to typical loggers, evented-logger does not print directly to an outputstream. Instead, log messages are emitted as events, decoupling the visualization/persistence of log messages.

evented-logger supports setting a log level to filter messages, logging arbitrary many arguments with one call, cus-tomizable formatting of objects and even custom log level hierarchies.

Events

Event: log

Signature:

"log", function (envelope) {}

Emitted every time data is logged and is allowed by the current log level. Any messages logged to the current level ora higher priority level will be emitted.

The argument to the callback is an Envelope.

Methods

Parts of the logger API is dynamically assembled by the eventedLogger.create() method. The API documen-tation also describes the methods dynamically generated by this method in the default setup.

eventedLogger.create()

create([options]);

Creates a new logger. The default behavior is to create a logger with the levels/methods error, warn, logand debug. "debug" is the default log level, meaning that all messages are emitted.

The options‘ argument can be used to control what logging methods the logger should have, default logginglevel and formatting method. See Options for details on the options object.

Typical usage

var logger = eventedLogger.create();

logger.on("log", function (msg) {console.log("[" + msg.level.toUpperCase() + "] " + msg.message);

});

logger.warn("Watch it!");logger.log([], 42, {});

// Prints the following to stdout:// [WARN] Watch it!// [LOG] [] 42 {}

Setting the default level

var logger = eventedLogger.create({ level: "warn" });

logger.on("log", function (msg) {console.log("[" + msg.level.toUpperCase() + "] " + msg.message);

2.1. Core modules 95

Page 100: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

});

logger.warn("Watch it!");logger.log([], 42, {});

// Will not print the log message, so stdout looks like:// [WARN] Watch it!

Creating custom loggers

Custom levels should be passed ordered from highest to lowest severity. The generated methods will passthrough messages if the current log level is set to either the same level as the message or one in the lowerindexes of the levels array.

When you create a logger with customized levels, the default log level will be set to the most permissive one,i.e. the last level in the array.

var logger = eventedLogger.create({levels: ["nuclear", "eerie", "info", "debug"]

});

logger.level == "debug"; //=> truetypeof logger.error == "undefined";

logger.nuclear("This is NOT good");

If you want the logger to have some other default log level than the most permissive one, include level:

var logger = eventedLogger.create({levels: ["nuclear", "eerie", "info", "debug"],level: "eerie"

});

logger.info("This is NOT good"); // Won't be emitted

logger.format()

format(object);

Formats a logged object. This function is called once for each argument passed to a logger method. The defaultimplementation serializes objects through JSON.stringify. Functions and primitives are converted to strings byway of their toString methods.

The method can be overridden to provide more powerful formatting of objects such as functions and problematichost objects.

buster-test provides more readable formatting through the buster-format module. There is basically three waysto achieve this:

Override the original method

eventedLogger.format = buster.format.ascii;

Override the method on an instance

var logger = eventedLogger.create();logger.format = buster.format.ascii;

Pass the formatter to ‘‘create‘‘

96 Chapter 2. Reference documentation

Page 101: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

var logger = eventedLogger.create({logger: buster.format.ascii

});

logger.error()

logger.error(message1[, message2, ...]);

Logs messages with the "error" level. Messages will always be emitted from the logger unless the log levelhas been set to a non-existent level.

var logger = eventedLogger.create();// ...

logger.error("Something went wrong", myObjToDebug);

Note: If you have created a logger with custom levels, the error method will not exist unless you explicitlyincluded it.

logger.warn()

logger.warn(message1[, message2, ...]);

Logs messages with the "warn" level. This message will be emitted from the logger unless its level is set to"error" or a non-existent level.

var logger = eventedLogger.create();// ...

logger.warn("Something fishy?", myObjToDebug);

Note: If you have created a logger with custom levels, the warn method will not exist unless you explicitlyincluded it.

logger.log()

logger.log(message1[, message2, ...]);

Logs messages with the "log" level. This message will be emitted from the logger if its level is set to "log"or "debug" (default).

var logger = eventedLogger.create();// ...

logger.log("Here's an object", myObjToDebug);

Note: If you have created a logger with custom levels, the log method will not exist unless you explicitlyincluded it.

logger.debug()

2.1. Core modules 97

Page 102: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

logger.debug(message1[, message2, ...]);

Logs messages with the "debug" level. This message will only be emitted from the logger if its level is set to"debug" (default).

var logger = eventedLogger.create();// ...

logger.debug("What's going on??", myObjToDebug);

Note: If you have created a logger with custom levels, the debug method will not exist unless you explicitlyincluded it.

Properties

logger.levelDefault: "debug"

Set the level of the logger, silence all messages for less severe levels. The default level is the most permissiveone – "debug" – when not using custom levels.

Supporting objects

Envelope

An object representing a logged message. Contains two properties:

loggerEnvelope.levelThe log level as a lower case string, e.g. "debug".

loggerEnvelope.messageA formatted log message, containing all arguments passed to the log method joined by a single blank space.

Options

Options passed to eventedLogger.create().

loggerOptions.levelThe default log level, i.e. the minimum required level the logger will emit events for. Default value is "debug",i.e. all messages.

loggerOptions.levelsAn array of levels the logger supports. Default is ["error", "warn", "log", "debug"]. Each stringin this array names methods created on the logger.

loggerOptions.formatterThe function that should format arguments. See logger.format().

2.1.11 posix-argv-parser

Version: 0.1.0 (2012-06-13)

Module: require("posix-argv-parser");

98 Chapter 2. Reference documentation

Page 103: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

An command line interface (CLI) argument parser that is:

• POSIX “Utility Argument Syntax” compliant

• Unobtrusive - Does not mandate flow control, does not print to STDOUT on your behalf, and does not magicallymanage --help

• Ambiguity aware - lets you specify how to handle ambiguities such as -bar, which can mean both -b -a-r and -b=ar.

var pap = require("posix-argv-parser");var args = pap.create();var v = pap.validators;

args.createOption(["-p", "--port"], {// All options are optional

// Implies hasValue: true, which allows parser to read -p2345 as -p=2345defaultValue: 8282,

// Both built-in and custom validations supported,// synchronous as well as asynchronous (promise based)validators: [v.integer("Custom message. ${1} must be a number.")],

// Transforms allow you to get more intelligent values// than raw strings backtransform: function (value) { return parseInt(value, 10); }

});

args.createOption(["-v"], {validators: [function (opt) {

// See also asynchronous validatorsif (opt.timesSet < 1) {

throw new Error("Set " + opt.signature + " at least once!");}

}]});

// Operands are statements without options.// Example: the path in `mything --port=1234 path/to/stuff`args.createOperand("rootPath", {

// Used in error msgssignature: "Presentation root directory",// Both will use default error messagesvalidators: [v.file(), v.required()]

});

posixArgvParser.parse(process.argv.slice(2), function (errors, options) {if (errors) { return console.log(errors[0]); }

// Various useful ways to get the values from the options.options["-v"].timesSet;options["--port"].isSet;// Will be a true number thanks to the transformoptions["--port"].value;options.rootPath.value;

});

2.1. Core modules 99

Page 104: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Methods

posixArgvParser.create()

var args = require("posix-argv-parser").create();

Creates a new instance of posix-argv-parser that holds a collection of options and operands.

posixArgvParser.createOption(flags[, options])

args.createOption(["-h", "--help"]);

Creates a new option. An option has all the properties of an argument, as well as option.hasValueand option.timesSet. The options object is optional.

posixArgvParser.addShorthand(opt[, argv1, ...])A shorthand is a convenience method for adding options to your CLI that simply set other options.

args.createOption("--env", { hasValue: true });args.addShorthand("--dev", ["--env", "dev"]);args.addShorthand("--prod", ["--env", "prod"]);

This makes passing --dev an equlvalent to passing --env dev.

posixArgvParser.createOperand([name][, options])

args.createOperand();

Creates a new operand. An operand has all the properties of an argument, as well as greedy:true|false - i.e. whether or not it will eat many arguments or just one (defaults to false, just one). Thename is optional, and should be a string. The name is used to access the value through the options ob-ject passed to the parse callback. If not provided, it defaults to “OPD” (beware when using more than oneoperand).

posixArgvParser.parse(args, callback)Performs parsing and validation of argv. In Node.JS, make sure to discard the first two items of process.argv, asthey contain unrelated arguments (“node” and the file name).

The callback is called with two arguments, errors, which is either undefined, or an array of errors and/orvalidation messages, and an options object, which is used to retrieve data from configured options.

var args = require("posix-argv-parser").create();args.handle(process.argv.slice(2), function (errors, options) {

if (errors) {// Print an error msg, i.e. console.log(errors[0])return;

}// Continue with normal operation. I.e. options["-v"].hasValue,// options["-v"].timesSet, options["-p"].value, etc.

});

Arguments (options and operands)

Options and operands are the two types of arguments handled by posix-argv-parser, and they share commonfunctionality, listed below this introduction.

100 Chapter 2. Reference documentation

Page 105: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

An option is a flag, with or without a value. -p, -p abc, -pabc, -p=abc, --port abc and --port=abc areall supported by posix-argv-parser.

-pabc can mean both -p -a -b -c and -p=abc. posix-argv-parser uses opt.hasValue to separate the two.With opt.hasValue set to true, -pabc will be handled as -p=abc. When false (default), it will be handled as -p-a -b -c. In that case you also need to have option handlers for -a, -b and -c, or you’ll get a validation error suchas "unknown option -a" (depending on which option posix-argv-parser first encountered that didn’t exist).

An operand is an option-less value, i.e. foo (with no -b or --myopt prefixing it). It’s commonly usedfor arguments that always have to be passed. Examples are nano path/to/file.txt, git checkoutmaster, rmdir my_dir, etc. The validators validators.file(), validators.directory(), andvalidators.fileOrDirectory() are very useful for operands.

Note that the parser can handle a mix and match of options and operands in any order, i.e. mycommand --port1234 my/directory and mycommand my/directory --port 1234 will both work.

Multiple operands will be applied in order of creation. I.e. mycommand something with two operands will assign"something" to the first and undefined to the second, unless the first is greedy, in which case it will receive allthe operand values.

See example usage at the beginning of this document for more information.

When creating options and operands, the following properties can be passed in with the “options” object.

opt.validatorsAn array of validators. A validator is a function that accepts the argument result object as input. See below fora description of argument result objects. To fail validation, the validator can either throw an error, or return arejecting promise.

opt.transformA function that transforms the raw string value provided before assigning it to the opt.value property of anargument result object. The function receives the string value as input, and should return any value back.

opt.hasValueIf the argument takes a value, set to true. Defaults to false for options, is always true for operands (thusit can be omitted).

opt.defaultValueThe default value to use if the argument was not provided. When opt.defaultValue is provided,opt.hasValue is implied and can be omitted. The default value should be a string, and will be validatedand transformed like actual values.

opt.signatureThe signature is used to identify options and operands in validation errors. Options automatically gets a signatureconsisting of the option flags assigned to it:

var opt = args.createOption(["-v", "--version"]);opt.signature; // "-v/--version"opt.signature = "-v"; // custom signature

Specifying a signature is more useful for operands, since an operand doesn’t have any data that it can use to autogenerate a signature (their default signature is “OPD”):

var rootDir = args.createOperand();rootDir.signature; // "OPD", as the default namerootDir.signature = "Root directory";

Options

Options has additional properties that operands doesn’t have.

2.1. Core modules 101

Page 106: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

opt.requiresValueOnly makes sense if opt.hasValue is true. When this property is false, an option can both be providedas a flag with no value or as an option with a value.

A common example of options that work with and without values are help options, that may be provided aloneto get general help, e.g. mything –help, and with values to get help for specific topics, e.g. mything –help bisect.

Argument result

Argument result objects are produced when calling args.parse() to parse argv into the predefined options andoperands. There is one result object per original option/operand. These objects have the following properties:

argumentResult.isSettrue or false depending on whether or not the argument was present in argv.

argumentResult.valueThe value of the argument. Is normally a string, but may be any object if the argument had a transform function.

argumentResult.timesSetThe number of times an argument was set. Useful for options like -v (verbose) which you might want to allowsetting multiple times, giving the user more and more verbose output from your program:

-v // 1-vv // 2-v -v -v -v // 4-v -vv -vv -vvv // 8

Validators

Validators let you add requirements with associated error messages to options and operands.

posix-argv-parser has a number of built-in validators, and creating custom ones is dead simple, as a validator is just afunction.

Built-in validators

The built in validators provides a selection of generic validators. You can customize the error messages by passingstrings with tokens like "${1}" in them. The number and value maps are documented for each validator.

Validators are functions, yet the built-in validators are used by calling them directly with custom error messages. Thisworks because the built-in validators all return the actual validation function.

// Uses built-in error messageposixArgvParser.validators.required();

// Specify your own error messageposixArgvParser.validators.required("${1} has to be set");

validators.required(errorMessage)Fails if the option is not set.

Custom error message:

${1}: The option opt.signature

validators.integer(errorMessage)Will fail validation if the option was not an integer, i.e. "foo" and 42.5.

102 Chapter 2. Reference documentation

Page 107: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Custom error message:

${1}: The specified number

${2}: The option opt.signature

validators.number(errorMessage)Will fail validation if the option was not a number, i.e. "foo" and ?.

Custom error message:

${1}: The specified number

${2}: The option opt.signature

validators.file(errorMessage)Will fail validation if the option was not a path pointing to an existing file in the file system.

Custom error message:

${1}: The specified file

${2}: The option opt.signature

validators.directory(errorMessage)Will fail validation if the option was not a path pointing to an existing directory in the file system.

Custom error message:

${1}: The specified directory

${2}: The option opt.signature

validators.fileOrDirectory(errorMessage)Will fail validation if the option was not a path pointing to an existing file or directory in the file system. Willfail for block devices, sockets, et c.

Custom error message:

${1}: The specified file or directory

${2}: The option opt.signature

Custom validators

A validator is a function that throws an error or returns a promise. If it does not do any of those things, it is immediatelyconsidered passed. The function is passed an argument result object.

args.createOption("-v", {validators: [function (opt) {

if (opt.value == "can not be this value") {throw new Error("This is the error message.");

}}]

});

Promises are used to facilitate asynchronous validators. Here’s an example of a validator that checks if a file is largerthan 1MB:

var when = require("when");args.createOption(["-f"], {

validators: [function (opt) {var deferred = when.defer();fs.stat(opt.value, function (err, stat) {

2.1. Core modules 103

Page 108: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

if (err) { deferred.reject("Unknown error: " + err); }

if (stat.size > 1024) {deferred.reject(opt.value +

" (" + opt.signature + ") was larger than 1MB");} else {

deferred.resolve();}

});return deferred.promise;

}]});

Given --myopt /path/to/file and the file is larger than 1MB, you’ll get the error message"/path/to/file (--myopt) was larger than 1MB".

Rejecting the promise counts as an error. The first argument should be a string, and is the error message. (TODO: Thiswill likely change to an error object with a message property).

Transforms

Transforms can mutate the values of options. A transform is a simple function that receives the raw string value asinput, and can return whatever it likes.:

args.createOption(["-p"], {transform: function (value) { return parseInt(value, 10); }

});

Types

Types are predefined “options” objects that you can pass when creating options and/or operands. For instance, the“number” type includes the number validator, sets opt.hasValue to true, and includes a transform that convertsthe raw string to an actual number (by way of parseFloat):

args.createOption(["-n"], args.types.number());

Note that the type is a function call - it returns the options object. You can pass in additional options. The followingexample piggy-backs the number type to create an option that only takes positive numbers:

args.createOption(["-n"], args.types.number({validators: [function (opt) {

if (parseFloat(opt.value) < 0) {throw new Error("Oh noes, negative number!");

}}]

}));

Providing --help

It’s not in the nature of posix-argv-parser to automatically handle --help for you. It is however very easy to addsuch an option to your program. To help you keep all CLI option data in one place, options and operands are allowedto have a opt.description property that posix-argv-parser does not care about:

104 Chapter 2. Reference documentation

Page 109: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

var args = require("posix-argv-parser").create();

args.createOption(["--port"], {defaultValue: 1234description: "The port to start the server on."

});

args.createOption(["-v"], {description: "Level of detail in output. " +

"Pass multiple times (i.e. -vvv) for more output."});

args.createOption(["--help", "-h"], { description: "Show this text" });help.helpText = "Show this text";

args.parse(process.argv.slice(2), function (errors, options) {if (errors) { return console.log(errors[0]); }

if (options["-h"].isSet) {args.options.forEach(function (opt) {

console.log(opt.signature + ": " + opt.description);});

} else {// Proceed with normal program operation

}});

2.1.12 prefsink

Version: 0.2.0 (2012-05-07)

Module: require("prefsink");

Manage user-provided preferences for your Node programs through a file in the user’s home directory, environmentvariables and default values.

var prefsink = require("prefsink");

// Assume ~/.buster contains// module.exports = {// reporter: "specification"// };

prefsink.load("buster", function (err, prefs) {if (err) { throw err; }

prefs.get("reporter", "dots"); //=> "specification"prefs.get("logLevel", "warn"); //=> "warn"process.env.BUSTER_LOG_LEVEL = "info"prefs.get("logLevel", "warn"); //=> "info"

});

Preference modules

2.1. Core modules 105

Page 110: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

prefsink.load("myproject", function (err, prefs) {/* ... */

});

Prefsink will use the first available of the following files (~/ denotes ‘home directory’, which on Windows means thedirectory specified by USERPROFILE):

1. ~/.myproject.d/index.js (lets the user organize all related files in one directory)

2. ~/.myproject.js (the suffix may be useful for editor syntax highlighting etc)

3. ~/.myproject (iconic Unix style preference file)

Prefsink expects the settings file to be a node module that can be require‘d.

If you want Prefsink to look for other files, or with a different ordering, just set prefsink.locations to an arrayof desired paths. The array should contain full paths, optionally with "{namespace}" which will be replaced withthe namespace.

Preference property lookup

prefs.get("id", 42);

Given one of those modules, Prefsink uses the following property lookup:

1. Does the preference module export id? Use that

2. Is process.env.MYPROJECT_ID set? Use that

3. Otherwise, use the default (42 in the above example)

Properties

prefsink.homeString, contains the path to where Prefsink thinks the user’s home directory is.

prefsink.locationsArray of strings. The locations Prefsink will attempt to load, in preferred order. Default value is:

exports.locations = [Path.join(exports.home, ".{namespace}.d", "index.js"),Path.join(exports.home, ".{namespace}.js"),Path.join(exports.home, ".{namespace}")

];

Methods

prefsink.findFile()

prefsink.findFile(namespace, callback(err, fileName));

Finds the filename for the preferred preference module according to the lookup described above. Yields nullif none of the files are available. The error object is currently not being used as any error will simply result in anull file name.

prefsink.findFileSync()

106 Chapter 2. Reference documentation

Page 111: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

prefsink.findFileSync(namespace);

Blocking version of findFile.

prefsink.create()

var prefsJar = prefsink.create(namespace[, prefs[, source]]);

Creates a preference “jar” (see API below).

namespace: A string, typically the name of your project, like “buster”. It will be used to find environmentvariables relevant to your preferences.

prefs: An object with properties. When asking the preference jar for properties, properties on this object willbe preferred.

source: A string that reveals which source prefs were loaded from. It’s simply exposed asprefsJar.source.

prefsink.load()

prefsink.load(namespace, callback(err, prefsJar));

Figures out which file to use, loads its contents and creates a preference jar that is passed to the callback. Theerror object is used when require-ing the preference file fails (i.e. when the file exists but is not loadable).

prefsink.loadSync()

prefsink.loadSync(namespace);

Blocking version of load.

Preference jar

prefJar.namespaceThe corresponding string passed in as argument to create

prefJar.sourceThe corresponding string passed in as argument to create

prefJar.get()

prefJar.get(name[, defaultVal]);

Returns the named property according to the property lookup described above. Dashes and spaces are convertedto underscores when trying environment variables, e.g. get("something-nice") will try the environmentvariable MYPROJECT_SOMETHING_NICE. Camel cased properties will map to underscored and upper casedenvironment variables.

2.1.13 referee

Module: require("referee");

In browsers: buster.referee;

2.1. Core modules 107

Page 112: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

A collection of assertions to be used with a unit testing framework. referee works well with any CommonJS complianttesting framework out of the box, and can easily be configured to work with most any testing framework. See alsoExpectations if you like the alternative API (expect(thing).toBe*).

referee contains lots of assertions. We strongly believe that high-level assertions are essential in the interest of pro-ducing clear and intent-revealing tests, and they also give you to-the-point failure messages.

Assertions and refutations

Unlike most assertion libraries, referee does not have assert.notXyz assertions to refute some fact. Instead, ithas refutations, heavily inspired by Ruby’s minitest:

var assert = buster.referee.assert; // or short: buster.assertvar refute = buster.referee.refute; // or short: buster.refute

assert.equals(42, 42);refute.equals(42, 43);

Refutations help express “assert not ...” style verification in a much clearer way. It also brings with it a nice consistencyin that any assert.xyz always has a corresponding refute.xyz that does the opposite check.

assert()

assert(actual[, message]);

Fails if actual is falsy (0, "", null, undefined, NaN). Fails with either the provided message or “Expectednull to be truthy”. This behavior differs from all other assertions, which prepend the optional message argument.

assert({ not: "Falsy" }, "This will pass");assert(null, "This will fail"); // Fails with custom messageassert(null); // Failsassert(34); // Passes

refute()

refute(actual[, message])

Fails if actual is truthy. Fails with either the provided message or “Expected null to be falsy”. This behaviordiffers from all other refutations, which prepend the optional message argument.

refute({ not: "Falsy" }, "This will fail"); // Fails with custom messagerefute(null, "This will pass");refute(null); // Passesrefute(34); // Fails

Predefined Assertions

The following assertions can be used with assert and refute. They are described for assert, but the corre-sponding failure messages for refute are also mentioned. For refute the behaviour is exactly opposed.

All assertions support an optional message argument, which is prepended to the failure message.

Overview:

• same()

• equals()

108 Chapter 2. Reference documentation

Page 113: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

• greater()

• less()

• defined()

• isNull()

• match()

• isObject()

• isFunction()

• isTrue()

• isFalse()

• isString()

• isBoolean()

• isNumber()

• isNaN()

• isArray()

• isArrayLike()

• exception()

• near()

• hasPrototype()

• contains()

• tagName()

• className()

same()

assert.same(actual, expected[, message])

Fails if actual is not the same object (===) as expected. To compare similar objects, such as {name: "Chris", id: 42 } and { id: 42, name: "Chris" } (not the same instance), seeequals().

var obj = { id: 42, name: "Chris" };assert.same(obj, obj); // Passesassert.same(obj, { id: 42, name: "Chris" }); // Fails

Messages

assert.same.message = "${actual} expected to be the same object as ${expected}";refute.same.message = "${actual} expected not to be the same object as ${expected}";

equals()

assert.equals(actual, expected[, message])

2.1. Core modules 109

Page 114: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Compares actual to expected property by property. If the property count does not match, or if any ofactual‘s properties does not match the corresponding property in expected, the assertion fails. Objectproperties are verified recursively.

If actual is null or undefined, an exact match is required. Date objects are compared by their getTimemethod. Regular expressions are compared by their string representations. Primitives are compared using ==,i.e., with coercion.

equals passes when comparing an arguments object to an array if the both contain the same elements.

assert.equals({ name: "Professor Chaos" }, { name: "Professor Chaos" }); // Passesassert.equals({ name: "Professor Chaos" }, { name: "Dr Evil" }); // Fails

Messages

assert.equals.message = "${actual} expected to be equal to ${expected}";refute.equals.message = "${actual} expected not to be equal to ${expected}";

greater()

assert.greater(actual, expected[, message])

Fails if actual is equal to or less than expected.

assert.greater(2, 1); // Passesassert.greater(1, 1); // Failsassert.greater(1, 2); // Fails

Messages

assert.greater.message = "Expected ${actual} to be greater than ${expected}";refute.greater.message = "Expected ${actual} to be less than or equal to ${expected}";

less()

assert.less(actual, expected[, message])

Fails if actual is equal to or greater than expected.

assert.less(1, 2); // Passesassert.less(1, 1); // Failsassert.less(2, 1); // Fails

Messages

assert.less.message = "Expected ${actual} to be less than ${expected}";refute.less.message = "Expected ${actual} to be greater than or equal to ${expected}";

defined()

assert.defined(object[, message])

Fails if object is undefined.

var a;assert.defined({}); // Passesassert.defined(a); // Fails

Messages

110 Chapter 2. Reference documentation

Page 115: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

assert.defined.message = "Expected to be defined";refute.defined.message = "Expected ${actual} (${actualType}) not to be defined";

${actualType}: typeof object

isNull()

assert.isNull(object[, message])

Fails if object is not null.

assert.isNull(null, "This will pass");assert.isNull({}, "This will fail");assert.isNull(null); // Passesassert.isNull({}); // Fails

Messages

assert.isNull.message = "Expected ${actual} to be null";refute.isNull.message = "Expected not to be null";

match()

assert.match(actual, matcher[, message])

Fails if matcher is not a partial match for actual. Accepts a wide range of input combinations.Note that assert.match is not symmetric - in some cases assert.match(a, b) may pass whileassert.match(b, a) fails.

String matcher

In its simplest form, assert.match performs a case insensitive substring match. When the matcher is astring, the actual object is converted to a string, and the assertion passes if actual is a case-insensitivesubstring of expected as a string.

assert.match("Give me something", "Give"); // Passesassert.match("Give me something", "sumptn"); // Failsassert.match({ toString: function () { return "yeah"; } }, "Yeah!"); // Passes

The last example is not symmetric. When the matcher is a string, the actual value is coerced to a string - in thiscase using toString. Changing the order of the arguments would cause the matcher to be an object, in whichcase different rules apply (see below).

Boolean matcher

Performs a strict (i.e. ===) match with the object. So, only true matches true, and only false matchesfalse.

Regular expression matcher

When the matcher is a regular expression, the assertion will pass if expected.test(actual) is true.assert.match is written in a generic way, so any object with a test method will be used as a matcher thisway.

assert.match("Give me something", /^[a-z\s]$/i); // Passesassert.match("Give me something", /[0-9]/); // Failsassert.match({ toString: function () { return "yeah!"; } }, /yeah/); // Passesassert.match(234, /[a-z]/); // Fails

2.1. Core modules 111

Page 116: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Number matcher

When the matcher is a number, the assertion will pass if matcher == actual.

assert.match("123", 123); // Passesassert.match("Give me something", 425); // Failsassert.match({ toString: function () { return "42"; } }, 42); // Passesassert.match(234, 1234); // Fails

Function matcher

When the matcher is a function, it is called with actual as its only argument. The assertion will pass if thefunction returns true. A strict match is performed against the return value, so a boolean true is required,truthy is not enough.

// Passesassert.match("123", function (exp) {

return exp == "123";});

// Failsassert.match("Give me something", function () {

return "ok";});

// Passesassert.match({

toString: function () {return "42";

}}, function () { return true; });

// Failsassert.match(234, function () {});

Object matcher

As mentioned above, if an object matcher defines a test method the assertion will pass ifmatcher.test(actual) returns truthy. If the object does not have a test method, a recursive matchis performed. If all properties of matcher matches corresponding properties in actual, the assertion passes.Note that the object matcher does not care if the number of properties in the two objects are the same - only ifall properties in the matcher recursively “matches” ones in the actual object.

// Passesassert.match("123", {

test: function (arg) {return arg == 123;

}});

// Failsassert.match({}, { prop: 42 });

// Passesassert.match({

name: "Chris",profession: "Programmer"

}, {name: "Chris"

});

112 Chapter 2. Reference documentation

Page 117: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

// Failsassert.match(234, {

name: "Chris"});

DOM elements

assert.match can be very helpful when asserting on DOM elements, because it allows you to compareseveral properties with one assertion:

var el = document.getElementById("myEl");

assert.match(el, {tagName: "h2",className: "item",innerHTML: "Howdy"

});

Messages

assert.match.exceptionMessage = "${exceptionMessage}";refute.match.exceptionMessage = "${exceptionMessage}";

Used when the matcher function throws an exception. This happens if the matcher is not any of the acceptedtypes, for instance, a boolean.

assert.match.message = "${actual} expected to match ${expected}";refute.match.message = "${actual} expected not to match ${expected}";

isObject()

assert.isObject(object[, message])

Fails if object is not an object or if it is null.

assert.isObject({}); // Passesassert.isObject(42); // Failsassert.isObject([1, 2, 3]); // Passesassert.isObject(function () {}); // Fails

Messages

assert.isObject.message = "${actual} (${actualType}) expected to be object and not null";refute.isObject.message = "${actual} expected to be null or not an object";

${actualType}: typeof object

isFunction()

assert.isFunction(actual[, message])

Fails if actual is not a function.

assert.isFunction({}); // Failsassert.isFunction(42); // Failsassert.isFunction(function () {}); // Passes

2.1. Core modules 113

Page 118: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Messages

assert.isFunction.message = "${actual} (${actualType}) expected to be function";refute.isFunction.message = "${actual} expected not to be function";

${actualType} typeof actual value

isTrue()

assert.isTrue(actual[, message])

Fails if actual is not true.

assert.isTrue("2" == 2); // Passesassert.isTrue("2" === 2); // Fails

Messages

assert.isTrue.message = "Expected ${actual} to be true";refute.isTrue.message = "Expected ${actual} to not be true";

isFalse()

assert.isFalse(actual[, message])

Fails if actual is not false.

assert.isFalse("2" === 2); // Passesassert.isFalse("2" == 2); // Fails

Messages

assert.isFalse.message = "Expected ${actual} to be false";refute.isFalse.message = "Expected ${actual} to not be false";

isString()

assert.isString(actual[, message])

Fails if the type of actual is not "string".

assert.isString("2"); // Passesassert.isString(2); // Fails

Messages

assert.isString.message = "Expected ${actual} (${actualType}) to be string";refute.isString.message = "Expected ${actual} not to be string";

${actualType}: The type of the actual value

isBoolean()

assert.isBoolean(actual[, message])

Fails if the type of actual is not "boolean".

114 Chapter 2. Reference documentation

Page 119: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

assert.isBoolean(true); // Passesassert.isBoolean(2 < 2); // Passesassert.isBoolean("true"); // Fails

Messages

assert.isBoolean.message = "Expected ${actual} (${actualType}) to be boolean";refute.isBoolean.message = "Expected ${actual} not to be boolean";

${actualType}: The type of the actual value

isNumber()

assert.isNumber(actual[, message])

Fails if the type of actual is not "number" or is NaN.

assert.isNumber(12); // Passesassert.isNumber("12"); // Failsassert.isNumber(NaN); // Fails

Messages

assert.isNumber.message = "Expected ${actual} (${actualType}) to be a non-NaN number";refute.isNumber.message = "Expected ${actual} to be NaN or a non-number value";

${actualType}: The type of the actual value

isNaN()

assert.isNaN(actual[, message])

Fails if actual is not NaN. Does not perform coercion in contrast to the standard javascript function isNaN.

assert.isNaN(NaN); // Passesassert.isNaN("abc" / "def"); // Passesassert.isNaN(12); // Failsassert.isNaN({}); // Fails, would pass for standard javascript function isNaN

Messages

assert.isNaN.message = "Expected ${actual} to be NaN";refute.isNaN.message = "Expected not to be NaN";

isArray()

assert.isArray(actual[, message])

Fails if the object type of actual is not Array.

assert.isArray([1, 2, 3]); // Passesassert.isArray({}); // Fails

Messages

2.1. Core modules 115

Page 120: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

assert.isArray.message = "Expected ${actual} to be array";refute.isArray.message = "Expected ${actual} not to be array";

isArrayLike()

assert.isArrayLike(actual[, message])

Fails if none of the following conditions is fulfilled:

•the object type of actual is Array

•actual is an arguments object

•actual is an object providing a property length of type "number" and a property splice of type"function"

assert.isArrayLike([1, 2, 3]); // Passesassert.isArrayLike(arguments); // Passesassert.isArrayLike({ length: 0, splice: function() {} }); // Passesassert.isArrayLike({}); // Fails

Messages

assert.isArrayLike.message = "Expected ${actual} to be array like";refute.isArrayLike.message = "Expected ${actual} not to be array like";

keys()

assert.keys(object, keyArray[, message])

Fails if object’s own properties are not exactly the same as a given list.

assert.keys({ test1: 't1', test2: 't2' }, ['test1']); // Fails - 'test2' is unexpectedassert.keys({ test1: 't1', test2: 't2' }, ['test1','test2','test3']); // Fails - 'test3' is not presentassert.keys({ test1: 't1', test2: 't2' }, ['test1','test2']); // Passes

Messages

assert.keys.message = "Expected ${actualObject} to have exact keys ${keys}";refute.keys.message = "Expected not to have exact keys ${keys}";

exception()

assert.exception(callback[, matcher, message])

Fails if callback does not throw an exception. If the optional matcher is provided, the assertion fails ifthe callback either does not throw an exception, or if the exception does not meet the criterias of the givenmatcher.

The matcher can be of type object or function. If the matcher is of type object, the captured errorobject and the matcher are passed to match().

If the matcher is of type function, the captured error object is passed as argument to the matcher func-tion, which has to return true for a matching error object, otherwise false.

// Passesassert.exception(function () {

throw new Error("Ooops!");});

116 Chapter 2. Reference documentation

Page 121: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

// Failsassert.exception(function () {});

// Passesassert.exception(function () {

throw new TypeError("Ooops!");}, { name: "TypeError" });

// Fails, wrong exception typeassert.exception(function () {

throw new Error("Aww");}, { name: "TypeError" });

// Fails, wrong exception messageassert.exception(function () {

throw new Error("Aww");}, { message: "Ooops!" });

// Fails, wrong exception typeassert.exception(function () {

throw new Error("Aww");}, function (err) {

if (err.name !== "TypeError") {return false;

}return true;

}, "Type of exception is wrong!"); // with message to print, if test fails

Messages

assert.exception.typeNoExceptionMessage = "Expected ${expected} but no exception was thrown";assert.exception.message = "Expected exception";assert.exception.typeFailMessage = "Expected ${expected} but threw ${actualExceptionType} (${actualExceptionMessage})\n${actualExceptionStack}";assert.exception.matchFailMessage = "Expected thrown ${actualExceptionType} (${actualExceptionMessage}) to pass matcher function";refute.exception.message = "Expected not to throw but threw ${actualExceptionType} (${actualExceptionMessage})";

near()

assert.near(actual, expected, delta[, message])

Fails if the difference between actual and expected is greater than delta.

assert.near(10.3, 10, 0.5); // Passesassert.near(10.5, 10, 0.5); // Passesassert.near(10.6, 10, 0.5); // Fails

Messages

assert.near.message = "Expected ${actual} to be equal to ${expected} +/- ${delta}";refute.near.message = "Expected ${actual} not to be equal to ${expected} +/- ${delta}";

hasPrototype()

assert.hasPrototype(actual, prototype[, message])

Fails if prototype does not exist in the prototype chain of actual.

2.1. Core modules 117

Page 122: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

assert.hasPrototype(function() {}, Function.prototype); // Passesassert.hasPrototype(function() {}, Object.prototype); // Passesassert.hasPrototype({}, Function.prototype); // Fails

Messages

assert.hasPrototype.message = "Expected ${actual} to have ${expected} on its prototype chain";refute.hasPrototype.message = "Expected ${actual} not to have ${expected} on its prototype chain";

${expected}: The prototype object

contains()

assert.contains(haystack, needle[, message])

Fails if the array like object haystack does not contain the needle object.

assert.contains([1, 2, 3], 2); // Passesassert.contains([1, 2, 3], 4); // Failsassert.contains([1, 2, 3], "2"); // Fails

Messages

assert.contains.message = "Expected [${actual}] to contain ${expected}";refute.contains.message = "Expected [${actual}] not to contain ${expected}";

${actual}: The haystack object

${expected}: The needle object

tagName()

assert.tagName(element, tagName[, message])

Fails if the element either does not specify a tagName property, or if its value is not a case-insensitive matchwith the expected tagName. Works with any object.

assert.tagName(document.createElement("p"), "p"); // Passesassert.tagName(document.createElement("h2"), "H2"); // Passesassert.tagName(document.createElement("p"), "li"); // Fails

Messages

assert.tagName.noTagNameMessage = "Expected ${actualElement} to have tagName property";assert.tagName.message = "Expected tagName to be ${expected} but was ${actual}";refute.tagName.noTagNameMessage = "Expected ${actualElement} to have tagName property";refute.tagName.refuteMessage = "Expected tagName not to be ${actual}";

className()

assert.className(element, className[, message])

Fails if the element either does not specify a className property, or if its value is not a space-separated listof all class names in classNames.

118 Chapter 2. Reference documentation

Page 123: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

classNames can be either a space-delimited string or an array of class names. Every class specified byclassNames must be found in the object’s className property for the assertion to pass, but order does notmatter.

var el = document.createElement("p");el.className = "feed item blog-post";

assert.className(el, "item"); // Passesassert.className(el, "news"); // Failsassert.className(el, "blog-post feed"); // Passesassert.className(el, "feed items"); // Fails, "items" is not a matchassert.className(el, ["item", "feed"]); // Passes

Messages

assert.className.noClassNameMessage = "Expected object to have className property";assert.className.message = "Expected object's className to include ${expected} but was ${actual}";refute.className.noClassNameMessage = "Expected object to have className property";refute.className.message = "Expected object's className not to include ${expected}";

Custom assertions

Custom, domain-specific assertions helps improve clarity and reveal intent in tests. They also facilitate much betterfeedback when they fail. You can add custom assertions that behave exactly like the built-in ones (i.e. with counting,message formatting, expectations and more) by using the referee.add() method.

Overriding assertion messages

The default assertion messages can be overridden. The messages to overwrite are listed with each assertion. You canuse the same keys for string interpolation (e.g. ${actual}, ${expected}). equals():

var assert = buster.referee.assert;assert.equals.message = "I wanted ${actual} == ${expected}!"

try {assert.equals(3, 4);

} catch (e) {console.log(e.message);

}

// Prints:// "I wanted 3 == 4!"

Events

buster.referee is an Event emitter. Listen to events with on:

buster.referee.on("failure", function (err) {console.log(err.message);

});

pass event

Signature:

2.1. Core modules 119

Page 124: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

"pass", function () {}

Assertion passed. The callback is invoked with the assertion name, e.g. "equals", as its only argument. Note thatthis event is also emitted when refutations pass.

failure event

Signature:

"failure", function (error) {}

Assertion failed. The callback is invoked with an AssertionError() object.

Stubs and spies

The default Buster.JS bundle comes with built-in spies, stubs and mocks provided by Sinon.JS. The assertions areindisposable when working with spies and stubs. However, note that these assertions are technically provided by theintegration package buster-sinon, not referee. This only matters if you use this package stand-alone.

As for the normal assertions, the assertions for stubs and spies can be used with assert and refute. The descriptionis for assert, but the corresponding failure messages for refute are also mentioned. For refute the behaviouris exactly opposed.

Overview:

• called()

• callOrder()

• calledOnce()

• calledTwice()

• calledThrice()

• calledOn()

• alwaysCalledOn()

• calledWith()

• alwaysCalledWith()

• calledOnceWith()

• calledWithExactly()

• alwaysCalledWithExactly()

• threw()

• alwaysThrew()

called()

assert.called(spy)

Fails if the spy has never been called.

120 Chapter 2. Reference documentation

Page 125: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

var spy = this.spy();

assert.called(spy); // Fails

spy();assert.called(spy); // Passes

spy();assert.called(spy); // Passes

Messages

assert.called.message = "Expected ${0} to be called at least once but was never called";

${0}: The spy

refute.called.message = "Expected ${0} to not be called but was called ${1}${2}";

${0}: The spy

${1}: The number of calls as a string. Ex: “two times”.

${2}: All calls formatted as a multi-line string.

callOrder()

assert.callOrder(spy, spy2, ...)

Fails if the spies were not called in the specified order.

var spy1 = this.spy();var spy2 = this.spy();var spy3 = this.spy();

spy1();spy2();spy3();

assert.callOrder(spy1, spy3, spy2); // Failsassert.callOrder(spy1, spy2, spy3); // Passes

Messages

assert.callOrder.message = "Expected ${expected} to be called in order but were called as ${actual}";refute.callOrder.message = "Expected ${expected} not to be called in order";

${expected}: A string representation of the expected call order

${actual}: A string representation of the actual call order

calledOnce()

assert.calledOnce(spy)

Fails if the spy has never been called or if it was called more than once.

2.1. Core modules 121

Page 126: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

var spy = this.spy();

assert.calledOnce(spy); // Fails

spy();assert.calledOnce(spy); // Passes

spy();assert.calledOnce(spy); // Fails

Messages

assert.calledOnce.message = "Expected ${0} to be called once but was called ${1}${2}";refute.calledOnce.message = "Expected ${0} to not be called exactly once${2}";

${0}: The spy

${1}: The number of calls, as a string. Ex: “two times”

${2}: The call log. All calls as a string. Each line is one call and includes passed arguments, returned valueand more.

calledTwice()

assert.calledTwice(spy)

Only passes if the spy was called exactly two times.

var spy = this.spy();

assert.calledTwice(spy); // Fails

spy();assert.calledTwice(spy); // Fails

spy();assert.calledTwice(spy); // Passes

spy();assert.calledTwice(spy); // Fails

Messages

assert.calledTwice.message = "Expected ${0} to be called twice but was called ${1}${2}";refute.calledTwice.message = "Expected ${0} to not be called exactly twice${2}";

${0}: The spy

${1}: The number of calls, as a string. Ex: “two times”

${2}: The call log. All calls as a string. Each line is one call and includes passed arguments, returned valueand more.

calledThrice()

assert.calledThrice(spy)

122 Chapter 2. Reference documentation

Page 127: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Only passes if the spy has been called exactly three times.

var spy = this.spy();

assert.calledThrice(spy); // Fails

spy();assert.calledThrice(spy); // Fails

spy();assert.calledThrice(spy); // Passes

spy();assert.calledThrice(spy); // Fails

Messages

assert.calledThrice.message = "Expected ${0} to be called thrice but was called ${1}${2}";refute.calledThrice.message = "Expected ${0} to not be called exactly thrice${2}";

${0}: The spy

${1}: The number of calls, as a string. Ex: “two times”

${2}: The call log. All calls as a string. Each line is one call and includes passed arguments, returned valueand more.

calledOn()

assert.calledOn(spy, obj)

Passes if the spy was called at least once with obj as its this value.

var spy = this.spy();var obj1 = {};var obj2 = {};var obj3 = {};

spy.call(obj2);spy.call(obj3);

assert.calledOn(spy, obj1); // Failsassert.calledOn(spy, obj2); // Passesassert.calledOn(spy, obj3); // Passes

Messages

assert.calledOn.message = "Expected ${0} to be called with ${1} as this but was called on ${2}";refute.calledOn.message = "Expected ${0} not to be called with ${1} as this";

${0}: The spy

${1}: The object obj which is expected to have been this at least once

${2}: List of objects which actually have been this

alwaysCalledOn()

2.1. Core modules 123

Page 128: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

assert.alwaysCalledOn(spy, obj)

Passes if the spy was always called with obj as its this value.

var spy1 = this.spy();var spy2 = this.spy();var obj1 = {};var obj2 = {};

spy1.call(obj1);spy1.call(obj2);

spy2.call(obj2);spy2.call(obj2);

assert.alwaysCalledOn(spy1, obj1); // Failsassert.alwaysCalledOn(spy1, obj2); // Failsassert.alwaysCalledOn(spy2, obj1); // Failsassert.alwaysCalledOn(spy2, obj2); // Passes

Messages

assert.alwaysCalledOn.message = "Expected ${0} to always be called with ${1} as this but was called on ${2}";refute.alwaysCalledOn.message = "Expected ${0} not to always be called with ${1} as this";

${0}: The spy

${1}: The object obj which is expected always to have been this

${2}: List of objects which actually have been this

calledWith()

assert.calledWith(spy, arg1, arg2, ...)

Passes if the spy was called at least once with the specified arguments. Other arguments may have been passedafter the specified ones.

var spy = this.spy();var arr = [1, 2, 3];spy(12);spy(42, 13);spy("Hey", arr, 2);

assert.calledWith(spy, 12); // Passesassert.calledWith(spy, "Hey"); // Passesassert.calledWith(spy, "Hey", 12); // Failsassert.calledWith(spy, "Hey", arr); // Passes

Messages

assert.calledWith.message = "Expected ${0} to be called with arguments ${1}${2}";refute.calledWith.message = "Expected ${0} not to be called with arguments ${1}${2}";

${0}: The spy

${1}: The expected arguments

${2}: String representation of all calls.

124 Chapter 2. Reference documentation

Page 129: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

alwaysCalledWith()

assert.alwaysCalledWith(spy, arg1, arg2, ...)

Passes if the spy was always called with the specified arguments. Other arguments may have been passed afterthe specified ones.

var spy = this.spy();var arr = [1, 2, 3];spy("Hey", arr, 12);spy("Hey", arr, 13);

assert.alwaysCalledWith(spy, "Hey"); // Passesassert.alwaysCalledWith(spy, "Hey", arr); // Passesassert.alwaysCalledWith(spy, "Hey", arr, 12); // Fails

Messages

assert.alwaysCalledWith.message = "Expected ${0} to always be called with arguments ${1}${2}";refute.alwaysCalledWith.message = "Expected ${0} not to always be called with arguments${1}${2}";

${0}: The spy

${1}: The expected arguments

${2}: String representation of all calls.

calledOnceWith()

assert.calledOnceWith(spy, arg1, arg2, ...)

Passes if the spy was called exactly once and with the specified arguments. Other arguments may have beenpassed after the specified ones.

var spy = this.spy();var arr = [1, 2, 3];spy(12);

assert.calledOnceWith(spy, 12); // Passesassert.calledOnceWith(spy, 42); // Fails

spy(42, 13);assert.calledOnceWith(spy, 42, 13); // Fails

Messages

assert.calledOnceWith.message = "Expected ${0} to be called once with arguments ${1}${2}";refute.calledOnceWith.message = "Expected ${0} not to be called once with arguments ${1}${2}";

${0}: The spy

${1}: The expected arguments

${2}: String representation of all calls.

calledWithExactly()

2.1. Core modules 125

Page 130: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

assert.calledWithExactly(spy, arg1, arg2, ...)

Passes if the spy was called at least once with exact the arguments specified.

var spy = this.spy();var arr = [1, 2, 3];spy("Hey", arr, 12);spy("Hey", arr, 13);

assert.calledWithExactly(spy, "Hey", arr, 12); // Passesassert.calledWithExactly(spy, "Hey", arr, 13); // Passesassert.calledWithExactly(spy, "Hey", arr); // Failsassert.calledWithExactly(spy, "Hey"); // Fails

Messages

assert.calledWithExactly.message = "Expected ${0} to be called with exact arguments ${1}${2}";refute.calledWithExactly.message = "Expected ${0} not to be called with exact arguments${1}${2}";

${0}: The spy

${1}: The expected arguments

${2}: String representation of all calls.

alwaysCalledWithExactly()

assert.alwaysCalledWithExactly(spy, arg1, arg2, ...)

Passes if the spy was always called with exact the arguments specified.

var spy = this.spy();var arr = [1, 2, 3];spy("Hey", arr, 12);

assert.alwaysCalledWithExactly(spy, "Hey", arr, 12); // Passesassert.alwaysCalledWithExactly(spy, "Hey", arr); // Failsassert.alwaysCalledWithExactly(spy, "Hey"); // Fails

spy("Hey", arr, 13);assert.alwaysCalledWithExactly(spy, "Hey", arr, 12); // Fails

Messages

assert.alwaysCalledWithExactly.message = "Expected ${0} to always be called with exact arguments ${1}${2}";refute.alwaysCalledWithExactly.message = "Expected ${0} not to always be called with exact arguments${1}${2}";

${0}: The spy

${1}: The expected arguments

${2}: String representation of all calls.

threw()

assert.threw(spy[, exception])

126 Chapter 2. Reference documentation

Page 131: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Passes if the spy threw at least once the specified exception. The exception can be a string denotingits type, or an actual object. If exception is not specified, the assertion passes if the spy ever threw anyexception.

var exception1 = new TypeError(); var exception2 = new TypeError(); var exception3 = new TypeError(); varspy = this.spy(function(exception) {

throw exception;

}); function callAndCatchException(spy, exception) {

try { spy(exception);

} catch(e) { }

}

callAndCatchException(spy, exception1); callAndCatchException(spy, exception2);

assert.threw(spy); // Passes assert.threw(spy, “TypeError”); // Passes assert.threw(spy, exception1); // Passesassert.threw(spy, exception2); // Passes assert.threw(spy, exception3); // Fails

callAndCatchException(spy, exception3); assert.threw(spy, exception3); // Passes

Messages

assert.threw.message = "Expected ${0} to throw an exception${1}";refute.threw.message = "Expected ${0} not to throw an exception${1}";

${0}: The spy

${1}: The expected exception

alwaysThrew()

assert.alwaysThrew(spy[, exception])

Passes if the spy always threw the specified exception. The exception can be a string denoting its type,or an actual object. If exception is not specified, the assertion passes if the spy ever threw any exception.

var exception1 = new TypeError(); var exception2 = new TypeError(); var spy = this.spy(function(exception) {

throw exception;

}); function callAndCatchException(spy, exception) {

try { spy(exception);

} catch(e) { }

}

callAndCatchException(spy, exception1);

assert.alwaysThrew(spy); // Passes assert.alwaysThrew(spy, “TypeError”); // Passes assert.alwaysThrew(spy,exception1); // Passes

callAndCatchException(spy, exception2); assert.alwaysThrew(spy); // Passes assert.alwaysThrew(spy, “Type-Error”); // Passes assert.alwaysThrew(spy, exception1); // Fails

Messages

assert.alwaysThrew.message = "Expected ${0} to always throw an exception${1}";refute.alwaysThrew.message = "Expected ${0} not to always throw an exception${1}";

2.1. Core modules 127

Page 132: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

${0}: The spy

${1}: The expected exception

Expectations

All of referee’s assertions and refutations are also exposed as “expectations”. Expectations is just a slightly differentfront-end to the same functionality, often preferred by the BDD inclined.

Expectations mirror assertions under different names. Refutations can be expressed using expect(obj).not andthen calling either of the expectations on the resulting object.

var expect = buster.referee.expect;

expect({ id: 42 }).toBeObject(); // Passesexpect("Somewhere in here").toMatch("in"); // Passesexpect(42).not.toEqual(43); // Passes

expect.toBe()

expect(actual).toBe(expected)

See same()

expect.toEqual()

expect(actual).toEqual(expected)

See equals()

expect.toBeGreaterThan()

expect(actual).toBeGreaterThan(expected)

See greater()

expect.toBeLessThan()

expect(actual).toBeLessThan(expected)

See less()

expect.toBeDefined()

expect(actual).toBeDefined(expected)

See defined()

expect.toBeNull()

expect(actual).toBeNull(expected)

See isNull()

expect.toMatch()

128 Chapter 2. Reference documentation

Page 133: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

expect(actual).toMatch(expected)

See match()

expect.toBeObject()

expect(actual).toBeObject(expected)

See isObject()

expect.toBeFunction()

expect(actual).toBeFunction(expected)

See isFunction()

expect.toBeTrue()

expect(actual).toBeTrue()

See isTrue()

expect.toBeFalse()

expect(actual).toBeFalse()

See isFalse()

expect.toBeString()

expect(actual).toBeString()

See isString()

expect.toBeBoolean()

expect(actual).toBeBoolean()

See isBoolean()

expect.toBeNumber()

expect(actual).toBeNumber()

See isNumber()

expect.toBeNaN()

expect(actual).toBeNaN()

See isNaN()

expect.toBeArray()

2.1. Core modules 129

Page 134: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

expect(actual).toBeArray()

See isArray()

expect.toBeArrayLike()

expect(actual).toBeArrayLike()

See isArrayLike()

expect.toHaveKeys()

expect(object).toHaveKeys(keyArray)

See keys()

expect.toThrow()

expect(actual).toThrow(expected)

See exception()

expect.toBeNear()

expect(actual).toBeNear(expected, delta)

See near()

expect.toHavePrototype()

expect(actual).toHavePrototype(prototype)

See hasPrototype()

expect.toContain()

expect(haystack).toContain(needle)

See contains()

expect.toHaveTagName()

expect(actual).toHaveTagName(expected)

See tagName()

expect.toHaveClassName()

expect(actual).toHaveClassName(expected)

See className()

expect.toHaveBeenCalled()

130 Chapter 2. Reference documentation

Page 135: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

expect(spy).toHaveBeenCalled()

See called()

expect.toHaveBeenCalledOnce()

expect(spy).toHaveBeenCalledOnce(expected)

See calledOnce()

expect.toHaveBeenCalledTwice()

expect(spy).toHaveBeenCalledTwice(expected)

See calledTwice()

expect.toHaveBeenCalledThrice()

expect(spy).toHaveBeenCalledThrice(expected)

See calledThrice()

expect.toHaveBeenCalledWith()

expect(spy).toHaveBeenCalledWith(arg1, arg2, ...)

See calledWith()

expect.toHaveBeenCalledOnceWith()

expect(spy).toHaveBeenCalledOnceWith(arg1, arg2, ...)

See calledOnceWith()

Methods

referee.fail()

buster.referee.fail(message)

When an assertion fails, it calls referee.fail() with the failure message as the only argument. The built-infail function both throws an AssertionError() and emits it to the failure event. The error can be caughtand handled by the test runner. If this behavior is not suitable for your testing framework of choice, you canoverride referee.fail() to make it do the right thing.

Example: To use referee with JsTestDriver, you can simply configure it as follows:

buster.referee.fail = function (message) {fail(message);

};

Where the global fail function is the one provided by JsTestDriver.

2.1. Core modules 131

Page 136: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

It is possible to make the default assert.fail method only emit an event and not throw an error. This maybe suitable in asynchronous test runners, where you might not be able to catch exceptions. To silence exceptions,see the throwOnFailure property.

referee.format()

buster.referee.format(object)

Values inserted into assertion messages using the ${n} switches are formatted using referee.format().By default this method simply coerces the object to a string.

A more expressive option is to use buster-format, which is a generic function for formatting objects nicely asASCII. For nice ASCII formatting of objects (including DOM elements) do:

buster.referee.format = buster.format.ascii;

referee.add()

buster.referee.add(name, options)

Add a custom assertion. Using this ‘macro’ to add project specific assertions has a few advantages:

•Assertions will be counted.

•Failure messages will have interpolated arguments formatted by referee.format().

•A single function generates both an assertion and a refutation.

•If using expectations, an expectation can easily be generated as well.

•When ‘failOnNoAssertions <#failOnNoAssertions>‘_ is set to true, the assertion will behavecorrectly (may be important for asynchronous tests).

•The assertion will fail if too few arguments are passed.

Here’s an example of adding a “foo” assertion, that only passes when its only argument is the string “foo”:

var assert = buster.referee.assert;var refute = buster.referee.refute;var expect = buster.referee.expect;

buster.referee.add("isFoo", {assert: function (actual) {

return actual == "foo";},assertMessage: "Expected ${0} to be foo!",refuteMessage: "Expected not to be foo!",expectation: "toBeFoo"

});

// Now you can do:// Passesassert.isFoo("foo");

// Fails: "[assert.isFoo] Expected { id: 42 } to be foo!"assert.isFoo({ id: 42 });

// Fails: "[refute.isFoo] Expected not to be foo!"refute.isFoo("foo");

132 Chapter 2. Reference documentation

Page 137: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

// Passesexpect("foo").toBeFoo();

// To support custom messages, do this:buster.referee.add("isFoo", {

assert: function (actual) {return actual == "foo";

},assertMessage: "${1}Expected ${0} to be foo!",refuteMessage: "${1}Expected not to be foo!",expectation: "toBeFoo",values: function (thing, message) {

return [thing, message ? message + " " : ""];}

});

// Fails: "[assert.isFoo] Ouch: Expected { id: 42 } to be foo!"assert.isFoo({ id: 42 }, "Ouch");

Error message value interpolation

Arguments are available in assertion failure messages using the "${n}" switches, where n is a number. Youcan also use named variables by setting properties on this in the assertion/refutation function:

buster.referee.add("isString", {assert: function (actual) {

this.actualType = typeof actual;return this.actualType == "string";

},assertMessage: "Expected ${0} (${actualType}) to be string",refuteMessage: "Expected not to be string",expectation: "toBeString"

});

Arguments

name: The name of the new assertion/refutation.

options:

assert:

The verification function. Should return true when the assertion passes. The generatedrefutation will pass when the function returns false.

In some cases the refutation may not be the exact opposite of the assertion. If that is thecase you should provide options.refute for the custom refutation.

The number of formal parameters the function accepts determines the number of requiredarguments to the function. If the assertion is called with less arguments than expected,Buster will fail it before your custom function is even called.

All arguments are available for interpolation into the resulting error message. The firstargument will be available as "${0}", the second as "${1}" and so on. If you want toembed other values than exact arguments into the string, you can set properties on this inthe custom assertion, and refer to them as "${name}" in the message.

refute:

Custom refutation function. Used over !assert() if provided.

assertMessage:

2.1. Core modules 133

Page 138: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

The error message to use when the assertion fails. The message may refer to ar-guments through switches like "${0}" and so on (see above, under the assertargument). The message is exposed on the generated assertion as the propertyassert.[name].message.

refuteMessage:

Like assertFail, but for refutations. Exposed as refute.[name].message.

values:

A function that maps values to be interpolated into the failure messages. This can be usedwhen you need something more/else than the actual arguments in order.

expectation:

The name of the assertion as an expectation, e.g. “toBeSomething”. Optional.

Properties

referee.countNumber increasing from 0.

buster.referee.count is incremented anytime an assertion is called. The assertion counter can be resetto any number at your convenience.

throwOnFailureBoolean.

When using the default referee.fail() implementation, this property can be set to false to make asser-tion failures not throw exceptions (i.e. only emit events). This may be suitable in asynchronous test runners,where you might not be able to catch exceptions.

Supporting objects

class AssertionError()An exception (specifically, an Error object) whose name property is "AssertionError".

2.1.14 samsam

Same same, but different

samsam is a collection of predicate and comparison functions useful for identifiying the type of values and to comparevalues with varying degrees of strictness.

samsam is a general-purpose library with no dependencies. It works in browsers (including old and rowdy ones, likeIE6) and Node. It will define itself as an AMD module if you want it to (i.e. if there’s a define function available).

samsam was originally extracted from the referee assertion library, which ships with the Buster.JS testing framework.

Predicate functions

isArguments(object)

Returns true if object is an arguments object, false otherwise.

134 Chapter 2. Reference documentation

Page 139: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

isElement(object)

Returns true if object is a DOM element node

isDate(object)

Returns true if the object is a Date, or date-like. Duck typing of date objects work by checking that the object has agetTime function whose return value equals the return value from the object’s valueOf.

isNaN(value)

Returns true if passed in value is NaN. Unlike the globally available isNaN, this method does not attempt to coerceits argument to a number, instead it checks that the number is equal to itself.

isNegZero(value)

Returns true if value is -0.

Comparison functions

identical(x, y)

Strict equality check according to EcmaScript Harmony’s egal.

From the Harmony wiki:

An egal function simply makes available the internal SameValue function from section 9.12 of the ES5spec. If two values are egal, then they are not observably distinguishable.

identical returns true when === is true, except for -0 and +0, where it returns false. Additionally, itreturns true when NaN is compared to itself.

deepEqual(obj1, obj2)

Deep equal comparison. Two values are “deep equal” if:

• They are identical

• They are both date objects representing the same time

• They are both primitives and a == b

• They are both arrays containing elements that are all deepEqual

• They are objects with the same set of properties, and each property in obj1 is deepEqual to the correspondingproperty in obj2

2.1. Core modules 135

Page 140: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

match(object, matcher)

Partial equality check. Compares object with matcher according a wide set of rules:

String matcher

In its simplest form, match performs a case insensitive substring match. When the matcher is a string, object isconverted to a string, and the function returns true if the matcher is a case-insensitive substring of object as astring.

samsam.match("Give me something", "Give"); //truesamsam.match("Give me something", "sumptn"); // falsesamsam.match({ toString: function () { return "yeah"; } }, "Yeah!"); // true

The last example is not symmetric. When the matcher is a string, the object is coerced to a string - in this case usingtoString. Changing the order of the arguments would cause the matcher to be an object, in which case differentrules apply (see below).

Boolean matcher

Performs a strict (i.e. ===) match with the object. So, only true matches true, and only false matches false.

Regular expression matcher

When the matcher is a regular expression, the function will pass if object.test(matcher) is true. match iswritten in a generic way, so any object with a test method will be used as a matcher this way.

samsam.match("Give me something", /^[a-z\s]$/i); // truesamsam.match("Give me something", /[0-9]/); // falsesamsam.match({ toString: function () { return "yeah!"; } }, /yeah/); // truesamsam.match(234, /[a-z]/); // false

Number matcher

When the matcher is a number, the assertion will pass if object == matcher.

samsam.match("123", 123); // truesamsam.match("Give me something", 425); // falsesamsam.match({ toString: function () { return "42"; } }, 42); // truesamsam.match(234, 1234); // false

Function matcher

When the matcher is a function, it is called with object as its only argument. match returns true if the functionreturns true. A strict match is performed against the return value, so a boolean true is required, truthy is notenough.

// truesamsam.match("123", function (exp) {

return exp == "123";});

// falsesamsam.match("Give me something", function () {

return "ok";});

// truesamsam.match({

toString: function () {return "42";

136 Chapter 2. Reference documentation

Page 141: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

}}, function () { return true; });

// falsesamsam.match(234, function () {});

Object matcher

As mentioned above, if an object matcher defines a test method, match will return true ifmatcher.test(object) returns truthy.

If the matcher does not have a test method, a recursive match is performed. If all properties of matcher matchescorresponding properties in object, match returns true. Note that the object matcher does not care if the numberof properties in the two objects are the same - only if all properties in the matcher recursively matches ones in object.

// truesamsam.match("123", {

test: function (arg) {return arg == 123;

}});

// falsesamsam.match({}, { prop: 42 });

// truesamsam.match({

name: "Chris",profession: "Programmer"

}, {name: "Chris"

});

// falsesamsam.match(234, { name: "Chris" });

DOM elements

match can be very helpful when comparing DOM elements, because it allows you to compare several properties withone call:

var el = document.getElementById("myEl");

samsam.match(el, {tagName: "h2",className: "item",innerHTML: "Howdy"

});

2.1.15 user-agent-parser

Version: 0.2.1 (2011-08-25)

Module: require("buster-user-agent-parser");

Parse the user agent string, attempting to guess browser vendor and version as well as the operating system. This mod-ule should only be used for (somewhat unreliable) information, not for “feature” detection or control flow alteration.

Buster.JS uses the user agent parser to display browser name/version in its test runner.

2.1. Core modules 137

Page 142: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

var userAgentParser = require("buster-user-agent-parser");

var ua = "Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.7 " +"(KHTML, like Gecko) Chrome/7.0.517.44 Safari/534.7";

var browser = userAgentParser.parse(ua);

browser == {platform: "Linux",browser: "Chrome",version: "7.0.517.44"

};

Methods

userAgentParser.parse()

var browserInfo = userAgentParser.parse(userAgentStr);

“Parse” the user agent string. Tries to determine OS, browser vendor and browser version. Returns a Browserinfo object.

Browser info

browserInfo.platformThe ‘OS’ name; Windows, Linux, OS X, iPad, iPhone, Android

browserInfo.browserBrowser name, like Firefox, Safari, Chrome, and so on

browserInfo.versionBrowser version string

2.2 Extensions

2.2.1 buster-amd

Use an AMD loader to test asynchronous modules. You must provide your own loader. By default, a loader thatprovides require(deps, callback) is assumed. This will eventually be pluggable.

Install

Installation is done using npm:

npm install buster-amd

Usage

Load in your configuration file, specifying your loader and the required configuration file as libs. You also need to addthe buster-amd extension to your configuration:

138 Chapter 2. Reference documentation

Page 143: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

var config = module.exports;

config["Browser tests"] = {environment: "browser",rootPath: "../",libs: [

"libs/require.js","requirejs-config.js"

],sources: ["src/**/*.js"],tests: ["test/**/*.js"],extensions: [require("buster-amd")]

};

Note: You should list your tests and sources as normal. Your sources must be specified in the configuration even ifyou will require them from your tests, otherwise, Buster will not make them available on the test server.

If you have any issues with paths for your required files, check the configuration section below.

Your tests will drive the show. To run tests with the AMD extension, your tests should be wrapped in a call to define,which pulls in dependencies (i.e. your modules) and in the callback define specs/test cases as usual:

define(['moduleToTest.js'], function(moduleToTest){buster.testCase("A test case", {

"test the module": function(){assert.isObject(moduleToTest);

}});

});

Configuration

The AMD extension has one configuration option: a path mapper. The path mapper is an optional function thattranslates Buster.JS paths (which are absolute, e.g. /test/my-test.js) to AMD friendly module IDs.

The default mapper converts /test/my-test.js to test/my-test, i.e. strips leading slash and file suffix:

function (path) {return path.replace(/\.js$/, "").replace(/^\//, "");

}

However, if your AMD loader specifies a basePath in its configuration the default mapper might cause you issues:

require.config({baseUrl: 'src/'

});

In this case, every module your loader attempts to load will be prefixed with this basePath:

src/test/my-test.js

You don’t need to restructure your project to solve this issue. If your tests live outside of that directory, you can fixthat with a different mapping function:

config["Browser tests"] = {environment: "browser",rootPath: "../",

2.2. Extensions 139

Page 144: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

libs: ["libs/require.js","requirejs-config.js"

],sources: ["src/**/*.js"],tests: ["test/**/*.js"],extensions: [require("buster-amd")],"buster-amd": {

pathMapper: function (path) {// prefix any path starting with a slash with ../return path.replace(/\.js$/, "").replace(/^\//, "../");

}}

};

In this case, your AMD loader will load the files with the following path in the browser with the pathsrc/../test/my-test.js which is equivalent to test/my-test.js

Note: If you specify your own mapper and decide not to remove the file extension make sure you understand howyour loader deals with files with an extension.

require.js for instance will load them with an absolute path, not prefixing these with a baseUrl option, but curl.jswill treat these files as any other modules.

Another example: use the following mapper for AMD loader plugins:

var config = module.exports;

config["Browser tests"] = {environment: "browser",rootPath: "../",sources: ["src/**/*.js"],tests: ["test/**/*.js"],extensions: [require("buster-amd")],"buster-amd": {

pathMapper: function (path) {return "plugin!" + path.replace(/^\//, "").replace(/\.js$/, "");

}}

};

Examples

Check the demos repository for example projects.

Source code

buster-amd on GitHub

2.2.2 buster-coffee

Automatically compile CoffeeScript files before running tests. In its current state, this extension does not work forfiles that are to be included using require(), and is thus not very useful for Node.js projects.

140 Chapter 2. Reference documentation

Page 145: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Install

Installation is done using npm:

npm install buster-coffee

Usage

Load in your configuration file:

var config = module.exports;

config["Browser tests"] = {environment: "browser",rootPath: "../",sources: ["src/**/*.coffee"],tests: ["test/**/*.coffee"],extensions: [require("buster-coffee")]

};

Source code

buster-coffee on GitHub

2.2.3 buster-coverage

TODO: Write usage documentation

2.2.4 buster-html-doc

TODO: Write usage documentation

2.2.5 buster-jstestdriver

Run test cases written for JsTestDriver with the Buster runner. The extension does not currently support :DOC stylecomments or async test cases.

Install

Installation is done using npm:

npm install buster-jstestdriver

Usage

Load in your configuration file:

2.2. Extensions 141

Page 146: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

var config = module.exports;

config["Browser tests"] = {environment: "browser",rootPath: "../",sources: ["src/**/*.js"],tests: ["test/**/*.js"],extensions: [require("buster-jstestdriver")]

};

Source code

busrer-jstestdriver on GitHub

2.2.6 buster-lint

Incorporate linting (JsLint or JsHint) in your test runs. Optionally fail test runs if lint is found.

Install

Installation is done using npm:

npm install buster-lint

Usage

Load in your configuration file:

var config = module.exports;

config["Browser tests"] = {environment: "browser",rootPath: "../",sources: ["src/**/*.js"],tests: ["test/**/*.js"],extensions: [require("buster-lint")]

};

Configure

Configuration options are those supported by the wonderful autolint tool by Magnar Sveen. In fact, if you’re alreadyusing autolint, you can integrate it with Buster.JS by simply requiring your existing configuration (assuming you’renot still using pre-1.0 json config files):

var config = module.exports;

config["Browser tests"] = {environment: "browser",rootPath: "../",sources: ["src/**/*.js"],tests: ["test/**/*.js"],extensions: [require("buster-lint")],

142 Chapter 2. Reference documentation

Page 147: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

"buster-lint": require("./autolint")};

If you don’t already have an autolint configuration, here’s to get you started. All options are documented in the GitHubrepository.:

var config = module.exports;

config["Browser tests"] = {environment: "browser",rootPath: "../",sources: ["src/**/*.js"],tests: ["test/**/*.js"],extensions: [require("buster-lint")],"buster-lint": {

linterOptions: {node: true

},

excludes: ["jquery","underscore","raphael"

]}

};

Source code

buster-lint on GitHub

2.2.7 buster-syntax

This extension is unique in that it is bundled by default when you run tests in browsers. It verifies that all files aresyntactically correct before sending them to the server for execution. This ensures good error messages and reducesbrowser hangs (especially in older less stable browsers).

Source code

buster-syntax on GitHub

2.2. Extensions 143

Page 148: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

144 Chapter 2. Reference documentation

Page 149: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

CHAPTER 3

Project resources

Here you can find out more about the Buster.JS project, changelogs, how to contribute, etc.

3.1 Download

3.1.1 Node.js module

To get the most out of Buster.JS, we recommend you install Buster using Node.js and npm, as described in Gettingstarted.

3.1.2 Script for static browser testing

For simple browser tests, you can use the pre-built script (and CSS):

• Latest (URL always points to most recent release): buster-test.js (latest), buster-test.css (latest)

• 0.6.2 (2012-07-10): buster-test.js (0.6.2), buster-test.css (0.6.2)

• 0.6.1 (2012-07-09): buster-test.js (0.6.1), buster-test.css (0.6.1)

• 0.6.0 (2012-06-20): buster-test.js (0.6.0), buster-test.css (0.6.0)

• 0.5.3 (2012-05-04): buster-test.js (0.5.3), buster-test.css (0.5.3)

• 0.5.2 (2012-05-02): buster-test.js (0.5.2), buster-test.css (0.5.2)

• 0.5.1 (2012-04-25): buster-test.js (0.5.1), buster-test.css (0.5.1)

• 0.5.0 (2012-04-17): buster-test.js (0.5.0), buster-test.css (0.5.0)

• 0.4.6: buster-test.js (0.4.6), buster-test.css (0.4.6)

• 0.4.5: buster-test.js (0.4.5), buster-test.css (0.4.5)

3.2 Community

3.2.1 Development

Buster.JS is developed in the open. The source code is hosted at github.com/busterjs and gitorious.org/buster. Devel-opment discussion happens in the issue tracker and the development mailing list.

145

Page 150: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

3.2.2 Twitter

We tweet on twitter.com/buster_js.

3.2.3 IRC

Come visit us at #buster.js on irc.freenode.net. Activity is spiky so stay around for a few hours if you ask us a question.The channel logs are available at irclogger.com.

3.2.4 Mailing list

There’s a mailing list on Google Groups.

3.2.5 Contributors

See Contributors.

3.2.6 Community watch

A collection of links with more information about the community’s usage of Buster.JS.

• GitHub search for buster.js

• Twitter search

• Try Buster (quick and easy VM setup)

• Buster TextMate bundle

• Buster on Rails

• Yahtzee Kata with Buster.JS

• Testable widget with Buster.JS

3.3 Contributors

We welcome anyone who want to contribute to make Buster.JS even better. The following people have commits in oneor several Buster.JS repositories:

• August Lilleaas

• Brian Cavalier

• Calle Arnesten

• Christian Johansen

• Daniel Wittner

• Dave Geddes

• Dominykas Blyž

• Fabian Vogler

• Fábio M. Costa

146 Chapter 3. Project resources

Page 151: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

• Felix Geisendörfer

• Jesper Haug Karsrud

• Joakim Ohlrogge

• Magnar Sveen

• Malcolm Locke

• Matthias Kling

• Morgan Roderick

• Rod Vagg

• Sasha Depold

• Stein Magnus Jodal

• Thomas Pickert

• Tiago Rodrigues

• Tobias Ebnöther

Thank you!

3.4 Developers

This page contains useful information for Buster.JS developers/contributors.

Important: You should definitely avoid to have a global installation of Buster.JS while developing Buster.JS. Other-wise chances are high that it will be involved when running Buster.JS and tests in the development environment.

3.4.1 Setting up a development environment

First time setup

If you don’t already have Node.js installed, install it on your system. The same goes for Git.

For Windows we recommend mysysgit and TortoiseGit. These will also get you the so-called “Git Bash” which is(almost) a Unix shell on your Windows system. It’s invoked by a right-click to bring up the context menu and thenselecting “Git Bash” from that.

The development environment is managed with a CLI (Command Line Interface), buster-dev-tools. To boot-strap, you create a folder of your choice, e.g. busterDevEnv, to hold all the packages. Inside of that you clonebuster-dev-tools from GitHub:

mkdir busterDevEnvcd busterDevEnvgit clone https://github.com/busterjs/buster-dev-tools.gitnpm install

Note: the name busterDevEnv is the only thing that you might want to change to your liking. Everything else can(and should be) copied&pasted as is. Next, two environment variables need to be adjusted: NODE_PATH and PATH.The former, NODE_PATH, affects where Node.js is looking for packages, and we want it to do so in the developmentenvironment (busterDevEnv in this example).

3.4. Developers 147

Page 152: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

On Linux and Mac OS X (or in Git Bash on Windows):

export NODE_PATH=`pwd`export PATH=$NODE_PATH/buster-dev-tools/bin:$PATHexport PATH=$NODE_PATH/buster/bin:$PATH

Tip: Put the export statements into a shell script in the busterDevEnv directory, for example busterEnv.sh:

#!/bin/sh

export NODE_PATH=`pwd`export PATH=$NODE_PATH/buster-dev-tools/bin:$PATHexport PATH=$NODE_PATH/buster/bin:$PATHexec bash

Then make the shell script executable by chmod u+x busterEnv.sh. From now on you only have to open aterminal and execute the shell script in the busterDevEnv directory to make that terminal ready for work. You canomit the line exec bash, if you execute the script either with . busterEnv.sh or source busterEnv.sh.

On Windows (DOS-box):

SET NODE_PATH=%CD%SET PATH=%NODE_PATH%\buster-dev-tools\bin;%PATH%

Tip: Put the SET statements into a batch file in the busterDevEnv directory, for example busterEnv.bat.Then you only need to execute it in a command shell in the busterDevEnv directory to make that command shellready for work.

Finally you run the tool to get all the buster packages plus external dependencies:

buster-dev-tools pull

Refreshing all repositories

After some time you might want to update all the repos, including buster-dev-tools itself. To do so, simply repeat thepull command above.

3.4.2 Useful information around the development process

Run Buster.JS

To run a manual test open a new terminal, change to your development directory of Buster.JS, execute the shell script(or batch file) to set the PATH and NODE_PATH, change to the directory of the example project and run the test, forexample just by buster-test, depending on which tests and what kind of tests (browser or node) you want to runand how you want them to run (for example buster-static for browser tests).

Important: Before you run Buster.JS, you should run buster-dev-tools clear and thenbuster-dev-tools deps. The first command deletes the node_modules folder of all projects (except forproject buster-dev-tools). The second one installs the non-buster dependencies for all projects. That way youget back the state you have had right after setting up the development environment, concerning to the dependencies.Your changes to the source code are still there, of course.

148 Chapter 3. Project resources

Page 153: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

This approach is especially important for the final manual test you make, just before you commit your changes.

Run tests

During the setup of the development environment via buster-dev-tools pull only the dependencies spec-ified under dependencies in the package.json file are installed, not the devDependencies and not theoptionalDependencies. They are not needed to run Buster.JS, but to run the tests. Therefore they have to beinstalled first. You can do this by changing to the root directory of the project you want to run the tests for and typingnpm install.

Tip: The installation of the devDependencies can lead to problems, if a package has to be compiled, but youhaven’t established a build toolchain for node-gyp. Read the installation chapter of node-gyp to learn more about this.

If you get the message Error: spawn ENOENT for the step node-gyp configure, try to set the paths for python asfollows:

PYTHONPATH=C:\Python27PYTHON=%PYTHONPATH%\python.exe

PYTHONPATH must point to your actual installation directory of Python 2.7.x, of course.

To run the tests type npm test in the root directory of the project.

Important: You shouldn’t run the tests in an environment, where you have adjusted NODE_PATH and PATH fordevelopment as described here. There are two main reasons for that:

1. Most of the projects use Buster.JS (or parts of it) for testing, which means, Buster.JS (or parts of it) will beinstalled in the node_modules directory of the project. Having NODE_PATH and PATH adjusted for devel-opment could lead to weird behaviour, because both versions of Buster.JS (or parts of it) are mixed up together.

2. Running the test without adjusting NODE_PATH and PATH corresponds to how the tests run on Travis CI.

Debugging

A comfortable way to debug Node applications is to use node-inspector. If you haven’t it installed yet, install itby:

npm install -g node-inspector

Open a terminal and start the inspector:

node-inspector

Debugging a Buster.JS run

Open the file buster/bin/buster-test and change the first line from #!/usr/bin/env node to#!/usr/bin/node --debug-brk.

Open another terminal, change to your development directory of Buster.JS, run the shell script (or batch file) to set thePATH and NODE_PATH, change to the example project and run the test by buster-test. The execution will behalted at the first instruction and you will get the info “debugger listening on port 5858”, the same as for debugging anautomated test run. From that point on there is no difference between debugging an automated and a manual test run.

3.4. Developers 149

Page 154: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Note: If you want to run other command than buster-test, for example buster-static, you have to edit thecorresponding file instead.

Debugging a test run

To debug a test run just run npm run-script test-debug in the root directory of the project. The executionwill be halted at the first instruction and you will get the info debugger listening on port 5858.

Open a Chrome browser, go to http://127.0.0.1:8080/debug?port5858 and you are ready to debug. More informationabout debugging with node-inspector can be found at node-inspector.

How to get your changes to the Buster.JS repositories

Because you don’t have write permission to the Buster.JS repositories you have to push your changes to a forked repos-itory first and to create a pull request. One of the owner of the project will merge your changes into the correspondingBuster.JS repository at a later point, if we decide they are useful for the application.

This is one possible workflow:

1. Create a fork of the repository you want to edit by clicking the “Fork” button on github.

2. Open a terminal and change to the project you want to edit

3. Type git remote -v and you should see something like this:

origin https://github.com/busterjs/buster-cli.git (fetch)origin https://github.com/busterjs/buster-cli.git (push)

This output is for the buster-cli repository and means, that we currently have only one remote directoryconnected to it and therefore can only fetch changes from there and can push our changes only to that repository,but unfortunately we don’t have write permission for it.

4. Type git remote add fork https://github.com/<your_github_username>/<name_of_repository>.git

Tip: If you open the forked repository on your Github account you will find the Url next to it. You can copyand paste it to prevent mistyping.

5. Type git remote -v again and this time you should see something like this:

fork https://github.com/<your_github_username>/buster-cli.git (fetch)fork https://github.com/<your_github_username>/buster-cli.git (push)origin https://github.com/busterjs/buster-cli.git (fetch)origin https://github.com/busterjs/buster-cli.git (push)

6. Now you can specify to which remote repository you want to push your changes. Type git push forkmaster to push the changes to the master branch of the forked repository.

7. Go to the forked repository on your Github account and press the “Compare and review” button to verify yourchanges and to create a pull request.

150 Chapter 3. Project resources

Page 155: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Finding your way around the code

We know that it’s hard to navigate the source code of Buster.JS if you are new at the project, because of the amount ofprojects/repositories. But hold on and don’t give up and you will see soon, that it’s not that complicated. A good pointto start is to have a look at the Architecture overview, especially at the example.

3.4.3 Contribution guidelines

Post questions to the busterjs-dev mailing list

The busterjs-dev mailing list is a place for general discussion regarding development of Buster.JS. In many cases youcan just post an issue to the issue tracker and the discussion can happen there. But you can also discuss on the mailinglist if you’re more comfortable with that. For example, you might prefer to use email for discussion, or you want todiscuss your contribution before posting it to the issue tracker.

Coding style

Use your favorite IDE to edit files, but please always use autolint. If you don’t have installed it yet, you can do that by:

npm install -g autolint

Before you edit a file, run autolint in the root directory of the related project. Keep an eye on the output of the toolwhile you are editing and fix all mentioned issues before you commit your changes.

Further it’s a good idea to look at existing code to get an idea of the coding style of the project.

Automated tests

It is important that you write good unit tests for your changes. Best way to do that is to develop test-driven. We areconvinced test-driven developers and we would be very pleased, if you’re one too.

How to run tests

Manual testing

To verify that your changes also work in the real life, besides the automated test world, you have to test them manually.It’s useful to have an example project for that. If you want to fix an issue it is recommened to create an example projectto reproduce the issue first. Later you can use the same project to verify the issue is really fixed.

How to run Buster.JS

Understanding Buster.JS

See Architecture overview.

3.4.4 Architecture overview

Buster.JS consists of many small Git repositories/npm modules. We try to keep things small and separated. The repos-itories and installable modules both promotes reusability (e.g. you can use Buster assertions with any test framework)and helps us avoid tight coupling between modules. However, some people feel that the number of repositories are

3.4. Developers 151

Page 156: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

a bit daunting when trying to contribute. This document sheds some light on existing modules, what they’re for, andwhat role they play in the bigger part.

Note that some of our modules contain stronger abstractions than others, and the less obvious ones may very wellchange until we have something that we’re comfortable with. If you have suggestions for how certain modules canimprove (renaming/merging/splitting/refactoring/whatever), feel free to let us know.

Types of modules

Buster.JS core modules

Core modules are those that are installed when you type npm install buster. They constitute thecore of the test framework, and contains everything you need to run node tests, simple browser tests, andautomated crowd-sourced browser tests.

Buster.JS auxilliary modules

Developer tools and docs.

Buster.JS extensions and optional modules

These modules provide additional and optional features/extensions for Buster.JS, such as linting, JsTest-Driver support, and more.

Dependency graphs

Matthias Kling generated some visual dependency graphs. They’re a great complement to this article, visualizing howpackages depend on each other.

Core modules

buster

Status: Stable

Source code: buster

Build status:

Meta-package that’s the install target, thus carries quite a lot of dependencies. Includes some very rudimentary wiringacross Buster repositories.

buster-analyzer

Status: In development, may change significantly

Source code: buster-analyzer

Build status:

A simple and generic mechanism for flagging warnings. The analyzer is an event emitter, and provides fatal,error and warning methods, which emit corresponding events. Additionally, the analyzer has a concept of ok/notok. This is decided from a threshold (i.e., a threshold of “error” means “not ok” if any error or fatal events whereflagged).

152 Chapter 3. Project resources

Page 157: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

The analyzer also comes with a reporter which can be used to log events of interest. The analyzer and the reporter isused by buster-test-cli and extensions to provide various insight about your code. Examples of practical usage includeslinting and syntax checking (for browser tests).

buster-autotest

Status: TODO

Source code: buster-autotest

Build status:

TODO Write description

buster-bayeux-emitter

Status: Stable

Source code: buster-bayeux-emitter

Build status:

Given subscribe and publish methods, this module produces an object that looks and behaves like an eventemitter (i.e. no specific requirements on event names and so on).

Specifically, the bayeux emitter is used to allow the test runner in the browser (via ramp) ship its progress eventsdirectly over the wire (which is a Bayeux wire).

ramp

Status: Unstable, currently undergoing API changes.

Source code: ramp

Build status:

The capture server captures browsers as slaves, and offers a completely generic API for carrying out work across thoseslaves. A workload is known as a “session”, and a test run is typically a session. Other uses include for instancesynced-across-devices slide shows (for which a POC has been built).

In general, the server knows nothing specifically of testing. It knows how to accept and server resource sets, captureand command browser slaves, and coordinate every piece using messaging (Bayeux on the HTTP level).

buster-cli

Status: Stable

Source code: buster-cli

Build status:

Somewhat arbitrary collection of utilities useful to CLIs that aim to behave more or less like existing Buster.JS CLIs.Is used by buster-test-cli and buster-static.

3.4. Developers 153

Page 158: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

buster-configuration

Status: Stable. Occasionally learns about new properties.

Source code: buster-configuration

Build status:

Programmatic access to buster.js configuration files. Allows you to extract resourceSets (i.e. all the filenames/contents), environment options, run extension hooks and filter out groups.

buster-core

Status: Stable

Source code: buster-core

Build status:

Somewhat arbitrary collection of functions used in several other buster modules. Includes the event emitter implemen-tation used throughout, some limited flow-control utilities, and a few functional enhancements. Hopefully, we can getrid of this one day.

buster-evented-logger

Status: Stable

Source code: buster-evented-logger

Build status:

A logger-like utility that simply emits events. This is useful in any number of cases, most importantly when runningtests in browsers via ramp. In this case, we pass the events over the wire instead of printing them to the console.

buster-format

Status: Stable

Source code: buster-format

Build status:

ASCII formatting of arbitrary JavaScript objects. This module is used to give pretty feedback in certain cases. It isused to format objects in assertion error messages, to format objects passed to buster.log (and console.log,if captured) and may be used in more places later. Also intended for reuse outside of the Buster.JS sphere.

buster-glob

Status: TODO

Source code: buster-glob

Build status:

TODO Write description

154 Chapter 3. Project resources

Page 159: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

ramp-resources

Status: Stable, has a few known issues waiting to be fixed

Source code: ramp-resources

Build status:

Represents files in a project that may be included in a test run. For Node.js, Buster.JS only use ramp-resourcesto look up which paths to require. For browsers, Buster.JS uses ramp-resources to build a virtual file system,send it over HTTP and mount it on the server. All of these components are available in this module.

ramp-resources also includes intelligent caching of resources to allow test runs that only reads changed testsfrom file and so on. Resources typically map to files on disk, but really can be anything, including one-off strings in aconfiguration file.

buster-sinon

Status: Stable

Source code: buster-sinon

Build status:

Integrating Sinon.JS with Buster.JS. Adds Sinon specific assertions, wires up Sinon.JS to use buster-format forerror messages, adds automatic sandboxing/restoration of fakes for test cases and so on.

buster-static

Status: Largely incomplete

Source code: buster-static

Build status:

A small and (currently, too) simple/limited way of easily running tests directly in a browser (i.e. without buster-server).Builds scaffolding markup and serves tests on a simple server.

stream-logger

Status: Stable

Source code: stream-logger

Build status:

Accepts a standard and error output stream, and returns a buster-evented-logger object that will print certainsevents directly to the passed-in stdout, and certain errors to stderr.

buster-syntax

Status: Stable, but integrates with buster-analyzer, which is not.

Source code: buster-syntax

Build status:

3.4. Developers 155

Page 160: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

A small extension (but installed and activated by default) that provides server side syntax checking of scripts sent fortesting with ramp. When Buster.JS loads scripts in browsers, the browser in question will be the one responsible forthe level of detail when errors arise, Syntax checking on the server allows us to catch these errors in one place, andproduce a pretty nice report, regardless of browser intended to run the tests.

buster-terminal

Status: Stable, mostly complete.

Source code: buster-terminal

Build status:

A small library for working with ANSI escape sequences in the terminal. Mostly used for colored output, and posi-tional output. Also includes a “labeled list” object that is used to progressively print multiple lines of output at once,e.g. when running tests on multiple browsers (the dots reporter).

buster-test

Status: May be split into several modules and/or renamed.

Source code: buster-test

Build status:

Implements testCase, describe (and friends), the actual test runner, reporters and supporting objects.buster-test is centered around the concept of “test contexts”, which is just a bag of tests, and possibly morebags of tests. This is the shared data format produced by both the xUnit and BDD style tests/specs.

The reason we’re considering breaking up this module is that it includes parts that are complete and unlikely to change(such as test case and spec definitions, the context data format and the test runner) <strong>and</strong> parts thatare likely to change and/or have abilities added, such as reporters. The name also indicates it is what powers thebuster-test binary, which is not true.

buster-test-cli

Status: In development

Source code: buster-test-cli

Build status:

“The kitchen sink” behind buster test. Coordinates many other modules to read configuration file, loop allmatching groups, creating runners and running those groups. In charge of options passed to buster test, coloredprinting and so on.

This module is mostly stable, but is rapidly gaining features and extension points. My gut feeling tells me that thismodule houses too many things, and it will likely be broken up before we go 1.0.

buster-user-agent-parser

Status: Stable (new user agents occasionally added)

Source code: buster-user-agent-parser

Build status:

156 Chapter 3. Project resources

Page 161: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

A generic user-agent parser that does a best-effort attempt at extracting browser, version and platform. Only used for“friendly” browser names in test result reports, list of slaves and so on.

fs-watch-tree

Status: TODO

Source code: fs-watch-tree

Build status:

TODO Write description

posix-argv-parser

Status: Stable, has a few known (API design) issues waiting to be fixed

Source code: posix-argv-parser

Build status:

General purpose command line argument parser. Only parses command line options, no printing to the console, no--help generation, no flow control. Also tries as best it can to adhere to UNIX conventions. Fails early (typicallywhen using non-existent options ++).

referee

Status: Stable, awaiting a few additions before 1.0

Source code: referee

Build status:

Assertions and expectations, for Buster.JS and everyone else.

Auxilliary modules

buster-dev-tools

Status: In development, awaiting Windows support

Source code: buster-dev-tools

Build status:

Allows developers to set up their Buster.JS development environment quickly and painlessly.

buster-docs

Status: Will never be “done”

Source code: buster-docs

You’re reading them.

3.4. Developers 157

Page 162: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

buster-util

Status: Stable, but will hopefully be removed down the line

Source code: buster-util

Contains a simple and ugly test runner that’s used to test some of the more fundamental parts of Buster.JS.

Extensions and optional modules

buster-amd

Status: In development

Source code: https://github.com/johlrogge/buster-amd

Work in progress. Extension that will allow AMD projects to use Buster.JS without any specific configuration. Itmodifies the load path of the resourceSet used to represent user files and creates an anonymous AMD module thatdepends on all tests, thus loading files using an AMD loader rather than simple script tags. Currently developed byJoakim Ohlrogge.

buster-coffee

Status: Stable, but future changes may be required to support Node.js and require()

Source code: https://github.com/busterjs/buster-coffee

Build status:

Extension that automatically compile CoffeeScript files before running tests. In its current state, this extension doesnot work for files that are to be included using require(), and is thus not very useful for Node.js projects. Currentlydeveloped by Stein Magnus Jodal.

buster-coverage

Status: In development

Source code: https://github.com/ebi/buster-coverage

Work in progress. Extension to calculate line coverage. Uses the resourceSet to instrument code, and emitscustom messages over the test runner to build up the report. Currently developed by Tobias Ebnöther.

buster-html-doc

Status: Stable

Source code: buster-html-doc

Build status:

An extension that implements “markup-in-comments”, using the /*:DOC el = ... */ format originallyfound in JsTestDriver. The extension was originally developed to be API compatible with JsTestDriver in thebuster-jstestdriver extension, but works well with vanilla Buster.JS test cases (and specs) too.

158 Chapter 3. Project resources

Page 163: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

buster-jstestdriver

Status: Stable, but lacks async test cases.

Source code: buster-jstestdriver

Build status:

An extension that allows Buster.JS to run JsTestDriver test suites, given a configuration file Buster.JS understands.

buster-lint

Status: Stable, but relies on buster-analyzer, which is not.

Source code: buster-lint

Extension that enables the integration of JsLint and JsHint by way of autolint. Using the buster-analyzermodule, the lint extension is able to flag lint errors as “error” in buster. This allows the end-user to choose if linterrors should only be printed as warnings, or actually fail the build (which can be achieved with buster test -Ferror). Currently developed by Magnar Sveen <https://github.com/magnars>.

By example: buster test --browser

This section runs through what happens when you automate browser tests from the command line, e.g. when you typesomething like buster test --browser. The idea is to highlight roughly the flow through the various parts ofBuster.JS, and to illustrate practically how the modules depend on and interact with each other.

In this section, files are referred to as package/path/to/file, meaning thatbuster/lib/buster/buster-wiring.js refers to the file lib/buster/buster-wiring.js in the buster package.

The binary

buster test executes the “binary” script buster/bin/buster This is a small wrapper script that can print somehelp, and that can look for other commands on the path called buster-<something>. In this case, it finds thebuster/bin/buster-test script in the same package. The buster package is a “meta package”, meaning that it does notcontain much implementation, it’s just there to glue all the pieces together and give you a convenient install target.

Command line options

The buster-test “binary” simply delegates to buster-test-cli/lib/buster-test-cli/cli/test.js which defines the CLIinterface for running tests. Command line options are handled by posix-argv-parser, and to some extend,buster-cli.

buster-cli/lib/buster-cli.js is not so much a real abstraction, as it is a collection of routines useful in buster CLIs. Itcentralizes help text formatting, provides helpers for adding CLI options with help text, locates the configuration fileand coordinates loading it with running.

The --browser option is a posix-argv-parser shorthand that expands to --environment browser,which is the long form for specifying environment.

3.4. Developers 159

Page 164: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Loading configuration

The configuration file is located and “resolved” in buster-cli/lib/buster-cli.js. It tries to find the configuration file inone of ./, ./test/ or ./spec/. If it is not found, the parent directory will be consulted in the same way untilwe’re at the root.

If the --config option was provided, only that file will be consulted. buster-cli contains some error handlingin case configuration could not be located.

For loading the contents of the configuration file into memory, a separate package, buster-configuration, isused. Buster.JS defers actually reading source files from disks as long as possible, so “resolving” the configuration fileonly loads relevant groups with their extensions and builds lazy resource sets to represent files. buster-cli usesseveral options to filter out the groups found in the configuration file to figure out which ones will eventually be run.

Detour: Extension hooks

A configuration group has a method called runExtensionHook. You call this method with the name of a hook andsome arguments. Any extension in the configuration that has a method of the same name will then be called with thepassed in arguments.

Loading the browser runner

Depending on what groups resulted from reading the configuration file and filtering it according to command lineoptions, the following steps may be repeated several times. For simplicity, this example assumes only one configurationwas loaded.

Now that buster-test-cli knows that we’re running tests for the browser environment, it loads the browserrunner. The runner will have its run method called with the configuration loaded from file, an options object, whichcontains prepared options for things like color etc, and a callback that will be called when the run is over.

The runner now uses a little abstraction that is shared between the browser and the node runner. It creates an ana-lyzer for general-purpose health-checks, and fires the "beforeRun" extension hook, allowing extensions to registeranalyzers.

The browser runner then proceeds to instantiate a buster-client/lib/client.js. This object is a JavaScript interface thatspeaks HTTP to a running buster server. Because the server component is currently being reworked, this documentwill only briefly touch on the concepts it implements.

The server: A brief overview

The server has the ability to capture browsers as slaves. A slave is a browser that has loaded a frameset, where oneframe, “the control frame”, keeps a persitent connection to the server, awaiting instructions. The server also providesan HTTP API for creating a session - a piece of work to be carried out in available slaves. When this happens, theserver uses the bidirectional connection to instruct slaves to load the session in a separate frame.

When loading a session in a browser, an index.html file is loaded in a separate frame, and this file will in-clude <script> tags that loads all the files originally specified in the configuration under libs, sources,testHelpers and tests.

The browser part of the server

Alongside the sources, a little wiring script is loaded. This file configures a listener for new test cases and specs Finallyit wires up a test runner with a JSON proxy reporter and defines buster.run() as a way to start the whole thing.

160 Chapter 3. Project resources

Page 165: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

The test runner is completely evented, and the JSON proxy reporter is just a way of making sure the events are onlydata, thus HTTP-encodable. The events from the test runner are sent directly over the wire.

Back on the client

Back on the client, buster-test-cli is now ready to use its HTTP client to create a session. The client startsby asking the server for available cache manifests. These will be handed to the resourceSet, and will make sureBuster does not read any files from disk that are already hosted in the same version on the server.

Any file that isn’t already cached will now be “serialized” (i.e. read from disk) and sent to the server as part of theHTTP POST request to create a session. The server uses a resource set cache to cache and look up cached resources,and a resource set middleware to actually serve them over HTTP.

With the session readily created, buster-test-cli‘s browser runner is listening for messages. These messagesare piped into its remote runner. This object accepts messages from multiple test runners (i.e. one per browser), andemits messages as if it was one test runner. The originating browser is represented as an outer context for all tests.This allows the “remote runner” to be used directly with any existing reporter written for the regular test runner.

The “testRun” extension hook

After the remote runner has been initialized, but before the tests are actually started, the client issues the "testRun"extension hook, which allows extensions to interact with the test runner (e.g. to listen to specific messages etc).

Finishing up

When the session is created and the remote runner is initialized, the browser runner will listen for the test runner’s"suite:end" event. This event comes with a short summary, which is passed to the browser runner’s done callback(passed to run).

The test.js CLI interface will now use the test report to decide if the run was successful or not and exit with acorresponding exit code. In the case where there are more configuration groups to be run, these will be run beforeexiting.

In summary

This is of course a brief and incomplete overview, but it should provide some insight into how some of the moreimportant parts work together.

3.4.5 Building Extensions

Note: Extension hooks are still in their infancy. If you find it impossible to add some desired behavior through anextension, file an issue.

Extensions adds to or enhances the capabilities of Buster.JS at runtime. An extension will typically use regular BusterAPIs to do their bidding. However, in order to hook you into the right places, Buster.JS provides a series of extensionpoints where you can add custom functionality.

A Buster.JS extension is an object that optionally exposes a create method, that will receive custom configuration,and one or more methods that implement an extension hook. The number of hooks is expected to increase in the nearfuture.

3.4. Developers 161

Page 166: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Create: var instance = ext.create([options]);

If provided, the create method is called with any custom configuration for the extension. Custom configuration isany value assigned to the property named after the extension in the configuration file, e.g.:

module.exports["Some tests"] = {extensions: [require("my-extension")],"my-extension": whatever

};

In order for this to work, the extension must export a name property, i.e. module.exports = { name:"my-extension", ... } in the case above. Although you don’t explicitly have to, it’s good practice to namethe extension after its package name.

The create method is not required. If it’s not provided, the extension will not receive its custom configuration.

Following is a description of the currently available hooks, in the order they are run.

Hook: preConfigure

The preConfigure hook is run, before the configuration groups are resolved. This allows extensions to manipulate,add and remove configuration groups.

The arguments passed to this hook are group and config.

For a usage example see buster-testbed-extension.

Hook: analyze

The analyze hook is run after the analyzer is created and can be used to flag issues about the code base.

The argument passed to this hook is analyzer.

buster-lint and buster-syntax uses the hook to warn about lint and syntax errors.

Proper documentation for the analyzer is pending. For now, refer to buster-lint for a usage example.

Hook: beforeRun

The beforeRun hook is run, after the test run configuration is fully loaded, but before the test runner has beeninitialized.

Currently the hook doesn’t receive arguments.

Hook: configure

The configure hook allows extensions to manipulate Resource sets assigned to a test run. Resource sets contain allfiles and other resources required for a test run. You can use this hook to modify only sources, only tests, frameworkresources, everything or any other combination. Read the documentation for buster-configuration to understand howfiles are loaded and how you can hook into that process.

To implement this hook, simply provide a configure method on your extension object. The following exampleadds a resource to the framework group:

162 Chapter 3. Project resources

Page 167: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

module.exports = {create: function (options) {

var instance = Object.create(this);instance.options = options;return instance;

},

configure: function (group) {group.on("load:framework", function (resourceSet) {

resourceSet.addResource({path: "/oh-yeah.js",content: "buster.log('Extension calling!');"

});});

}};

Hook: testRun

The testRun hook is executed right before tests are run. It receives one or two arguments, depending on theenvironment.

Browser environment: testRunner, messagingClient

Both arguments are event emitters. The testRunner is a “remoteRunner” (not yet documented). It behaves like aTest runner, i.e. it emits all the same events. However, because the run potentially includes more than one browser,the remote runner wraps all test cases in an additional top-level context which is named after the browser that ran it.

The messagingClient contains all raw messages emitted in the browsers. The messages are wrapped in anenvelop that also contains information about the browser that sent it:

{data: { name: 'My context' },topic: 'context:start',clientId: 'eaebee40-ff08-4fcd-bc97-2da569e837c3',client: { emit: [Function] }

}

Node environment: testRunner

Node tests only receives a single runner argument. It is a plain Test runner.

3.5 Roadmap

This is a rough road map of how we imagine getting Buster.JS to a rock solid v1.0. When we slap Buster.JS with thebig ‘ole “1.0”, we guarantee that:

• Tests will not break (false positives/negatives, other breakage) when upgrading Buster.JS

• Extensions will not break from one release to another

• The APIs that make up Buster.JS will stay backwards-compatible

3.5. Roadmap 163

Page 168: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

• The testing experience will be stable and fun

• Buster.JS works equally well on Linux, Windows and OSX

Another goal of 1.0 is to have APIs that we feel gives us some room to “grow” new features in the future. Obviously,this is a “soft goal”, and one that’s hard to quantify, but it will at least account for some of the more lofty dreams wecurrently have.

3.5.1 When will you support Windows?

Windows support is a requirement for us to tag Buster.JS with “1.0”, but we haven’t planned it in more detail than that.

3.5.2 Buster.JS 0.6 (AKA Beta 4)

Beta 4 is expected in early June 2012. It features several rewritten/reworked modules, deprecates some old ones, andshould generally vastly improve the stability of browser tests. It will also improve browser support for older browsers.

Highlights

• New buster-capture-server. A more stable implementation, better handling of connection edge-cases,better suited for older browsers.

• Revamped buster-server CLI. Mostly interesting for people looking to reuse Buster.JS’ server compo-nents for other testing frameworks. The new implementation allows skinning and customization, and separatesit from the implementation of other CLIs.

• Revamped buster-test CLI Huge changes in APIs, focusing on reusability. The CLI is now completelygeneric, and does not come with any pre-existing knowledge about the Buster.JS testing framework. Thespecifics are injected at runtime, which means the buster-test “binary”/script. Some minor tweaks inuser-facing behavior.

• Any module that does not have pending changes will be tagged as 1.0.

Status

• The browser-runner in the buster-test CLI is close to complete

• Some pending API additions in the capture server’s client

3.5.3 Buster.JS 0.7 (AKA Beta 5/RC 1)

The final “big” changes will land. Bug fixes. New documentation site.

Highlights

• Naming changes. See thread #1, and thread #2 Most importantly, some generally useful modules gain fullystand-alone names (i.e. they’ll drop the buster- prefix and/or change names altogether).

• Internal browser modules will use AMD to avoid leaking globals.

• buster-resources API change. The proposed change gives resources the ability to have multiple representa-tions, based on the desired content type. This will significantly up the game for extensions that make big changesto resources, such as compile-to languages and other pre-processors.

164 Chapter 3. Project resources

Page 169: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

• buster-test changes. Currently, every configuration group is run as isolated test runs, and the dots reporterhas a very specific mode for the multi-browser runs. The proposed change fixes both of these by representingall configuration groups with a test runner. All of them will be coordinated by a master “multi runner”, and thisis where you plug in the reporters etc. This removes some duplication in the implementation, makes it possibleto have e.g. one XML report for any number of buster.js configuration files, and makes environments a nativepart of the test runner/reporters.

• New documentation site. Work is being put into a new documentation site based on Sphinx. There are plans forAPI docs to be extracted from module Readme’s and source code. The site is proposed to launch with Buster.JS0.7.

• buster-assertions 1.0. There’s currently a pending change for assert.exception. Additionally, buster-assertions’ equals and match algorithms will be extracted into a separate module (that among others Sinon.JSwill use).

Status

Not yet in progress. Expected to complete early July, but may delay into August due to vacations and so on. This pagewill be updated with todo items and individual progress when 0.6 is out.

3.5.4 Release candidates

If necessary, we will fix bugs and iron out issues from 0.7 and release as successive RC’s until things stableize. At thispoint, we expect roughly one RC per week/two weeks until we hit the sweet-spot, which is...

3.5.5 Buster.JS 1.0

Buster.JS 1.0 will be released when 0.7 has been tested in the wild, any breaking bugs have been fixed, and all currentextensions have been updated to accommodate for API changes etc. buster-static will likely not be includedwith 1.0, but installable as an add-on.

3.5.6 Buster.JS 1.1

A revamped buster-static that can do both Node.js and browser tests from within the browser is included in thedefault installation.

Installers for OS X and Windows.

buster-ci a new binary that can automate everything - start server, capture browsers, run tests, wind down. Head-less testing. See this thread for the current draft, and pitch in your own ideas/requirements.

3.6 Changelog

Here you find details about what has changed with each release of Buster.JS.

3.6.1 v0.7.18

Released 2014-12-17.

• breaking change for buster-ci, arguments can now be passed to test run

3.6. Changelog 165

Page 170: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

3.6.2 v0.7.17

Released 2014-10-31.

• Version for referee increased, which has changed the direction of dependency between referee.js andexpect.js.

3.6.3 v0.7.16

Released 2014-10-23.

• buster-autotest uses now chokidar instead of fs-watch-tree

3.6.4 v0.7.15

Released 2014-10-20.

• Fix for issue #396 - Async test case continues to execute after assertion failure.

• handleUncaughtError now allows more than 3 arguments.

• buster-ci

3.6.5 v0.7.14

Released 2014-09-17.

• Fix for issue #416 - buster-server crash with IE 11 on W7 only if there is two browsers captured.

3.6.6 v0.7.13

Released 2014-05-05.

• Necessary modification for refactoring of buster-test (Remove runtime throttler and pre-event runtime).

3.6.7 v0.7.12

Released 2014-04-30.

• Fix for issue #404 - Add missing Sinon.JS behavior module.

• Expose buster.sinon.match for node.js

3.6.8 v0.7.11

Released 2014-04-04.

• Sinon version ~1.9

3.6.9 v0.7.10

Released 2014-03-19.

• Fix for issue #401 - env: noder: No such file or directory.

166 Chapter 3. Project resources

Page 171: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

3.6.10 v0.7.9

Released 2014-03-17.

• Fix for issue #400 - IE <= 8 throwing error: Object doesn’t support this action.

3.6.11 v0.7.4

Released 2013-09-17.

• New buster-server, aka Ramp. Vastly improved stability, better handling of misbehaving clients, faster.

• Windows support; installs and runs cleanly on Windows

• assert.equals now handles cyclic objects

• assert.equals no longer coerces arguments, so assert.equals(“10”, 10); used to pass, but will now fail

• The test runner now uses and supports providing random seeds for test ordering

• Allow to specify files to be excluded in config file (#292)

• Extact configuration values from query string when running static browser tests

• Almost half of the modules that make up Buster are now stable 1.x.y versions

• New default console reporter (dots reporter is gone)

• Test runner has new event suite:configuration that provides info on runtime (i.e. Browser, Node version), ex-pected number of tests, random seed.

• Tons of bug fixes

Breaking changes

• Sub-commands such as buster test are no longer supported, use the dashed versions buster-test.

• The property environment is no longer set to browser by default, it must be explicitly set in all configura-tion groups.

• assert, refute and other globals or gone. Buster only exposes the buster global now.

A quick work-around for the now missing globals is to create test/helper.js with

var assert = buster.assert;var refute = buster.refute;var expect = buster.expect;

And then add this to your configuration file:

module.exports["My config"] = {environment: "browser",sources: [...],tests: [...],testHelpers: ["test/helper.js"]

};

3.6. Changelog 167

Page 172: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Bug fixes

• sources key in config file isn’t parsed correctly when extending base configuration (#222)

• when using run the suite name is undefined (#238)

• beforeAll is not working properly with nested descriptions (#250)

• Failed creating session: EISDIR, read (#256)

• toEqual goes into infinite recursion for cyclic data (#258)

• buster-test returns undefined, when you use not known configuration key (#267)

• defer should work the same as “focus rocket” (#280)

• HTML runner displays undefined for test names (#300)

• async test returning resolved promise with truthy value is treated as an error (#308)

• Tests being skipped when extending Object.prototype (#342)

3.6.12 v0.6.13

Released 2013-09-16.

A frozen version of the 0.6.x series; locks all dependencies at specific versions.

3.6.13 v0.6.12 (formerly: v0.6.3)

Released 2012-12-22.

Update capture-server and use new implementation, “ramp”. This should vastly improve the stability of the server aswell as print proper error messages (and use correct exit codes) when the server is not running or has no connectedslaves.

This release also introduces a few of the 1.0-ready modules slated for 0.7, but few user-facing updates.

Breaking changes

No breaking changes in this release.

Additions

No additions in this release.

3.6.14 v0.6.11 (formerly: v0.6.2)

Released 2012-12-22.

Minor fix.

Breaking changes

No breaking changes in this release.

168 Chapter 3. Project resources

Page 173: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Additions

No additions in this release.

Bug fixes

• Exit code was always 1 (#221)

3.6.15 v0.6.2 - v.0.6.10

To be ignored.

3.6.16 v0.6.1

Released 2012-07-09.

Buster.JS 0.6.1 is a fairly small maintenance release, mostly correcting a bunch of bugs of minor/medium significance.

Breaking changes

No breaking changes in this release.

Additions

Buster.JS 0.6.1 ships with Sinon.JS 1.4.0, a significant update with lots of interesting new features, see Sinon.JSchangelog.

Bug fixes

• Cyclic objects in buster-format (#215)

• Exit code 1 for wrong arguments (#210)

• assert.equals and Prototype.js arrays (#206)

• Focus rocket on test case name (#200)

• Configure this.timeout in setUp and prepare (#199)

• Red status line when there are timeouts (#196)

• Exit code 1 when no tests are run (#195)

• assert.match with empty strings now passes (#178)

• Autotest and symlinks (#168)

• “Too much recursion” when combining stubs and cyclical data structures (#124 and #201)

• Clean up dangling proxy requests when test run completes (#117)

• Acknowledge Sinon mock expectations as assertions (#62)

• posix-argv-parser: Unknown short options “with extras” (i.e. -node) fails with a humanized error message.

3.6. Changelog 169

Page 174: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

3.6.17 v0.6.0 – Buster.JS Beta 4

Released 2012-06-20.

Beta 4 packs a lot of changes, increased stability and new features. Tests written for older versions do not need anysyntactical updates, while extensions and other “general API consumers” may.

Documentation is currently lacking. There will be a documentation sprint prior to 1.0, but probably not before the nextbeta. For planned progress, refer to Roadmap.

Breaking changes

This is a list of breaking changes in this release. Since we haven’t reached 1.0 stable yet, we’re taking the freedom tochange APIs without making them backwards compatible in the hope of making them better. There are a few morebreaking changes planned for the next (last) beta, see Roadmap.

Naming changes

In an effort to improve navigation in the many Buster.JS modules, we have started renaming some of them, as discussedon the mailing list. These naming changes will only affect you if you are depending on either of these modules in yourown projects.

• buster-resources is now ramp-resources (the capture server will eventually become “ramp”)

• buster-args is now posix-argv-parser

• buster-stdio-logger is now stream-logger

• sinon-buster is now buster-sinon

Command line interface buster-test

--log-all is gone. In Beta 3, Buster.JS would silence log messages for passing tests and this option wouldshow all messages. In Beta 4, Buster.JS shows all messages by default, and silences those from passing tests with--quiet-log.

Deprecated modules

Some modules are no longer needed and will not receive further upgrades:

• buster-client

• buster-bayeux-emitter

Extension hooks

Hooks fire in a given order. The beforeRun no longer comes with any arguments. To get hold of theanalyzer and configuration objects that used to be passed to it, implement analyze(analyzer) andconfigure(configuration) (called in that order) in addition.

170 Chapter 3. Project resources

Page 175: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

New features

The main theme of this release is a rewritten and vastly more stable capture server. Significant work has also been putinto making it easy to use the server and the related command-line interfaces with any test framework (e.g. it shouldnow be possible to use these tools to create a qunit-test binary that runs QUnit tests over the server).

Command-line interface buster-test

• --full-stacks disables the stack filter that’s used to hide Buster.JS internals from stack traces.

• Implementation and API-wise, the buster-test-cli module is now completely test framework-agnostic.The framework sources are injected as an extension in the “binary” script that uses. In other words, the Buster.JStest framework is now just a regular extension to the Buster.JS CLI tools. For an example, see buster-test.

Command-line interface buster-server

This CLI is now backed by a dedicated module that supports skinning and customization.

npm test

All modules now have a working npm test. All modules are also configured with continuous integration on TravisCI, but will need further love to make the setups work nicely on Travis (basically we have some ugly circular depen-dencies that needs to be done away with).

Analyzer improvements

The analyzer is the object that is used for quality assurance metrics, such as the lint extension.

• Errors can be objects with either a content or a message property for the error message. Support formessage is new.

• In addition to “OK” and “failed”, the analyzer can now have an “unclean” state, which means it’s passing, butdid receive non-fatal warnings or errors.

Autotest improvements

The autotest module has seen significant improvements through Magnar Sveen’s work on fs-watch-tree. The autotestcommand-line interface itself also received some usability upgrades. Autotest should now work flawlessly on Linuxand OSX (Windows unconfirmed at this point).

• Re-run all tests by tapping Ctrl-C. Hit Ctrl-C twice to stop. Currently only works for buster-autotest, notbuster autotest.

• Screen is cleared between each run.

Ramp resources improvements

• Don’t put duplicate objects in the cache

• Individual resources have cacheable: true|false. This means extensions can control cacheability (i.e. repeatabil-ity for warnings etc) on a very fine-grained level.

3.6. Changelog 171

Page 176: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

• Resource Etag changes when adding processors. Avoids caching issues: If an extension is added in a configura-tion file, the cache manifest would not update. With this change, any extension that adds processors will causethe cache manifest for affected resources to update, avoiding any stale cache lookups.

• Propagate resource content processor exceptions.

• Root resources can specify where to insert scripts by adding {{scripts}} to the template contents.

• Improve error message for missing paths.

• Path normalization now accounts for Windows paths.

• Only globbing once for appendLoad and prependLoad.

buster-test improvements (focus rocket!)

• Focus rocket: Sort of the opposite of a deferred test. Prepend any test name with the focus rocket “=>” and onlytests with the rocket will run. See this short screencast on it.

• The dots reporter tracks elapsed time.

• buster.testContext is now an event emitter, and:

buster.testContext.on("create", function () {});

takes over for:

buster.testCase.onCreate(function () {});

and:

buster.spec.onCreate(function () {});

~/.buster.js

The buster.js configuration file you put in your projects has a strict focus on project-related settings. This meansthat it intentionally does not support personal preferences like --color dim. This is where ~/.buster.js (or~/.buster.d/index.js if you prefer) enters. Currently the following settings can be provided:

• test.releaseConsole. If true, never capture the console.

• test.quietLog. If true, never print log messages for passing tests.

• test.color. One of “dim”, “bright” (default) or “none”.

To specify preferences, ~/.buster.js (or (~/.buster.d/index.js) should look like this:

module.exports = {"test.color": "dim"

// More settings as needed};

Partial Windows support

Windows support work is ongoing. In this version, Node tests with the buster-test command-line interface isworking, while the server and browser automation part is still not quite there. If you need Windows support, pleaseconsider chipping in.

172 Chapter 3. Project resources

Page 177: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Argv parsing

buster-args is now posix-argv-parser and has an overhauled API. Highlights:

• Support for transforms

• Support for types

• New, close-to-stateless API

Various additions

• buster-core Event emitter: it is now safe to remove a listener inside a listener.

• buster-core Event emitter: It is now possible to subscribe to all events with one call, obj.on(function(event, data) {});

• buster-core: Extracted tmpFile method from buster-configuration.

• buster-format Bug fix: hasOwnProperty issue on IE9.

• buster-lint: Prevent caching of files containing lint.

• buster-sinon: callOrder accepts array of spies.

3.6.18 v0.5.3

Released 2012-05-04.

Breaking changes

• TODO Fill out

Additions

• TODO Fill out

Bugs

• TODO Fill out

3.6.19 v0.5.2

Released 2012-05-02.

Breaking changes

No breaking changes in this release.

3.6. Changelog 173

Page 178: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Additions

• Allow --config/-c for buster test to accept a comma separated list of configuration files. (#171)

• Capture browser page displays how many browsers in total are captured.

Bugs

• buster-glob requires a newer glob, which solves a problem with same glob patterns in different working direc-tories.

• Use path.join for cross-platform paths (only partially solved)

3.6.20 v0.5.1

Released 2012-04-26.

Breaking changes

No breaking changes in this release.

Additions

• Only log messages (buster.log) for failed tests by default log all with --log-all/-L (#163)

• Added more detailed information about OS (Sasha Depold, buster-user-agent-parser #1, buster-test-cli #1)

Bugs

• assert.same now is compatible with ES Harmony “egal”. assert.equals recognizes NaN as equal toNaN. (#162)

3.6.21 v0.5.0 – Buster.JS Beta 3

Released 2012-04-17.

Breaking changes

This is a list of breaking changes in this release. Since we haven’t reached 1.0 stable yet, we’re taking the freedom tochange APIs without making them backwards compatible in the hope of making them better.

• testLibs removed, testHelpers added (#95)

This is a simple change of words. testHelpers resonates better with most uses of the property thantestLibs. It behaves like before, meaning that e.g. when you run single tests with buster test -ttest/my-test.js, everything in testHelpers will still be loaded.

• Some expectations changed names (#91)

We’re renaming some expectations, basically to match the expectations in Jasmine. We were already prettyclose to their API, and being 1:1 means way easier migration. Some expectations have also been added, you canfind them in the “Changes” section below.

174 Chapter 3. Project resources

Page 179: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

– toBeSameAs is now toBe. Example: expect(true).toBeTruthy()

– toBeInDelta is now toBeNear, aliased to toBeCloseTo. Example:expect(4.5).toBeCloseTo(4, 0.5)

– not() is now a property, not a function. Example: expect(false).not.toBeTruthy()

• Removed assertion

assert.typeOf was removed in favor of the more specific ones (e.g. assert.isString)

• buster.env.path is removed

Use buster.env.contextPath (was also available before beta 3) instead. Note thatbuster.env.contextPath does not include a trailing slash.

Additions

• buster-autotest works on all platforms where fs.watch is supported. Autotest is also slightly clever, onlyrunning affected tests on each save and running the entire suite when going from red to green.

• Adding support for JsTestDriver style /*:DOC+=<div>test</div>*/with the new extension buster-html-doc. This extension can be used both in vanilla buster tests and alongside buster-jstestdriver. (#47)

• The body of the testbed HTML in browser tests will now reset between each test run. It will not be cleared outentirely, it will be set to what it was initially. Note: this is not yet fixed in buster-static. (#74)

• Added new expectations toContain, toBeTruthy and toBeFalsy. (#91)

• Added new assertion contains (#91)

• Added new CLI option, --release-console, to buster test. Buster now proxies all console log-gings to buster.log by default, and you can use this setting to disable it. (#96)

• Highlighting uncaught exceptions with colors to make them stand out. (#105)

• The reporters now let you know if a timeout happened in setUp, tearDown or in the test itself. (#12)

• Proper exit codes for failing tests and other error situations (buster test) (#81)

Bugs

• Fixed some bugs in server proxying for browser tests (#57)

• Browser tests now fail when a test times out when there are successful tests in the same test run. (#77)

• Browser tests now fail when there’s no assertions in a test. (#69)

• buster.log(function(){}); would log undefined, as it called the function because of internals inbuster-evented-logger. It no longer calls the function, and logs what you’d expect it to log. (#94)

• Asserts are now counted properly in the JsTestDriver extension. (#49, #31)

• At some point in time, an unknown change fixed a small problem with assert.calledOnce. Nobodyknows what, where and why. (#70)

• No longer running setUp/tearDown for deferred tests. (#107)

• Chrome no longer periodically reloads the entire slave frameset when the tab is in the background. (#84)

• Browser tests fail properly when there’s no assertions in a test. (#69)

• buster-static now properly made available when installing buster (#43)

• Supporting "// deferred tests" in the BDD syntax as well. (#55)

3.6. Changelog 175

Page 180: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

• Removing the use of Array.some and Object.create in browser code, for old browser compat. (#121,#120)

• extends on config groups now also copy extensions and other custom configurations. (#100)

• Failing assertions are counted as assertions by the test runner. (#87)

• Only installing one version of Sinon. (#14)

• toBeCalledWith expectation now works when the stub/spy is called multiple times. (#82)

• Properly counting assertions in buster-jstestdriver. (#49)

• Making jstestdirver.jQuery available in buster-jstestdriver. (#48)

• Now failing for non-existant files in the config file. (#78)

• Status code is now non-zero when buster test fails with test errors etc. (#81)

• Dot reporter wraps lines. (#32)

• No longer warning with syntax error for files where the last line is a comment. (#144)

• Fixing assert.exception failures causing stack overflows. (#63)

• Logging a function no longer logs "undefined". (#94)

• XML reporter now reports uncaught exceptions. (#134)

• Dots reporter wraps lines when they become too long

• Uncaught exceptions does not print overlapping with dots

• Proper support for asynchronous test cases/specs (#15)

3.6.22 v0.4.0 – Buster.JS Beta 2

Released 2012-02-21.

This is a brief (i.e. not exhaustive) overview of changes from Beta 1. Beta 2 introduces quite a few fundamentalrefactorings and rewrites, and is significantly closer to a stable 1.0 release than its predecessor.

With Beta 2, we’ve entered a more rapid iterative development and release cycle. In the four days since the initialrelease, three patch updates have already been shipped. “Beta 2” refers to Buster.JS version 0.4.1 or newer, until wedecide to do a release candidate (or another major beta, if necessary).

Problems?

Please report as many issues as you can, and consider contributing docs or file feature requests so we can improvedocumentation. Docs are behind on some things, but we’re working on it.

Breaking change: Config files can no longer read files outside of rootPath

Since we haven’t reached 1.0 stable yet, we’re changing APIs without making them backwards compatible.

Configuration file loading is revamped (most importantly, buster-resources was completely rewritten).

sources, tests, etc can no longer contain paths outside the root path. The root path defaults to the path theconfiguration file is in. You can also provide the rootPath property in the configuration file to base the projectoutside the directory where the configuration file is located.

176 Chapter 3. Project resources

Page 181: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

config["My tests"] = {sources: ["../src/**/*.js"], // Will not work!tests: ["**/*-test.js"]

};

config["My tests"] = {rootPath: "../", // Will work (or just move the config file up one folder)sources: ["src/**/*.js"],tests: ["tests/**/*-test.js"]

};

Changes

• Stronger Node.JS inferences across the board.

• Capture server: significant refactor. “Clients” are now “slaves” and several URLs have changed.

• Configuration file can now load extensions. A few are already availble, and others, like buster-amd (#15) andcoverage is right around the corner.

• buster-promise is now deprecated and will not receive further updates. We recommend the wonderful when.jsinstead–it’s what we use.

• Buster now syntax checks files before attempting to run tests in browsers. This ensures a stable environmentwith good feedback, regardless of target browser.

• The test runner was rewritten. It now supports per-test timeouts, the done callback can be used to wrap functions(“we’re done when this function is called”), asynchronous testCase and describe, and TeamCity reporter.

• The test runner now has a system for including other measures in a test run, issuing warnings, or even preventingtests from running at all. The first external tool included in this system is buster-lint. Expect more thoroughdocumentation of this system as it evolves.

3.6.23 v0.3.0 – Buster.JS Beta 1

The beta is upon us!

See getting started and the overview for usage, installation, features, etc.

So far we have QUnit style static html page testing, JsTestDriver style browser automation, and node testing. We havestubbing and mocking, setUp and tearDown, asynchronous tests, hybrid browser/Node tests, and much more.

We don’t have a super stable 1.0 that you can connect to a zillion old browsers to and have it run in a stable fashion inyour CI environment. Getting there requires field testing, and that’s where you come in.

You will run into issues, and when you do, we want to know about them. Please don’t hesitate posting issues in theissue tracker.

See also mailing list, #buster.js at irc.freenode.net, and @buster_js at Twitter.

Known issues

IE7 and lower, and Safari, doesn’t work with buster server. You can still use buster static to run yourtests in these browsers.

3.6. Changelog 177

Page 182: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

Roadmap

• Running browser tests without a browser and a server via PhantomJS

• Stability for CI environments etc.

• ...and more. This list is incomplete.

3.7 Licenses

Buster.JS is open source software. You are free to use, modify, and distrbute the source code and documentation underthe following licenses.

3.7.1 Source code license

The Buster.JS source code is licensed under the Simplified BSD license.

3.7.2 Documentaton license

The Buster.JS documentation is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported license.

178 Chapter 3. Project resources

Page 183: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Index

Symbols-C, –color

buster-test command line option, 94-F, –fail-on

buster-test command line option, 94-L, –log-all

buster-test command line option, 94-R, –reset

buster-test command line option, 94-W, –warnings

buster-test command line option, 94-c, –config

buster-test command line option, 94-e, –environment

buster-test command line option, 94-g, –config-group

buster-test command line option, 94-h, –help

buster-test command line option, 94-l, –log-level

buster-test command line option, 94-o, –release-console

buster-test command line option, 94-p, –static-paths

buster-test command line option, 94-r, –reporter

buster-test command line option, 94-s, –server

buster-test command line option, 94-t, –tests

buster-test command line option, 94-v, –verbose

buster-test command line option, 94

AalwaysCalledOn() (built-in function), 123alwaysCalledWith() (built-in function), 125alwaysCalledWithExactly() (built-in function), 126alwaysThrew() (built-in function), 127argumentResult.isSet (argumentResult attribute), 102

argumentResult.timesSet (argumentResult attribute), 102argumentResult.value (argumentResult attribute), 102assert() (built-in function), 108AssertionError() (class), 134

BbrowserInfo.browser (browserInfo attribute), 138browserInfo.platform (browserInfo attribute), 138browserInfo.version (browserInfo attribute), 138buster-test command line option

-C, –color, 94-F, –fail-on, 94-L, –log-all, 94-R, –reset, 94-W, –warnings, 94-c, –config, 94-e, –environment, 94-g, –config-group, 94-h, –help, 94-l, –log-level, 94-o, –release-console, 94-p, –static-paths, 94-r, –reporter, 94-s, –server, 94-t, –tests, 94-v, –verbose, 94

buster.bind() (buster method), 43buster.create() (buster method), 43buster.emit() (buster method), 37buster.env.contextPath (buster.env attribute), 36buster.env.id (buster.env attribute), 36buster.extend() (buster method), 43buster.functionName() (buster method), 44buster.nextTick() (buster method), 44buster.on() (buster method), 37buster.testCase() (buster method), 79

Ccalled() (built-in function), 120calledOn() (built-in function), 123

179

Page 184: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

calledOnce() (built-in function), 121calledOnceWith() (built-in function), 125calledThrice() (built-in function), 122calledTwice() (built-in function), 122calledWith() (built-in function), 124calledWithExactly() (built-in function), 125callOrder() (built-in function), 121captureServerModule.createServer() (captureServerMod-

ule method), 33captureServerModule.createServerClient() (capture-

ServerModule method), 34captureServerModule.createSessionClient() (capture-

ServerModule method), 35className() (built-in function), 118config.addGroup() (config method), 41config.filterEnv() (config method), 41config.filterGroup() (config method), 41config.groups (config attribute), 40config.resolveGroups() (config method), 40configGroup.resolve() (configGroup method), 41configGroup.resourceSet (configGroup attribute), 41configGroup.setupFrameworkResources() (configGroup

method), 41contains() (built-in function), 118

Ddefined() (built-in function), 110dotsReporter.create() (dotsReporter method), 61dotsReporter.listen() (dotsReporter method), 61

Eequals() (built-in function), 109eventedLogger.create() (eventedLogger method), 95eventEmitter.addListener() (eventEmitter method), 44eventEmitter.create() (eventEmitter method), 44eventEmitter.emit() (eventEmitter method), 45eventEmitter.hasListener() (eventEmitter method), 45eventEmitter.on() (eventEmitter method), 44eventEmitter.once() (eventEmitter method), 45eventEmitter.removeListener() (eventEmitter method), 45exception() (built-in function), 116expect.toBe() (expect method), 128expect.toBeArray() (expect method), 129expect.toBeArrayLike() (expect method), 130expect.toBeBoolean() (expect method), 129expect.toBeDefined() (expect method), 128expect.toBeFalse() (expect method), 129expect.toBeFunction() (expect method), 129expect.toBeGreaterThan() (expect method), 128expect.toBeLessThan() (expect method), 128expect.toBeNaN() (expect method), 129expect.toBeNear() (expect method), 130expect.toBeNull() (expect method), 128expect.toBeNumber() (expect method), 129

expect.toBeObject() (expect method), 129expect.toBeString() (expect method), 129expect.toBeTrue() (expect method), 129expect.toContain() (expect method), 130expect.toEqual() (expect method), 128expect.toHaveBeenCalled() (expect method), 130expect.toHaveBeenCalledOnce() (expect method), 131expect.toHaveBeenCalledOnceWith() (expect method),

131expect.toHaveBeenCalledThrice() (expect method), 131expect.toHaveBeenCalledTwice() (expect method), 131expect.toHaveBeenCalledWith() (expect method), 131expect.toHaveClassName() (expect method), 130expect.toHaveKeys() (expect method), 130expect.toHavePrototype() (expect method), 130expect.toHaveTagName() (expect method), 130expect.toMatch() (expect method), 128expect.toThrow() (expect method), 130

Fformat.ascii() (format method), 46format.ascii.array() (format.ascii method), 48format.ascii.constructorName() (format.ascii method), 48format.ascii.element() (format.ascii method), 48format.ascii.func() (format.ascii method), 47format.ascii.functionName() (format.ascii method), 47format.ascii.object() (format.ascii method), 48format.excludeConstructors (format attribute), 48format.quoteStrings (format attribute), 48

Ggreater() (built-in function), 110

HhasPrototype() (built-in function), 117htmlReporter.create() (htmlReporter method), 66htmlReporter.listen() (htmlReporter method), 67

IisArray() (built-in function), 115isArrayLike() (built-in function), 116isBoolean() (built-in function), 114isFalse() (built-in function), 114isFunction() (built-in function), 113isNaN() (built-in function), 115isNull() (built-in function), 111isNumber() (built-in function), 115isObject() (built-in function), 113isString() (built-in function), 114isTrue() (built-in function), 114

JjsonProxyReporter.create() (jsonProxyReporter method),

69

180 Index

Page 185: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

jsonProxyReporter.listen() (jsonProxyReporter method),69

Kkeys() (built-in function), 116

Lless() (built-in function), 110loadPath.append() (loadPath method), 54loadPath.clear() (loadPath method), 54loadPath.paths() (loadPath method), 54loadPath.prepend() (loadPath method), 54loadPath.remove() (loadPath method), 54logger.debug() (logger method), 97logger.error() (logger method), 97logger.format() (logger method), 96logger.level (logger attribute), 98logger.log() (logger method), 97logger.warn() (logger method), 97loggerEnvelope.level (loggerEnvelope attribute), 98loggerEnvelope.message (loggerEnvelope attribute), 98loggerOptions.formatter (loggerOptions attribute), 98loggerOptions.level (loggerOptions attribute), 98loggerOptions.levels (loggerOptions attribute), 98

Mmatch() (built-in function), 111

Nnear() (built-in function), 117

Oopt.defaultValue (opt attribute), 101opt.hasValue (opt attribute), 101opt.requiresValue (opt attribute), 101opt.signature (opt attribute), 101opt.transform (opt attribute), 101opt.validators (opt attribute), 101

PposixArgvParser.addShorthand() (posixArgvParser

method), 100posixArgvParser.create() (posixArgvParser method), 100posixArgvParser.createOperand() (posixArgvParser

method), 100posixArgvParser.createOption() (posixArgvParser

method), 100posixArgvParser.parse() (posixArgvParser method), 100prefJar.get() (prefJar method), 107prefJar.namespace (prefJar attribute), 107prefJar.source (prefJar attribute), 107prefsink.create() (prefsink method), 107prefsink.findFile() (prefsink method), 106

prefsink.findFileSync() (prefsink method), 106prefsink.home (prefsink attribute), 106prefsink.load() (prefsink method), 107prefsink.loadSync() (prefsink method), 107prefsink.locations (prefsink attribute), 106

QquietReporter.create() (quietReporter method), 64quietReporter.listen() (quietReporter method), 64

Rreferee.add() (referee method), 132referee.count (referee attribute), 134referee.fail() (referee method), 131referee.format() (referee method), 132refute() (built-in function), 108resourceMiddleware.create() (resourceMiddleware

method), 50resourceMiddleware.mount() (resourceMiddleware

method), 50resourceMiddleware.respons() (resourceMiddleware

method), 50resourceMiddleware.setContextPath() (resourceMiddle-

ware method), 50resourceSet.addCombinedResource() (resourceSet

method), 53resourceSet.addFileResource() (resourceSet method), 53resourceSet.addFileResources() (resourceSet method), 52resourceSet.addGlobResource() (resourceSet method), 52resourceSet.addResource() (resourceSet method), 52resourceSet.addResources() (resourceSet method), 52resourceSet.appendLoad() (resourceSet method), 53resourceSet.concat() (resourceSet method), 53resourceSet.create() (resourceSet method), 52resourceSet.deserialize() (resourceSet method), 51resourceSet.get() (resourceSet method), 53resourceSet.length (resourceSet attribute), 52resourceSet.loadPath (resourceSet attribute), 53resourceSet.prependLoad() (resourceSet method), 53resourceSet.remove() (resourceSet method), 53resourceSet.serialize() (resourceSet method), 53resourceSetCache.create() (resourceSetCache method),

50resourceSetCache.inflate() (resourceSetCache method),

51resourceSetCache.resourceVersions() (resourceSetCache

method), 51resourceSetPayload.load (resourceSetPayload attribute),

54resourceSetPayload.resources (resourceSetPayload

attribute), 54

Ssame() (built-in function), 109

Index 181

Page 186: Release 0.7 Christian Johansen and August Lilleaas · A browser JavaScript testing toolkit. It does browser testing with browser automation (think JsTestDriver), QUnit style static

Buster.JS Documentation, Release 0.7

server.attach() (server method), 33serverClient.connect() (serverClient method), 34serverClient.createSession() (serverClient method), 34serverClient.disconnect() (serverClient method), 34sessionClient.connect() (sessionClient method), 35sessionClient.disconnect() (sessionClient method), 35sessionClient.emit() (sessionClient method), 35sessionClient.end() (sessionClient method), 36sessionClient.on() (sessionClient method), 35slave.browser (slave attribute), 57slave.os (slave attribute), 57slave.platform (slave attribute), 57slave.userAgent (slave attribute), 57slave.version (slave attribute), 57spec.describe() (spec method), 71specificationReporter.create() (specificationReporter

method), 62specificationReporter.listen() (specificationReporter

method), 63stackFilter() (built-in function), 78stackFilter.filters (stackFilter attribute), 78stackFilter.match() (stackFilter method), 78

TtagName() (built-in function), 118test.context (test attribute), 85test.deferred (test attribute), 85test.func (test attribute), 85test.name (test attribute), 85testContext.contexts (testContext attribute), 85testContext.name (testContext attribute), 85testContext.parent (testContext attribute), 85testContext.setUp (testContext attribute), 85testContext.tearDown (testContext attribute), 85testContext.testCase (testContext attribute), 85testContext.tests (testContext attribute), 85testRunner.assertionCount() (testRunner method), 91testRunner.assertionFailure() (testRunner method), 92testRunner.create() (testRunner method), 91testRunner.onCreate() (testRunner method), 91testRunner.run() (testRunner method), 91testRunner.runSuite() (testRunner method), 91testRunnerOptions.failOnNoAssertions: (testRunnerOp-

tions attribute), 92testRunnerOptions.handleUncaughtExceptions (testRun-

nerOptions attribute), 93testRunnerOptions.timeout (testRunnerOptions attribute),

92threw() (built-in function), 126throwOnFailure (None attribute), 134

UuserAgentParser.parse() (userAgentParser method), 138

Vvalidators.directory() (validators method), 103validators.file() (validators method), 103validators.fileOrDirectory() (validators method), 103validators.integer() (validators method), 102validators.number() (validators method), 103validators.required() (validators method), 102

XxmlReporter.create() (xmlReporter method), 65xmlReporter.listen() (xmlReporter method), 65

182 Index


Recommended