From 8270a603d32c2228c4acca1d5482af7dd6d90ff3 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Thu, 18 Jun 2026 20:41:43 -0400 Subject: [PATCH] test(playwright): update pager/markup selectors to M10 component hooks (INT) --- .../Audit/AuditConfigurationTests.cs | 11 ++++---- .../Notifications/NotificationActionTests.cs | 14 +++++----- .../SiteCalls/SiteCallsPageTests.cs | 27 +++++++++---------- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Audit/AuditConfigurationTests.cs b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Audit/AuditConfigurationTests.cs index 5900f2b4..e6747284 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Audit/AuditConfigurationTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Audit/AuditConfigurationTests.cs @@ -91,7 +91,7 @@ public class AuditConfigurationTests // is exactly 3 (filtering by the unique marker makes this deterministic // regardless of the other rows the live cluster holds). await Assertions.Expect(page.Locator($"tr:has-text('{marker}-0')")).ToBeVisibleAsync(); - await Assertions.Expect(page.Locator("span:has-text('(3 total)')")).ToBeVisibleAsync(); + await Assertions.Expect(page.Locator("[data-test='pager-summary']")).ToContainTextAsync("3 total"); } finally { @@ -119,9 +119,10 @@ public class AuditConfigurationTests await page.Locator("button.btn.btn-primary.btn-sm:has-text('Search')").ClickAsync(); await page.WaitForLoadStateAsync(LoadState.NetworkIdle); - // Page 1 of 2: Previous disabled, Next enabled. - await Assertions.Expect(page.Locator("span:has-text('Page 1 of 2')")).ToBeVisibleAsync(); - await Assertions.Expect(page.Locator("span:has-text('(55 total)')")).ToBeVisibleAsync(); + // Page 1 of 2: Previous disabled, Next enabled. (M10 OffsetPager summary: + // "Page {N} of {Y} · {Total} total".) + await Assertions.Expect(page.Locator("[data-test='pager-summary']")).ToContainTextAsync("Page 1 of 2"); + await Assertions.Expect(page.Locator("[data-test='pager-summary']")).ToContainTextAsync("55 total"); await Assertions.Expect(page.Locator("button.btn-outline-secondary.btn-sm:has-text('Previous')")).ToBeDisabledAsync(); await Assertions.Expect(page.Locator("button.btn-outline-secondary.btn-sm:has-text('Next')")).ToBeEnabledAsync(); @@ -129,7 +130,7 @@ public class AuditConfigurationTests await page.Locator("button.btn-outline-secondary.btn-sm:has-text('Next')").ClickAsync(); await page.WaitForLoadStateAsync(LoadState.NetworkIdle); - await Assertions.Expect(page.Locator("span:has-text('Page 2 of 2')")).ToBeVisibleAsync(); + await Assertions.Expect(page.Locator("[data-test='pager-summary']")).ToContainTextAsync("Page 2 of 2"); await Assertions.Expect(page.Locator("button.btn-outline-secondary.btn-sm:has-text('Previous')")).ToBeEnabledAsync(); await Assertions.Expect(page.Locator("button.btn-outline-secondary.btn-sm:has-text('Next')")).ToBeDisabledAsync(); } diff --git a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Notifications/NotificationActionTests.cs b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Notifications/NotificationActionTests.cs index 66fcb312..0121fd24 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Notifications/NotificationActionTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Notifications/NotificationActionTests.cs @@ -409,13 +409,13 @@ public class NotificationActionTests await page.Locator("button.btn-primary:has-text('Query')").ClickAsync(); await page.WaitForLoadStateAsync(LoadState.NetworkIdle); - // Pager locators. Previous/Next are scoped by their text (the page header's - // Refresh button is also a .btn-outline-secondary.btn-sm). The indicator span is - // the pager's only `span.text-muted.small` once rows render — the "Loading…" - // placeholder that shares that class renders only while `_notifications == null`. - var prev = page.Locator("button.btn-outline-secondary.btn-sm:has-text('Previous')"); - var next = page.Locator("button.btn-outline-secondary.btn-sm:has-text('Next')"); - var indicator = page.Locator(".d-flex.justify-content-between.align-items-center span.text-muted.small"); + // Pager locators (M10 OffsetPager). Previous/Next are the pager's data-test + // hooks (the page header's Refresh button is also a .btn-outline-secondary.btn-sm, + // so we no longer scope by text). The summary span carries the page/total readout + // ("Page {N} of {Y} · {Total} total"). + var prev = page.Locator("[data-test='pager-prev']"); + var next = page.Locator("[data-test='pager-next']"); + var indicator = page.Locator("[data-test='pager-summary']"); // ── Page 1 ── (count first — it waits out the fetch — then indicator + buttons). await Assertions.Expect(page.Locator("tbody tr")).ToHaveCountAsync(50, new() { Timeout = 15_000 }); diff --git a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/SiteCalls/SiteCallsPageTests.cs b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/SiteCalls/SiteCallsPageTests.cs index 44066514..90cf0fae 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/SiteCalls/SiteCallsPageTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/SiteCalls/SiteCallsPageTests.cs @@ -546,36 +546,33 @@ public class SiteCallsPageTests await SetSearchKeywordAsync(page, sharedTarget); await page.ClickAsync("[data-test='site-calls-query']"); - // The pager indicator span (`Page {N} · {rows} rows`). Scope the - // locator to the pager wrapper div - // (`.d-flex.justify-content-between.align-items-center`) so a future - // second `span.text-muted.small` elsewhere on the page can't make - // this match ambiguous under strict mode. - var pageIndicator = page.Locator( - ".d-flex.justify-content-between.align-items-center span.text-muted.small"); + // The M10 KeysetPager summary span (`Page {N} · {rows} rows`), exposed + // via its stable data-test hook so a future markup tweak can't make this + // match ambiguous under strict mode. + var pageIndicator = page.Locator("[data-test='keyset-summary']"); // ── Page 1: full page (50 rows). Assert COUNT first (waits for the // fetch), then the indicator and the button states. ── await Assertions.Expect(page.Locator("tbody tr")).ToHaveCountAsync(50); await Assertions.Expect(pageIndicator).ToContainTextAsync("Page 1"); - await Assertions.Expect(page.Locator("[data-test='site-calls-prev']")).ToBeDisabledAsync(); - await Assertions.Expect(page.Locator("[data-test='site-calls-next']")).ToBeEnabledAsync(); + await Assertions.Expect(page.Locator("[data-test='keyset-prev']")).ToBeDisabledAsync(); + await Assertions.Expect(page.Locator("[data-test='keyset-next']")).ToBeEnabledAsync(); // ── Next → Page 2: short page (1 row). Last page, so Next disables. ── - await page.ClickAsync("[data-test='site-calls-next']"); + await page.ClickAsync("[data-test='keyset-next']"); await Assertions.Expect(page.Locator("tbody tr")).ToHaveCountAsync(1); await Assertions.Expect(pageIndicator).ToContainTextAsync("Page 2"); - await Assertions.Expect(page.Locator("[data-test='site-calls-prev']")).ToBeEnabledAsync(); - await Assertions.Expect(page.Locator("[data-test='site-calls-next']")).ToBeDisabledAsync(); + await Assertions.Expect(page.Locator("[data-test='keyset-prev']")).ToBeEnabledAsync(); + await Assertions.Expect(page.Locator("[data-test='keyset-next']")).ToBeDisabledAsync(); // ── Previous → back on Page 1: full page again, Prev disables. ── - await page.ClickAsync("[data-test='site-calls-prev']"); + await page.ClickAsync("[data-test='keyset-prev']"); await Assertions.Expect(page.Locator("tbody tr")).ToHaveCountAsync(50); await Assertions.Expect(pageIndicator).ToContainTextAsync("Page 1"); - await Assertions.Expect(page.Locator("[data-test='site-calls-prev']")).ToBeDisabledAsync(); + await Assertions.Expect(page.Locator("[data-test='keyset-prev']")).ToBeDisabledAsync(); // Page 1 is full again on the back-leg, so Next must re-enable — // catches a regression that left Next disabled after a page-back. - await Assertions.Expect(page.Locator("[data-test='site-calls-next']")).ToBeEnabledAsync(); + await Assertions.Expect(page.Locator("[data-test='keyset-next']")).ToBeEnabledAsync(); } finally {