Created
July 12, 2017 20:15
-
-
Save paulirish/78f46a302083dd757288b5fcc660d75c to your computer and use it in GitHub Desktop.
JS coverage profiler data via protocol
This file contains 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
'use strict'; | |
const chromeLauncher = require('chrome-launcher'); | |
const CDP = require('chrome-remote-interface'); | |
const launchChrome = () => | |
chromeLauncher.launch({ | |
chromeFlags: ['--disable-gpu', '--headless'] | |
}); | |
launchChrome() | |
.then(async chrome => { | |
const protocol = await CDP({port: chrome.port}); | |
try { | |
const {Page, Profiler} = protocol; | |
await Profiler.enable(); | |
await Page.enable(); | |
await Profiler.startPreciseCoverage(); | |
Page.navigate({url: 'https://paulirish.com/'}); | |
await Page.loadEventFired(); | |
const res = await Profiler.takePreciseCoverage(); | |
await Profiler.stopPreciseCoverage(); | |
const coverage = calculateCoverage(res); | |
console.log(coverage); | |
} catch (err) { | |
console.error(err); | |
} finally { | |
protocol.close(); | |
chrome.kill(); | |
} | |
}) | |
.catch(err => console.error(err)); | |
// `calculateCoverage` is roughly stolen from https://github.com/joelgriffith/navalia/blob/master/src/Chrome.ts | |
// Haven't looked closely but handling these offsets is hard, so I'm dubious the below is correct | |
// Here is the DevTools' equivalent: https://github.com/ChromeDevTools/devtools-frontend/blob/master/front_end/coverage/CoverageModel.js | |
// see _processJSCoverage() | |
function calculateCoverage(res) { | |
const src = 'https://www.youtube.com/yts/jsbin/www-embed-player-vflOvovMJ/www-embed-player.js'; | |
const scriptCoverage = res.result.find(script => script.url === src); | |
if (!scriptCoverage) { | |
console.log(`:coverage() > ${src} not found on the page.`); | |
return new Error(`Couldn't locat script ${src} on the page.`); | |
} | |
if (scriptCoverage && scriptCoverage.functions && scriptCoverage.functions.length) { | |
const coverageData = scriptCoverage.functions.reduce( | |
(fnAccum, coverageStats) => { | |
const functionStats = coverageStats.ranges.reduce( | |
(rangeAccum, range) => { | |
return { | |
total: range.endOffset > rangeAccum.total ? range.endOffset : rangeAccum.total, | |
unused: | |
rangeAccum.unused + (range.count === 0 ? range.endOffset - range.startOffset : 0) | |
}; | |
}, | |
{ | |
total: 0, | |
unused: 0 | |
} | |
); | |
return { | |
total: functionStats.total > fnAccum.total ? functionStats.total : fnAccum.total, | |
unused: fnAccum.unused + functionStats.unused | |
}; | |
}, | |
{ | |
total: 0, | |
unused: 0 | |
} | |
); | |
return Object.assign(coverageData, { | |
percentUnused: coverageData.unused / coverageData.total | |
}); | |
} | |
return Error('unexpected'); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment