puppeteer/docs/guides/debugging.md
2024-04-04 07:20:32 +00:00

5.5 KiB

Debugging

Debugging with Puppeteer can be an arduous task. There is no single method for debugging all possible issues since Puppeteer touches many distinct components of a browser such as network requests and Web APIs. On a high note, Puppeteer provides several methods for debugging which hopefully does cover all possible issues.

Background

In general, there are two possible sources of an issue: Code running on Node.js (which we call server code), and code running in the browser (which we call client code). There is also a third possible source being the browser itself (which we call internal code or browser code), but if you suspect this is the source after attempting the methods below, we suggest searching existing issues before filing an issue.

Debugging methods for all situations

These methods can be used to debug any situation. These should be used as a quick sanity check before diving into more complex methods.

Turn off headless

Sometimes it's useful to see what the browser is displaying. Instead of launching in headless mode, launch a full version of the browser with headless set to false:

const browser = await puppeteer.launch({headless: false});

Puppeteer "slow-mo"

The slowMo option slows down Puppeteer operations by a specified amount of milliseconds. It's another way to help see what's going on.

const browser = await puppeteer.launch({
  headless: false,
  slowMo: 250, // slow down by 250ms
});

Debugging methods for client code

Capture console.* output

Since client code runs in the browser, doing console.* in client code will not directly log to Node.js. However, you can listen (page.on) for the console event which returns a payload with the logged text.

page.on('console', msg => console.log('PAGE LOG:', msg.text()));

await page.evaluate(() => console.log(`url is ${location.href}`));

Use the debugger in the browser

  1. Set devtools to true when launching Puppeteer:

    const browser = await puppeteer.launch({devtools: true});
    
  2. Add debugger inside any client code you want debugged. For example,

    await page.evaluate(() => {
      debugger;
    });
    

    The Browser will now stop in the location the debugger word is found in debug mode.

Debugging methods for server code

Use the debugger in Node.js (Chrome/Chromium-only)

Since server code intermingles with client code, this method of debugging is closely tied with the browser. For example, you can step over await page.click() in the server script and see the click happen in the browser.

Note that you won't be able to run await page.click() in DevTools console due to this Chromium bug, so if you want to try something out, you have to add it to your test file.

  1. Set headless to false.

  2. Add debugger to any server code you want debugged. For example,

    debugger;
    await page.click('a[target=_blank]');
    
  3. Run your server code with --inspect-brk. For example,

    node --inspect-brk path/to/script.js
    
  4. In the opened Chrome/Chromium browser, open chrome://inspect/#devices and click inspect.

  5. In the newly opened test browser, press F8 to resume test execution.

  6. Now your debugger statement will be hit and you can debug in the test browser.

Log DevTools protocol traffic

If all else fails, it's possible there may be an issue between Puppeteer and the DevTools protocol. You can debug this by setting the DEBUG environment variable before running your script. This will log internal traffic via debug under the puppeteer namespace.

# Basic verbose logging
env DEBUG="puppeteer:*" node script.js

# Prevent truncating of long messages
env DEBUG="puppeteer:*" env DEBUG_MAX_STRING_LENGTH=null node script.js

# Protocol traffic can be rather noisy. This example filters out all Network domain messages
env DEBUG="puppeteer:*" env DEBUG_COLORS=true node script.js 2>&1 | grep -v '"Network'

# Filter out all protocol messages but keep all other logging
env DEBUG="puppeteer:*,-puppeteer:protocol:*" node script.js

Log pending protocol calls

If you encounter issues with async Puppeteer calls not getting resolved, try logging pending callbacks by using the debugInfo interface to see what call is the cause:

console.log(browser.debugInfo.pendingProtocolErrors);

The getter returns a list of Error objects and the stacktraces of the error objects indicate which code triggered a protocol call.

Debugging methods for the browser code

Print browser logs

If the browser unexpectedly crashes or does not launch properly, it could be useful to inspect logs from the browser process by setting the launch attribute dumpio to true.

const browser = await puppeteer.launch({
  dumpio: true,
});

In this case, Puppeteer forwards browser logs to the Node process' stdio.