Skip to main content

Chrome 擴充功能

簡介

note

擴充功能只能在使用持久情境啟動的 Chromium 中運作。使用自訂瀏覽器參數需自行承擔風險,因為其中某些參數可能會破壞 Playwright 功能。

Google Chrome 和 Microsoft Edge 移除了載入擴充功能所需的命令列旗標,因此請使用 Playwright 隨附的 Chromium。

下面的程式碼片段會取得 Manifest v3 擴充功能的 Service Worker,其原始碼位於 ./my-extension

請注意使用 chromium 通道來允許在無頭模式下執行擴充功能。或者,您也可以在有頭模式下啟動瀏覽器。

const { chromium } = require('playwright');

(async () => {
const pathToExtension = require('path').join(__dirname, 'my-extension');
const userDataDir = '/tmp/test-user-data-dir';
const browserContext = await chromium.launchPersistentContext(userDataDir, {
channel: 'chromium',
args: [
`--disable-extensions-except=${pathToExtension}`,
`--load-extension=${pathToExtension}`
]
});
let [serviceWorker] = browserContext.serviceWorkers();
if (!serviceWorker)
serviceWorker = await browserContext.waitForEvent('serviceworker');

// 像測試任何其他 worker 一樣測試 Service Worker。
await browserContext.close();
})();

測試

要讓擴充功能在執行測試時載入,您可以使用測試佈置來設定情境。您還可以動態取得擴充功能 ID,並使用它來載入和測試 popup 頁面。

請注意使用 chromium 通道來允許在無頭模式下執行擴充功能。或者,您也可以在有頭模式下啟動瀏覽器。

首先,新增會載入擴充功能的佈置:

fixtures.ts
import { test as base, chromium, type BrowserContext } from '@playwright/test';
import path from 'path';

export const test = base.extend<{
context: BrowserContext;
extensionId: string;
}>({
context: async ({ }, use) => {
const pathToExtension = path.join(__dirname, 'my-extension');
const context = await chromium.launchPersistentContext('', {
channel: 'chromium',
args: [
`--disable-extensions-except=${pathToExtension}`,
`--load-extension=${pathToExtension}`,
],
});
await use(context);
await context.close();
},
extensionId: async ({ context }, use) => {
// for manifest v3:
let [serviceWorker] = context.serviceWorkers();
if (!serviceWorker)
serviceWorker = await context.waitForEvent('serviceworker');

const extensionId = serviceWorker.url().split('/')[2];
await use(extensionId);
},
});
export const expect = test.expect;

然後在測試中使用這些佈置:

import { test, expect } from './fixtures';

test('example test', async ({ page }) => {
await page.goto('https://example.com');
await expect(page.locator('body')).toHaveText('Changed by my-extension');
});

test('popup page', async ({ page, extensionId }) => {
await page.goto(`chrome-extension://${extensionId}/popup.html`);
await expect(page.locator('body')).toHaveText('my-extension popup');
});