WebView2
简介
以下将解释如何在Microsoft Edge WebView2中使用Playwright。WebView2是一个WinForms控件,底层会使用Microsoft Edge来渲染网页内容。它是Microsoft Edge浏览器的一部分,可在Windows 10和Windows 11上使用。Playwright可用于自动化WebView2应用程序,并测试WebView2中的网页内容。为了连接WebView2,Playwright使用browser_type.connect_over_cdp()通过Chrome DevTools协议(CDP)进行连接。
概述
可以通过设置环境变量WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS
为--remote-debugging-port=9222
,或者调用EnsureCoreWebView2Async方法并传入--remote-debugging-port=9222
参数,来指示WebView2控件监听传入的CDP连接。这将启用Chrome开发者工具协议的WebView2进程启动,从而允许通过Playwright实现自动化。9222在此处是示例端口,也可以使用任何其他未被占用的端口。
await this.webView.EnsureCoreWebView2Async(await CoreWebView2Environment.CreateAsync(null, null, new CoreWebView2EnvironmentOptions()
{
AdditionalBrowserArguments = "--remote-debugging-port=9222",
})).ConfigureAwait(false);
一旦您的应用程序运行了WebView2控件,您就可以通过Playwright连接到它:
- Sync
- 异步
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"以打开开发者工具,或按下F12键。您也可以使用WebView2.CoreWebView2.OpenDevToolsWindow方法以编程方式打开开发者工具。
如需调试测试,请参阅Playwright的调试指南。