Phantomjs & Quality Engineering

I’m not about to dismiss the need for selenium or other tools to test specific browsers, but when it comes to quickly getting an indication of how long it takes for a site to render and whether there are any errors, phantomjs is hard to beat. The script below opens a webpage in a specific viewport size, prints the title, reports the timing and captures the result as a png.

This is critical for testing responsive design when the website will render differently at different screen sizes (break points). Having something like this configured and scheduled to run early for all of a project’s templates means that it is easy to track and identify when changes in latency or failures occur. As always transparency becomes key and having this executed automatically as part of the build process creates a small closed feedback loop that helps ensure quick turn around times in the event of a problem.


var page = require('webpage').create(),
system = require('system'),
t, address;
swidth = '1366';
sheight = '768';
if (system.args.length === 1) {
  console.log('Usage: test.js optional( <screen width> <screen height> )');
phantom.exit();
}
t = Date.now();
address = system.args[1];
if (system.args[2]) {
  swidth = system.args[2];
}
if (system.args[3]) {
  sheight = system.args[3];
}
page.onConsoleMessage = function (msg) {
  console.log('Page title is ' + msg);
};
page.onInitialized = function () {
  page.evaluate(function (swidth, sheight) {
    (function () {
      window.screen = {
        width: swidth,
        height: sheight
      };
    })();
  }, swidth, sheight);
};
page.open(address, function (status) {
  if (status !== 'success') {
    console.log('FAIL to load the address');
  } else {
    t = Date.now() - t;
    console.log('The default user agent is ' + page.settings.userAgent);
    console.log('Loading time ' + t + ' msec');
    console.log(JSON.stringify(page.evaluate(function () { return window.screen })));
    page.render('images/test.png');
    page.evaluate(function () {
      console.log(document.title);
    });
  }
  phantom.exit();
});

Taken a step further you can then calculate the average render time for an entire site backed by a CMS by tracking outbound links from a given entry point (the homepage).

Pulling the links off the page looks like this:

function getLinks() {
  var links = document.querySelectorAll('li a');
  return Array.prototype.map.call(links, function(aLink) {
    return aLink.getAttribute('href');
  });
}

Using this method also creates a report of all the pages for a website weighted by outbound links. For high content sites that are backed by a CMS this means that I now have a current list of pages that is representative of inbound traffic to the website. This ends up being a critical piece of performance testing (in addition to any transactional elements).