Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a har file be programmatically generated from headless chrome using Puppeteer?

I would like to control a headless chrome instance using puppeteer, taking snapshots and clicking on various page elements, while capturing a har file. Is this possible? I have looked at the API but haven't found anything useful.

like image 341
Atlas1j Avatar asked Nov 21 '17 16:11

Atlas1j


People also ask

What is headless mode in puppeteer?

Puppeteer is a Node.js library which provides a high-level API to control Chrome/Chromium over the DevTools Protocol. Puppeteer runs in headless mode by default, but can be configured to run in full (non-headless) Chrome/Chromium.

How do I create a Har file in Chrome or Firefox?

Within the Networks tab, select Preserve log option. In the center of the Networks tab select refresh. Refresh the page and allow Firefox to record the browser-website interaction. Once the page is loaded, right click and "Save All As HAR".


2 Answers

There is no HAR generator helper in Puppeteer. But you can use chrome-har to generate HAR file.

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

Here you can find an article about this solution.

like image 144
Everettss Avatar answered Sep 21 '22 12:09

Everettss


Solution proposed by @Everettss is the only option (so far), but is not as good as HAR saved in browser. Look at this, in both cases I generated HAR for google.com page. At top you have HAR generated by puppeteer-har (which is using chrome-har). Too little requests here, no metrics for main document, strangely different timing.

enter image description here

Puppeteer is not a perfect option for HAR files. Therefore I am suggesting to use https://github.com/cyrus-and/chrome-har-capturer

like image 42
user1660210 Avatar answered Sep 22 '22 12:09

user1660210