What does “headless” mean?

A headless browser is a web browser without a graphical user interface.

Headless browsers are executed via a command line interface. They use the same network connection and provide the same control of a web page as normal browsers. Because they render DOM elements and execute javascript in the same way, they can be extremely useful for testing web pages.

Why do it?

It’s really not a question of “why testing is important” but “how can we (developers and testers) do it in better way”. Front end testing doesn’t have to be a slow and painful experience if you utilise the right tool. Instead of going through each page or scenario manually you can write a UI test and integrate it into build process, then run it in the background. It will generate a fail report if something goes wrong. It’s that simple!

Meet PhantomJS and CasperJS

  • PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast and native support for various web standards. It is command-line based with a pre-commit hook as part of a CI (continuous integration) system. There are plenty of testing frameworks that interact with it.
  • CasperJS is an open source navigation scripting and testing utility written in Javascript. It runs on top of PhantomJS and is able to simulate user behaviour and various test scenarios.

Setup

Install PhantomJS
You can use NPM (node package manager), or download here

$npm install phantomjs -g

To see if PhantomJS has installed, type in terminal

$phantomjs -v

This should return the version number. Now you can test scripts by a simple command like:

$phantomjs [your-test-scripts.js]

Install CasperJS
You can use NPM, or other installation options here.

$npm install casperjs -g

To see if CasperJS has installed, type below in terminal

$casperjs -version

This should return a version number. Now you’re ready to create a test file!

A typical test script looks like:

var casper = require(‘casper’).create();
casper.start(‘http://yoursite.com/', function() {     
  // test code here
});
casper.then(function() {
  // more test code here
}
casper.run();
  • casper.create() : Create a new Casper instance
  • casper.start() : Configures and starts Casper
  • casper.then() : Define and order the navigation steps
  • casper.run() : Run Casper unit

The basic testing

Simulate user actions

  • fill — fills the fields of with given values with optional submit
casper.start('http://yoursite.form', function() {
    this.fill('form#contact-form', {
        'email':      'chuck@norris.com'
    }, true);
});

casper.then(function() {
    this.evaluateOrDie(function() {
        return /message sent/.test(document.body.innerText);
    }, 'sending message failed');
});
  • mouseEvent — supported events like mouseup, mousedown, click, mouseover, mouseout
casper.start('http://yoursite.com/', function() {
    this.mouseEvent('click', 'h2 a');
});
casper.start('http://foo.bar/home', function() {
    this.scrollTo(500, 300);
    this.scrollToBottom();
});

Assertions

Given condition and return true or false. Casper has a range of assertions from tester API, including:

and so on….

Advance usage

  • back and forward — move a step back or forward in browser’s history
casper.start('http://yoursite.com/1')
casper.thenOpen('http://yoursite.com/2');
casper.back();    // http://yoursite.com/1
casper.forward(); // http://yoursite.com/2
  • userAgent — set to different browsers
casper.userAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X)');
  • viewport — change current viewport size, usually for testing breakpoints
casper.viewport(1024, 768).then(function() {
    // new view port is now effective
});
  • captureSelector— take screenshot of particular element and save files to target location
casper.start('http://yoursite.com/', function() {
    this.captureSelector('screenshot.png', '#container');
});
  • download — saves a remote resource onto file system
casper.start('http://yoursite.com/', function() {
    var url = 'http://yoursite.com/about';
    this.download(url, 'about.html');
});

And many many more, such as logging, bypass ..etc. Full list of functions can be found here.

Can I do visual regression testing too?

The answer is YES. I’m gonna write about visual regression testing and how PhantomJS helps to achieve it in my next blog post.

Summary

Now we’ve walked through concept, structure and commands, you can define a scenario and sequence of events to test a page. Start with testing what is important and critical parts of the page and slowly build up your test suite as you go along.

Happy testing!

Jessie Wang, Senior frontend developer

Written by Jessie W.

“I have no special talent, I am only passionately curious.“— Albert Einstein

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s