Send messages to Chrome using the Chrome DevTools Protocol. This only works in Chrome/Edge. You can send, send and get and listen on events. This is a super powerful feature that enables you to do almost whatever you want with the browser.
Sending a command
Send a command to Chrome and don’t expect something back.
Here’s an example of injecting JavaScript that runs on every new document.
/**
* @param {import('browsertime').BrowsertimeContext} context
* @param {import('browsertime').BrowsertimeCommands} commands
*/
export default async function (context, commands) {
await commands.cdp.send('Page.addScriptToEvaluateOnNewDocument',{source: 'console.log("hello");'});
await commands.measure.start('https://www.sitespeed.io');
}
Send and get something back
Send a command to Chrome and get the result back.
/**
* @param {import('browsertime').BrowsertimeContext} context
* @param {import('browsertime').BrowsertimeCommands} commands
*/
export default async function (context, commands) {
await commands.measure.start('https://www.sitespeed.io');
const domCounters = await commands.cdp.sendAndGet('Memory.getDOMCounters');
context.log.info('Memory.getDOMCounters %j', domCounters);
}
Listen on events
Here’s an example to get hold of all responses for a page.
/**
* @param {import('browsertime').BrowsertimeContext} context
* @param {import('browsertime').BrowsertimeCommands} commands
*/
export default async function (context, commands) {
const responses = [];
await commands.cdp.on('Network.responseReceived', params => {
responses.push(params);
});
await commands.measure.start('https://www.sitespeed.io/search/');
context.log.info('Responses %j', responses);
};
Use the raw CDP client
Under the hood Browsertime uses the chrome-remote-interface. If you need you can get the raw CDP client so you can do whatever you want. Here’s an example on how to change the server header on the response.
/**
* @param {import('browsertime').BrowsertimeContext} context
* @param {import('browsertime').BrowsertimeCommands} commands
*/
export default async function (context, commands) {
const cdpClient = commands.cdp.getRawClient();
await cdpClient.Fetch.enable({
patterns: [
{
urlPattern: '*',
requestStage: 'Response'
}
]
});
cdpClient.Fetch.requestPaused(async reqEvent => {
const { requestId } = reqEvent;
let responseHeaders = reqEvent.responseHeaders || [];
const newServerHeader = { name: 'server', value: 'Haxxor' };
const foundHeaderIndex = responseHeaders.findIndex(
h => h.name === 'server'
);
if (foundHeaderIndex) {
responseHeaders[foundHeaderIndex] = newServerHeader;
} else {
responseHeaders.push(newServerHeader);
}
return cdpClient.Fetch.continueResponse({
requestId,
responseCode: 200,
responseHeaders
});
});
return commands.measure.start('https://www.sitespeed.io/search/');
}