test(e2e): standardize AuditLog tests on SkippableFact + skip summary log

This commit is contained in:
Joseph Doherty
2026-06-05 10:25:16 -04:00
parent 234ddb5201
commit 271f70b1d2
2 changed files with 44 additions and 49 deletions
@@ -1,4 +1,5 @@
using Microsoft.Playwright;
using ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Cluster;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Audit;
@@ -54,18 +55,10 @@ public class AuditLogPageTests
_fixture = fixture;
}
[Fact]
[SkippableFact]
public async Task FilterNarrowing_ChannelFilterShrinksGrid()
{
// Skip with a clear message when MSSQL is not reachable — the rest of
// the Playwright suite is UI-only and does not need the DB, so this
// surfaces a setup gap explicitly rather than as an opaque SqlException.
if (!await AuditDataSeeder.IsAvailableAsync())
{
throw new InvalidOperationException(
"AuditDataSeeder cannot reach MSSQL at localhost:1433 — bring up infra/docker-compose and docker/deploy.sh, " +
"or set SCADABRIDGE_PLAYWRIGHT_DB to a reachable connection string.");
}
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
var runId = Guid.NewGuid().ToString("N");
var targetPrefix = $"playwright-test/filter-narrow/{runId}/";
@@ -119,13 +112,10 @@ public class AuditLogPageTests
}
}
[Fact]
[SkippableFact]
public async Task DrilldownDrawer_JsonPrettyPrintsRequestBody()
{
if (!await AuditDataSeeder.IsAvailableAsync())
{
throw new InvalidOperationException("MSSQL unavailable; see FilterNarrowing test for setup instructions.");
}
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
var runId = Guid.NewGuid().ToString("N");
var targetPrefix = $"playwright-test/drilldown-json/{runId}/";
@@ -184,13 +174,10 @@ public class AuditLogPageTests
}
}
[Fact]
[SkippableFact]
public async Task CopyAsCurlButton_IsVisibleAndClickableForApiInbound()
{
if (!await AuditDataSeeder.IsAvailableAsync())
{
throw new InvalidOperationException("MSSQL unavailable; see FilterNarrowing test for setup instructions.");
}
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
var runId = Guid.NewGuid().ToString("N");
var targetPrefix = $"playwright-test/curl-button/{runId}/";
@@ -239,13 +226,10 @@ public class AuditLogPageTests
}
}
[Fact]
[SkippableFact]
public async Task DrillInFromCorrelationId_LandsOnAuditLogWithFilterContext()
{
if (!await AuditDataSeeder.IsAvailableAsync())
{
throw new InvalidOperationException("MSSQL unavailable; see FilterNarrowing test for setup instructions.");
}
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
var runId = Guid.NewGuid().ToString("N");
var targetPrefix = $"playwright-test/drill-in/{runId}/";
@@ -299,18 +283,15 @@ public class AuditLogPageTests
}
}
[Fact]
[SkippableFact]
public async Task DrillInFromExecutionId_LandsOnAuditLogWithFilterContext()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
// Mirrors the correlationId drill-in: the "View this execution" drawer
// action navigates to /audit/log?executionId={ExecutionId}. We seed a row
// carrying that ExecutionId, hit the deep link directly, and assert the
// page deserializes the param and auto-loads the seeded row.
if (!await AuditDataSeeder.IsAvailableAsync())
{
throw new InvalidOperationException("MSSQL unavailable; see FilterNarrowing test for setup instructions.");
}
var runId = Guid.NewGuid().ToString("N");
var targetPrefix = $"playwright-test/exec-drill-in/{runId}/";
var executionId = Guid.NewGuid();
@@ -357,19 +338,16 @@ public class AuditLogPageTests
}
}
[Fact]
[SkippableFact]
public async Task DrillInFromParentExecution_FiltersGridToSpawnerExecution()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
// The drawer's "View parent execution" action navigates a routed (child)
// row to /audit/log?executionId={ParentExecutionId}. We seed a spawner row
// (its ExecutionId == the parent id) and a child row (ParentExecutionId
// pointing at the spawner), open the child's drawer, click the action, and
// assert the grid auto-loads filtered to the spawner's own rows.
if (!await AuditDataSeeder.IsAvailableAsync())
{
throw new InvalidOperationException("MSSQL unavailable; see FilterNarrowing test for setup instructions.");
}
var runId = Guid.NewGuid().ToString("N");
var targetPrefix = $"playwright-test/parent-exec-drill-in/{runId}/";
var parentExecutionId = Guid.NewGuid();
@@ -437,19 +415,16 @@ public class AuditLogPageTests
}
}
[Fact]
[SkippableFact]
public async Task DrillInToExecutionChain_RendersTree_AndNodeClickFiltersGrid()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
// Audit Log ParentExecutionId feature, Task 10: the drawer's "View
// execution chain" action opens /audit/execution-tree?executionId={id}.
// We seed a spawner row + a child row, open the child's drawer, click
// "View execution chain", assert the tree renders BOTH executions, then
// click the spawner node and assert the Audit Log grid filters to it.
if (!await AuditDataSeeder.IsAvailableAsync())
{
throw new InvalidOperationException("MSSQL unavailable; see FilterNarrowing test for setup instructions.");
}
var runId = Guid.NewGuid().ToString("N");
var targetPrefix = $"playwright-test/exec-chain-tree/{runId}/";
var parentExecutionId = Guid.NewGuid();
@@ -519,9 +494,11 @@ public class AuditLogPageTests
}
}
[Fact]
[SkippableFact]
public async Task DoubleClickTreeNode_OpensExecutionRowModal()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
// Execution-Tree Node Detail Modal feature, Task 5: double-clicking a
// node on the /audit/execution-tree page opens ExecutionDetailModal —
// a modal listing that execution's audit rows, with click-through to
@@ -529,11 +506,6 @@ public class AuditLogPageTests
// TWO audit rows (so the modal opens to the list view, not straight to
// a single-row detail), open the tree, double-click the node, walk
// list → row → detail, then close the modal.
if (!await AuditDataSeeder.IsAvailableAsync())
{
throw new InvalidOperationException("MSSQL unavailable; see FilterNarrowing test for setup instructions.");
}
var runId = Guid.NewGuid().ToString("N");
var targetPrefix = $"playwright-test/exec-node-modal/{runId}/";
var executionId = Guid.NewGuid();
@@ -0,0 +1,23 @@
using System.Runtime.CompilerServices;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Cluster;
/// <summary>
/// Makes the suite's skip policy visible: at process exit, writes one console
/// line reporting how many cluster/DB-dependent test gates skipped because the
/// cluster was unavailable (see <see cref="ClusterAvailability.SkippedCount"/>).
/// Registered once via a <see cref="ModuleInitializerAttribute"/> so it runs
/// regardless of how the test host is launched (Task 3).
/// </summary>
internal static class SkipSummaryReporter
{
[ModuleInitializer]
internal static void Init() =>
AppDomain.CurrentDomain.ProcessExit += (_, _) =>
{
if (ClusterAvailability.SkippedCount > 0)
{
Console.WriteLine($"[E2E] Skipped {ClusterAvailability.SkippedCount} cluster/DB-dependent test gate(s) — {ClusterAvailability.SkipReason}");
}
};
}