Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
Chromium

How to Fix Incorrect JavaScript Coverage in Pyppeteer

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If Pyppeteer’s JavaScript coverage is missing code or reporting unexpected ranges, first check when coverage starts, what page activity you recorded, and how navigation and anonymous scripts are handled. Start coverage before the code you want to measure runs, exercise the relevant routes and interactions, and inspect each returned script’s URL, source text, and ranges. These are common measurement and interpretation issues; the available documentation does not establish one universal Pyppeteer defect or a specific version regression.

Start with a correctly timed capture

Coverage can only describe execution observed during its recording window. Start it before navigation or before the script activity under investigation. Starting after a page has already loaded cannot reliably recover code that ran earlier.

The V8 JavaScript protocol documentation cautions: “Coverage data for JavaScript executed before enabling precise code coverage may be incomplete.” Precise coverage also affects execution: enabling it resets execution counters and prevents optimized code from running. Treat the result as an instrumented capture, not as a perfectly neutral observation of ordinary runtime behavior. V8/DevTools Protocol coverage documentation

Minimal capture pattern

This example measures a navigation and a follow-up interaction, then prints the returned entries. Replace the URL and interaction with the page flow you need to investigate.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import asyncio
from pyppeteer import launch

async def main():
    browser = await launch()
    page = await browser.newPage()

    await page.coverage.startJSCoverage()
    try:
        await page.goto("https://example.com", {"waitUntil": "networkidle2"})
        # Exercise the route or interaction whose code you want to measure.
        # For example: await page.click("button[data-action='open']")
        coverage = await page.coverage.stopJSCoverage()
    finally:
        await browser.close()

    for entry in coverage:
        print("URL:", entry["url"])
        print("Source characters:", len(entry["text"]))
        print("Executed ranges:", entry["ranges"])

asyncio.run(main())

In normal use, stop coverage after the intended actions finish. If an exception can occur during navigation or interaction, use a cleanup path that stops coverage when possible before closing the browser, so you can still inspect what was captured. Avoid assuming that a page-load-only capture represents later routes, menu states, authenticated screens, or other user paths that were never visited.

Check whether navigation cleared earlier coverage

Pyppeteer 0.0.25 documents resetOnNavigation as defaulting to True. With that setting, navigation may clear accumulated coverage. If your workflow navigates between pages and expects one combined result, this default is an important diagnostic check. Pyppeteer API reference

You can request that coverage not reset on navigation:

await page.coverage.startJSCoverage({"resetOnNavigation": False})

Do not treat this option as a guarantee that coverage survives every navigation. The related Puppeteer documentation warns that browser architecture can still cause resets even when the option is false; Pyppeteer compatibility is not guaranteed by that documentation. Test the exact navigation flow in the browser build you use. Puppeteer CoverageOptions documentation

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Decide what you want the capture to represent

  • One document or route: Start coverage immediately before loading that route and stop after its relevant interactions.
  • Several routes: Record each route explicitly, or test whether your exact navigation sequence retains the data you need. Do not infer cross-navigation persistence from the option alone.
  • Single-page-app transitions: Trigger client-side navigation and interactions while the same recording remains active, then verify the resulting entries.

Include anonymous and dynamically generated scripts

Pyppeteer’s reportAnonymousScript option defaults to False. As a result, code created without an associated URL—such as some code evaluated through eval or new Function—may not appear in the output by default. Enable anonymous reporting when that code is part of the question:

await page.coverage.startJSCoverage({"reportAnonymousScript": True})

Pyppeteer uses the singular spelling reportAnonymousScript. Reported anonymous scripts are labeled __pyppeteer_evaluation_script__. Code with a source URL can be attributed and reported under that URL. If an expected entry is absent, check whether the code is anonymous and whether the option was enabled before it ran. Pyppeteer API reference

Read the entries and ranges without double-counting

stopJSCoverage() returns a list of entries containing a script URL, source text, and executed ranges. Look at all three together. An entry with an unexpected URL may be an attribution issue; missing source text or URL can also result in an entry being skipped by the implementation. An empty range list is not the same thing as a missing script entry.

Pyppeteer normalizes function coverage ranges into sorted, disjoint ranges. The documented offsets are half-open intervals, [start, end): the start offset is included and the end offset is excluded. Use the returned offsets consistently, and do not add overlapping raw ranges as if each represented distinct source characters. When calculating covered source length, sum the lengths of the disjoint ranges rather than counting shared spans twice.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Inspect a single result

for entry in coverage:
    text = entry["text"]
    ranges = entry["ranges"]
    covered = sum(r["end"] - r["start"] for r in ranges)
    print(entry["url"], "covered offsets:", covered, "source characters:", len(text))
    for r in ranges:
        print("  start:", r["start"], "end:", r["end"])

This arithmetic is useful for understanding character-offset spans in these returned ranges; it is not automatically a byte count, a percentage of meaningful application code, or a result that can be transferred to another tool without checking that tool’s offset conventions. Bundlers, source maps, generated scripts, and wrapper code can also make raw script text differ from the source files developers edit.

Make the captured page flow representative

Coverage is a record of what was loaded and exercised during a session, not a complete inventory of everything an application could execute. Chrome DevTools’ Coverage workflow similarly records a reload and subsequent interactions; its report depends on the resources and behavior observed during that recording. Chrome DevTools Coverage guide

Before deciding that a function is unused or a script is missing, include the relevant conditions in the capture:

  • Load the route that owns the code, including direct visits as well as in-app navigation if both matter.
  • Trigger menus, dialogs, lazy-loaded sections, form validation, and other interactions that execute code conditionally.
  • Use the authentication state, feature flags, viewport, and data state relevant to the behavior you are diagnosing.
  • Wait for the target activity to finish before stopping coverage; a request or delayed callback that has not run yet cannot appear as executed.
  • Repeat the same page flow when comparing tools or runs, rather than comparing a full interaction recording with a load-only capture.

Verify the browser build and reproduce before blaming a release

Pyppeteer’s documentation says it works best with its bundled Chromium. A separately configured executable may differ in DevTools Protocol behavior or version. Record the Pyppeteer version, Chromium version and executable path, operating system, navigation sequence, and interaction steps whenever results appear inconsistent. Reproduce with the bundled browser before attributing the discrepancy to Pyppeteer itself. The sources available do not identify a specific version regression or Chromium defect for this issue. Pyppeteer documentation

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Capture environment details in Python

import pyppeteer

print("Pyppeteer version:", pyppeteer.__version__)

browser = await launch()
print("Chromium version:", await browser.version())
print("Browser process:", browser.process.args[0] if browser.process else "unknown")

If your installed package does not expose the version attribute as shown, obtain the package version from the same Python environment that runs the script. Include the complete capture code and exact steps in a reproducible report; “coverage looks wrong” alone does not distinguish timing, navigation, attribution, range interpretation, or a browser difference.

Compare with Chrome DevTools carefully

DevTools Coverage can help determine whether a discrepancy comes from the Pyppeteer capture path or from the page flow, but it is not an automatic correctness oracle. Use the same browser build where possible, reload in the same way, exercise the same interactions, and compare the actual scripts and ranges. A mismatch can reflect different recording scope, script attribution, or tool behavior; the comparison alone does not prove a Pyppeteer bug.

Troubleshoot by symptom

Symptom Likely check Action
Expected code is absent Coverage began after that code ran, the path was not exercised, or a generated script was anonymous. Start coverage earlier, repeat the intended interaction, and enable reportAnonymousScript for anonymous code.
Earlier route data disappears resetOnNavigation defaults to true; navigation resets may also occur despite requesting false. Inspect the option and test the actual navigation sequence; capture routes separately if necessary.
Unexpected synthetic URL appears The script is anonymous and reported through Pyppeteer’s synthetic evaluation label. Associate a source URL where appropriate or recognize __pyppeteer_evaluation_script__ as anonymous-script attribution.
Covered total is larger than expected Downstream code may count overlapping intervals or use the wrong offset interpretation. Use the returned disjoint ranges and half-open offsets; do not count a shared span twice.
An entry has no usable source text or URL The implementation skips entries when required source or attribution data is missing. Inspect the underlying script source and whether it has a URL; capture the full entry before filtering it downstream.
Pyppeteer and DevTools disagree The browser build, capture start, route, interactions, or attribution may differ. Align the environment and page flow first; treat remaining disagreement as a clue, not proof of a library regression.
Coverage changes runtime behavior Precise coverage instrumentation alters optimization and execution counters. Use coverage to diagnose observed execution, and avoid treating an instrumented run as a performance benchmark.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

For a screenshot of the rendered page rather than JavaScript execution ranges, ScreenshotNeo offers a one-request screenshot API and an MCP server for AI agents. It does not replace Pyppeteer coverage: use the browser workflow above when you need executed script ranges.

cURL:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the ScreenshotNeo API documentation for request options. Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never 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.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Sign up free for ScreenshotNeo and try 1,000 screenshots a month with no card.

Frequently Asked Questions

Does Pyppeteer coverage show every line in my application?

No. It records scripts and execution observed during the capture session, not an inventory of every possible application path.

Is an empty range list proof that a JavaScript file was never used?

Not on its own. Confirm that the entry has usable source and attribution, and that the relevant code ran after coverage began.

Can ScreenshotNeo return Pyppeteer JavaScript coverage ranges?

No. ScreenshotNeo captures screenshots or PDFs; use Pyppeteer coverage when you need JavaScript execution ranges.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.