To write end-to-end tests for an application hosting a WebView2 component, you can use Playwright. Playwright is a well-known tool that lets you control the browser and interact with the DOM.
To attach Playwright to a WebView2 component, you need to use the Chromium DevTools Protocol. You can enable it by passing the --remote-debugging-port option when initializing WebView2, either directly or via the WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS environment variable to automatically pass additional arguments to the browser.
First, you need to add a reference to the Microsoft.Playwright NuGet package:
Shell
dotnet add package Microsoft.Playwright
Then, you can use the following code to start the application and attach Playwright to the WebView2 components:
C#
// Start the external application with WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS which allows
// to specify the port to use for the protocol.
//
// note: If the component is in the current process, you can use the following code before instantiating the WebView2:
// Environment.SetEnvironmentVariable("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", "--remote-debugging-port=" + Port);
const int Port = 9334;
var psi = new ProcessStartInfo
{
FileName = @"ApplicationContainingWebViews.exe",
Environment =
{
// If you start multiple instances of your application, you may need to use a different port for each instance
{ "WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", "--remote-debugging-port=" + Port },
// If you start multiple instances of your application, you may need to use different
// data folder for each instance to avoid sharing state
// https://learn.microsoft.com/en-us/microsoft-edge/webview2/concepts/user-data-folder?tabs=win32&WT.mc_id=DT-MVP-5003978
// { "WEBVIEW2_USER_DATA_FOLDER", Path.Combine(Path.GetTempPath(), "WebView2") },
},
};
var process = Process.Start(psi);
using var httpClient = new HttpClient();
// Wait for the WebView2 to be initialized and get the protocol URL
string? url = null;
while (url == null)
{
try
{
var version = await httpClient.GetFromJsonAsync<JsonElement>($"http://localhost:{Port}/json/version/");
url = version.GetProperty("webSocketDebuggerUrl").GetString();
}
catch
{
await Task.Delay(100);
}
}
// Initialize playwright using the protocol url
using var playwright = await Microsoft.Playwright.Playwright.CreateAsync();
await using var browser = await playwright.Chromium.ConnectOverCDPAsync(url);
// If you have multiple webviews, you can iterate on Pages to find the right one
var page = browser.Contexts[0].Pages[0];
// Interact with the page
await page.GotoAsync("https://www.meziantou.net");
var element = await page.QuerySelectorAsync("aside h3");
Assert.Equal("Gérald Barré", await element.TextContentAsync());
Do you have a question or a suggestion about this post? Contact me!