YamlEditorOtherKindTests.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. using Microsoft.Playwright;
  2. using Tests.E2e.Infra;
  3. using Xunit.Abstractions;
  4. namespace Tests.E2e;
  5. /// <summary>
  6. /// Repro for an unfiled bug found during issue triage: the /yaml editor's
  7. /// YamlFileComponent carries its own copy of the kind discriminator map
  8. /// (YamlFileComponent.razor:212-224), and `Other` was never added to it —
  9. /// the fourth hand-maintained kind registry to drift. Saving any config
  10. /// that contains a `kind: Other` resource through the /yaml page fails
  11. /// validation, even though the loader, importer, CLI and MCP all accept
  12. /// it. This test fails on staging until the map (ideally all four
  13. /// registries) is unified.
  14. /// </summary>
  15. public class YamlEditorOtherKindTests(
  16. PlaywrightFixture fixture,
  17. ITestOutputHelper output) : E2ETestBase(fixture, output) {
  18. private readonly PlaywrightFixture _fixture = fixture;
  19. private readonly ITestOutputHelper _output = output;
  20. private static string ConfigWithOther(string name) =>
  21. $"""
  22. version: 4
  23. resources:
  24. - kind: Other
  25. name: {name}
  26. model: KVM-4P
  27. description: Rack KVM switch
  28. connections: []
  29. """;
  30. [Fact]
  31. public async Task The_Yaml_Editor_Accepts_A_Config_Containing_An_Other_Resource() {
  32. (IBrowserContext context, IPage page) = await CreatePageAsync();
  33. var name = $"e2e-oth-{Guid.NewGuid():N}"[..14];
  34. try {
  35. await page.GotoAsync($"{_fixture.BaseUrl}/yaml");
  36. ILocator content = page.GetByTestId("yaml-file-content");
  37. await Assertions.Expect(content).ToBeVisibleAsync();
  38. await Assertions.Expect(page.GetByTestId("circuit-probe"))
  39. .ToHaveAttributeAsync("data-circuit-ready", "true");
  40. await page.GetByRole(AriaRole.Button, new() { Name = "Edit" }).ClickAsync();
  41. ILocator textarea = page.Locator("textarea");
  42. await Assertions.Expect(textarea).ToBeVisibleAsync();
  43. await textarea.FillAsync(ConfigWithOther(name));
  44. await page.GetByRole(AriaRole.Button, new() { Name = "Save" }).ClickAsync();
  45. // The same document loads fine through the CLI, the importer and
  46. // the MCP server; the editor must not reject it. Today it shows
  47. // a validation error because its discriminator map lacks Other.
  48. await Assertions.Expect(page.GetByTestId("yaml-file-error")).ToHaveCountAsync(0);
  49. await Assertions.Expect(content).ToBeVisibleAsync();
  50. await Assertions.Expect(content).ToContainTextAsync(name);
  51. }
  52. catch (Exception) {
  53. _output.WriteLine($"TEST FAILED — URL: {page.Url}");
  54. _output.WriteLine(await page.ContentAsync());
  55. throw;
  56. }
  57. finally {
  58. await context.CloseAsync();
  59. }
  60. }
  61. }