Skip to main content

Chrome 擴充功能

簡介

note

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

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

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

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

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.service_workers) == 0:
service_worker = context.wait_for_event('serviceworker')
else:
service_worker = context.service_workers[0]

# 像測試任何其他 worker 一樣測試 Service Worker。
context.close()


with sync_playwright() as playwright:
run(playwright)

測試

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

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

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

conftest.py
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 v3:
service_worker = context.service_workers[0]
if not service_worker:
service_worker = context.wait_for_event("serviceworker")

extension_id = service_worker.url.split("/")[2]
yield extension_id

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

test_foo.py
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")