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。
概觀
可以指示 WebView2 控制項透過設定 WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS
環境變數 (使用 --remote-debugging-port=9222
) 或呼叫 EnsureCoreWebView2Async 並帶有 --remote-debugging-port=9222
引數,來偵聽傳入的 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]
browser = await 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 執行個體提供給您的測試
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.org.tw")
get_started = page.get_by_text("Get Started")
expect(get_started).to_be_visible()
偵錯
在您的 webview2 控制項內,您可以直接按一下滑鼠右鍵以開啟上下文選單,然後選取「檢查」以開啟 DevTools,或按下 F12。您也可以使用 WebView2.CoreWebView2.OpenDevToolsWindow 方法以程式設計方式開啟 DevTools。
如需偵錯測試,請參閱 Playwright 偵錯指南。