diff --git a/src/Playwright.Tests/PageAriaSnapshotTests.cs b/src/Playwright.Tests/PageAriaSnapshotTests.cs index c2d1eb443..0aca8b6f7 100644 --- a/src/Playwright.Tests/PageAriaSnapshotTests.cs +++ b/src/Playwright.Tests/PageAriaSnapshotTests.cs @@ -26,6 +26,39 @@ namespace Microsoft.Playwright.Tests; public class PageAriaSnapshotTests : PageTestEx { + [PlaywrightTest] + [TestCase(AriaSnapshotMode.Default)] + [TestCase(AriaSnapshotMode.Ai)] + public async Task ShouldIncludeBoundingBoxesInPageSnapshot(AriaSnapshotMode mode) + { + await Page.SetContentAsync(""); + + var snapshot = await Page.AriaSnapshotAsync(new() { Mode = mode }); + StringAssert.DoesNotContain("[box=", snapshot); + Assert.AreEqual(snapshot, await Page.AriaSnapshotAsync(new() { Mode = mode, Boxes = false })); + + var snapshotWithBoxes = await Page.AriaSnapshotAsync(new() { Mode = mode, Boxes = true }); + StringAssert.Contains("[box=20,30,100,40]", snapshotWithBoxes); + Assert.AreEqual(snapshot, await Page.AriaSnapshotAsync(new() { Mode = mode })); + } + + [PlaywrightTest] + [TestCase(AriaSnapshotMode.Default)] + [TestCase(AriaSnapshotMode.Ai)] + public async Task ShouldIncludeBoundingBoxesInLocatorSnapshot(AriaSnapshotMode mode) + { + await Page.SetContentAsync(""); + var locator = Page.GetByRole(AriaRole.Button); + + var snapshot = await locator.AriaSnapshotAsync(new() { Mode = mode }); + StringAssert.DoesNotContain("[box=", snapshot); + Assert.AreEqual(snapshot, await locator.AriaSnapshotAsync(new() { Mode = mode, Boxes = false })); + + var snapshotWithBoxes = await locator.AriaSnapshotAsync(new() { Mode = mode, Boxes = true }); + StringAssert.Contains("[box=20,30,100,40]", snapshotWithBoxes); + Assert.AreEqual(snapshot, await locator.AriaSnapshotAsync(new() { Mode = mode })); + } + private string _unshift(string snapshot) { var lines = snapshot.Split('\n'); diff --git a/src/Playwright/Core/Locator.cs b/src/Playwright/Core/Locator.cs index 10be5e4f8..0451c9fec 100644 --- a/src/Playwright/Core/Locator.cs +++ b/src/Playwright/Core/Locator.cs @@ -674,6 +674,7 @@ public async Task AriaSnapshotAsync(LocatorAriaSnapshotOptions? options ["selector"] = _selector, ["mode"] = options?.Mode, ["depth"] = options?.Depth, + ["boxes"] = options?.Boxes, }, timeout: _frame.Timeout(options?.Timeout)).ConfigureAwait(false); return result!.Value.GetProperty("snapshot").ToString(); diff --git a/src/Playwright/Core/Page.cs b/src/Playwright/Core/Page.cs index a395384f0..c4aa49e6f 100644 --- a/src/Playwright/Core/Page.cs +++ b/src/Playwright/Core/Page.cs @@ -1572,6 +1572,7 @@ public async Task AriaSnapshotAsync(PageAriaSnapshotOptions? options = d { ["mode"] = options?.Mode, ["depth"] = options?.Depth, + ["boxes"] = options?.Boxes, }, timeout: MainFrame.Timeout(options?.Timeout)).ConfigureAwait(false); return result!.Value.GetProperty("snapshot").ToString(); diff --git a/src/tools/Playwright.Tooling/DriverDownloader.cs b/src/tools/Playwright.Tooling/DriverDownloader.cs index 2df90abea..a711f0ed7 100644 --- a/src/tools/Playwright.Tooling/DriverDownloader.cs +++ b/src/tools/Playwright.Tooling/DriverDownloader.cs @@ -144,6 +144,24 @@ private static async Task WithRetriesAsync(string url, Func action) } } + private static string ResolveNpmExecutable() + { + string name = OperatingSystem.IsWindows() ? "npm.cmd" : "npm"; + // On Windows npm.cmd must be started by its full path: launched by bare name, + // the script's %~dp0 expands to the working directory instead of its own + // directory and it fails to find node_modules/npm/bin/npm-cli.js. + string path = Environment.GetEnvironmentVariable("PATH") ?? string.Empty; + foreach (string directory in path.Split(Path.PathSeparator, StringSplitOptions.RemoveEmptyEntries)) + { + string candidate = Path.Combine(directory.Trim('"'), name); + if (File.Exists(candidate)) + { + return candidate; + } + } + return name; + } + private async Task ExecuteAsync() { var driversDirectory = new DirectoryInfo(Path.Combine(BasePath, "src", "Playwright", ".drivers")); @@ -186,24 +204,6 @@ private async Task ExecuteAsync() return true; } - private static string ResolveNpmExecutable() - { - string name = OperatingSystem.IsWindows() ? "npm.cmd" : "npm"; - // On Windows npm.cmd must be started by its full path: launched by bare name, - // the script's %~dp0 expands to the working directory instead of its own - // directory and it fails to find node_modules/npm/bin/npm-cli.js. - string path = Environment.GetEnvironmentVariable("PATH") ?? string.Empty; - foreach (string directory in path.Split(Path.PathSeparator, StringSplitOptions.RemoveEmptyEntries)) - { - string candidate = Path.Combine(directory.Trim('"'), name); - if (File.Exists(candidate)) - { - return candidate; - } - } - return name; - } - private async Task DownloadPlaywrightPackageAsync(string driversDirectory) { // Fetched with `npm pack` rather than a hard-coded registry URL so that the