跳到主要内容

WebView2

简介

以下内容将解释如何将 Playwright 与 Microsoft Edge WebView2 一起使用。WebView2 是一个 WinForms 控件,它将在后台使用 Microsoft Edge 来渲染 Web 内容。它是 Microsoft Edge 浏览器的一部分,可在 Windows 10 和 Windows 11 上使用。Playwright 可用于自动化 WebView2 应用程序,并可用于测试 WebView2 中的 Web 内容。为了连接到 WebView2,Playwright 使用 browser_type.connect_over_cdp(),它通过 Chrome DevTools Protocol (CDP) 连接到它。

概述

可以通过设置带有 --remote-debugging-port=9222WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS 环境变量或调用带有 --remote-debugging-port=9222 参数的 EnsureCoreWebView2Async 来指示 WebView2 控件侦听传入的 CDP 连接。这将启动启用 Chrome DevTools Protocol 的 WebView2 进程,从而允许 Playwright 进行自动化。9222 在本例中是一个示例端口,但也可以使用任何其他未使用的端口。

await this.webView.EnsureCoreWebView2Async(await CoreWebView2Environment.CreateAsync(null, null, new CoreWebView2EnvironmentOptions()
{
AdditionalBrowserArguments = "--remote-debugging-port=9222",
})).ConfigureAwait(false);

一旦您的带有 WebView2 控件的应用程序正在运行,您就可以通过 Playwright 连接到它

browser = playwright.chromium.connect_over_cdp("https://127.0.0.1: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 方法)到不同的文件夹。这将确保每个测试都在其自己的用户数据目录中运行。

使用以下方法,Playwright 将把您的 WebView2 应用程序作为子进程运行,为其分配唯一的用户数据目录,并为您的测试提供 Page 实例

conftest.py
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")
test_webview2.py
from playwright.sync_api import Page, expect


def test_webview2(page: Page):
page.goto("https://playwright.net.cn")
get_started = page.get_by_text("Get Started")
expect(get_started).to_be_visible()

调试

在您的 webview2 控件中,您可以右键单击以打开上下文菜单并选择“检查”以打开 DevTools 或按 F12。您还可以使用 WebView2.CoreWebView2.OpenDevToolsWindow 方法以编程方式打开 DevTools。

有关调试测试,请参阅 Playwright 调试指南