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
-
Set
devtools
totrue
when launching Puppeteer:const browser = await puppeteer.launch({devtools: true});
-
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.
-
Set
headless
tofalse
. -
Add
debugger
to any server code you want debugged. For example,debugger;
await page.click('a[target=_blank]'); -
Run your server code with
--inspect-brk
. For example,node --inspect-brk path/to/script.js
-
In the opened Chrome/Chromium browser, open
chrome://inspect/#devices
and clickinspect
. -
In the newly opened test browser, press
F8
to resume test execution. -
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.