Files
VolcanicAgenticCore/tests/Volcanic.AgenticCore.Extensions.Tests/Mcp/PlaywrightPresetTests.cs
EugeneTes 7bb41f0b5b fix(docker): address review findings
Entrypoint drops the capability bounding set and sets no_new_privs. Security docs
and spec no longer claim the agent can't reach the secrets; docker exec fallbacks
use a clean environment. PLAYWRIGHT_ENABLED drops the nested compose default.
Tests pin the Dockerfile's Playwright install step and the compose model fallback.
2026-09-27 12:34:58 +02:00

114 lines
5.2 KiB
C#

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=(?<version>\S+)\s*$", RegexOptions.Multiline);
var match = Assert.Single(matches);
Assert.Equal(PlaywrightPreset.PackageVersion, match.Groups["version"].Value);
// The install step must use the ARG, not a version of its own.
Assert.Contains("\"@playwright/mcp@${PLAYWRIGHT_MCP_VERSION}\"", dockerfile, StringComparison.Ordinal);
}
/// <summary>A file in the repository root, found by walking up from the test output to <c>VolcanicAgenticCore.slnx</c>.</summary>
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);
}
}