Supported technologies: Browserify

Wallaby.js supports browserify via the wallabify postprocessor.

Installation

npm install wallabify --save-dev

Usage

// Wallaby.js configuration

var wallabify = require('wallabify');
var wallabyPostprocessor = wallabify({
    // browserify options, such as
    // insertGlobals: false
  }
  // you may also pass an initializer function to chain other
  // browserify options, such as transformers
  // , b => b.exclude('mkdirp').transform(require('babelify'))
);

module.exports = function () {
  return {
    // set `load: false` to all of the browserified source files and tests,
    // as they should not be loaded in browser,
    // their browserified versions will be loaded instead
    files: [
      {pattern: 'src/**/*.js', load: false}
    ],

    tests: [
      {pattern: 'test/**/*Spec.js', load: false}
    ],

    postprocessor: wallabyPostprocessor,

    setup: function () {
      // required to trigger tests loading
      window.__moduleBundler.loadTests();
    }
  };
};

You may find the working sample of wallaby.js configuration for browserify in this repository.

browserify

Browserify options

To make your tests run as fast as possible, specify only the options you need for your tests to run – avoid doing anything that would make each test run slower. When possible, consider using b.ignore(file) for dependencies that you don’t test and that your tests don’t depend on.

You don’t need to specify any output options because wallabify doesn’t use concatenated bundle. While concatenating files is beneficial for a production environment, in a testing environment it is different. Serving a large bundle every time one of many files (that the bundle consists of) changes is wasteful. So instead, each compiled module code is passed to wallaby, wallaby caches it in memory (and when required, writes it to disk) and serves each requested module file separately to properly leverage browser caching.

For your tests you don’t have to use the module bundler transformers; where possible, you may use wallaby.js preprocessors instead. For example, if you are using ES6 or JSX, instead of using .transform(require('babelify')) in the initializer function, you may specify wallaby.js preprocessor(s) or, better, compiler(s):

    files: [
      {pattern: 'src/**/*.js', load: false}
    ],

    tests: [
      {pattern: 'test/**/*Spec.js', load: false}
    ],

    compilers: {
      '**/*.js*': wallaby.compilers.babel()
    },

    postprocessor: wallabyPostprocessor

TypeScript and CoffeeScript

Please note that if you are using CoffeeScript or TypeScript, then you need to use a built-in compiler instead of a transformer, because with a transformer in the postprocessor, it is too late for wallaby to instrument the resulting JavaScript. Compilers should just work without any additional configuration, unless you need to pass some compiler specific options for TypeScript or CoffeeScript.

Files and tests

All source files and tests (except external files/libs) must have a load: false set, as wallaby will load browserified versions of these files on the window.__moduleBundler.loadTests() call in setup function. Node modules should not be listed in the files list; they are loaded automatically.

The order of source files does not matter, so patterns can be used instead of listing all the files.

The code inside each file is wrapped in such a way that, when the file is loaded in browser, it doesn’t execute the code immediately. Instead, it just adds some function that executes the file code to the test loader’s cache. Tests and dependent files are loaded from wallaby setup function, by calling __moduleBundler.loadTests(), and then executed.

Entry patterns

By default wallaby.js uses your tests as entry points for Browserify compilation. The rest of files are just require-ed from test files.

If you would like to load other files into the test sandbox without having to require them, you may just specify those files in your files list with load: true (default) flag. These files will just be loaded into the sandbox via script tags.

Sometimes you may also want to load some files that require other files, so they need to be compiled with Browserify. To support the scenario, wallabify has a configuration option called entry patterns, where you may specify all entry points for Browserify compilation done by wallaby.js. In this case, it will be your tests and those other files that you would like to load (and compile with Browserify) before your tests.

So, for example, if you have a fixture.js file that requires other files of your app and you would like it to be compiled by Browserify and loaded into the sandbox, then your wallaby config may look like:

var wallabify = require('wallabify');
var wallabyPostprocessor = wallabify({
        entryPatterns: [
                'fixture.js',
                'src/**/*.spec.js'
                ]
});

return {
        files: [
            // test libraries (chai, sinon, sinon-chai)
            // NOTE that with npm >=3 the file structure may be different
            {
              pattern: 'node_modules/karma-sinon-chai/node_modules/chai/chai.js',
              instrument: false
            },
            {
              pattern: 'node_modules/karma-sinon-chai/node_modules/sinon/pkg/sinon.js',
              instrument: false
            },
            {
              pattern: 'node_modules/karma-sinon-chai/node_modules/sinon-chai/lib/sinon-chai.js',
              instrument: false
            },

            { pattern: 'src/**/*.js', load: false },
            { pattern: 'fixture.js', load: false },
            { pattern: 'src/**/*.spec.js', ignore: true }
        ],

        tests: [
            { pattern: 'src/**/*.spec.js', load: false }
        ],

        postprocessor: wallabyPostprocessor,

        // I'll assume that you are using ES6 and mocha
        compilers: {
            '**/*.js': wallaby.compilers.babel({
                 /* babel options
                  * like `stage: n` for Babel 5.x or `presets: [...]` for Babel 6
                  * (no need to duplicate .babelrc, if you have it, it'll be automatically loaded) */
            })
        },

        testFramework: 'mocha',

        setup: function () {
            window.expect = chai.expect;
            window.__moduleBundler.loadTests();
        }
    };

Please note, that if you are using default TypeScript compiler with entry patterns, you need to specify entry patterns with .js extension because the compiler is executed before the wallabify postprocessor and it renames compiled files by default.

Proxyquireify

If you’d like to use Proxyquireify with wallaby.js, click here to see how to do it.

More configuration examples

You may find a few projects with wallaby.js configuration for Browserify below.