Created
April 2, 2019 22:59
-
-
Save pganti/426d0dfcd101568e6988933352ff4c1c to your computer and use it in GitHub Desktop.
pupetter create har
This file contains hidden or 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
const fs = require('fs'); [2/6256] | |
const { promisify } = require('util'); | |
const puppeteer = require('puppeteer'); | |
const { harFromMessages } = require('chrome-har'); | |
// list of events for converting to HAR | |
const events = []; | |
// list of promises that get the response body for a given response event | |
// (Network.responseReceived) and that add it to the event. These must all be | |
// resolved/rejected before we create the HAR from these events using | |
// chrome-har. | |
const addResponseBodyPromises: Array<Promise<void>> = []; | |
// 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 => { | |
// push the event onto the array of events first, before potentially | |
// blocking while fetching the response body, so the events remain in | |
// order. This is required by chrome-har. | |
const harEvent = { method, params }; | |
events.push(harEvent); | |
if (method === 'Network.responseReceived') { | |
const response = harEvent.params.response; | |
const requestId = harEvent.params.requestId; | |
// response body is unavailable for redirects, no-content, image, audio | |
// and video responses | |
if (response.status !== 204 && | |
response.headers.location == null && | |
!response.mimeType.includes('image') && | |
!response.mimeType.includes('audio') && | |
!response.mimeType.includes('video') | |
) { | |
const addResponseBodyPromise = client.send( | |
'Network.getResponseBody', | |
{ requestId }, | |
).then((responseBody) => { | |
// set the response so chrome-har can add it to the HAR | |
harEvent.params.response = { | |
...response, | |
body: new Buffer( | |
responseBody.body, | |
responseBody.base64Encoded ? 'base64' : undefined, | |
).toString(), | |
}; | |
}, (reason) => { | |
// resources (i.e. response bodies) are flushed after page commits | |
// navigation and we are no longer able to retrieve them. In this | |
// case, fail soft so we still add the rest of the response to the | |
// HAR. | |
}); | |
addResponseBodyPromises.push(addResponseBodyPromise); | |
} | |
} | |
}); | |
}); | |
// perform tests | |
await page.goto('https://en.wikipedia.org'); | |
page.click('#n-help > a'); | |
await page.waitForNavigation({ waitUntil: 'networkidle2' }); | |
await browser.close(); | |
// wait for the response body to be added to all of the | |
// Network.responseReceived events before passing them to chrome-har to be | |
// converted into a HAR. | |
await Promise.all(addResponseBodyPromises); | |
// convert events to HAR file | |
const har = harFromMessages(events); | |
await promisify(fs.writeFile)('en.wikipedia.org.har', JSON.stringify(har)); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment