Skip to content

catchpoint/WebPageTest.api-recipes

Repository files navigation

Webpagetest Recipes Banner

WebPageTest API Recipes

👩‍🍳 A collection of useful recipes for the WebPageTest API

🍔 What's your favorite recipe?

đź“–Table Of Contents

Emulate a slow network

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);
  }
});

Slow-network

Source

Emulate a slow network and CPU throttling

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);
  }
});

Source

Emulate a custom connectivity (Bandwidth, Latency, PacketLossRate)

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);
  }
});

Source

Emulate a test on mobile device

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);
  }
});

Source

Retrieve your Core Web Vitals

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);
  }
});

Webvitals

Source

Retrieve your Core Web Vitals + CrUX data for the tested URL

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);
  }
});

Webvitals + CrUX

Source

Run a test with a third-party domain blocked

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);
  }
});

Source

Run a test and get the filmstrip screenshots

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);
  }
});

Screenshot strip

Source

Run a test and generate a lighthouse report

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);
  }
});

Lighthouse scores by Webpagetest WPT

Lighthouse report by Webpagetest WPT

Source

Run a multi-step test with scripting

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

Source

Run a test and generate a waterfall image

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);
  }
});

Waterfall image by WbePagetest WPT

Source

Run tests on multiple URLs

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);
  });
})();

Bulk Tests URLs using WebPageTest WPT

Source

Create a URL endpoint

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);
  }
});

Generate a url using dryRun option

Source

Run a test and check a budget using testspecs

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 a budget using testspecs

Check Testspecs for more details on setting a budget

Source

Run a test using webpagetest chrome recorder

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);
  }
});

Run a test using webpagetest chrome recorder

Check Webpagetest Chrome Recorder for more details

Source

Retrieving chrome trace data

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);
  }
});

Retrieving chrome trace data

Source

Retrieving Response Body

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);
  }
});

Retrieving Response Body

Source

About

A collection of useful recipes for the WebPageTest API

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published