Chrome 扩展程序
介绍
¥Introduction
扩展程序仅适用于通过持久上下文启动的 Chrome / Chromium。使用自定义浏览器参数需要你自担风险,因为其中一些参数可能会破坏 Playwright 功能。
¥Extensions only work in Chrome / Chromium launched with a persistent context. Use custom browser args at your own risk, as some of them may break Playwright functionality.
下面的代码片段检索源位于 ./my-extension
中的 清单 v2 扩展的 背景页。
¥The snippet below retrieves the background page of a Manifest v2 extension whose source is located in ./my-extension
.
请注意使用 chromium
通道,该通道允许在无头模式下运行扩展。或者,你可以在头模式下启动浏览器。
¥Note the use of the chromium
channel that allows to run extensions in headless mode. Alternatively, you can launch the browser in headed mode.
- Sync
- Async
from playwright.sync_api import sync_playwright, Playwright
path_to_extension = "./my-extension"
user_data_dir = "/tmp/test-user-data-dir"
def run(playwright: Playwright):
context = playwright.chromium.launch_persistent_context(
user_data_dir,
channel="chromium",
args=[
f"--disable-extensions-except={path_to_extension}",
f"--load-extension={path_to_extension}",
],
)
if len(context.background_pages) == 0:
background_page = context.wait_for_event('backgroundpage')
else:
background_page = context.background_pages[0]
# Test the background page as you would any other page.
context.close()
with sync_playwright() as playwright:
run(playwright)
import asyncio
from playwright.async_api import async_playwright, Playwright
path_to_extension = "./my-extension"
user_data_dir = "/tmp/test-user-data-dir"
async def run(playwright: Playwright):
context = await playwright.chromium.launch_persistent_context(
user_data_dir,
channel="chromium",
args=[
f"--disable-extensions-except={path_to_extension}",
f"--load-extension={path_to_extension}",
],
)
if len(context.background_pages) == 0:
background_page = await context.wait_for_event('backgroundpage')
else:
background_page = context.background_pages[0]
# Test the background page as you would any other page.
await context.close()
async def main():
async with async_playwright() as playwright:
await run(playwright)
asyncio.run(main())
测试
¥Testing
要在运行测试时加载扩展,你可以使用测试装置来设置上下文。例如,你还可以动态检索扩展 ID 并使用它来加载和测试弹出页面。
¥To have the extension loaded when running tests you can use a test fixture to set the context. You can also dynamically retrieve the extension id and use it to load and test the popup page for example.
请注意使用 chromium
通道,该通道允许在无头模式下运行扩展。或者,你可以在头模式下启动浏览器。
¥Note the use of the chromium
channel that allows to run extensions in headless mode. Alternatively, you can launch the browser in headed mode.
首先,添加将加载扩展的装置:
¥First, add fixtures that will load the extension:
from typing import Generator
from pathlib import Path
from playwright.sync_api import Playwright, BrowserContext
import pytest
@pytest.fixture()
def context(playwright: Playwright) -> Generator[BrowserContext, None, None]:
path_to_extension = Path(__file__).parent.joinpath("my-extension")
context = playwright.chromium.launch_persistent_context(
"",
channel="chromium",
args=[
f"--disable-extensions-except={path_to_extension}",
f"--load-extension={path_to_extension}",
],
)
yield context
context.close()
@pytest.fixture()
def extension_id(context) -> Generator[str, None, None]:
# for manifest v2:
# background = context.background_pages[0]
# if not background:
# background = context.wait_for_event("backgroundpage")
# for manifest v3:
background = context.service_workers[0]
if not background:
background = context.wait_for_event("serviceworker")
extension_id = background.url.split("/")[2]
yield extension_id
然后在测试中使用这些装置:
¥Then use these fixtures in a test:
from playwright.sync_api import expect, Page
def test_example_test(page: Page) -> None:
page.goto("https://example.com")
expect(page.locator("body")).to_contain_text("Changed by my-extension")
def test_popup_page(page: Page, extension_id: str) -> None:
page.goto(f"chrome-extension://{extension_id}/popup.html")
expect(page.locator("body")).to_have_text("my-extension popup")