Automate mobile testing: phantom.js

Phantom.js can be used for many purposes and this is a quite primitive one. It uses node.js and I've included the async.js module to create picture after picture and not clog up the RAM.

website_screenshot_phantomjs_multiple_resolutions

Installing phantom.js

npm install phantomjs -g

This installs phantom.js globally, so you have access to the phantomjs command.

Test for multiple resolutions with phantom.js

Automatic screen capturing used to be quite complicated, but the following script does exactly that and reveals how little I've taken care of the responsive design of one of my blogs. This will become a tool in my workflow to test different resolutions for the webkit engine, since the big two, Android and iOS use it as their default mobile browser engine.

/*
    requires: phantomjs, async
    usage: phantomjs index.js
*/

var async = require('async');
var sizes = ['1920x1080','1600x1200','1400x900','1024x768','800x600','420x360'];
var siteURL = 'http://vollzeitblogger.de';
var siteName = siteURL.replace('http://','');
siteName = siteName.replace('.','_') + '_';

var imageDir = './images/';

function scrot(sizes, callback){
    size = sizes.split('x');
    var page = require('webpage').create();
    page.viewportSize = { width: size[0], height: size[1] };
    page.zoomFactor = 1;

    // checking the viewport settings
    console.log(JSON.stringify(page.viewportSize));

    page.open(siteURL, function (status) {

        var filename = siteName + size[0] + 'x' + size[1] + '.png';

        page.render(imageDir + filename);
        page.close();
        callback.apply();
    });
}

async.eachSeries(sizes, scrot, function(err){
    if (err) console.log(err);
    console.log('done, quitting');
    phantom.exit();
});

I use async to pass one resolution at a time to the scrot function which then renders the page to a .png file. It's quite simple and captures the full website, not only the viewport.

More flexibility

I'm pretty new to npm, so I have to figure out if I can meaningfully publish this as a module, but I'll put the code on github one of the next days.

Thank you for reading! If you have any comments, additions or questions, please tweet or toot them at me!