Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Node script for running a test with WebPagetest and writing the results to InfluxDB and to file
// Imports
const WebPageTest = require("webpagetest");
const fs = require("fs");
var download = require("download-file"); // Install download-file https://www.npmjs.com/package/download-file
const Influx = require("influx"); // Download and install InfluxDB https://v2.docs.influxdata.com/v2.0/get-started/
const influx = new Influx.InfluxDB({
host: "localhost",
database: "webpagetest",
port: 8086
});
module.exports = influx;
// Variables that are input from a command to run this node script,
// e.g. 'node webpagetest.js "https://www.example.com/" example-home "3GFast" true'
let testURL = process.argv[2];
let pageName = process.argv[3];
let connectivityProfile = process.argv[4];
let mobileEmulationBool = process.argv[5];
// Paths for the file outputs
let path = "./results/";
let videoDownloadURL = "https://www.webpagetest.org/video/download.php?id=";
let filmstripURL_start =
"https://www.webpagetest.org/video/filmstrip.php?tests=";
let filmstripURL_end =
"-r:1-c:0&thumbSize=200&ival=500&end=visual&text=ffffff&bg=000000";
// Other variables
let testStart = new Date().toISOString();
const key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // Enter your WebPagetest API key from https://www.webpagetest.org/getkey.php
const wpt = new WebPageTest("www.webpagetest.org", key);
const testOpts = {
emulateMobile: mobileEmulationBool,
location: "ec2-eu-central-1", // Or set a different test location
firstViewOnly: false,
connectivity: connectivityProfile,
pollResults: 5,
video: true,
lighthouse: true
};
const script = wpt.scriptToString([
{ navigate: testURL },
"waitForComplete"
]);
// Run a test on WebPagetest
console.log(
`${testStart}:\nStarting Webpagetest for ${testURL} with ${connectivityProfile} connectivity...`
);
wpt.runTest(script, testOpts, (err, result) => {
if (err) {
console.log("Can't run the test for some reason.");
throw err;
}
let date = result.data.completed;
let fileName = path + date + " - " + pageName + ".json";
let testID = result.data.id;
let stats = JSON.stringify(result.data, null, 2);
// Metrics
let firstView = result.data.median.firstView;
let firstMeaningfulPaint = firstView.firstMeaningfulPaint,
loadTime = firstView.loadTime,
TTI = firstView["lighthouse.Performance.interactive"],
bytesInDoc = firstView.bytesInDoc,
requestsDoc = firstView.requestsDoc,
fullyLoaded = firstView.fullyLoaded,
timeToFirstByte = firstView.TTFB,
firstContentfulPaint =
firstView["lighthouse.Performance.first-contentful-paint"],
wptSpeedIndex = firstView["lighthouse.Performance.speed-index"],
bytesHTML = firstView.breakdown.html.bytes,
bytesJS = firstView.breakdown.js.bytes,
bytesCSS = firstView.breakdown.css.bytes,
bytesImages = firstView.breakdown.image.bytes,
bytesFonts = firstView.breakdown.font.bytes;
// Log some metrics to console
let metrics = [loadTime, timeToFirstByte, firstLayout, firstContentfulPaint, TTI, SpeedIndex, lastPaintedHero, firstCPUIdle];
for (metric of metrics) {
console.log(metric);
}
// Write data to InfluxDB
date *= 1000000000;
influx
.writePoints([
{
measurement: "webpagetest",
tags: {
pageName: pageName,
run: 1
},
fields: {
timeToInteractive: TTI,
bytesInDoc: bytesInDoc,
fullyLoaded: fullyLoaded,
requestsDoc: requestsDoc,
loadTime: loadTime,
timeToFirstByte: timeToFirstByte,
firstContentfulPaint: firstContentfulPaint,
performance: performance,
speedIndex: wptSpeedIndex,
bytesHTML: bytesHTML,
bytesJS: bytesJS,
bytesCSS: bytesCSS,
bytesImages: bytesImages,
bytesFonts: bytesFonts
},
timestamp: date
}
])
.then(() => {
return influx.query(`
select * from webpagetest
order by time desc
`);
})
.catch(err => {
console.error(`Error creating Influx database!`);
});
// Save test results as JSON file
fs.writeFile(fileName, stats, err => {
if (err) throw err;
console.log("Data for " + pageName + "written to file: " + fileName);
});
// Optionally create a video
var videoOptions = {
directory: path,
filename: date + " - " + pageName + ".mp4"
};
wpt.createVideo(testID, testOpts, (err, data) => {
console.log(err || data);
let videoId = data.data.videoId;
videoDownloadURL += videoId;
setTimeout(function() {
download(videoDownloadURL, videoOptions, function(err) {
if (err) throw err;
console.log(
"Video download URL for " + pageName + ": " + videoDownloadURL
);
});
}, 5000);
// Optionally download the filmstrip
var filmstripOptions = {
directory: path,
filename: date + " - " + pageName + ".png"
};
var filmstripURL = filmstripURL_start + testID + filmstripURL_end;
download(filmstripURL, filmstripOptions, function(err) {
if (err) throw err;
console.log(
"Filmstrip download URL for " + pageName + ": " + filmstripURL
);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment