メインコンテンツにスキップ

WebView2

はじめに

ここでは、PlaywrightをMicrosoft Edge WebView2と連携して使用する方法について説明します。WebView2は、内部でMicrosoft Edgeを使用してWebコンテンツをレンダリングするWinFormsコントロールです。これはMicrosoft Edgeブラウザの一部であり、Windows 10およびWindows 11で利用可能です。PlaywrightはWebView2アプリケーションの自動化や、WebView2内のWebコンテンツのテストに使用できます。WebView2への接続には、PlaywrightはChrome DevTools Protocol (CDP) を介して接続するbrowserType.connectOverCDP()を使用します。

概要

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('https://:9222');
const context = browser.contexts()[0];
const 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インスタンスを提供します。

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.dokyumento.jp');
const getStarted = page.getByText('Get Started');
await expect(getStarted).toBeVisible();
});

デバッグ

WebView2コントロール内で右クリックしてコンテキストメニューを開き、「検証 (Inspect)」を選択するか、F12キーを押すことでDevToolsを開くことができます。また、WebView2.CoreWebView2.OpenDevToolsWindowメソッドを使用して、プログラムでDevToolsを開くこともできます。

テストのデバッグについては、Playwrightのデバッグガイドを参照してください。