playwright、puppeteer 和 selenium-webdriver 都是用于浏览器自动化的主流 npm 包,广泛应用于端到端测试、爬虫、截图生成等场景。它们都能控制真实浏览器执行用户操作,但底层架构、支持的浏览器范围、API 设计和维护策略存在显著差异。playwright 由 Microsoft 开发,支持 Chromium、WebKit 和 Firefox;puppeteer 由 Google 主导,主要聚焦于 Chromium;selenium-webdriver 是 Selenium 项目的一部分,通过 WebDriver 协议支持多语言和多浏览器,但在 Node.js 环境中使用时需额外配置浏览器驱动。
在构建健壮的端到端(E2E)测试套件或实现高级浏览器自动化任务时,playwright、puppeteer 和 selenium-webdriver 是三个主流选择。它们都能操控真实浏览器,但设计理念、功能覆盖和开发体验差异显著。本文从实际工程角度出发,通过代码示例对比关键能力。
puppeteer 仅支持 Chromium 系浏览器(Chrome、Edge 等)。虽然可通过实验性方式连接 Firefox,但官方不推荐用于生产。
// puppeteer: 启动 Chromium
const browser = await puppeteer.launch();
const page = await browser.newPage();
playwright 原生支持 Chromium、WebKit(Safari 内核)和 Firefox,三者 API 行为高度一致。
// playwright: 启动任意浏览器
const { chromium, webkit, firefox } = require('playwright');
const browser = await chromium.launch(); // 或 webkit.launch(), firefox.launch()
const page = await browser.newPage();
selenium-webdriver 理论上支持所有实现 WebDriver 协议 的浏览器(Chrome、Firefox、Safari、Edge),但需为每种浏览器单独安装对应驱动(如 chromedriver、geckodriver)。
// selenium-webdriver: 需显式指定驱动
const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const driver = new Builder()
.forBrowser('chrome')
.setChromeOptions(new chrome.Options())
.build();
💡 关键区别:Playwright 内置所有浏览器二进制文件,开箱即用;Selenium 需手动管理驱动版本兼容性。
现代 Web 应用大量依赖异步加载,可靠的等待策略至关重要。
playwright 提供 自动等待:几乎所有操作(如 click()、fill())会自动等待元素可交互,无需额外代码。
// playwright: 自动等待按钮可点击
await page.click('#submit-button');
// 自动等待输入框就绪
await page.fill('#email', 'test@example.com');
puppeteer 需要 手动等待 元素状态,否则容易因竞态条件失败。
// puppeteer: 必须显式等待
await page.waitForSelector('#submit-button', { visible: true });
await page.click('#submit-button');
await page.waitForFunction(() => document.querySelector('#email').offsetParent !== null);
await page.type('#email', 'test@example.com');
selenium-webdriver 提供 显式等待(Explicit Waits),但需开发者自行编写条件逻辑。
// selenium-webdriver: 使用 WebDriverWait
const { until } = require('selenium-webdriver');
await driver.wait(until.elementLocated({ id: 'submit-button' }), 5000);
const button = await driver.findElement({ id: 'submit-button' });
await button.click();
💡 实践建议:Playwright 的自动等待大幅减少 flaky tests(不稳定测试),而 Puppeteer 和 Selenium 需要更多样板代码确保稳定性。
拦截请求、模拟响应对测试边界条件至关重要。
playwright 支持 路由(Routing),可拦截并修改任意请求。
// playwright: 拦截 API 请求并返回 mock 数据
await page.route('**/api/user', route => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ name: 'Mock User' })
});
});
await page.goto('/profile');
puppeteer 通过 .setRequestInterception 实现类似功能,但需手动处理请求继续或响应。
// puppeteer: 拦截请求
await page.setRequestInterception(true);
page.on('request', interceptedRequest => {
if (interceptedRequest.url().includes('/api/user')) {
interceptedRequest.respond({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ name: 'Mock User' })
});
} else {
interceptedRequest.continue();
}
});
await page.goto('/profile');
selenium-webdriver 原生不支持网络拦截。需借助外部代理(如 BrowserMob Proxy)或浏览器扩展实现,大幅增加复杂度。
// selenium-webdriver: 无法直接拦截,需额外工具链
// 通常需启动独立代理服务并配置浏览器使用该代理
💡 结论:Playwright 和 Puppeteer 在网络控制上远胜 Selenium,尤其适合需要模拟慢速网络、错误响应或认证令牌的场景。
playwright 内置 设备预设(如 iPhone 12、Pixel 5),一键模拟视口、UA 和触摸事件。
// playwright: 使用设备预设
const { devices } = require('playwright');
const iPhone = devices['iPhone 12'];
const context = await browser.newContext({ ...iPhone });
const page = await context.newPage();
puppeteer 需手动设置视口和 UA 字符串。
// puppeteer: 手动配置移动设备
await page.setViewport({ width: 390, height: 844, isMobile: true });
await page.setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) ...');
selenium-webdriver 可通过 Chrome DevTools Protocol (CDP) 或 Firefox 配置 模拟设备,但 API 繁琐且浏览器间不一致。
// selenium-webdriver: 通过 CDP 设置(仅限 Chrome)
await driver.executeCdpCommand('Emulation.setDeviceMetricsOverride', {
width: 390,
height: 844,
mobile: true,
deviceScaleFactor: 2
});
playwright 原生支持 测试隔离:每个测试可拥有独立的浏览器上下文(Context),共享浏览器进程但内存隔离,启动速度快。
// playwright: 每个测试新建上下文
const context = await browser.newContext();
const page = await context.newPage();
// 测试结束后关闭上下文,而非整个浏览器
await context.close();
puppeteer 通常为每个测试启动 全新浏览器实例,资源开销大、速度慢。
// puppeteer: 常见做法(低效)
const browser = await puppeteer.launch();
const page = await browser.newPage();
// 测试结束需关闭整个浏览器
await browser.close();
selenium-webdriver 依赖外部 Grid 或本地驱动管理,无内置并行抽象,需自行设计资源池。
playwright:活跃维护,Microsoft 主导,持续增加新特性(如组件测试、录制器)。puppeteer:Google 维护,稳定但更新节奏放缓,重心转向 Chrome DevTools 集成。selenium-webdriver:Selenium 项目核心部分,长期支持,但 Node.js 版本 API 相对陈旧,缺乏现代 E2E 工具的便利性。| 场景 | 推荐工具 | 理由 |
|---|---|---|
| 跨浏览器 E2E 测试(含 Safari/Firefox) | playwright | 唯一提供 WebKit 和 Firefox 一致支持的现代方案 |
| 仅 Chromium 环境的轻量自动化(如 PDF 生成) | puppeteer | 启动快、API 简洁、社区成熟 |
| 已有 Selenium 基础设施或多语言测试团队 | selenium-webdriver | 与现有 Grid/Hub 无缝集成,语言无关 |
| 需要网络拦截、设备模拟、自动等待等高级特性 | playwright | 开箱即用,减少样板代码 |
| 资源受限环境(如 CI)需快速并行测试 | playwright | 上下文隔离比新建浏览器实例更高效 |
playwright:它解决了 Puppeteer 和 Selenium 的多数痛点,提供更可靠、更简洁的自动化体验。puppeteer:如果你不需要跨浏览器,且已有 Puppeteer 脚本,迁移成本可能不值得。selenium-webdriver:除非你深度依赖 Selenium 生态(如企业级 Grid),否则其繁琐的配置和底层 API 会拖慢开发效率。无论选择哪个,都应结合具体需求权衡——但对大多数现代前端团队而言,Playwright 正迅速成为事实上的标准。
选择 playwright 如果你需要跨浏览器(包括 WebKit 和 Firefox)的一致性测试能力、内置等待机制、网络拦截、设备模拟以及开箱即用的并行测试支持。它特别适合现代 Web 应用的复杂 E2E 测试场景,且希望避免手动管理浏览器驱动或处理竞态条件问题。
选择 puppeteer 如果你的项目仅针对 Chromium 系浏览器(如 Chrome 或 Edge),且需要轻量级、高性能的自动化控制。它在 PDF 生成、页面截图、无头渲染等任务上表现优异,但不支持非 Chromium 内核浏览器,且对现代前端框架的异步等待支持不如 Playwright 完善。
选择 selenium-webdriver 如果你已在使用 Selenium 生态(如 Java/Python 测试套件),或需要与现有 Selenium Grid 集成。它在多语言团队中具有优势,但在 Node.js 中使用时需手动下载和管理浏览器驱动,API 较为底层,缺乏现代 E2E 工具的便捷特性(如自动等待、网络 mocking)。
Playwright is a framework for web automation and testing. It drives Chromium, Firefox, and WebKit with a single API — in your tests, in your scripts, and as a tool for AI agents.
Choose the path that fits your workflow:
| Best for | Install | |
|---|---|---|
| Playwright Test | End-to-end testing | npm init playwright@latest |
| Playwright CLI | Coding agents (Claude Code, Copilot) | npm i -g @playwright/cli@latest |
| Playwright MCP | AI agents and LLM-driven automation | npx @playwright/mcp@latest |
| Playwright Library | Browser automation scripts | npm i playwright |
| VS Code Extension | Test authoring and debugging in VS Code | Install from Marketplace |
Playwright Test is a full-featured test runner built for end-to-end testing. It runs tests across Chromium, Firefox, and WebKit with full browser isolation, auto-waiting, and web-first assertions.
npm init playwright@latest
Or add manually:
npm i -D @playwright/test
npx playwright install
import { test, expect } from '@playwright/test';
test('has title', async ({ page }) => {
await page.goto('https://playwright.dev/');
await expect(page).toHaveTitle(/Playwright/);
});
test('get started link', async ({ page }) => {
await page.goto('https://playwright.dev/');
await page.getByRole('link', { name: 'Get started' }).click();
await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible();
});
npx playwright test
Tests run in parallel across all configured browsers, in headless mode by default. Each test gets a fresh browser context — full isolation with near-zero overhead.
Auto-wait and web-first assertions. No artificial timeouts. Playwright waits for elements to be actionable, and assertions automatically retry until conditions are met.
Locators. Find elements with resilient locators that mirror how users see the page:
page.getByRole('button', { name: 'Submit' })
page.getByLabel('Email')
page.getByPlaceholder('Search...')
page.getByTestId('login-form')
Test isolation. Each test runs in its own browser context — equivalent to a fresh browser profile. Save authentication state once and reuse it across tests:
// Save state after login
await page.context().storageState({ path: 'auth.json' });
// Reuse in other tests
test.use({ storageState: 'auth.json' });
Tracing. Capture execution traces, screenshots, and videos on failure. Inspect every action, DOM snapshot, network request, and console message in the Trace Viewer:
// playwright.config.ts
export default defineConfig({
use: {
trace: 'on-first-retry',
},
});
npx playwright show-trace trace.zip
Parallelism. Tests run in parallel by default across all configured browsers.
Playwright CLI is a command-line interface for browser automation designed for coding agents. It's more token-efficient than MCP — commands avoid loading large tool schemas and accessibility trees into the model context.
npm install -g @playwright/cli@latest
Optionally install skills for richer agent integration:
playwright-cli install --skills
Point your coding agent at a task:
Test the "add todo" flow on https://demo.playwright.dev/todomvc using playwright-cli.
Take screenshots for all successful and failing scenarios.
Or run commands directly:
playwright-cli open https://demo.playwright.dev/todomvc/ --headed
playwright-cli type "Buy groceries"
playwright-cli press Enter
playwright-cli screenshot
Use playwright-cli show to open a visual dashboard with live screencast previews of all running browser sessions. Click any session to zoom in and take remote control.
playwright-cli show
Full CLI documentation | GitHub
The Playwright MCP server gives AI agents full browser control through the Model Context Protocol. Agents interact with pages using structured accessibility snapshots — no vision models or screenshots required.
Add to your MCP client (VS Code, Cursor, Claude Desktop, Windsurf, etc.):
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
}
}
}
One-click install for VS Code:
For Claude Code:
claude mcp add playwright npx @playwright/mcp@latest
Ask your AI assistant to interact with any web page:
Navigate to https://demo.playwright.dev/todomvc and add a few todo items.
The agent sees the page as a structured accessibility tree:
- heading "todos" [level=1]
- textbox "What needs to be done?" [ref=e5]
- listitem:
- checkbox "Toggle Todo" [ref=e10]
- text: "Buy groceries"
It uses element refs like e5 and e10 to click, type, and interact — deterministically and without visual ambiguity. Tools cover navigation, form filling, screenshots, network mocking, storage management, and more.
Full MCP documentation | GitHub
Use playwright as a library for browser automation scripts — web scraping, PDF generation, screenshot capture, and any workflow that needs programmatic browser control without a test runner.
npm i playwright
Take a screenshot:
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://playwright.dev/');
await page.screenshot({ path: 'screenshot.png' });
await browser.close();
Generate a PDF:
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://playwright.dev/');
await page.pdf({ path: 'page.pdf', format: 'A4' });
await browser.close();
Emulate a mobile device:
import { chromium, devices } from 'playwright';
const browser = await chromium.launch();
const context = await browser.newContext(devices['iPhone 15']);
const page = await context.newPage();
await page.goto('https://playwright.dev/');
await page.screenshot({ path: 'mobile.png' });
await browser.close();
Intercept network requests:
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage();
await page.route('**/*.{png,jpg,jpeg}', route => route.abort());
await page.goto('https://playwright.dev/');
await browser.close();
Library documentation | API reference
The Playwright VS Code extension brings test running, debugging, and code generation directly into your editor.
Run and debug tests from the editor with a single click. Set breakpoints, inspect variables, and step through test execution with a live browser view.
Generate tests with CodeGen. Click "Record new" to open a browser — navigate and interact with your app while Playwright writes the test code for you.
Pick locators. Hover over any element in the browser to see the best available locator, then click to copy it to your clipboard.
Trace Viewer integration. Enable "Show Trace Viewer" in the sidebar to get a full execution trace after each test run — DOM snapshots, network requests, console logs, and screenshots at every step.
Install the extension | VS Code guide
| Linux | macOS | Windows | |
|---|---|---|---|
| Chromium1 148.0.7778.96 | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| WebKit 26.4 | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Firefox 150.0.2 | :white_check_mark: | :white_check_mark: | :white_check_mark: |
Headless and headed execution on all platforms. 1 Uses Chrome for Testing by default.
Playwright is also available for Python, .NET, and Java.