Расширения Chrome
Запуск Chromium с расширениями, тестирование и отладка
Обзор
Playwright поддерживает загрузку расширений Chrome (CRX) при запуске браузера. Это полезно для тестирования ваших собственных расширений или проверки совместимости с популярными дополнениями.
Важно: Расширения Chrome работают только в Chromium с параметром
headless=False. Режим headless не поддерживает расширения. Также рекомендуется указывать channel="chrome" для использования системного Chrome.
Запуск Chromium с расширением
Путь к расширению — это директория, содержащая файл manifest.json:
from playwright.sync_api import sync_playwright
EXT_PATH = "/path/to/my-extension"
with sync_playwright() as p:
browser = p.chromium.launch(
headless=False,
channel="chrome",
args=[
f"--disable-extensions-except={EXT_PATH}",
f"--load-extension={EXT_PATH}"
]
)
context = browser.new_context()
page = context.new_page()
page.goto("https://example.com")
Структура расширения
Минимальный manifest.json:
{
"manifest_version": 3,
"name": "My Extension",
"version": "1.0",
"permissions": ["storage", "activeTab"],
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "popup.html"
}
}
Получение background page / Service Worker
У контекста есть свойство background_page, которое указывает на Service Worker расширения (Manifest V3):
browser = p.chromium.launch(
headless=False,
channel="chrome",
args=[
f"--disable-extensions-except={EXT_PATH}",
f"--load-extension={EXT_PATH}"
]
)
context = browser.new_context()
# Ждём загрузки Service Worker расширения
background_page = context.background_page
if background_page:
print("Service Worker загружен:", background_page.url)
Примечание:
context.background_page доступен только после полной инициализации расширения. Если расширение использует Manifest V2 и background page, она также будет доступна через это свойство. Для Manifest V3 возвращается Service Worker.
Доступ к chrome.* API через page.evaluate()
На страницах расширения API chrome.* доступен напрямую. На обычных веб-страницах он отсутствует, но вы можете взаимодействовать с расширением через его Service Worker:
# Открыть popup расширения
page.goto("chrome-extension://EXTENSION_ID/popup.html")
# Вызвать chrome API внутри popup
result = page.evaluate("""() => {
return new Promise((resolve) => {
chrome.storage.local.get(['key'], (data) => {
resolve(data.key);
});
});
}""")
Тестирование расширения: открыть popup
import re
EXT_ID = "abcdefghijklmnopabcdefghijklmn"
# Открываем popup расширения
page = context.new_page()
page.goto(f"chrome-extension://{EXT_ID}/popup.html")
# Взаимодействуем с popup
page.fill("#input", "test")
page.click("#save")
assert page.locator(".status").text_content() == "Сохранено"
Совет: ID расширения можно получить из URL при открытии
chrome://extensions/ или из chrome.runtime.id через evaluate. Если ID неизвестен, используйте context.pages после открытия popup.
Проверка контента на странице с расширением
# Загружаем страницу, на которой расширение добавляет элементы
page.goto("https://example.com")
# Проверяем, что расширение внедрило свой контент
injected = page.locator(".extension-injected-element")
assert injected.is_visible()
Полный пример
from playwright.sync_api import sync_playwright
import os
EXT_PATH = os.path.abspath("./my-extension")
def test_extension():
with sync_playwright() as p:
browser = p.chromium.launch(
headless=False,
channel="chrome",
args=[
f"--disable-extensions-except={EXT_PATH}",
f"--load-extension={EXT_PATH}"
]
)
context = browser.new_context()
# Ждём Service Worker
background = context.background_page
assert background is not None, "Расширение не загружено"
# Открываем popup
page = context.pages[0]
page.goto(f"chrome-extension://{background.url.split('/')[2]}/popup.html")
# Проверяем функциональность
page.fill("#search-input", "playwright")
page.click("#search-btn")
assert page.locator(".results").is_visible()
# Вызов chrome API через background page
storage_data = background.evaluate("""() => {
return new Promise((resolve) => {
chrome.storage.local.get(null, resolve);
});
}""")
print("Данные хранилища:", storage_data)
browser.close()
test_extension()