從 Puppeteer 遷移
遷移原則
本指南描述了從 Puppeteer 遷移到 Playwright 函式庫 和 Playwright Test 的過程。這些 API 有相似之處,但 Playwright 為網頁測試和跨瀏覽器自動化提供了更多可能性。
- 大多數 Puppeteer API 可以直接使用
- 不鼓勵使用 ElementHandle,請改用 Locator 物件和網頁優先的斷言。
- Playwright 是跨瀏覽器的
- 您可能不需要顯式等待
速查表
Puppeteer | Playwright 函式庫 |
---|---|
await puppeteer.launch() | await playwright.chromium.launch() |
puppeteer.launch({product: 'firefox'}) | await playwright.firefox.launch() |
Puppeteer 不支援 WebKit | 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(...) | 通常可以使用斷言來驗證文字、屬性、類別... |
await page.$(...) | 不鼓勵使用,請改用 Locator |
await page.$x(xpath_selector) | 不鼓勵使用,請改用 Locator |
沒有專用於複選框或單選輸入的方法 | 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(...) 為了攔截和修改請求,請參閱 page.route() |
page.waitForNavigation
和 page.waitForSelector
仍然存在,但在許多情況下,由於自動等待,將不再需要。
不鼓勵使用 ElementHandle,請改用 Locator 物件和網頁優先的斷言。
定位器是 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.org.tw/', {
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.org.tw/', {
waitUntil: 'networkidle', // 4
});
await page.screenshot({ path: 'example.png' });
await browser.close();
})();
遷移重點(請參閱 Playwright 程式碼片段中的內嵌註解)
- 每個 Playwright 函式庫檔案都明確導入了
chromium
。可以使用其他瀏覽器webkit
或firefox
。 - 對於瀏覽器狀態隔離,請考慮瀏覽器上下文
setViewport
變為setViewportSize
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.org.tw/');
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.org.tw/');
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 中眾多有用的夾具之一。Playwright Test 為每個測試建立一個隔離的 Page 物件。但是,如果您想在多個測試之間重複使用單個 Page 物件,您可以在 test.beforeAll() 中建立自己的物件,並在 test.afterAll() 中關閉它。 - 使用 page.locator() 建立定位器是少數同步方法之一。
- 使用斷言來驗證狀態,而不是
page.$eval()
。
測試
為了改進測試,建議使用 Locator 和網頁優先的 斷言。請參閱編寫測試
在使用 Puppeteer 時,通常使用 page.evaluate()
或 page.$eval()
來檢查 ElementHandle 並提取文字內容、屬性、類別的值... 網頁優先的 斷言 為此目的提供了幾個匹配器,它更可靠且更易讀。
Playwright Test 是我們首推的測試執行器,用於 Playwright。它提供了多種功能,如頁面物件模型、平行處理、夾具或報告器。
Playwright Test 超能力
一旦您使用 Playwright Test,您將獲得很多!
- 完整的零配置 TypeScript 支援
- 在 所有網頁引擎 (Chrome、Firefox、Safari) 和 任何流行的作業系統 (Windows、macOS、Ubuntu) 上執行測試
- 完全支援多個來源、(i)框架、標籤頁和上下文
- 在多個瀏覽器中並行隔離執行測試
- 內建測試產物收集
您還可以獲得所有這些 ✨ 令人驚嘆的工具 ✨,這些工具與 Playwright Test 捆綁在一起
延伸閱讀
了解更多關於 Playwright Test 執行器的資訊