SwitchCardTests.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. using Microsoft.Playwright;
  2. using Tests.E2e.Infra;
  3. using Tests.E2e.PageObjectModels;
  4. using Xunit.Abstractions;
  5. namespace Tests.E2e;
  6. public class SwitchCardTests(
  7. PlaywrightFixture fixture,
  8. ITestOutputHelper output) : E2ETestBase(fixture, output) {
  9. private readonly PlaywrightFixture _fixture = fixture;
  10. private readonly ITestOutputHelper _output = output;
  11. [Fact]
  12. public async Task User_Can_Edit_Switch_Model_And_Features() {
  13. (IBrowserContext context, IPage page) = await CreatePageAsync();
  14. var name = $"e2e-fw-{Guid.NewGuid():N}"[..16];
  15. try {
  16. await page.GotoAsync(_fixture.BaseUrl);
  17. var layout = new MainLayoutPom(page);
  18. await layout.AssertLoadedAsync();
  19. await layout.GotoHardwareAsync();
  20. var hardwareTree = new HardwareTreePom(page);
  21. await hardwareTree.AssertLoadedAsync();
  22. await hardwareTree.GotoSwitchesListAsync();
  23. var list = new SwitchListPom(page);
  24. await list.AssertLoadedAsync();
  25. await list.AddSwitchAsync(name);
  26. await list.AssertSwitchExists(name);
  27. // Go to details page so we can exercise the card component
  28. await list.OpenSwitchAsync(name);
  29. var card = new SwitchCardPom(page);
  30. await Assertions.Expect(card.SwitchItem(name)).ToBeVisibleAsync();
  31. // Enter edit mode
  32. await card.EnterEditModeAsync(name);
  33. // Update Model + toggle features
  34. var newModel = "e2e-model-123";
  35. await card.ModelInput(name).FillAsync(newModel);
  36. // Ensure both toggles are ON (idempotent)
  37. if (!await card.ManagedCheckbox(name).IsCheckedAsync())
  38. await card.ManagedCheckbox(name).CheckAsync();
  39. if (!await card.PoeCheckbox(name).IsCheckedAsync())
  40. await card.PoeCheckbox(name).CheckAsync();
  41. await card.SaveEditsAsync(name);
  42. // Validate view mode reflects changes
  43. await Assertions.Expect(card.ModelValue(name)).ToHaveTextAsync(newModel);
  44. await Assertions.Expect(card.ManagedBadge(name)).ToBeVisibleAsync();
  45. await Assertions.Expect(card.PoeBadge(name)).ToBeVisibleAsync();
  46. }
  47. catch (Exception) {
  48. _output.WriteLine("TEST FAILED — Capturing diagnostics");
  49. _output.WriteLine($"Current URL: {page.Url}");
  50. var html = await page.ContentAsync();
  51. _output.WriteLine("==== DOM SNAPSHOT START ====");
  52. _output.WriteLine(html);
  53. _output.WriteLine("==== DOM SNAPSHOT END ====");
  54. throw;
  55. }
  56. finally {
  57. await context.CloseAsync();
  58. }
  59. }
  60. [Fact]
  61. public async Task User_Can_Rename_Switch_From_Details_Page() {
  62. (IBrowserContext context, IPage page) = await CreatePageAsync();
  63. var name = $"e2e-fw-{Guid.NewGuid():N}"[..16];
  64. var renamed = $"{name}-ren";
  65. try {
  66. await page.GotoAsync(_fixture.BaseUrl);
  67. var layout = new MainLayoutPom(page);
  68. await layout.AssertLoadedAsync();
  69. await layout.GotoHardwareAsync();
  70. var hardwareTree = new HardwareTreePom(page);
  71. await hardwareTree.AssertLoadedAsync();
  72. await hardwareTree.GotoSwitchesListAsync();
  73. var list = new SwitchListPom(page);
  74. await list.AssertLoadedAsync();
  75. await list.AddSwitchAsync(name);
  76. await list.OpenSwitchAsync(name);
  77. var card = new SwitchCardPom(page);
  78. await card.RenameSwitchAsync(name, renamed);
  79. // after rename we should be on new URL and see the renamed card root
  80. await Assertions.Expect(card.SwitchItem(renamed)).ToBeVisibleAsync();
  81. }
  82. catch (Exception) {
  83. _output.WriteLine("TEST FAILED — Capturing diagnostics");
  84. _output.WriteLine($"Current URL: {page.Url}");
  85. var html = await page.ContentAsync();
  86. _output.WriteLine("==== DOM SNAPSHOT START ====");
  87. _output.WriteLine(html);
  88. _output.WriteLine("==== DOM SNAPSHOT END ====");
  89. throw;
  90. }
  91. finally {
  92. await context.CloseAsync();
  93. }
  94. }
  95. [Fact]
  96. public async Task User_Can_Clone_Switch_From_Details_Page() {
  97. (IBrowserContext context, IPage page) = await CreatePageAsync();
  98. var name = $"e2e-fw-{Guid.NewGuid():N}"[..16];
  99. var clone = $"{name}-cpy";
  100. try {
  101. await page.GotoAsync(_fixture.BaseUrl);
  102. var layout = new MainLayoutPom(page);
  103. await layout.AssertLoadedAsync();
  104. await layout.GotoHardwareAsync();
  105. var hardwareTree = new HardwareTreePom(page);
  106. await hardwareTree.AssertLoadedAsync();
  107. await hardwareTree.GotoSwitchesListAsync();
  108. var list = new SwitchListPom(page);
  109. await list.AssertLoadedAsync();
  110. await list.AddSwitchAsync(name);
  111. await list.OpenSwitchAsync(name);
  112. var card = new SwitchCardPom(page);
  113. await card.CloneSwitchAsync(name, clone);
  114. // should be on the clone's details URL and see the clone card
  115. await Assertions.Expect(card.SwitchItem(clone)).ToBeVisibleAsync();
  116. }
  117. catch (Exception) {
  118. _output.WriteLine("TEST FAILED — Capturing diagnostics");
  119. _output.WriteLine($"Current URL: {page.Url}");
  120. var html = await page.ContentAsync();
  121. _output.WriteLine("==== DOM SNAPSHOT START ====");
  122. _output.WriteLine(html);
  123. _output.WriteLine("==== DOM SNAPSHOT END ====");
  124. throw;
  125. }
  126. finally {
  127. await context.CloseAsync();
  128. }
  129. }
  130. [Fact]
  131. public async Task User_Can_Delete_Switch_From_Details_Page() {
  132. (IBrowserContext context, IPage page) = await CreatePageAsync();
  133. var name = $"e2e-fw-{Guid.NewGuid():N}"[..16];
  134. try {
  135. await page.GotoAsync(_fixture.BaseUrl);
  136. var layout = new MainLayoutPom(page);
  137. await layout.AssertLoadedAsync();
  138. await layout.GotoHardwareAsync();
  139. var hardwareTree = new HardwareTreePom(page);
  140. await hardwareTree.AssertLoadedAsync();
  141. await hardwareTree.GotoSwitchesListAsync();
  142. var list = new SwitchListPom(page);
  143. await list.AssertLoadedAsync();
  144. await list.AddSwitchAsync(name);
  145. await list.OpenSwitchAsync(name);
  146. var card = new SwitchCardPom(page);
  147. await card.DeleteSwitchAsync(name);
  148. // After delete, your page navigates away (Nav.NavigateTo("/hardware/tree"))
  149. await page.WaitForURLAsync("**/hardware/tree");
  150. }
  151. catch (Exception) {
  152. _output.WriteLine("TEST FAILED — Capturing diagnostics");
  153. _output.WriteLine($"Current URL: {page.Url}");
  154. var html = await page.ContentAsync();
  155. _output.WriteLine("==== DOM SNAPSHOT START ====");
  156. _output.WriteLine(html);
  157. _output.WriteLine("==== DOM SNAPSHOT END ====");
  158. throw;
  159. }
  160. finally {
  161. await context.CloseAsync();
  162. }
  163. }
  164. [Fact]
  165. public async Task User_Can_Add_And_Remove_Tags_From_Switch_Card() {
  166. (IBrowserContext context, IPage page) = await CreatePageAsync();
  167. var name = $"e2e-ap-{Guid.NewGuid():N}"[..16];
  168. try {
  169. await page.GotoAsync(_fixture.BaseUrl);
  170. var layout = new MainLayoutPom(page);
  171. await layout.AssertLoadedAsync();
  172. await layout.GotoHardwareAsync();
  173. var hardwareTree = new HardwareTreePom(page);
  174. await hardwareTree.AssertLoadedAsync();
  175. await hardwareTree.GotoSwitchesListAsync();
  176. var list = new SwitchListPom(page);
  177. await list.AssertLoadedAsync();
  178. await list.AddSwitchAsync(name);
  179. await page.WaitForURLAsync($"**/resources/hardware/{name}");
  180. var card = new SwitchCardPom(page);
  181. TagsPom tags = card.Tags;
  182. // -------------------------------------------------
  183. // Add multiple tags in one modal interaction
  184. // -------------------------------------------------
  185. await tags.AddTagsAsync("switch", "Foo", "Bar", "Baz");
  186. await tags.AssertTagVisibleAsync("switch", "Foo");
  187. await tags.AssertTagVisibleAsync("switch", "Bar");
  188. await tags.AssertTagVisibleAsync("switch", "Baz");
  189. // -------------------------------------------------
  190. // Remove a single tag
  191. // -------------------------------------------------
  192. await tags.RemoveTagAsync("switch", "Bar");
  193. await tags.AssertTagNotVisibleAsync("switch", "Bar");
  194. await tags.AssertTagVisibleAsync("switch", "Foo");
  195. await tags.AssertTagVisibleAsync("switch", "Baz");
  196. // -------------------------------------------------
  197. // Reload to verify persistence
  198. // -------------------------------------------------
  199. await page.ReloadAsync();
  200. await tags.AssertTagVisibleAsync("switch", "Foo");
  201. await tags.AssertTagVisibleAsync("switch", "Baz");
  202. await tags.AssertTagNotVisibleAsync("switch", "Bar");
  203. await context.CloseAsync();
  204. }
  205. finally {
  206. await context.CloseAsync();
  207. }
  208. }
  209. }