What Are the Debugging Techniques Available in Playwright?
Playwright offers a comprehensive suite of debugging tools and techniques that help developers identify and resolve issues in their web automation scripts. Whether you're dealing with flaky tests, element selection problems, or timing issues, Playwright provides multiple approaches to debug your code effectively.
Debug Mode with Playwright Inspector
The most powerful debugging feature in Playwright is the Playwright Inspector, which provides a visual debugging interface with step-by-step execution capabilities.
Enabling Debug Mode
To enable debug mode, you can use the --debug
flag or set the PWDEBUG
environment variable:
# Using command line flag
npx playwright test --debug
# Using environment variable
PWDEBUG=1 npx playwright test
# Debug specific test
npx playwright test example.spec.js --debug
In Python:
import os
from playwright.sync_api import sync_playwright
# Set debug mode
os.environ["PWDEBUG"] = "1"
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://example.com")
page.pause() # This will open the inspector
browser.close()
Using page.pause() for Interactive Debugging
The page.pause()
method stops execution and opens the Playwright Inspector, allowing you to:
- Step through actions one by one
- Inspect the current page state
- Try different selectors
- Modify and re-run actions
// JavaScript/TypeScript
await page.goto('https://example.com');
await page.pause(); // Opens inspector here
await page.click('#submit-button');
# Python
page.goto('https://example.com')
page.pause() # Opens inspector here
page.click('#submit-button')
Browser Developer Tools Integration
Playwright allows you to access browser developer tools directly, which is invaluable for debugging DOM-related issues and network problems.
Launching with DevTools Open
// JavaScript/TypeScript
const browser = await chromium.launch({
devtools: true,
headless: false
});
# Python
browser = p.chromium.launch(devtools=True, headless=False)
Using slowMo for Visual Debugging
The slowMo
option slows down operations, making it easier to observe what's happening:
const browser = await chromium.launch({
headless: false,
slowMo: 1000 // 1 second delay between actions
});
Network Monitoring and Request Debugging
Playwright provides excellent tools for monitoring and debugging network requests, which is crucial for understanding API interactions and resource loading issues.
Listening to Network Events
// Monitor all network requests
page.on('request', request => {
console.log('Request:', request.url());
});
page.on('response', response => {
console.log('Response:', response.url(), response.status());
});
// Monitor failed requests
page.on('requestfailed', request => {
console.log('Failed request:', request.url(), request.failure());
});
Intercepting and Modifying Requests
// Intercept and log requests
await page.route('**/*', (route, request) => {
console.log('Intercepted:', request.url());
route.continue();
});
// Block specific resources for testing
await page.route('**/*.{png,jpg,jpeg}', route => route.abort());
Screenshot and Video Debugging
Visual debugging through screenshots and videos helps identify what went wrong during test execution.
Taking Screenshots on Failure
// Automatic screenshot on test failure
test('example test', async ({ page }) => {
try {
await page.goto('https://example.com');
await page.click('#non-existent-button');
} catch (error) {
await page.screenshot({ path: 'failure-screenshot.png' });
throw error;
}
});
Recording Videos
// Configure video recording in playwright.config.js
module.exports = {
use: {
video: 'retain-on-failure', // or 'on', 'off'
screenshot: 'only-on-failure'
}
};
Console Output and Logging
Playwright captures console messages from the browser, which is essential for debugging client-side JavaScript issues.
Listening to Console Messages
page.on('console', msg => {
console.log('Browser console:', msg.type(), msg.text());
});
page.on('pageerror', exception => {
console.log('Page error:', exception.message);
});
Adding Custom Logging
// Inject custom logging into the page
await page.addInitScript(() => {
window.debugInfo = (message) => {
console.log('DEBUG:', message);
};
});
Element Selection and Locator Debugging
Playwright provides tools to debug element selection issues, which are common sources of test failures.
Using page.locator() with Debug Information
// Get detailed information about locators
const locator = page.locator('#submit-button');
console.log('Locator count:', await locator.count());
console.log('Locator visible:', await locator.isVisible());
Playwright Inspector for Selector Testing
The Playwright Inspector allows you to test selectors interactively:
- Open the inspector with
page.pause()
- Use the selector input to test different strategies
- See real-time highlighting of matched elements
- Copy working selectors directly to your code
Timeout and Timing Debugging
Timing issues are common in web automation. Playwright provides several debugging techniques for these scenarios.
Custom Timeout Configuration
// Set custom timeouts for debugging
await page.waitForSelector('#dynamic-content', { timeout: 30000 });
await page.click('#button', { timeout: 5000 });
Wait Strategies for Dynamic Content
// Wait for network to be idle
await page.waitForLoadState('networkidle');
// Wait for specific conditions
await page.waitForFunction(() => {
return document.querySelector('#data-loaded') !== null;
});
Trace Viewer for Comprehensive Debugging
Playwright's Trace Viewer provides a comprehensive timeline of all actions performed during test execution.
Enabling Trace Collection
// In playwright.config.js
module.exports = {
use: {
trace: 'on-first-retry', // or 'on', 'retain-on-failure'
}
};
Viewing Traces
# Open trace viewer
npx playwright show-trace trace.zip
The trace viewer shows: - Timeline of all actions - Screenshots at each step - Network requests and responses - Console messages - DOM snapshots
Advanced Debugging Techniques
Custom Debug Functions
// Create reusable debug utilities
async function debugPageState(page, label) {
console.log(`=== DEBUG: ${label} ===`);
console.log('URL:', page.url());
console.log('Title:', await page.title());
// Take screenshot with timestamp
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
await page.screenshot({ path: `debug-${label}-${timestamp}.png` });
}
// Usage
await debugPageState(page, 'before-login');
await page.fill('#username', 'testuser');
await debugPageState(page, 'after-username');
Debugging in Different Browser Contexts
// Test across different browsers for debugging
for (const browserName of ['chromium', 'firefox', 'webkit']) {
const browser = await playwright[browserName].launch();
const page = await browser.newPage();
try {
await page.goto('https://example.com');
// Your test logic here
} catch (error) {
console.log(`Error in ${browserName}:`, error.message);
} finally {
await browser.close();
}
}
Best Practices for Debugging
- Start with Simple Debugging: Use
page.pause()
and console logs before moving to advanced techniques - Use Descriptive Screenshots: Name screenshots with meaningful descriptions and timestamps
- Monitor Network Activity: Many issues stem from failed API calls or resource loading problems
- Test in Multiple Browsers: Cross-browser issues are common and require targeted debugging
- Leverage Trace Viewer: For complex issues, the trace viewer provides the most comprehensive debugging information
Integration with Testing Frameworks
Playwright debugging works seamlessly with popular testing frameworks:
// Jest integration
test('debug example', async () => {
await page.goto('https://example.com');
await page.pause(); // Will pause only when debugging
expect(await page.title()).toBe('Expected Title');
});
// Mocha integration
it('should handle complex interactions', async function() {
this.timeout(60000); // Increase timeout for debugging
await page.goto('https://example.com');
// Debug logic here
});
Understanding these debugging techniques will significantly improve your ability to create reliable web automation scripts with Playwright. The combination of visual debugging, network monitoring, and comprehensive tracing makes Playwright one of the most developer-friendly automation tools available.
For more advanced browser automation scenarios, you might also want to explore how to handle authentication in Puppeteer or learn about monitoring network requests in Puppeteer for additional debugging insights across different automation tools.