Generate HAR with Puppeteer

There is no out-of-the-box solution build in Puppeteer for recording HAR file. But you can easily construct one.

Published: 2018-02-25

For network timeline analysis Puppeteer suggest using timeline trace (results from Chrome performance tab), this can be done with recording page.tracing. But results from performance trace can be too raw and hard to interpretation.

So you want to record the good old HAR with Puppeteer because you have some legacy workflow or you want to use well-established tools to analyze HAR file.

To achieve final results you have to listen to events like 'Page.loadEventFired', 'Network.requestWillBeSent' and rest needed for generating propper HAR, record them in an array and then parse with library chrome-har. The example below shows full configuration for recording HAR on Wikipedia homepage and transition to the help page.

const fs = require('fs');
const { promisify } = require('util');

const puppeteer = require('puppeteer');
const { harFromMessages } = require('chrome-har');

// list of events for converting to HAR
const events = [];

// event types to observe
const observe = [
  'Page.loadEventFired',
  'Page.domContentEventFired',
  'Page.frameStartedLoading',
  'Page.frameAttached',
  'Network.requestWillBeSent',
  'Network.requestServedFromCache',
  'Network.dataReceived',
  'Network.responseReceived',
  'Network.resourceChangedPriority',
  'Network.loadingFinished',
  'Network.loadingFailed',
];

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // register events listeners
  const client = await page.target().createCDPSession();
  await client.send('Page.enable');
  await client.send('Network.enable');
  observe.forEach(method => {
    client.on(method, params => {
      events.push({ method, params });
    });
  });

  // perform tests
  await page.goto('https://en.wikipedia.org');
  page.click('#n-help > a');
  await page.waitForNavigation({ waitUntil: 'networkidle2' });
  await browser.close();

  // convert events to HAR file
  const har = harFromMessages(events);
  await promisify(fs.writeFile)('en.wikipedia.org.har', JSON.stringify(har));
})();

For proving that this code works I'm presenting results from softwareishard.com HAR viewer:

HAR result