github microsoft/playwright-dotnet v1.64.0

5 hours ago

🧰 WebMCP

New page.Webmcp and frame.Webmcp give access to the tools that a page registers through the experimental WebMCP browser API, so you can test them like
any other part of your app:

var browser = await playwright.Chromium.LaunchAsync(new() { Args = new[] { "--enable-features=WebMCP" } });
var page = await browser.NewPageAsync();
await page.GotoAsync("https://example.com");

foreach (var tool in await page.Webmcp.ToolsAsync())
    Console.WriteLine($"{tool.Name}: {tool.Description}");

var result = await page.Webmcp.CallToolAsync("add", new { a = 2, b = 40 });
Console.WriteLine(result?.GetProperty("content")[0].GetProperty("text")); // "42"

Playwright MCP also supports WebMCP by default, with page-defined tools offered to the agent as webmcp_<tool>. Pass --no-webmcp to opt out.

playwright-cli exposes them as well:

playwright-cli webmcp-list
playwright-cli webmcp-call search_catalog --params '{"query":"cats"}'

🎬 Better videos

Videos can now be recorded at a custom frame rate, and the decorations for actions are styled with plain CSS:

await page.Screencast.StartAsync(new()
{
    Path = "video.webm",
    Size = new() { Width = 1920, Height = 1080 },
    Fps = 60,
});
await page.Screencast.ShowActionsAsync(new()
{
    Style = new()
    {
        Point = "width: 20px; height: 20px; border-radius: 50%; background: red",
        Highlight = "outline: 2px solid #333; background: rgba(0, 128, 255, .15)",
        Title = "font-size: 16px",
    },
});
  • New RecordVideoFps option and new Fps option in Screencast.StartAsync(). Firefox and WebKit currently capture up to 25 frames per second.
  • New Style option takes CSS declarations for the Point marker, the target Highlight and the action Title. It replaces the FontSize option, which is now deprecated.
  • The cursor stays visible at the last action point, survives navigations and travels along a natural, eased path.
  • Videos are encoded with VP9 instead of VP8, which takes less CPU and produces smaller files of the same or better
    quality.
  • All video options are also available in Playwright MCP and playwright-cli.

🪆 Locator.Within()

New Locator.Within() combines two locators that you already have, reading in the natural order - "this button, within that dialog":

var saveButton = page.GetByRole(AriaRole.Button, new() { Name = "Save" });
var dialog = page.GetByTestId("settings-dialog");

await saveButton.Within(dialog).ClickAsync();

Relative locators such as Locator.Nth() or Locator.First are resolved inside each parent separately, which makes column-like queries straightforward:

// The third cell of every row, not the third cell in the table.
var thirdColumn = page.GetByRole(AriaRole.Cell).Nth(2).Within(page.GetByRole(AriaRole.Row));
await Expect(thirdColumn).ToHaveTextAsync(new[] { "Apple", "Banana", "Cherry" });

New APIs

Breaking Changes ⚠️

Browser Versions

  • Chromium 156.0.8078.4
  • Mozilla Firefox 157.0
  • WebKit 27.2

This version was also tested against the following stable channels:

  • Google Chrome 155
  • Microsoft Edge 155

Don't miss a new playwright-dotnet release

NewReleases is sending notifications on new releases.