👩‍🍳 A collection of useful recipes for the WebPageTest API
🍔 What's your favorite recipe?
- Emulate a slow network
- Emulate a slow network and CPU throttling
- Emulate a custom connectivity (Bandwidth, Latency, PacketLossRate)
- Emulate a test on mobile device
- Retrieve your Core Web Vitals
- Retrieve your Core Web Vitals + CrUX data for the tested URL
- Run a test with a third-party domain blocked
- Run a test and get the filmstrip screenshots
- Run a test and generate a lighthouse report
- Run a multi-step test with scripting
- Run a test and generate a waterfall image
- Run tests on multiple URLs
- Create a URL endpoint
- Run a test and check a budget using testspecs
- Run a test using webpagetest chrome recorder
- Retrieving chrome trace data
- Retrieving response body
import WebPageTest from "webpagetest";
const wptServer = "https://www.webpagetest.org";
const wpt = new WebPageTest(wptServer, "YOUR_API_KEY");
let testURL = "https://docs.webpagetest.org/"; //Your URL here
// Simulated network throttling (Slow 3G)
let options = {
location: "Dulles:Chrome", //mandatory with connectivity
connectivity: "3G",
};
// Run the test
wpt.runTest(testURL, options, (err, result) => {
if (result) {
console.log(result);
} else {
console.log(err);
}
});
import WebPageTest from "webpagetest";
const wptServer = "https://www.webpagetest.org";
const wpt = new WebPageTest(wptServer, "YOUR_API_KEY");
let testURL = "https://docs.webpagetest.org/"; //Your URL here
// Simulated network & cpu throttling
let options = {
location: "Dulles:Chrome",
connectivity: "3G",
throttleCPU: 5,
};
// Run the test
wpt.runTest(testURL, options, (err, result) => {
if (result) {
console.log(result);
} else {
console.log(err);
}
});
import WebPageTest from "webpagetest";
const wptServer = "https://www.webpagetest.org";
const wpt = new WebPageTest(wptServer, "YOUR_API_KEY");
let testURL = "https://docs.webpagetest.org/"; //Your URL here
// Simulated custom connectivity options (custom)
let options = {
connectivity: "custom",
location: "ec2-us-east-1:Chrome",
label: "custom connectivity",
bandwidthDown: 1000,
bandwidthUp: 1000,
latency: 5,
packetLossRate: 5,
};
// Run the test
wpt.runTest(testURL, options, (err, result) => {
if (result) {
console.log(result);
} else {
console.log(err);
}
});
import WebPageTest from "webpagetest";
const wptServer = "https://www.webpagetest.org";
const wpt = new WebPageTest(wptServer, "YOUR_API_KEY");
let testURL = "https://docs.webpagetest.org/"; //Your URL here
let options = {
location: "ec2-us-east-1:Chrome",
label: "emulate mobile device",
firstViewOnly: true,
emulateMobile: true,
device: "Nexus5", // optional (default: MotoG4)
};
//Supported devices: https://github.com/WPO-Foundation/webpagetest/blob/master/www/settings/mobile_devices.ini
// Run the test
wpt.runTest(testURL, options, (err, result) => {
if (result) {
console.log(result);
} else {
console.log(err);
}
});
import WebPageTest from "webpagetest";
const wptServer = "https://www.webpagetest.org";
const wpt = new WebPageTest(wptServer, "YOUR_API_KEY");
let testURL = "https://docs.webpagetest.org/"; //Your URL here
let options = {
firstViewOnly: true,
location: "Dulles:Chrome",
pollResults: 5,
timeout: 240,
};
wpt.runTest(testURL, options, (err, result) => {
if (result) {
console.log({
CumulativeLayoutShift: result.data.average.firstView["chromeUserTiming.CumulativeLayoutShift"],
LargestContentfulPaint: result.data.average.firstView["chromeUserTiming.LargestContentfulPaint"],
TotalBlockingTime: result.data.average.firstView["TotalBlockingTime"],
});
} else {
console.log(err);
}
});
import WebPageTest from "webpagetest";
const wptServer = "https://www.webpagetest.org";
const wpt = new WebPageTest(wptServer, "YOUR_API_KEY");
let testURL = "https://www.webpagetest.org/"; //Your URL here
let options = {
firstViewOnly: true,
location: "Dulles:Chrome",
pollResults: 5,
timeout: 240,
};
wpt.runTest(testURL, options, (err, result) => {
if (result) {
console.log("<-------------Core Web Vitals------------->");
console.log({
CumulativeLayoutShift: result.data.average.firstView["chromeUserTiming.CumulativeLayoutShift"],
LargestContentfulPaint: result.data.average.firstView["chromeUserTiming.LargestContentfulPaint"],
TotalBlockingTime: result.data.average.firstView["TotalBlockingTime"],
});
if (result.data.median.firstView.CrUX !== undefined) {
console.log("<----------------Crux Data---------------->");
console.log(result.data.median.firstView.CrUX);
} else {
console.log("No CrUX Data Found");
}
} else {
console.log(err);
}
});
import WebPageTest from "webpagetest";
const wptServer = "https://www.webpagetest.org";
const wpt = new WebPageTest(wptServer, "YOUR_API_KEY");
let testURL = "https://theverge.com"; //Your URL here
// URL's must be seprated by spaces (space-delimited)
let options = {
block:
"https://pagead2.googlesyndication.com https://creativecdn.com https://www.googletagmanager.com https://cdn.krxd.net https://adservice.google.com https://cdn.concert.io https://z.moatads.com https://cdn.permutive.com",
};
// Run the test
wpt.runTest(testURL, options, (err, result) => {
if (result) {
console.log(result);
} else {
console.log(err);
}
});
import WebPageTest from "webpagetest";
import fs from "fs";
import axios from "axios";
const wptServer = "https://www.webpagetest.org";
const wpt = new WebPageTest(wptServer, "YOUR_API_KEY");
let testURL = "https://docs.webpagetest.org/"; //Your URL here
let options = {
firstViewOnly: true,
location: "Dulles:Chrome",
connectivity: "4G",
pollResults: 5, //keep polling for results after test is scheduled
};
wpt.runTest(testURL, options, (err, result) => {
if (result) {
result.data.median.firstView.videoFrames.forEach((item, index) => {
axios({
method: "get",
url: item.image,
responseType: "stream",
}).then(function (response) {
response.data.pipe(fs.createWriteStream(`screenshot-${index}.png`));
});
});
} else {
console.log(err);
}
});
import WebPageTest from "webpagetest";
const wptServer = "https://www.webpagetest.org";
const wpt = new WebPageTest(wptServer, "YOUR_API_KEY");
let testURL = "https://docs.webpagetest.org/"; //Your URL here
let options = {
pollResults: 5,
timeout: 240,
lighthouse: 1, // This parameter will generate both WPT results and Lighthouse report
};
// Run the test
wpt.runTest(testURL, options, (err, result) => {
if (result) {
console.log(`\n
Lighthouse scores:
Performance: ${result.data.lighthouse.categories.performance.score * 100},
Accessibility: ${result.data.lighthouse.categories.accessibility.score * 100},
Best Practices: ${result.data.lighthouse.categories['best-practices'].score * 100},
SEO: ${result.data.lighthouse.categories.seo.score * 100},
PWA: ${result.data.lighthouse.categories.pwa.score * 100}
Lighthouse report: https://www.webpagetest.org/lighthouse.php?test=${result.data.id}
Full WebPageTest results: ${result.data.summary}
`);
} else {
console.log(err);
}
});
import WebPageTest from "webpagetest";
const wptServer = "https://www.webpagetest.org";
const wpt = new WebPageTest(wptServer, "YOUR_API_KEY");
let options = {
pollResults: 5,
firstViewOnly: true, //Skips the Repeat View test
};
const script = wpt.scriptToString([
{ logData: 0 },
{ navigate: "http://foo.com/login" },
{ logData: 1 },
{ setValue: ["name=username", "johndoe"] },
{ setValue: ["name=password", "12345"] },
{ submitForm: "action=http://foo.com/main" },
"waitForComplete",
]);
// Run the test
wpt.runTest(script, options, (err, result) => {
if (result) {
console.log(result);
} else {
console.log(err);
}
});
Visit Scripting Docs for more information
import WebPageTest from "webpagetest";
import fs from "fs";
import axios from "axios";
const wptServer = "https://www.webpagetest.org";
const wpt = new WebPageTest(wptServer, "YOUR_API_KEY");
let testURL = "https://docs.webpagetest.org/"; //Your URL here
let options = {
firstViewOnly: true,
location: "Dulles:Chrome",
connectivity: "4G",
pollResults: 5, //keep polling for results after test is scheduled
};
wpt.runTest(testURL, options, (err, result) => {
if (result) {
let imgurl = result.data.median.firstView.images.waterfall;
axios({
method: "get",
url: imgurl,
responseType: "stream",
}).then(function (response) {
response.data.pipe(fs.createWriteStream("waterfall.png"));
});
} else {
console.log(err);
}
});
import WebPageTest from "webpagetest";
const wpt = new WebPageTest("www.webpagetest.org", "YOUR_API_KEY");
const finalResults = [];
// Your list of URLs to test
let urls = [
"https://www.webpagetest.org/",
"https://www.product.webpagetest.org/api",
"https://docs.webpagetest.org/api/",
"https://blog.webpagetest.org/",
"https://www.webpagetest.org/about",
];
let options = {
firstViewOnly: true,
location: "Dulles:Chrome",
connectivity: "4G",
pollResults: 5,
timeout: 240,
};
const runTest = (wpt, url, options) => {
return new Promise((resolve, reject) => {
console.log(`Submitting test for ${url}...`);
wpt.runTest(url, options, async (err, result) => {
try {
if (result) {
return resolve(result);
} else {
return reject(err);
}
} catch (e) {
console.info(e);
}
});
});
};
(async function () {
Promise.all(
urls.map(async (url) => {
try {
await runTest(wpt, url, options).then(async (result) => {
if (result.data) {
let median = result.data.median.firstView;
//Pushing the data into the Array
finalResults.push({
id: result.data.id,
url: result.data.url,
cls: median["chromeUserTiming.CumulativeLayoutShift"],
lcp: median["chromeUserTiming.LargestContentfulPaint"],
tbt: median["TotalBlockingTime"],
});
}
});
} catch (e) {
console.error(e);
}
})
).then(() => {
console.info(finalResults);
});
})();
import WebPageTest from "webpagetest";
const wptServer = "https://www.webpagetest.org";
const wpt = new WebPageTest(wptServer, "YOUR_API_KEY");
let options = {
dryRun: true, // outputs the api endpoint
};
// multistep script
const script = wpt.scriptToString([
{ navigate: 'https://timkadlec.com/' },
{ execAndWait: 'document.querySelector("#nav > ul > li:nth-child(2) > a").click();' },
{ execAndWait: 'document.querySelector("#nav > ul > li:nth-child(3) > a").click();' },
{ execAndWait: 'document.querySelector("#nav > ul > li:nth-child(4) > a").click();' },
]);
// fire up the runtest function with a script or a url
wpt.runTest(script, options, (err, result) => {
if (result) {
console.log(result);
} else {
console.log(err);
}
});
import WebPageTest from "webpagetest";
const wptServer = "https://www.webpagetest.org";
const wpt = new WebPageTest(wptServer, "YOUR_API_KEY");
let testURL = "https://docs.webpagetest.org/"; //Your URL here
let options = {
firstViewOnly: true,
location: "Dulles:Chrome",
pollResults: 5,
timeout: 240,
// Set you budget specs here
specs: {
average: {
firstView: {
"chromeUserTiming.CumulativeLayoutShift": 0.1,
"chromeUserTiming.LargestContentfulPaint": 2500,
firstContentfulPaint: 2000,
TotalBlockingTime: 0.1,
},
},
},
};
wpt.runTest(testURL, options, (err, result) => {
if (result) {
console.log(`Your results are here for test ID:- ${result.testId}`);
} else {
console.log(err);
}
});
Check Testspecs for more details on setting a budget
import WebPageTest from "webpagetest";
import { WPTStringifyChromeRecording } from "webpagetest-chrome-recorder";
//Recording generated using chrome recorder
const recordingContent = {
title: "Webpagetest Chrome Recorder",
steps: [
{
type: "setViewport",
width: 1263,
height: 600,
deviceScaleFactor: 1,
isMobile: false,
hasTouch: false,
isLandscape: false,
},
{
type: "navigate",
url: "https://blog.webpagetest.org/",
assertedEvents: [
{
type: "navigation",
url: "https://blog.webpagetest.org/",
title: "WebPageTest Blog",
},
],
},
{
type: "click",
target: "main",
selectors: [["header li:nth-of-type(2) > a"]],
offsetY: 27.802078247070312,
offsetX: 26.427078247070312,
assertedEvents: [
{
type: "navigation",
url: "https://blog.webpagetest.org/categories/webpagetest-news/",
title: "",
},
],
},
],
};
//Converting json recording to webpagetest script
const script = await WPTStringifyChromeRecording(recordingContent);
console.log("Stringified Webpagetest Recorder Script: \n\n" + script + "\n");
// Initializing webpagetest
const wptServer = "https://www.webpagetest.org";
const wpt = new WebPageTest(wptServer, "YOUR_API_KEY");
let options = {
firstViewOnly: true,
label: recordingContent.title,
};
console.log("Webpagetest Custom Script Test Result: \n");
// Run the test using webpagetest script
wpt.runTest(script, options, (err, result) => {
if (result) {
console.log(result);
} else {
console.log(err);
}
});
Check Webpagetest Chrome Recorder for more details
import WebPageTest from "webpagetest";
const wptServer = "https://www.webpagetest.org";
const wpt = new WebPageTest(wptServer, "YOUR_API_KEY");
let testId = "YOUR_TEST_ID"; //Your URL here
// Retrieving Chrome Trace Data
wpt.getChromeTraceData(testId, (err, result) => {
if (result) {
console.log(result);
} else {
console.log(err);
}
});
import WebPageTest from "webpagetest";
const wptServer = "https://www.webpagetest.org";
const wpt = new WebPageTest(wptServer, "YOUR_API_KEY");
let testID = "YOUR_TEST_ID";
let options = {
run: 1, // the run from which you'd want to fetch the response body
request: 2, // the request number same as waterfall
cached: 0, // check for the repeat view
};
// Retrieving response body (Make sure you've enabled the save response body on this test)
wpt.getResponseBody(testID, options, (err, result) => {
if (result) {
console.log(result);
} else {
console.log(err);
}
});