从 Puppeteer 迁移
迁移原则
🌐 Migration Principles
本指南描述了从 Puppeteer 迁移到 Playwright 库 和 Playwright 测试。两者的 API 有相似之处,但 Playwright 在网页测试和跨浏览器自动化方面提供了更多可能性。
🌐 This guide describes migration to Playwright Library and Playwright Test from Puppeteer. The APIs have similarities, but Playwright offers much more possibilities for web testing and cross-browser automation.
- 大多数 Puppeteer API 都可以按原样使用
- 不建议使用 ElementHandle,应使用 Locator 对象和以网页为先的断言。
- Playwriter 是跨浏览器的
- 你可能不需要显式等待
备忘单
🌐 Cheat Sheet
| Puppeteer | Playwright Library |
|---|---|
await puppeteer.launch() | await playwright.chromium.launch() |
puppeteer.launch({product: 'firefox'}) | await playwright.firefox.launch() |
| WebKit is not supported by Puppeteer | await playwright.webkit.launch() |
await browser.createIncognitoBrowserContext(...) | await browser.newContext(...) |
await page.setViewport(...) | await page.setViewportSize(...) |
await page.waitForXPath(XPathSelector) | await page.waitForSelector(XPathSelector) |
await page.waitForNetworkIdle(...) | await page.waitForLoadState('networkidle') |
await page.$eval(...) | Assertions can often be used instead to verify text, attribute, class... |
await page.$(...) | Discouraged, use Locators instead |
await page.$x(xpath_selector) | Discouraged, use Locators instead |
| No methods dedicated to checkbox or radio input | await page.locator(selector).check()await page.locator(selector).uncheck() |
await page.click(selector) | await page.locator(selector).click() |
await page.focus(selector) | await page.locator(selector).focus() |
await page.hover(selector) | await page.locator(selector).hover() |
await page.select(selector, values) | await page.locator(selector).selectOption(values) |
await page.tap(selector) | await page.locator(selector).tap() |
await page.type(selector, ...) | await page.locator(selector).fill(...) |
await page.waitForFileChooser(...)await elementHandle.uploadFile(...) | await page.locator(selector).setInputFiles(...) |
await page.cookies([...urls]) | await browserContext.cookies([urls]) |
await page.deleteCookie(...cookies) | await browserContext.clearCookies() |
await page.setCookie(...cookies) | await browserContext.addCookies(cookies) |
page.on(...) | page.on(...)In order to intercept and mutate requests, see page.route() |
page.waitForNavigation 和 page.waitForSelector 仍然存在,但在许多情况下,由于 自动等待,它们将不再是必需的。
不建议使用 ElementHandle,应使用 Locator 对象和以网页为先的断言。
🌐 The use of ElementHandle is discouraged, use Locator objects and web-first assertions instead.
定位器是 Playwright 自动等待和重试功能的核心部分。定位器是严格的。这意味着对定位器进行的所有涉及某个目标 DOM 元素的操作,如果有多个元素匹配给定的选择器,将会抛出异常。
🌐 Locators are the central piece of Playwright's auto-waiting and retry-ability. Locators are strict. This means that all operations on locators that imply some target DOM element will throw an exception if more than one element matches a given selector.
示例
🌐 Examples
自动化示例
🌐 Automation example
Puppeteer:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 800 });
await page.goto('https://playwright.nodejs.cn/', {
waitUntil: 'networkidle2',
});
await page.screenshot({ path: 'example.png' });
await browser.close();
})();
逐行迁移到 Playwright:
🌐 Line-by-line migration to Playwright:
const { chromium } = require('playwright'); // 1
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage(); // 2
await page.setViewportSize({ width: 1280, height: 800 }); // 3
await page.goto('https://playwright.nodejs.cn/', {
waitUntil: 'networkidle', // 4
});
await page.screenshot({ path: 'example.png' });
await browser.close();
})();
迁移亮点(请参阅 Playwright 代码片段中的内联注释):
🌐 Migration highlights (see inline comments in the Playwright code snippet):
- 每个 Playwright 库文件都明确导入了
chromium。也可以使用其他浏览器webkit或firefox。 - 对于浏览器状态隔离,请考虑 浏览器上下文
setViewport变成setViewportSizenetworkidle2变为networkidle。请注意,在大多数情况下它没有用,因为有自动等待功能。
测试示例
🌐 Test example
使用 Jest 的 Puppeteer:
🌐 Puppeteer with Jest:
import puppeteer from 'puppeteer';
describe('Playwright homepage', () => {
let browser;
let page;
beforeAll(async () => {
browser = await puppeteer.launch();
page = await browser.newPage();
});
it('contains hero title', async () => {
await page.goto('https://playwright.nodejs.cn/');
await page.waitForSelector('.hero__title');
const text = await page.$eval('.hero__title', e => e.textContent);
expect(text).toContain('Playwright enables reliable end-to-end testing'); // 5
});
afterAll(() => browser.close());
});
逐行迁移到 Playwright 测试:
🌐 Line-by-line migration to Playwright Test:
import { test, expect } from '@playwright/test'; // 1
test.describe('Playwright homepage', () => {
test('contains hero title', async ({ page }) => { // 2, 3
await page.goto('https://playwright.nodejs.cn/');
const titleLocator = page.locator('.hero__title'); // 4
await expect(titleLocator).toContainText( // 5
'Playwright enables reliable end-to-end testing'
);
});
});
- 每个 Playwright Test 文件都显式导入了
test和expect函数 - 测试函数被标记为
async - Playwright Test 会将
page作为其参数之一。这是 Playwright Test 中许多有用的 fixture之一。Playwright Test 会为每个测试创建一个隔离的 Page 对象。然而,如果你希望在多个测试之间重用同一个 Page 对象,你可以在 test.beforeAll() 中创建它,并在 test.afterAll() 中关闭它。 - 使用 page.locator() 创建定位器是少数几个同步方法之一。
- 使用 断言 来验证状态,而不是
page.$eval()。
测试
🌐 Testing
为了改进测试,建议使用 定位器 和以网页为先的 断言。参见 编写测试
🌐 To improve testing, it is advised to use Locators and web-first Assertions. See Writing Tests
在 Puppeteer 中,使用 page.evaluate() 或 page.$eval() 来检查 ElementHandle 并提取文本内容、属性、类等的值是很常见的做法。Assertions 提供了多个匹配器用于此目的,它更可靠且可读性更高。
🌐 It is common with Puppeteer to use page.evaluate() or page.$eval() to inspect an ElementHandle and extract the value of text content, attribute, class... Web-first Assertions offers several matchers for this purpose, it is more reliable and readable.
Playwright Test 是我们官方推荐的、与 Playwright 配合使用的测试运行器。它提供了多种功能,如页面对象模型、并行执行、测试夹具以及报告工具。
Playwright 测试超能力
🌐 Playwright Test Super Powers
一旦参加 Playwright 测试,你就会收获很多!
🌐 Once you're on Playwright Test, you get a lot!
- 完全零配置 TypeScript 支持
- 在所有网页引擎(Chrome、Firefox、Safari)上,在任何流行操作系统(Windows、macOS、Ubuntu)上运行测试
- 完全支持多源、(i)frames、标签页和上下文
- 跨多个浏览器并行运行隔离测试
- 内置测试 工件收集
你还可以获得所有这些 ✨ 很棒的工具 ✨ 与 Playwright 测试打包在一起:
🌐 You also get all these ✨ awesome tools ✨ that come bundled with Playwright Test:
进一步阅读
🌐 Further Reading
了解有关 Playwright 测试运行程序的更多信息:
🌐 Learn more about Playwright Test runner: