Skip to main content

WebView2

簡介

以下將解釋如何使用 Playwright 搭配 Microsoft Edge WebView2。WebView2 是一個 WinForms 控制項,會使用 Microsoft Edge 來呈現網頁內容。它是 Microsoft Edge 瀏覽器的一部分,適用於 Windows 10 和 Windows 11。Playwright 可以用來自動化 WebView2 應用程式,並用來測試 WebView2 中的網頁內容。為了連接到 WebView2,Playwright 使用 browserType.connectOverCDP(),該方法通過 Chrome DevTools Protocol (CDP) 進行連接。

概述

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 連接到它:

const browser = await playwright.chromium.connectOverCDP('http://localhost:9222');
const context = browser.contexts()[0];
const page = context.pages()[0];

為了確保 WebView2 控制項已準備好,你可以等待 CoreWebView2InitializationCompleted 事件:

this.webView.CoreWebView2InitializationCompleted += (_, e) =>
{
if (e.IsSuccess)
{
Console.WriteLine("WebView2 initialized");
}
};

Writing and running tests

預設情況下,WebView2 控制項將對所有實例使用相同的用戶資料目錄。這意味著如果您平行執行多個測試,它們將互相干擾。為了避免這種情況,您應該為每個測試設置 WEBVIEW2_USER_DATA_FOLDER 環境變數(或使用 WebView2.EnsureCoreWebView2Async Method),以使用不同的文件夾。這將確保每個測試在其自己的用戶資料目錄中執行。

使用以下內容,Playwright 將會將你的 WebView2 應用程式作為子程序執行,為其分配一個唯一的使用者資料目錄,並將 Page 實例提供給你的測試:

webView2Test.ts
import { test as base } from '@playwright/test';
import fs from 'fs';
import os from 'os';
import path from 'path';
import childProcess from 'child_process';

const EXECUTABLE_PATH = path.join(
__dirname,
'../../webview2-app/bin/Debug/net8.0-windows/webview2.exe',
);

export const test = base.extend({
browser: async ({ playwright }, use, testInfo) => {
const cdpPort = 10000 + testInfo.workerIndex;
// Make sure that the executable exists and is executable
fs.accessSync(EXECUTABLE_PATH, fs.constants.X_OK);
const userDataDir = path.join(
fs.realpathSync.native(os.tmpdir()),
`playwright-webview2-tests/user-data-dir-${testInfo.workerIndex}`,
);
const webView2Process = childProcess.spawn(EXECUTABLE_PATH, [], {
shell: true,
env: {
...process.env,
WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS: `--remote-debugging-port=${cdpPort}`,
WEBVIEW2_USER_DATA_FOLDER: userDataDir,
}
});
await new Promise<void>(resolve => webView2Process.stdout.on('data', data => {
if (data.toString().includes('WebView2 initialized'))
resolve();
}));
const browser = await playwright.chromium.connectOverCDP(`http://127.0.0.1:${cdpPort}`);
await use(browser);
await browser.close();
childProcess.execSync(`taskkill /pid ${webView2Process.pid} /T /F`);
fs.rmdirSync(userDataDir, { recursive: true });
},
context: async ({ browser }, use) => {
const context = browser.contexts()[0];
await use(context);
},
page: async ({ context }, use) => {
const page = context.pages()[0];
await use(page);
},
});

export { expect } from '@playwright/test';
example.spec.ts
import { test, expect } from './webView2Test';

test('test WebView2', async ({ page }) => {
await page.goto('https://playwright.dev');
const getStarted = page.getByText('Get Started');
await expect(getStarted).toBeVisible();
});

除錯

在你的 webview2 控制項內,你可以右鍵點擊以打開上下文選單並選擇 "Inspect" 來打開 DevTools 或按 F12。你也可以使用 WebView2.CoreWebView2.OpenDevToolsWindow 方法以程式碼方式打開 DevTools。

如需除錯測試,請參閱 Playwright 除錯指南