springernature / webpagetest-mapper

Maps JSON result data from marcelduran/webpagetest-api into human-readable document formats.
GNU General Public License v3.0
96 stars 11 forks source link

webpagetest-mapper

Build status

Maps JSON result data from marcelduran/webpagetest-api into human-readable document formats. Read more.

Why would I want that?

Perhaps you'd like to generate a report containing sprauncy visualizations of your website's performance. Or maybe you want to analyse all of the raw data behind WebPageTest's median-based summaries using a spreadsheet.

This tool can help you do both of those things. It can also be extended to map WebPageTest result data into any conceivable format.

What formats does it support?

Three data mappers are provided out of the box: html-comparison, html-distribution and odf-spreadsheet.

html-comparison

The html-comparison mapper generates an HTML document containing three sections:

  1. A table summarising the salient metrics for each test. Each data cell in the table links to the equivalent results page on the WebPageTest instance. The page-title cells link to the page under test.
  2. SVG charts that draw comparisons between various aspects of the test results. These charts are rendered from static markup, so will display correctly even if JavaScript is disabled in the viewer's web browser.
  3. A table summarising the optimization scores that WebPageTest awards to each page. Each data cell in this table links to the optimization details.

Throughout the document, tests are identified consistently by colour, to help readers track trends from section to section.

Click here for an example.

Screenshot

html-distribution

The html-distribution mapper generates an HTML document containing SVG histograms that show the distribution of data. There is one histogram per metric per test.

Each bar on the histogram represents a standard deviation from the mean. The bars for data less than the mean are coloured green and the ones for figures greater than mean are red.

Click here for an example.

Screenshot

odf-spreadsheet

The odf-spreadsheet mapper generates an Open Document Format (ODF) spreadsheet.

For each test, a table is created in the spreadsheet which breaks down the salient metrics for every run. At the bottom of this table, a number of functions are applied to help show the distribution of the data.

Click here for an example.

Screenshot

Can I specify other formats?

Yes. Mappers are loaded with require, using a two-pass approach that enables custom extensions to be invoked.

Initially, mappers are speculatively loaded from the src/mappers sub-directory of the base installation. If that effort throws, a second attempt is made to load them from the specified module path verbatim. Thus, standard mappers are loaded at the first attempt and custom extensions are loaded at the second attempt.

Mappers are called with two arguments, options and results. They should return an ES6-compatible promise representing the mapped result.

Consult the standard mapper implementations for more information.

How do I install it?

If you're using npm:

npm install webpagetest-mapper --global

Or if you just want the git repo:

git clone git@github.com:nature/webpagetest-mapper.git

How do I use it?

From the command line

The executable name is wptmap.

For command-line help, run:

wptmap --help

Available options are:

From a node.js project

Import the library using require:

var wpt = require('webpagetest-mapper');

Three functions are exported from the main module: fetch, map and run. They each take an options object as their first argument and return an ES6 promise representing their result.

fetch (options)

fetch asynchronously invokes WebPageTest and returns an ES6 promise that resolves to the following data structure:

{
    data: [ ... ],      // Result array from WebPageTest
    options: { ... },   // Cloned options object normalised with default values
    times: {
        begin: { ... }, // JavaScript Date instance representing the start time
        end: { ... }    // JavaScript Date instance representing the finish time
    }
}

The returned promise is only resolved when all of the tests have completed. It is never rejected.

Instead, if any tests fail, the equivalent item in the results.data array will have a property named error which contains the Error instance. Handling errors in this way prevents rogue network issues from failing an entire run, while still propagating error information for inspection by the caller.

fetch accepts an options object as its only argument, supporting the following properties:

Example
wpt.fetch({
    uri: 'example.com',
    location: 'London:Firefox',
    tests: path.join(__dirname, 'tests.json'),
    count: 25,
    silent: true
}).then(function (result) {
    result.data.forEach(function (datum, index) {
        var id = '#' + index + ' [' + datum.name + ']';

        if (!datum.error) {
            return console.log('Test ' + id + ' passed: ' + datum.id);
        }

        console.log('Test ' + id + ' failed, reason: ' + datum.error.message);
    });
});

map (options, results)

map is not asynchronous but still returns a promise, to maintain consistency with the rest of the API.

The value of the promise is dependent on the result of the specific mapper that is invoked. Of the built-in mappers, html-comparison returns a string containing the document markup and odf-spreadsheet returns a Buffer instance containing the binary content.

This promise will be rejected if an error is thrown from the mapper.

map accepts an options object as its first argument, supporting the following properties:

The second argument to map is a results object, in the format returned by fetch.

Example
wpt.map({
    mapper: 'odf-spreadsheet',
    silent: true
}, results).then(function (mapped) {
    fs.writeFileSync(path.join(__dirname, 'results.ods'), mapped);
}).catch(function (error) {
    console.log(error.stack);
});

run (options)

run combines the actions from fetch and map, asynchronously invoking WebPageTest and returning a promise that represents the mapped data.

It accepts an options object as its only argument, supporting the aggregated properties from fetch and map.

Example
wpt.run({
    uri: 'example.com',
    location: 'London:Firefox',
    tests: path.join(__dirname, 'tests.json'),
    count: 25,
    mapper: 'odf-spreadsheet',
    silent: true
}).then(function (mapped) {
    fs.writeFileSync(path.join(__dirname, 'results.ods'), mapped);
}).catch(function (error) {
    console.log(error.stack);
});

What is the format of the test definitions file?

This is a very basic JSON file containing an array of test objects.

Each test object supports three properties, name, url and type:

Click here for an example test definitions file.

Is there a change log?

Yes.

How do I set up the dev environment?

The dev environment relies on node.js, JSHint, Mocha, Chai, Mockery and Spooks. Assuming that you already have node and NPM set up, you just need to run npm install to install all of the dependencies as listed in package.json.

You can lint the code with the command npm run lint.

You can run the unit tests with the command npm test.

What versions of node.js does it support?

0.12 or greater

What license is it released under?

GPL 3+

Copyright © 2015 Springer Nature