Closed hubitor closed 5 years ago
You can generate the event log with Puppeteer then pass it to CHC via the fromLog
method.
Thanks. I've tried to create a simple example but I couldn't make it work. This is what I have done so far:
const CHC = require("chrome-har-capturer");
const puppeteer = require("puppeteer");
const { promisify } = require("util");
const events = [];
const watchedEvents = [
"Network.dataReceived",
"Network.loadingFailed",
"Network.loadingFinished",
"Network.requestWillBeSent",
"Network.resourceChangedPriority",
"Network.responseReceived",
"Page.domContentEventFired",
"Page.loadEventFired"
];
const url = "https://example.com";
(async () => {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
const client = await page.target().createCDPSession();
await client.send("Page.enable");
await client.send("Network.enable");
watchedEvents.forEach(method => {
client.on(method, params => {
events.push({ method, params });
});
});
await page.goto(url);
try {
let har = await CHC.fromLog(url, events, { content: true });
await promisify(fs.writeFile)("out.har", JSON.stringify(har));
} catch (e) {
console.warn(e.message);
}
//await browser.close();
console.log(events);
})();
but I'm getting this:
Incomplete event log
[ { method: 'Network.requestWillBeSent',
params:
{ requestId: '6F472669FCAA2EDF428A875B329F4874',
loaderId: '6F472669FCAA2EDF428A875B329F4874',
documentURL: 'https://example.com/',
request: [Object],
timestamp: 90419.142093,
wallTime: 1568586127.407924,
initiator: [Object],
type: 'Document',
frameId: '6CAC968504C8589C4BF0BB4D543D1F60',
hasUserGesture: false } },
{ method: 'Network.responseReceived',
params:
{ requestId: '6F472669FCAA2EDF428A875B329F4874',
loaderId: '6F472669FCAA2EDF428A875B329F4874',
timestamp: 90419.548924,
type: 'Document',
response: [Object],
frameId: '6CAC968504C8589C4BF0BB4D543D1F60' } },
{ method: 'Network.dataReceived',
params:
{ requestId: '6F472669FCAA2EDF428A875B329F4874',
timestamp: 90419.561069,
dataLength: 1270,
encodedDataLength: 0 } },
{ method: 'Network.loadingFinished',
params:
{ requestId: '6F472669FCAA2EDF428A875B329F4874',
timestamp: 90419.547329,
encodedDataLength: 805,
shouldReportCorbBlocking: false } },
{ method: 'Page.loadEventFired',
params: { timestamp: 90419.562866 } },
{ method: 'Page.domContentEventFired',
params: { timestamp: 90419.613617 } } ]
and no HAR is being generated. Why I'm getting "Incomplete event log"?
That's because you're requesting the content (content: true
) but not providing synthetic Network.getResponseBody
events as requested by the fromLog
documentation.
Try the following, you'll still have to handle errors and maybe some corner case but this is the gist of it:
const CHC = require('chrome-har-capturer');
const puppeteer = require('puppeteer');
const fs = require('fs');
const { promisify } = require('util');
const events = [];
const watchedEvents = [
'Network.dataReceived',
'Network.loadingFailed',
'Network.loadingFinished',
'Network.requestWillBeSent',
'Network.resourceChangedPriority',
'Network.responseReceived',
'Page.domContentEventFired',
'Page.loadEventFired'
];
const url = 'https://example.com';
let counter = 0;
async function finish() {
try {
const har = await CHC.fromLog(url, events, { content: true });
await promisify(fs.writeFile)('out.har', JSON.stringify(har));
} catch (e) {
console.warn(e.message);
}
}
(async () => {
const browser = await puppeteer.launch({
headless: false,
args: [
'--no-sandbox',
'--disable-setuid-sandbox'
]
});
const page = await browser.newPage();
const client = await page.target().createCDPSession();
await client.send('Page.enable');
await client.send('Network.enable');
watchedEvents.forEach(method => {
client.on(method, params => {
events.push({method, params});
});
});
client.on('Network.loadingFinished', async ({requestId}) => {
// call Network.getResponsebody manually for each
// Network.loadingFinished events
counter++;
const params = await client.send('Network.getResponseBody', {requestId});
counter--;
// build the synthetic events
const {body, base64Encoded} = params;
events.push({
method: 'Network.getResponseBody',
params: {
requestId,
body,
base64Encoded
}
});
// when there are no more pending invocations build the HAR
if (counter === 0) {
finish();
}
});
await page.goto(url);
})();
OK, I clarified that section of the README, feel free to comment if you need further assistance.
I tried it and it looks good. Thanks!
As the title suggests: Is it possible to first press a button and then create a HAR with CHC? or to put it in another way: is it possible to combine puppeteer with CHC and how?