CasperJS, the friendly front-end testing ghost.

2 September 2014

Reading time ~10 min | Categories: geekery  javascript 

A client recently introduced a new requirement that all applications must have documented testing routines that should be manually completed before they are deployed.

That sounded like a lot of manual effort and I had read about automated front-end testing with CasperJS. This was my excuse to finally try it out properly.

This blog records how I got CasperJS up and running on my Windows 8.1 machine - not as difficult as I feared! I'll also note down my thinking as I learn how to write tests before my 'how do I do that' questions become, 'well that's obvious, I always new that and don't need to explain it' type learning.

I should say that it took me a while to understand what CapserJS did. Basically, it launches a 'headless browser' against which we can test results (my understanding or headless is like a browser that takes normal requests processes pages but doesn't display anything in an actual browser - it all happens in memory, hence it is run from the command line). My understanding may well be wrong!

Installation

CasperJS depends on PhantomJS and Python.

I downloaded and installed the 2.7.8 version Windows installer from https://www.python.org/downloads/. I would usually try the more advanced version but my blog runs on Jekyll and the pygments code highlighting will not work with version 3+.

I found that the installer did not write to my PATH (meaning my consoles would not be able to find it). So I appended C:\Python27;C:\Python27\Scripts; to my PATH. If you are not sure about this, try the following link: http://www.computerhope.com/issues/ch000549.htm.

PhantomJS lets you download a zip that contains an exe file http://phantomjs.org/download.html. I copied the contents of the zip to C:\ and then added the following to PATH: C:\phantomjs;

Finally, I installed CasperJS using NPM (this assumes you have installed Node: http://nodejs.org/) by typing the following into my console to install it globally: npm install -g casperjs

I then added the location of the batchbin to my PATH: C:\Users\Patrick\AppData\Roaming\npm\node_modules\casperjs\batchbin;

Checking Installation

I added a 'tests' directory to the scripts folder of my application (I've decided to ship them as well so the client has the source code for tests). I then created a simple JavaScript file and called it installCheck.js containing the following code:

var casper = require('casper').create();

casper.start('http://casperjs.org/', function() {
    this.echo(this.getTitle());
});

casper.thenOpen('http://phantomjs.org', function() {
    this.echo(this.getTitle());
});

casper.run();

Next, I navigate to the 'tests' folder in Explorer and right click on it to open Git Bash (my console of choice). Enter "casperjs installCheck.js" and press enter.

At first I didn't think it was working as it just returns to a new line, looking like it's ready to take another command - however, after a few seconds (as it gets requests back from the sites), the titles of each page are printed out! It works! Press ctrl+c to escape the routine.

First Tests

I'm testing an ASP.NET application. The search page posts back to itself and returns a list of aircraft based on filters. If a specific aircraft is selected, a new page is loaded with details of that specific aircarft.

The search page has three basic filters (one drop down and two inputs) and 15 advanced filters. 12 of the advanced filters also have an operator drop down with =, >=, <=, +/-. If the final value is selected an extra input appears so the user can enter a range.

So, how do I test this lot?

The most obvious was to check that if a basic filter has a valid value to make sure that aircraft are returned. Filling in the form was pretty simple:

var casper = require('casper').create();

casper.start('http://localhost:56689/default.aspx', function() {
    this.fill('form#wsBasicSearchForm', { NameFilter: 'air' }, true);
});

The fill function takes three parameters: the form found via CSS3 query selectors, a field name with a value to enter and a boolean to submit if true.

Then I would check that an HTML 'strong' element that displays the aircraft count had a count greater than 0.

I then made my first mistake, trying to use native JavaScript to get the inner text of the element:

document.getElementById('acftCount').innerHTML;

The element search returned null. The solution was to use a Casper method:

this.echo(this.fetchText('strong#acftCount'));

strong is the element type and # is the CSS3 selector for ID.

This works! I still have a long way to go but will post this now and update later.

the plan ahead is:

  • write actuall pass/fail tests instead of printing out results
  • create a suite of tests that can run across the whole application
  • check to see how to test the admin section of the site - I will need to log in and do CRUD operations.
  • In future do TDD from the start!