Debugging a WebView2 component using Playwright in .NET

 
 
  • Gérald Barré

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!

Follow me:
Enjoy this blog?