Puppeteer offers a range of methods to debug your Puppeteer scripts.
In this article, we’ll be discussing the various ways of debugging in Puppeteer along with the tools and techniques associated with it.
How to set up debugging in Puppeteer?
Assuming that you already have Puppeteer installed, let’s get started with a basic script to debug.
Step 1: Prepare a basic Puppeteer Script
By creating a simple script as shown below you would have a foundation to test the Puppeteer debug methods. Create a test file named example.js and add the following code.
<pre class="highlight pre-shadow">
<code class="js">
const puppeteer = require('puppeteer');
(async () => {
//with const browser await puppeteer,launch browser and import the puppeteer library
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://nodejs.org/en');
await page.screenshot({ path: 'example.png' });
await browser.close();
})();
</code>
</pre>This should launch a headless test browser, navigate to the specified URL ‘nodejs.org/en’, take a screenshot to store it in the same folder as your script, and close the newly opened test browser.
Step 2: Enable Debugging
To enable debugging in Puppeteer, you can use the --inspect flag when running your Node.js script. This flag allows you to debug puppeteer scripts using Chrome DevTools. Run the following command in your terminal by using an IDE like Visual Studio Code.
<pre class="highlight pre-shadow">
<code class="js">
node --inspect-brk example.js
</code>
</pre>The --inspect-brk flag starts the script in debug mode and pauses the execution at the very beginning of the script, allowing you to set additional breakpoints if needed.
Step 4: Open Chrome DevTools
After running the above command, you will see an output similar to this.
<pre class="highlight pre-shadow">
<code class="js">
Debugger listening on ws://127.0.0.1:9229/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
For help see https://nodejs.org/en/docs/inspector
</code>
</pre>Open Chrome and navigate to chrome://inspect. Click on the "Open dedicated DevTools for Node" link. This will open Chrome DevTools, where you can see your code, set breakpoints, and inspect variables.
Step 5: Set Breakpoints
In the Chrome DevTools window, navigate to the Sources tab. You will see your script (example.js) in the file explorer on the left. Click on the file to open it, and set breakpoints by clicking on the line numbers. If you don’t see your file there, you can add it by clicking on the ‘+’ symbol.
Step 6: Debug Your Script
With breakpoints set, you can now efficiently debug puppeteer scripts. Use the play, step over, step into, and step out buttons to control the execution flow. Inspect variables in the Scope panel and evaluate expressions in the Console output.
Example Setup of a Puppeteer Debugger
To provide a more comprehensive example, let’s expand our script and debug a more complex scenario.
Complex Puppeteer Script
Create a new file named complexExample.js and add the following test code.
<pre class="highlight pre-shadow">
<code class="js">
const puppeteer = require('puppeteer');
(async () => {
//with const browser await puppeteer,launch browser and import the puppeteer library
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
page.on('console', msg => console.log('PAGE LOG:', msg.text()));
await page.goto('https://nodejs.org/en');
// Simulate user interactions
await page.click('a');
await page.waitForSelector('h1');
const title = await page.title();
console.log(`Title: ${title}`);
await browser.close();
})();
</code>
</pre>Debugging Complex Script
Run the script with debugging enabled by entering this in the command terminal.
<pre class="highlight pre-shadow">
<code class="js">
node --inspect-brk complexExample.js
</code>
</pre>Open Chrome DevTools as described earlier. You can use the following tips for a more granular level of debugging.
Using debugger Statements
You can add debugger statements directly in your code to pause execution at specific points.
<pre class="highlight pre-shadow">
<code class="js">
const title = await page.title();
debugger;
console.log(`Title: ${title}`);
</code>
</pre>For instance, adding the above code will pause execution at the ‘debugger’ statement, allowing you to inspect variables and the current state of the script in Chrome DevTools.
Evaluating Expressions
In the Console tab of Chrome DevTools, you can analyze the console output and evaluate expressions within the context of your script. This is useful for inspecting variables or trying out code snippets, and once you're done, you can resume test execution.
Monitoring Network Requests
Puppeteer also allows you to intercept and monitor network requests. To do so you can add this code to your script.
<pre class="highlight pre-shadow">
<code class="js">
page.on('request', request => {
console.log('Request:', request.url());
});
</code>
</pre>This will allow your terminal to log each network request URL made by the page.
Best practices to debug puppeteer scripts
There is a collection of best practices that you can follow to make sure that your script is debugged effectively.
Set headless mode to false
Instead of launching a headless Chromium window, this toggles the headless mode setting to false, allowing you to use Chrome DevTools directly for inspecting elements, monitoring network activity, and debugging JavaScript.
<pre class="highlight pre-shadow">
<code class="js">
//with const browser await puppeteer,launch browser and import the puppeteer library
const browser = await puppeteer.launch({headless: false});
</code>
</pre>Use Slow Motion
Using slow motion allows you to slow down Puppeteer’s actions, loading the page step by step, which makes it easier to observe what’s happening. This comes in handy when identifying timing issues or understanding element interactions.
<pre class="highlight pre-shadow">
<code class="js">
const browser = await puppeteer.launch({headless: false, slowMo: 250});
</code>
</pre>Using an enhanced debugger
If you have complex debugging scenarios you would need to use a more enhanced debugger like ndb which was made specifically for Nodejs applications. You can install it using the following command.
<pre class="highlight pre-shadow">
<code class="js">
npm install -g ndb
</code>
</pre>When you use ndb before a command (like ndb jest), it launches a special debugging environment where you can execute and debug your script. This environment offers more sophisticated debugging features, such as better handling of asynchronous operations, a more user-friendly interface for navigating code, and enhanced visualization of the application's execution.
Capture screenshots
By using page.screenshot() you can capture screenshots of the web page when your script encounters errors. This allows you to analyze it and take preventative countermeasures.
<pre class="highlight pre-shadow">
<code class="js">
await page.goto('https://nodejs.org/en');
await page.screenshot({ path: 'screenshot.png' });
</code>
</pre>Try-Catch
Implementing the try-catch method involves wrapping code blocks that are prone to errors and catching any errors that might occur, preventing your node script from crashing.
This is an example of how you could use it.
<pre class="highlight pre-shadow">
<code class="js">
try {
await page.click('.nonexistent-button');
} catch (error) {
console.error("Error clicking button:", error);
}
</code>
</pre>Conclusion
Overall, while Puppeteer is a library with high functionality, it isn’t immune to errors like page crashes, selector problems, timeout issues, and so on. The causes of these errors and bugs can be detected by following the debugging methods and applying them to your script. However, debugging alone is not enough. It should be complemented with thorough testing, proper error handling, and continuous monitoring to ensure the reliability and robustness of your Puppeteer scripts.

