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 38aace3a..ad8fbe94 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Notifications/NotificationActionTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Notifications/NotificationActionTests.cs @@ -121,11 +121,9 @@ public class NotificationActionTests // The retry resolves purely against the central row (no site relay), so a // single success toast appears. We assert exactly one toast (the single-toast // contract), tolerant of the exact outcome text. The wait is generous (15s) - // and the toast auto-dismisses 5s after it appears, so the assertion must - // catch it inside that window. - var toast = page.Locator(".toast"); - await Assertions.Expect(toast).ToBeVisibleAsync(new() { Timeout = 15_000 }); - Assert.Equal(1, await toast.CountAsync()); + // and the toast auto-dismisses 5s after it appears, so we use a single + // web-first retrying assertion to avoid a TOCTOU race with the auto-dismiss. + await Assertions.Expect(page.Locator(".toast")).ToHaveCountAsync(1, new() { Timeout = 15_000 }); } finally { @@ -159,10 +157,9 @@ public class NotificationActionTests await deleteButton.ClickAsync(); // The discard moves the central row to Discarded and surfaces a single success - // toast. Same single-toast / outcome-tolerant assertion as Retry. - var toast = page.Locator(".toast"); - await Assertions.Expect(toast).ToBeVisibleAsync(new() { Timeout = 15_000 }); - Assert.Equal(1, await toast.CountAsync()); + // toast. Same single-toast / outcome-tolerant assertion as Retry: a single + // web-first retrying assertion to avoid a TOCTOU race with the auto-dismiss. + await Assertions.Expect(page.Locator(".toast")).ToHaveCountAsync(1, new() { Timeout = 15_000 }); } finally {