跳到主要内容

Chrome 扩展

简介

备注

扩展仅在使用持久化上下文启动的 Chrome/Chromium 中有效。使用自定义浏览器参数需自行承担风险,某些参数可能会破坏 Playwright 的功能。

以下代码片段获取了位于 ./my-extension 目录的 Manifest v2 扩展的 后台页面

注意使用了 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 [backgroundPage] = browserContext.backgroundPages();
if (!backgroundPage)
backgroundPage = await browserContext.waitForEvent('backgroundpage');

// 像测试其他页面一样测试后台页面
await browserContext.close();
})();

测试

要在运行测试时加载扩展,你可以使用测试夹具来设置上下文。你还可以动态获取扩展ID,并利用它来加载和测试弹出页面等。

注意使用 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) => {
/*
// 适用于manifest v2:
let [background] = context.backgroundPages()
if (!background)
background = await context.waitForEvent('backgroundpage')
*/

// 适用于manifest v3:
let [background] = context.serviceWorkers();
if (!background)
background = await context.waitForEvent('serviceworker');

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

然后在测试中使用这些夹具:

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

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

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