Puppeteer JavaScript coverage reports which source ranges ran during a particular collection window. To read a result, match each entry’s url, text and ranges, then calculate the documented aggregate as the covered range lengths divided by the returned source-text lengths. Treat that percentage as a measure of the scripts and browser activity captured in that run—not as a score for overall test quality.
What a JavaScript coverage entry contains
stopJSCoverage() returns an array of entries. Each JavaScript coverage entry includes a script url, the source text, and ranges identifying positions in that text that ran during collection. Each range has numeric start and end offsets. Interpret those offsets against the entry’s own source text, not against a different build or transformed copy. See Puppeteer’s CoverageEntry interface and JSCoverageEntry interface.
The entry may also contain rawScriptCoverage when raw V8 coverage is enabled. The URL helps identify the script; for an annotated report, retain the corresponding source version so ranges are applied to the correct text.
Collect the behavior you want to measure
Start JavaScript coverage before the page activity of interest, perform the navigation and interactions you want represented, and stop collection afterward. The report describes only the observed collection window. Code that ran before coverage began, or code excluded by the selected options, should not be assumed to appear.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problems#1 Best Overall
const coverage = await page.coverage();
await coverage.startJSCoverage();
await page.goto('https://example.com');
// Exercise the page behavior that matters to your test here.
const jsCoverage = await coverage.stopJSCoverage();
This follows Puppeteer’s documented start, navigate, stop flow; for version-specific signatures and settings, check the startJSCoverage() reference for the Puppeteer version installed in your project.
Calculate the documented percentage
Puppeteer’s example sums each entry’s source-text length and adds range.end - range.start - 1 for each covered range. The ratio multiplied by 100 is the example’s aggregate byte-based percentage. Applied to JavaScript entries only:
Rank #2
let totalBytes = 0;
let usedBytes = 0;
for (const entry of jsCoverage) {
totalBytes += entry.text.length;
for (const range of entry.ranges) {
usedBytes += range.end - range.start - 1;
}
}
const percentage = totalBytes === 0 ? 0 : (usedBytes / totalBytes) * 100;
console.log(`${percentage.toFixed(2)}%`);
The zero-denominator check avoids producing an invalid percentage if the result contains no source text. Puppeteer’s published example combines JavaScript and CSS entries before calculating its value. If you do that, label the denominator as combined JavaScript and CSS; do not describe it as JavaScript-only coverage. The calculation is a source-span aggregate, not a count of statements, tests, features or user journeys. See Puppeteer’s Coverage class for its example.
Understand settings that change the report
Block-level or function-level coverage
useBlockCoverage defaults to true, which records block-level coverage; setting it to false selects function-level coverage. The granularity changes where coverage is recorded, so use the same setting when comparing runs. Consult the JSCoverageOptions interface.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallAnonymous scripts
reportAnonymousScripts defaults to false. Anonymous scripts can include code created with eval or new Function. When reported, they may appear with URLs beginning debugger://VM; a //# sourceURL=... comment can provide a recognizable URL. This means coverage can omit such code unless anonymous-script reporting is enabled. Puppeteer documents this behavior in its startJSCoverage() reference and stopJSCoverage() reference.
Raw V8 coverage
includeRawScriptCoverage defaults to false. Turn it on if your workflow needs the optional raw V8 coverage data in JavaScript entries; it is distinct from the basic url, text and ranges fields.
Rank #4
Navigation and resets
resetOnNavigation defaults to true. Setting it to false does not guarantee that coverage survives a navigation: Chrome may discard the old page execution environment and its coverage data. To preserve results reliably across pages, stop collection before navigating, start it again on the next page, and merge the separate reports. Puppeteer describes the caveat in its JSCoverageOptions interface.
Compare coverage runs on equivalent terms
A percentage change is interpretable only when the collection and denominator are comparable. Keep these factors aligned or disclose the differences:
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Best Value
- Collection window: same page journey, interactions, and start/stop points.
- Script population: same script URLs and treatment of anonymous scripts.
- Granularity and options: same block/function choice and raw coverage configuration.
- Navigation strategy: same per-page capture method and report-merging approach.
- Denominator: same source text and calculation method, with JavaScript-only versus combined JavaScript/CSS clearly stated.
Even a well-matched percentage says only what ranges were observed across the returned entries. It does not establish that every feature or user journey was tested.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshoot misleading or unexpected results
Coverage is unexpectedly low
- Check that collection started before the relevant navigation and interactions.
- Verify that the test actually exercised the behavior associated with the uncovered source.
- Check whether anonymous scripts were excluded by the default
reportAnonymousScripts: falsesetting. - Confirm that the denominator contains only the intended entries and source text.
Coverage disappears after navigation
Do not rely on resetOnNavigation: false to preserve a previous page’s data. Stop coverage before navigation, start it again on the destination page, and merge the resulting reports if needed.
Offsets do not line up with a local file
Ranges refer to the text returned for that entry. If a local file has been rebuilt, minified, or transformed since capture, its offsets may no longer correspond. Use the returned source text or the exact matching source version when annotating ranges.
A comparison changes after an options edit
Check the block/function setting, anonymous-script handling, raw coverage setting, navigation handling, and JavaScript-versus-CSS denominator. An apparent trend can reflect changed collection scope rather than changed application behavior.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server; it is not a replacement for Puppeteer’s coverage instrumentation or a way to calculate JavaScript coverage. If your workflow also needs page screenshots, a single request can capture one:
Quick Recap
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
See the ScreenshotNeo API documentation for request options. ScreenshotNeo removes cookie banners, newsletter popups and chat widgets before capture; bot checks, blank pages and failed loads are not billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000. Sign up for ScreenshotNeo’s free plan.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




