WebView2
简介
以下将解释如何在Microsoft Edge WebView2中使用Playwright。WebView2是一个WinForms控件,底层会使用Microsoft Edge来渲染网页内容。它是Microsoft Edge浏览器的一部分,可在Windows 10和Windows 11上使用。Playwright可用于自动化WebView2应用程序,并测试WebView2中的网页内容。为了连接WebView2,Playwright使用BrowserType.ConnectOverCDPAsync()通过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连接到它:
var browser = await playwright.Chromium.ConnectOverCDPAsync("http://localhost:9222");
var context = browser.Contexts[0];
var 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.cs
using System.Diagnostics;
using Microsoft.Playwright;
using Microsoft.Playwright.MSTest;
namespace PlaywrightTests;
[TestClass]
public class ExampleTest : PlaywrightTest
{
public IBrowser Browser { get; internal set; } = null!;
public IBrowserContext Context { get; internal set; } = null!;
public IPage Page { get; internal set; } = null!;
private Process? _webView2Process = null;
private string _userDataDir = null!;
private string _executablePath = Path.Join(Directory.GetCurrentDirectory(), @"..\..\..\..\webview2-app\bin\Debug\net8.0-windows\webview2.exe");
[TestInitialize]
public async Task BrowserTestInitialize()
{
var cdpPort = 10000 + WorkerIndex;
Assert.IsTrue(File.Exists(_executablePath), "Make sure that the executable exists");
_userDataDir = Path.Join(Path.GetTempPath(), $"playwright-webview2-tests/user-data-dir-{WorkerIndex}");
// WebView2 does some lazy cleanups on shutdown so we can't clean it up after each test
if (Directory.Exists(_userDataDir))
{
Directory.Delete(_userDataDir, true);
}
_webView2Process = Process.Start(new ProcessStartInfo(_executablePath)
{
EnvironmentVariables =
{
["WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS"] = $"--remote-debugging-port={cdpPort}",
["WEBVIEW2_USER_DATA_FOLDER"] = _userDataDir,
},
RedirectStandardOutput = true,
});
while (!_webView2Process!.HasExited)
{
var output = await _webView2Process!.StandardOutput.ReadLineAsync();
if (_webView2Process!.HasExited)
{
throw new Exception("WebView2 process exited unexpectedly");
}
if (output != null && output.Contains("WebView2 initialized"))
{
break;
}
}
var cdpAddress = $"http://127.0.0.1:{cdpPort}";
Browser = await Playwright.Chromium.ConnectOverCDPAsync(cdpAddress);
Context = Browser.Contexts[0];
Page = Context.Pages[0];
}
[TestCleanup]
public async Task BrowserTestCleanup()
{
_webView2Process!.Kill(true);
await Browser.CloseAsync();
}
}
// UnitTest1.cs
using Microsoft.Playwright;
using Microsoft.Playwright.MSTest;
namespace PlaywrightTests;
[TestClass]
public class ExampleTest : WebView2Test
{
[TestMethod]
public async Task HomepageHasPlaywrightInTitleAndGetStartedLinkLinkingtoTheIntroPage()
{
await Page.GotoAsync("https://playwright.dev");
var getStarted = Page.GetByText("Get Started");
await Expect(getStarted).ToBeVisibleAsync();
}
}
调试
在您的webview2控件内,只需右键点击即可打开上下文菜单并选择"Inspect"以打开开发者工具,或按下F12键。您也可以使用WebView2.CoreWebView2.OpenDevToolsWindow方法以编程方式打开开发者工具。
如需调试测试,请参阅Playwright的调试指南。