WebView2
Введение
Далее будет объяснено, как использовать Playwright с Microsoft Edge WebView2. WebView2 — это элемент управления WinForms, который использует Microsoft Edge для отображения веб-контента. Он является частью браузера Microsoft Edge и доступен на Windows 10 и Windows 11. Playwright может использоваться для автоматизации приложений WebView2 и тестирования веб-контента в WebView2. Для подключения к WebView2 Playwright использует browser_type.connect_over_cdp(), который подключается к нему через протокол Chrome DevTools Protocol (CDP).
Обзор
Элемент управления WebView2 может быть настроен на прослушивание входящих CDP-соединений путем установки переменной окружения WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS
с --remote-debugging-port=9222
или вызова EnsureCoreWebView2Async с аргументом --remote-debugging-port=9222
. Это запустит процесс WebView2 с включенным протоколом Chrome DevTools, что позволит автоматизировать его с помощью Playwright. В данном случае 9222 — это пример порта, но можно использовать любой другой свободный порт.
await this.webView.EnsureCoreWebView2Async(await CoreWebView2Environment.CreateAsync(null, null, new CoreWebView2EnvironmentOptions()
{
AdditionalBrowserArguments = "--remote-debugging-port=9222",
})).ConfigureAwait(false);
После того как ваше приложение с элементом управления WebView2 запущено, вы можете подключиться к нему через Playwright:
- Sync
- Async
browser = playwright.chromium.connect_over_cdp("http://localhost:9222")
context = browser.contexts[0]
page = context.pages[0]
browser = await playwright.chromium.connect_over_cdp("http://localhost:9222")
context = browser.contexts[0]
page = context.pages[0]
Чтобы убедиться, что элемент управления WebView2 готов, вы можете дождаться события CoreWebView2InitializationCompleted
:
this.webView.CoreWebView2InitializationCompleted += (_, e) =>
{
if (e.IsSuccess)
{
Console.WriteLine("WebView2 initialized");
}
};
Написание и выполнение тестов
По умолчанию элемент управления WebView2 будет использовать один и тот же каталог данных пользователя для всех экземпляров. Это означает, что если вы запускаете несколько тестов параллельно, они будут мешать друг другу. Чтобы этого избежать, вы должны установить переменную окружения WEBVIEW2_USER_DATA_FOLDER
(или использовать WebView2.EnsureCoreWebView2Async Method) в разные папки для каждого теста. Это обеспечит выполнение каждого теста в собственном каталоге данных пользователя.
Используя следующее, Playwright запустит ваше приложение WebView2 как подпроцесс, назначит ему уникальный каталог данных пользователя и предоставит экземпляр Page вашему тесту:
import os
import socket
import tempfile
import pytest
from pathlib import Path
from playwright.sync_api import Playwright, Browser, BrowserContext
import subprocess
EXECUTABLE_PATH = (
Path(__file__).parent
/ ".."
/ "webview2-app"
/ "bin"
/ "Debug"
/ "net8.0-windows"
/ "webview2.exe"
)
@pytest.fixture(scope="session")
def data_dir():
with tempfile.TemporaryDirectory(
prefix="playwright-webview2-tests", ignore_cleanup_errors=True
) as tmpdirname:
yield tmpdirname
@pytest.fixture(scope="session")
def webview2_process_cdp_port(data_dir: str):
cdp_port = _find_free_port()
process = subprocess.Popen(
[EXECUTABLE_PATH],
env={
**dict(os.environ),
"WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS": f"--remote-debugging-port={cdp_port}",
"WEBVIEW2_USER_DATA_FOLDER": data_dir,
},
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True,
)
while True:
line = process.stdout.readline()
if "WebView2 initialized" in line:
break
yield cdp_port
process.terminate()
@pytest.fixture(scope="session")
def browser(playwright: Playwright, webview2_process_cdp_port: int):
browser = playwright.chromium.connect_over_cdp(
f"http://127.0.0.1:{webview2_process_cdp_port}"
)
yield browser
@pytest.fixture(scope="function")
def context(browser: Browser):
context = browser.contexts[0]
yield context
@pytest.fixture(scope="function")
def page(context: BrowserContext):
page = context.pages[0]
yield page
def _find_free_port(port=9000, max_port=65535):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while port <= max_port:
try:
sock.bind(("", port))
sock.close()
return port
except OSError:
port += 1
raise IOError("no free ports")
from playwright.sync_api import Page, expect
def test_webview2(page: Page):
page.goto("https://playwright.dev")
get_started = page.get_by_text("Get Started")
expect(get_started).to_be_visible()
Отладка
Внутри вашего элемента управления webview2 вы можете просто щелкнуть правой кнопкой мыши, чтобы открыть контекстное меню и выбрать "Inspect", чтобы открыть DevTools, или нажать F12. Вы также можете использовать метод WebView2.CoreWebView2.OpenDevToolsWindow, чтобы открыть DevTools программно.
Для отладки тестов смотрите руководство Playwright Debugging guide.