From d80737978d8c9a8d3a58830532e7cb201ef6f583 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Sat, 6 Jun 2026 13:33:48 -0400 Subject: [PATCH] test(e2e): SiteCalls Discard click-through on a Parked row surfaces a relay outcome toast --- .../SiteCalls/SiteCallsPageTests.cs | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) 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 a53837ea..0ff7d3fc 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/SiteCalls/SiteCallsPageTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/SiteCalls/SiteCallsPageTests.cs @@ -30,6 +30,9 @@ namespace ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.SiteCalls; /// rows, never on Failed (or other) rows. /// RetryClickThrough — clicking Retry on a Parked row confirms /// the dialog, relays to the owning site, and surfaces an outcome toast. +/// DiscardClickThrough — clicking Discard on a Parked row confirms +/// the danger dialog ("Delete"), relays to the owning site, and surfaces an +/// outcome toast. /// /// /// @@ -328,4 +331,60 @@ public class SiteCallsPageTests await SiteCallDataSeeder.DeleteByTargetPrefixAsync(targetPrefix); } } + + /// + /// Mirrors + /// but exercises the Discard path: clicking Discard opens a danger + /// confirm modal (Dialog.ConfirmAsync with danger: true), whose footer + /// button is labelled "Delete" (not "Confirm"). Confirming relays a discard to + /// the owning site and ShowRelayOutcome surfaces exactly one outcome toast. + /// + [SkippableFact] + public async Task DiscardClickThrough_OnParkedRow_ConfirmsRelayAndShowsOutcomeToast() + { + Skip.IfNot(await SiteCallDataSeeder.IsAvailableAsync(), DbUnavailableSkipReason); + + var runId = Guid.NewGuid().ToString("N"); + var targetPrefix = $"playwright-test/sc-discard-click/{runId}/"; + var parkedId = Guid.NewGuid(); + var now = DateTime.UtcNow; + + try + { + // Parked + real site-a so the discard relay resolves fast (NotParked ack for this + // freshly-seeded GUID), surfacing a toast. + await SiteCallDataSeeder.InsertSiteCallAsync( + trackedOperationId: parkedId, channel: "ApiOutbound", target: targetPrefix + "parked", + sourceSite: "site-a", status: "Parked", retryCount: 3, + lastError: "HTTP 503 from ERP", httpStatus: 503, + createdAtUtc: now, updatedAtUtc: now); + + var page = await _fixture.NewAuthenticatedPageAsync(); + await page.GotoAsync($"{PlaywrightFixture.BaseUrl}{SiteCallsUrl}"); + await page.WaitForLoadStateAsync(LoadState.NetworkIdle); + + await SetSearchKeywordAsync(page, targetPrefix + "parked"); + await page.Locator("[data-test='site-calls-query']").ClickAsync(); + await page.WaitForLoadStateAsync(LoadState.NetworkIdle); + + var parkedRow = page.Locator("tbody tr", new() { HasText = targetPrefix + "parked" }); + await Assertions.Expect(parkedRow).ToBeVisibleAsync(); + + // Discard opens the danger confirm modal. + await parkedRow.Locator("button:has-text('Discard')").ClickAsync(); + + // Danger confirm — labelled "Delete" (Dialog.ConfirmAsync(..., danger: true)). + var deleteButton = page.Locator(".modal-footer .btn-danger"); + await Assertions.Expect(deleteButton).ToBeVisibleAsync(); + await Assertions.Expect(deleteButton).ToHaveTextAsync("Delete"); + await deleteButton.ClickAsync(); + + // One outcome toast (Applied / NotParked / SiteUnreachable — tolerant). + await Assertions.Expect(page.Locator(".toast")).ToHaveCountAsync(1, new() { Timeout = 15_000 }); + } + finally + { + await SiteCallDataSeeder.DeleteByTargetPrefixAsync(targetPrefix); + } + } }