using System.Text.RegularExpressions; using Volcanic.AgenticCore.Extensions.Mcp; namespace Volcanic.AgenticCore.Extensions.Tests.Mcp; public class PlaywrightPresetTests { [Fact] public void Default_argv_runs_the_pinned_package_headless_with_chromium_and_workspace_paths() { var server = PlaywrightPreset.ToServer(new PlaywrightOptions { Enabled = true }); Assert.Equal("npx", server.Command); Assert.Equal( ["-y", PlaywrightPreset.DefaultPackage, "--headless", "--browser", "chromium", "--output-dir", "${workspace}/browser", "--user-data-dir", "${workspace}/.volcanic/browser-profile"], server.Args); Assert.Equal("${workspace}", server.Cwd); Assert.Null(server.ToolPrefix); Assert.Equal(120, server.StartupTimeoutSeconds); Assert.Equal(120, server.CallTimeoutSeconds); Assert.Empty(server.Env); } [Fact] public void Headed_browser_and_extra_args_are_passed_through() { var server = PlaywrightPreset.ToServer(new PlaywrightOptions { Enabled = true, Headless = false, Browser = "firefox", ExtraArgs = ["--no-sandbox", "--device", "iPhone 15"] }); Assert.DoesNotContain("--headless", server.Args); Assert.Equal("firefox", server.Args[server.Args.IndexOf("--browser") + 1]); Assert.Equal(["--no-sandbox", "--device", "iPhone 15"], server.Args.TakeLast(3)); } [Fact] public void Isolated_extra_arg_drops_the_profile_directory() { var server = PlaywrightPreset.ToServer(new PlaywrightOptions { Enabled = true, ExtraArgs = ["--isolated"] }); Assert.DoesNotContain("--user-data-dir", server.Args); Assert.Contains("--isolated", server.Args); Assert.Contains("--output-dir", server.Args); } [Fact] public void Package_override_replaces_the_pinned_spec() { var server = PlaywrightPreset.ToServer(new PlaywrightOptions { Enabled = true, Package = "@playwright/mcp@0.0.1" }); Assert.Equal(["-y", "@playwright/mcp@0.0.1"], server.Args.Take(2)); } [Fact] public void Command_runs_the_binary_directly_without_the_package() { var server = PlaywrightPreset.ToServer(new PlaywrightOptions { Enabled = true, Command = "playwright-mcp", Package = "ignored@1.0.0" }); Assert.Equal("playwright-mcp", server.Command); Assert.DoesNotContain("-y", server.Args); Assert.DoesNotContain(server.Args, a => a.Contains('@')); Assert.Equal("--headless", server.Args[0]); } [Fact] public void Default_package_is_pinned_to_an_exact_version() { Assert.Matches(new Regex(@"^@playwright/mcp@\d+\.\d+\.\d+$"), PlaywrightPreset.DefaultPackage); Assert.Equal("0.0.82", PlaywrightPreset.PackageVersion); } [Fact] public void Describe_reports_enabled_and_disabled() { Assert.Equal("MCP: playwright enabled (headless, chromium)", PlaywrightPreset.Describe(new PlaywrightOptions { Enabled = true })); Assert.Equal("MCP: playwright enabled (headed, firefox)", PlaywrightPreset.Describe(new PlaywrightOptions { Enabled = true, Headless = false, Browser = "firefox" })); Assert.Equal("MCP: playwright disabled (set PLAYWRIGHT_ENABLED=true)", PlaywrightPreset.Describe(new PlaywrightOptions())); Assert.Equal(PlaywrightPreset.Describe(new PlaywrightOptions()), new McpOptions().DescribePlaywright()); } [Fact] public void Prompt_section_mentions_send_only_when_asked() { var withSend = PlaywrightPreset.PromptSection(hasSend: true); var without = PlaywrightPreset.PromptSection(hasSend: false); Assert.StartsWith("## Browser", withSend, StringComparison.Ordinal); Assert.Contains("call `send` with that", withSend, StringComparison.Ordinal); Assert.DoesNotContain("`send`", without, StringComparison.Ordinal); Assert.Contains("browser/", without, StringComparison.Ordinal); Assert.Contains("browser_close", without, StringComparison.Ordinal); Assert.Contains("passwords", without, StringComparison.Ordinal); } [Fact] public void Dockerfile_version_matches_DefaultPackage() { var dockerfile = File.ReadAllText(RepoFile("Dockerfile")); var matches = Regex.Matches(dockerfile, @"^ARG PLAYWRIGHT_MCP_VERSION=(?\S+)\s*$", RegexOptions.Multiline); var match = Assert.Single(matches); Assert.Equal(PlaywrightPreset.PackageVersion, match.Groups["version"].Value); } /// A file in the repository root, found by walking up from the test output to VolcanicAgenticCore.slnx. private static string RepoFile(string name) { for (var dir = new DirectoryInfo(AppContext.BaseDirectory); dir is not null; dir = dir.Parent) { if (File.Exists(Path.Combine(dir.FullName, "VolcanicAgenticCore.slnx"))) return Path.Combine(dir.FullName, name); } throw new InvalidOperationException("VolcanicAgenticCore.slnx not found above " + AppContext.BaseDirectory); } }