node package manager

marko-devtools

Marko DevTools

Developer tools for Marko.

Installation

Global installation:

npm install marko-devtools --global

Local installation:

npm install marko-devtools --save-dev

Usage

marko <command> arg0 arg1 ... argn

Example:

marko test src/components/app-foo

Command line interface (CLI)

Core commands

create

Used to create a template Marko project in a specific directory.

Usage:

Create a Marko project in the current directory:

marko create myapp

Create a Marko project in a specific directory:

marko create myapp --dir /Users/me/Desktop

test

Used to run unit tests for UI components. See Component Testing below for more details on how to write unit tests for UI components.

Usage:

Run all of the tests in a project/directory:

marko test

Run all of the unit tests for a single UI component:

marko test src/components/app-foo

Run all of the unit tests for all UI components:

marko test src/components/

Run only server tests:

marko test src/components/ --server

Glob patterns

marko test **/test/test.js

Component testing

Marko DevTools includes a testing framework (built on top of mocha) that targets UI components built using Marko or Marko Widgets. Each UI component is expected to have a test/ directory that consists of one or more JavaScript test files with a name in any of the following formats:

  • test.js - runs only in the browser
  • test.server.js or test-server.js - runs only on the server
  • test.browser.js or test-browser.js - runs only in the browser

An optional prefix can also be provided for grouping tests:

  • foo.test.js or foo-test.js
  • foo.test.server.js or foo-test-server.js
  • foo.test.browser.js or foo-test-browser.js

Below is a sample set of tests:

/* globals test */
 
var expect = require('chai').expect;
 
 
test('variant-danger', function(context) {
    var output = context.render({ variant: 'danger' });
    expect(output.html).to.contain('app-button-danger');
});
 
// A similar test can be done using jQuery selectors (powered by cheerio): 
test('variant-info', function(context) {
    var output = context.render({ variant: 'info' });
    expect(output.$('button').attr('class')).to.equal('app-button app-button-info');
});
 
// Async test: 
test('my async test', function(context, done) {
    setTimeout(function() {
        done();
    }, 100);
});
 
// Use test.only to only run a single test: 
test.only('foo', function(context) {
    // ... 
});
 
// Use test.skip to skip tests 
test.skip('bar', function(context) {
    // ... 
});

Component testing API

Globals

it(desc, [done])

test(desc, context[, done])

test.only(desc, context[, done])

test.skip(desc, context[, done])

Context

render(data) : RenderResult

RenderResult

$(selector)

Returns a jQuery-compatible object for querying the rendered DOM. Utilizes cheerio.

html

The output HTML string.

component

In-browser only

Returns a rendered instance of the component.

widget

In-browser only

This is an alias for the above component getter.

Snapshots

When a component is rendered, a snapshot of the HTML output will automatically be saved into the test/snapshots/ directory. This directory should be excluded from source control. For example:

.gitignore

**/test/snapshots/

Code coverage

Use nyc to generate coverage reports. Just prefix any test commands with nyc:

nyc marko test

Plugins

Marko DevTools supports plugins as JavaScript functions:

module.exports = function(markoDevTools) {
    // Run any initialization code: 
    require('app-module-path').addPath(__dirname);
 
    // Register new commands... 
    // 
    // Add support for: `marko my-command arg0 arg1 ... argn` 
    markoDevTools.addCommand('my-command', {
        run(options) {
            return new Promise((resolve, reject) => {
                // Run the command 
            });
        },
 
        parse(args) {
            var options = {};
            return options;
        }
    });
 
    markoDevTools.plugin(require('marko-devtools-my-plugin'));
}

You can provide a package-specific plugin by creating a marko-devtools.js file at the root of your project:

my-app/.marko-devtools.js:

module.exports = function(markoDevTools) {
    // ... 
}

A package-specific plugin will automatically be loaded when marko is launched.

Some options can be specified on the config object that markoDevTools exposes.

For example, shared test dependencies can be specified with the dependencies option.

module.exports = function(markoDevTools) {
    markoDevTools.config.browserTestDependencies = [
        'bluebird/js/browser/bluebird.core.js',
        'require-run: ./tools/myDependency.js',
    ];
}

For more info on how to specify dependencies can be found here.

Lasso plugins and transforms can also be specified using the browserBuilder option.

module.exports = function(markoDevTools) {
    markoDevTools.config.browserBuilder = {
        plugins: [
            'lasso-marko',
            'lasso-less'
        ],
        require: {
           transforms: [
               {
                   transform: 'lasso-babel-transform'
               }
           ]
        }
    };
}

TODO

  • Don't write compiled templates to disk
  • Allow mocks for custom tags
  • File watching when running tests
    • marko test --watch
  • Helper API for simulating DOM events
  • Plugin API for adding helpers to context
  • In-browser UI component viewer with file watching
    • Drop down for inputs
    • Editor for input data
  • In-browser project explorer (with links to run browser tests and view UI components)
  • Image snapshots
  • Testing in jsdom
  • Launching tests in multiple browsers (both headless and real browsers)