Puppeteer与VSCode-Debugger融合调试
本节学习如何将 Puppeteer 与 VSCode Debugger 结合,实现自动化调试。
2024-2026 更新:VSCode js-debug 已内置支持,Puppeteer 调试配置更简单。Playwright 也提供了类似的调试体验。
融合调试的原理
Puppeteer 通过 CDP 控制浏览器,VSCode js-debug 也通过 CDP 调试代码。它们本质上是两个 CDP Client,连接到同一个 Chrome 实例。
图表渲染中…
关键:两个 CDP Client 可以同时连接到同一个 Chrome 实例,互不干扰。js-debug 使用 Debugger Domain 设置断点,Puppeteer 使用 Page/Network/DOM 等 Domain 控制页面。
方式一:Puppeteer 启动 Chrome + VSCode 附加
步骤
- 在 Puppeteer 脚本中启动 Chrome 并暴露调试端口
- VSCode 通过 attach 配置连接到该端口
javascript
// test.js
const puppeteer = require('puppeteer');
(async () => {
// 启动 Chrome,暴露调试端口
const browser = await puppeteer.launch({
headless: false,
args: ['--remote-debugging-port=9222'],
});
const page = await browser.newPage();
await page.goto('http://localhost:5173');
// 在此处可以设置 debugger 语句
// 或在 VSCode 中设置断点
await page.click('#submit');
await browser.close();
})();VSCode 调试配置:
json
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Puppeteer",
"type": "chrome",
"request": "attach",
"port": 9222,
"webRoot": "${workspaceFolder}",
"sourceMaps": true
}
]
}执行流程
图表渲染中…
方式二:VSCode 启动 Chrome + Puppeteer 附加
步骤
- VSCode 启动 Chrome 并打开页面
- Puppeteer 通过
puppeteer.connect()连接到已有的 Chrome
VSCode 调试配置:
json
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Chrome",
"type": "chrome",
"request": "launch",
"url": "http://localhost:5173",
"webRoot": "${workspaceFolder}",
"runtimeArgs": ["--remote-debugging-port=9222"]
}
]
}Puppeteer 脚本:
javascript
const puppeteer = require('puppeteer-core');
(async () => {
// 连接到 VSCode 启动的 Chrome
const browser = await puppeteer.connect({
browserURL: 'http://127.0.0.1:9222',
});
const pages = await browser.pages();
const page = pages[0];
// 执行自动化操作
await page.click('#submit');
await page.type('#search', 'hello');
})();方式三:使用 JavaScript Debug Terminal
2024-2026 更新:最简单的方式是使用 VSCode 的 JavaScript Debug Terminal:
步骤
- 在 VSCode 中打开 JavaScript Debug Terminal(
Cmd+Shift+P→ Debug: JavaScript Debug Terminal) - 在终端中运行 Puppeteer 脚本:
node test.js - VSCode 会自动检测到 Chrome 实例并附加调试
javascript
// test.js - 使用 debugger 语句触发调试
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: false,
});
const page = await browser.newPage();
await page.goto('http://localhost:5173');
// 方式一:在 Puppeteer 脚本中设置断点
debugger; // VSCode 会在这一行断住
// 方式二:在页面中注入 debugger
await page.evaluate(() => {
debugger; // 浏览器中会断住,VSCode 也会捕获
});
await browser.close();
})();JavaScript Debug Terminal 的原理
图表渲染中…
2024-2026 新增:Playwright 的调试模式与 Trace Viewer 见《Playwright 调试模式与 Trace Viewer》篇。
调试实战:自动化测试中定位问题
场景:E2E 测试失败
javascript
// test.spec.js
const puppeteer = require('puppeteer');
describe('Login Flow', () => {
it('should login successfully', async () => {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto('http://localhost:5173/login');
// 测试断住在这里
await page.type('#username', 'admin');
await page.type('#password', 'password');
await page.click('#login-button');
// 期望跳转到首页,但实际没跳转
// 注意:waitForNavigation 已在 v22+ 弃用,推荐 waitForURL
await page.waitForURL('**/dashboard', { timeout: 5000 });
expect(page.url()).toContain('/dashboard');
await browser.close();
});
});调试步骤
图表渲染中…
调试辅助代码
javascript
// 截图
await page.screenshot({ path: 'debug.png' });
// 监听 Console
page.on('console', msg => console.log('PAGE LOG:', msg.text()));
// 监听错误
page.on('pageerror', error => console.log('PAGE ERROR:', error.message));
// 监听网络请求失败
page.on('requestfailed', request => {
console.log('REQUEST FAILED:', request.url(), request.failure().errorText);
});
// 监听响应
page.on('response', response => {
if (response.status() >= 400) {
console.log('RESPONSE ERROR:', response.url(), response.status());
}
});
// 暂停执行,等待手动操作
// 注意:page.waitForTimeout() 已在 Puppeteer v23 中移除
await new Promise(r => setTimeout(r, 5000)); // 等待 5 秒
// Playwright 调试模式
await page.pause(); // 打开 Playwright Inspector