using Microsoft.Playwright;
namespace Tests.E2e.PageObjectModels;
///
/// The /labels/{LabelName} detail page — everything carrying one label key,
/// with that resource's value for it. Distinct from ,
/// which drives the label editor on a resource card.
///
public class LabelPagePom(IPage page) {
public ILocator Root
=> page.GetByTestId("label-page-root");
public ILocator Title
=> page.GetByTestId("label-page-title");
public ILocator List
=> page.GetByTestId("label-page-list");
public ILocator Empty
=> page.GetByTestId("label-page-empty");
public ILocator NoResults
=> page.GetByTestId("label-page-no-results");
public ILocator Filter
=> page.GetByTestId("label-page-filter");
public ILocator SortSelect
=> page.GetByTestId("label-page-sort");
public ILocator SortDirectionButton
=> page.GetByTestId("label-page-sort-direction");
public ILocator Item(string resourceName)
=> page.GetByTestId($"label-page-item-{resourceName.Replace(" ", "-")}");
public ILocator ItemValue(string resourceName)
=> Item(resourceName).GetByTestId("label-page-item-value");
// -------------------------------------------------
// High-Level Actions
// -------------------------------------------------
public async Task GotoAsync(string baseUrl, string labelKey) {
await page.GotoAsync($"{baseUrl}/labels/{Uri.EscapeDataString(labelKey)}");
await AssertLoadedAsync();
}
public async Task AssertLoadedAsync()
=> await Assertions.Expect(Root).ToBeVisibleAsync();
public async Task AssertTitleContainsAsync(string labelKey)
=> await Assertions.Expect(Title).ToContainTextAsync(labelKey);
public async Task AssertListsAsync(string resourceName)
=> await Assertions.Expect(Item(resourceName)).ToBeVisibleAsync();
public async Task AssertDoesNotListAsync(string resourceName)
=> await Assertions.Expect(Item(resourceName)).ToHaveCountAsync(0);
///
/// Asserts the resource's value for this label, plus the type the page
/// detected for it (TEXT / NUMBER / BOOL / DATE).
///
public async Task AssertValueAsync(string resourceName, string value, string detectedType) {
await Assertions.Expect(ItemValue(resourceName)).ToContainTextAsync(value);
await Assertions.Expect(ItemValue(resourceName)).ToContainTextAsync(detectedType);
}
///
/// The filter is a plain @bind, committing on change rather than input,
/// so the value needs an explicit blur — see DocsPom.SearchAsync.
///
public async Task FilterAsync(string value) {
await Filter.FillAsync(value);
await Filter.BlurAsync();
}
public async Task SortByAsync(string option)
=> await SortSelect.SelectOptionAsync(option);
public async Task ToggleSortDirectionAsync()
=> await SortDirectionButton.ClickAsync();
public async Task AssertNoResultsAsync()
=> await Assertions.Expect(NoResults).ToBeVisibleAsync();
///
/// Names of the listed resources, in render order.
///
public async Task> ListedOrderAsync() {
var ids = await List.Locator("[data-testid^='label-page-item-']")
.EvaluateAllAsync(
"els => els.map(e => e.getAttribute('data-testid'))");
return ids
.Where(id => id.StartsWith("label-page-item-", StringComparison.Ordinal))
.Select(id => id["label-page-item-".Length..])
.Where(name => name != "value")
.ToList();
}
}