LabelPagePom.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. using Microsoft.Playwright;
  2. namespace Tests.E2e.PageObjectModels;
  3. /// <summary>
  4. /// The /labels/{LabelName} detail page — everything carrying one label key,
  5. /// with that resource's value for it. Distinct from <see cref="LabelsPom" />,
  6. /// which drives the label editor on a resource card.
  7. /// </summary>
  8. public class LabelPagePom(IPage page) {
  9. public ILocator Root
  10. => page.GetByTestId("label-page-root");
  11. public ILocator Title
  12. => page.GetByTestId("label-page-title");
  13. public ILocator List
  14. => page.GetByTestId("label-page-list");
  15. public ILocator Empty
  16. => page.GetByTestId("label-page-empty");
  17. public ILocator NoResults
  18. => page.GetByTestId("label-page-no-results");
  19. public ILocator Filter
  20. => page.GetByTestId("label-page-filter");
  21. public ILocator SortSelect
  22. => page.GetByTestId("label-page-sort");
  23. public ILocator SortDirectionButton
  24. => page.GetByTestId("label-page-sort-direction");
  25. public ILocator Item(string resourceName)
  26. => page.GetByTestId($"label-page-item-{resourceName.Replace(" ", "-")}");
  27. public ILocator ItemValue(string resourceName)
  28. => Item(resourceName).GetByTestId("label-page-item-value");
  29. // -------------------------------------------------
  30. // High-Level Actions
  31. // -------------------------------------------------
  32. public async Task GotoAsync(string baseUrl, string labelKey) {
  33. await page.GotoAsync($"{baseUrl}/labels/{Uri.EscapeDataString(labelKey)}");
  34. await AssertLoadedAsync();
  35. }
  36. public async Task AssertLoadedAsync()
  37. => await Assertions.Expect(Root).ToBeVisibleAsync();
  38. public async Task AssertTitleContainsAsync(string labelKey)
  39. => await Assertions.Expect(Title).ToContainTextAsync(labelKey);
  40. public async Task AssertListsAsync(string resourceName)
  41. => await Assertions.Expect(Item(resourceName)).ToBeVisibleAsync();
  42. public async Task AssertDoesNotListAsync(string resourceName)
  43. => await Assertions.Expect(Item(resourceName)).ToHaveCountAsync(0);
  44. /// <summary>
  45. /// Asserts the resource's value for this label, plus the type the page
  46. /// detected for it (TEXT / NUMBER / BOOL / DATE).
  47. /// </summary>
  48. public async Task AssertValueAsync(string resourceName, string value, string detectedType) {
  49. await Assertions.Expect(ItemValue(resourceName)).ToContainTextAsync(value);
  50. await Assertions.Expect(ItemValue(resourceName)).ToContainTextAsync(detectedType);
  51. }
  52. /// <summary>
  53. /// The filter is a plain @bind, committing on change rather than input,
  54. /// so the value needs an explicit blur — see DocsPom.SearchAsync.
  55. /// </summary>
  56. public async Task FilterAsync(string value) {
  57. await Filter.FillAsync(value);
  58. await Filter.BlurAsync();
  59. }
  60. public async Task SortByAsync(string option)
  61. => await SortSelect.SelectOptionAsync(option);
  62. public async Task ToggleSortDirectionAsync()
  63. => await SortDirectionButton.ClickAsync();
  64. public async Task AssertNoResultsAsync()
  65. => await Assertions.Expect(NoResults).ToBeVisibleAsync();
  66. /// <summary>
  67. /// Names of the listed resources, in render order.
  68. /// </summary>
  69. public async Task<IReadOnlyList<string>> ListedOrderAsync() {
  70. var ids = await List.Locator("[data-testid^='label-page-item-']")
  71. .EvaluateAllAsync<string[]>(
  72. "els => els.map(e => e.getAttribute('data-testid'))");
  73. return ids
  74. .Where(id => id.StartsWith("label-page-item-", StringComparison.Ordinal))
  75. .Select(id => id["label-page-item-".Length..])
  76. .Where(name => name != "value")
  77. .ToList();
  78. }
  79. }