Skip to main content

從 Puppeteer 遷移

遷移原則

這個指南描述了從 Puppeteer 遷移到 Playwright LibraryPlaywright Test。這些 API 有相似之處,但 Playwright 提供了更多的網頁測試和跨瀏覽器自動化的可能性。

  • 大多數 Puppeteer API 可以按原樣使用
  • 不建議使用 ElementHandle,請改用 Locator 物件和 web-first 斷言。
  • Playwright 是跨瀏覽器的
  • 你可能不需要顯式等待

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 物件和 web-first 斷言。

定位器是 Playwright 自動等待和平行處理的核心部分。定位器是嚴格的。這意味著,所有涉及某些目標 DOM 元素的定位器操作,如果有多個元素符合給定的選擇器,將會拋出異常。

範例

自動化範例

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.dev/', {
waitUntil: 'networkidle2',
});
await page.screenshot({ path: 'example.png' });
await browser.close();
})();

逐行遷移到 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.dev/', {
waitUntil: 'networkidle', // 4
});
await page.screenshot({ path: 'example.png' });
await browser.close();
})();

遷移重點 (請參閱 Playwright 程式碼片段中的內嵌註釋):

  1. 每個 Playwright 函式庫文件都有明確匯入 chromium。其他瀏覽器 webkitfirefox 也可以使用。
  2. 為了瀏覽器狀態隔離,請考慮 browser contexts
  3. setViewport 變成 setViewportSize
  4. networkidle2 變成 networkidle。請注意,在大多數情況下,由於自動等待,它並不有用。

測試範例

Puppeteer 與 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.dev/');
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 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.dev/');
const titleLocator = page.locator('.hero__title'); // 4
await expect(titleLocator).toContainText( // 5
'Playwright enables reliable end-to-end testing'
);
});
});
  1. 每個 Playwright 測試文件都有明確匯入 testexpect 函式
  2. 測試函式標記為 async
  3. Playwright 測試將 page 作為其參數之一。這是 Playwright 測試中許多有用的 fixtures之一。Playwright 測試為每個測試建立一個獨立的 Page 物件。但是,如果您想在多個測試之間重複使用單個 Page 物件,您可以在 test.beforeAll() 中建立自己的物件,並在 test.afterAll() 中關閉它。
  4. 使用 page.locator() 建立 Locator 是少數同步方法之一。
  5. 使用斷言來驗證狀態,而不是 page.$eval()

測試

為了改進測試,建議使用 Locators 和 web-first Assertions。請參閱 Writing Tests

在使用 Puppeteer 時,通常會使用 page.evaluate()page.$eval() 來檢查 ElementHandle 並提取文本內容、屬性、類別的值... Web-first Assertions 提供了幾個匹配器用於此目的,它更可靠且可讀性更高。

Playwright Test 是我們推薦與 Playwright 一起使用的第一方測試執行器。它提供了多種功能,如 Page 物件模型、平行處理、固定裝置或報告器。

Playwright Test 超能力

一旦你使用 Playwright 測試,你會獲得很多!

  • 完整的零配置 TypeScript 支援
  • 所有網頁引擎(Chrome, Firefox, Safari)上執行測試,適用於任何流行的作業系統(Windows, macOS, Ubuntu)
  • 完整支援多個來源,(i)frames, 分頁和上下文
  • 在多個瀏覽器中平行獨立執行測試
  • 內建測試 artifact collection

你還會獲得所有這些 ✨ 很棒的工具 ✨,這些工具與 Playwright Test 一起捆綁提供:

延伸閱讀

了解更多關於 Playwright 測試執行器: