Home

Awesome

Atomus


A small utility library for testing client-side code in Node.js environment. Simulate the browser in your terminal.

The problem

We all know about Selenium and PhantomJS. They work well for testing client-side code. We may visit a page, fill forms, click buttons etc. However, it gets complex if we want to test only part of our application. We have to create a page that contains only the needed pieces. This definitely does not scale.

Atomus is helpful during unit or functional testing. That's where the name came from. It works good with the atoms of your application. You simply include your framework and the module that needs testing. Then create an instance and start playing with the DOM and the module's API.

Installation

npm install atomus

Simple usage

All you have to do is to require the module, call the ready method:

var htmlStr = '<body><h1>Atomus</h1></body>';
var atomus = require('atomus');
var browser = atomus().html(htmlStr).ready(function(errors, window) {
  ...
});

The window that is passed to our callback is the good old Window object that we have in every browser. Thankfully to jsdom we have a JavaScript implementation of the WHATWG DOM and HTML standards. So we may call window.document.querySelector or element.dispatchEvent. In practice we may interact with the page as we are in a real browser.

API

Once the ready method is called we have a few other methods and objects available.

JSDom has some problems with radio and checkboxes selecting. That's why we introduced API methods for triggering events. For sure you may use $('#link').trigger('click') but that's not working properly in some cases. So, we recommend using browser API for dispatching DOM events.

Example

Clicking a link on the page.

  var atomus = require('atomus');
  atomus()
  .html('<section><a href="#" id="link">click me</a></section>')
  .external(__dirname + '/libs/myframework.min.js')
  .ready(function(errors, window) {
    var $ = this.$; // jQuery
    $('#link').on('click', function() {
      console.log('link clicked');
    });
    this.clicked($('#link'));
  });

An alternative syntax for setting the initial HTML on the page and the external resources is:

var atomus = require('atomus');
var b = atomus({
  html: '<h1>Blah blah</h1>',
  scripts: [
    'vendor/angularjs.min.js',
    'src/my-module.js'
  ]
});

Mocking HTTP requests


var mockups = [
  { 
    url: '/api/method/action',
    response: {
      status: 200,
      responseText: JSON.stringify({"id": "AAA"})
    }
  },
  { 
    url: '/api/method/action',
    method: 'POST',
    response: {
      status: 200,
      responseText: JSON.stringify({"success": "OK"})
    }
  }
];

var atomus = require('../lib');
var b = atomus()
.external(__dirname + '/data/ajaxwrapper.js')
.ready(function(errors, window) {
  b.addXHRMock(mockups);

  window.AjaxWrapper().request({
    url: '/api/method/action',
    json: true
  }).done(function(result) {
    console.log(result.id); // AAA
    
    window.AjaxWrapper().request({
      url: '/api/method/action',
      json: true,
      method: 'POST'
    }).done(function(result) {
      console.log(result.success); // OK
    });

  });

});

Injecting JavaScript into the head of the document

var b = atomus()
.html('<html><head></head><body></body></html>')
.injectJS('var getTheAnswer = function() { return 42; }')
.ready(function(errors, window) {
  console.log(window.getTheAnswer()); // 42
});

Tests

Checkout the test folder. There are tests that run Atomus against AngularJS and Ractive.js frameworks.

Notes

Other resources

Contributers