Skip to main content

从 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

PuppeteerPlaywright Library
await puppeteer.launch()await playwright.chromium.launch()
puppeteer.launch({product: 'firefox'})await playwright.firefox.launch()
WebKit is not supported by Puppeteerawait 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 inputawait 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.waitForNavigationpage.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):

  1. 每个 Playwright 库文件都明确导入了 chromium。也可以使用其他浏览器 webkitfirefox
  2. 对于浏览器状态隔离,请考虑 浏览器上下文
  3. setViewport 变成 setViewportSize
  4. networkidle2 变为 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'
);
});
});
  1. 每个 Playwright Test 文件都显式导入了 testexpect 函数
  2. 测试函数被标记为 async
  3. Playwright Test 会将 page 作为其参数之一。这是 Playwright Test 中许多有用的 fixture之一。Playwright Test 会为每个测试创建一个隔离的 Page 对象。然而,如果你希望在多个测试之间重用同一个 Page 对象,你可以在 test.beforeAll() 中创建它,并在 test.afterAll() 中关闭它。
  4. 使用 page.locator() 创建定位器是少数几个同步方法之一。
  5. 使用 断言 来验证状态,而不是 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: