Created
March 9, 2020 13:16
-
-
Save screenspan/376de61185f5a6227068753d5812794e to your computer and use it in GitHub Desktop.
Node script for running a test with WebPagetest and writing the results to InfluxDB and to file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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