test(e2e): standardize AuditLog tests on SkippableFact + skip summary log
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.Playwright;
|
using Microsoft.Playwright;
|
||||||
|
using ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Cluster;
|
||||||
|
|
||||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Audit;
|
namespace ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Audit;
|
||||||
|
|
||||||
@@ -54,18 +55,10 @@ public class AuditLogPageTests
|
|||||||
_fixture = fixture;
|
_fixture = fixture;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[SkippableFact]
|
||||||
public async Task FilterNarrowing_ChannelFilterShrinksGrid()
|
public async Task FilterNarrowing_ChannelFilterShrinksGrid()
|
||||||
{
|
{
|
||||||
// Skip with a clear message when MSSQL is not reachable — the rest of
|
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
|
||||||
// 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.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var runId = Guid.NewGuid().ToString("N");
|
var runId = Guid.NewGuid().ToString("N");
|
||||||
var targetPrefix = $"playwright-test/filter-narrow/{runId}/";
|
var targetPrefix = $"playwright-test/filter-narrow/{runId}/";
|
||||||
@@ -119,13 +112,10 @@ public class AuditLogPageTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[SkippableFact]
|
||||||
public async Task DrilldownDrawer_JsonPrettyPrintsRequestBody()
|
public async Task DrilldownDrawer_JsonPrettyPrintsRequestBody()
|
||||||
{
|
{
|
||||||
if (!await AuditDataSeeder.IsAvailableAsync())
|
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
|
||||||
{
|
|
||||||
throw new InvalidOperationException("MSSQL unavailable; see FilterNarrowing test for setup instructions.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var runId = Guid.NewGuid().ToString("N");
|
var runId = Guid.NewGuid().ToString("N");
|
||||||
var targetPrefix = $"playwright-test/drilldown-json/{runId}/";
|
var targetPrefix = $"playwright-test/drilldown-json/{runId}/";
|
||||||
@@ -184,13 +174,10 @@ public class AuditLogPageTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[SkippableFact]
|
||||||
public async Task CopyAsCurlButton_IsVisibleAndClickableForApiInbound()
|
public async Task CopyAsCurlButton_IsVisibleAndClickableForApiInbound()
|
||||||
{
|
{
|
||||||
if (!await AuditDataSeeder.IsAvailableAsync())
|
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
|
||||||
{
|
|
||||||
throw new InvalidOperationException("MSSQL unavailable; see FilterNarrowing test for setup instructions.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var runId = Guid.NewGuid().ToString("N");
|
var runId = Guid.NewGuid().ToString("N");
|
||||||
var targetPrefix = $"playwright-test/curl-button/{runId}/";
|
var targetPrefix = $"playwright-test/curl-button/{runId}/";
|
||||||
@@ -239,13 +226,10 @@ public class AuditLogPageTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[SkippableFact]
|
||||||
public async Task DrillInFromCorrelationId_LandsOnAuditLogWithFilterContext()
|
public async Task DrillInFromCorrelationId_LandsOnAuditLogWithFilterContext()
|
||||||
{
|
{
|
||||||
if (!await AuditDataSeeder.IsAvailableAsync())
|
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
|
||||||
{
|
|
||||||
throw new InvalidOperationException("MSSQL unavailable; see FilterNarrowing test for setup instructions.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var runId = Guid.NewGuid().ToString("N");
|
var runId = Guid.NewGuid().ToString("N");
|
||||||
var targetPrefix = $"playwright-test/drill-in/{runId}/";
|
var targetPrefix = $"playwright-test/drill-in/{runId}/";
|
||||||
@@ -299,18 +283,15 @@ public class AuditLogPageTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[SkippableFact]
|
||||||
public async Task DrillInFromExecutionId_LandsOnAuditLogWithFilterContext()
|
public async Task DrillInFromExecutionId_LandsOnAuditLogWithFilterContext()
|
||||||
{
|
{
|
||||||
|
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
|
||||||
|
|
||||||
// Mirrors the correlationId drill-in: the "View this execution" drawer
|
// Mirrors the correlationId drill-in: the "View this execution" drawer
|
||||||
// action navigates to /audit/log?executionId={ExecutionId}. We seed a row
|
// action navigates to /audit/log?executionId={ExecutionId}. We seed a row
|
||||||
// carrying that ExecutionId, hit the deep link directly, and assert the
|
// carrying that ExecutionId, hit the deep link directly, and assert the
|
||||||
// page deserializes the param and auto-loads the seeded row.
|
// 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 runId = Guid.NewGuid().ToString("N");
|
||||||
var targetPrefix = $"playwright-test/exec-drill-in/{runId}/";
|
var targetPrefix = $"playwright-test/exec-drill-in/{runId}/";
|
||||||
var executionId = Guid.NewGuid();
|
var executionId = Guid.NewGuid();
|
||||||
@@ -357,19 +338,16 @@ public class AuditLogPageTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[SkippableFact]
|
||||||
public async Task DrillInFromParentExecution_FiltersGridToSpawnerExecution()
|
public async Task DrillInFromParentExecution_FiltersGridToSpawnerExecution()
|
||||||
{
|
{
|
||||||
|
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
|
||||||
|
|
||||||
// The drawer's "View parent execution" action navigates a routed (child)
|
// The drawer's "View parent execution" action navigates a routed (child)
|
||||||
// row to /audit/log?executionId={ParentExecutionId}. We seed a spawner row
|
// row to /audit/log?executionId={ParentExecutionId}. We seed a spawner row
|
||||||
// (its ExecutionId == the parent id) and a child row (ParentExecutionId
|
// (its ExecutionId == the parent id) and a child row (ParentExecutionId
|
||||||
// pointing at the spawner), open the child's drawer, click the action, and
|
// 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.
|
// 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 runId = Guid.NewGuid().ToString("N");
|
||||||
var targetPrefix = $"playwright-test/parent-exec-drill-in/{runId}/";
|
var targetPrefix = $"playwright-test/parent-exec-drill-in/{runId}/";
|
||||||
var parentExecutionId = Guid.NewGuid();
|
var parentExecutionId = Guid.NewGuid();
|
||||||
@@ -437,19 +415,16 @@ public class AuditLogPageTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[SkippableFact]
|
||||||
public async Task DrillInToExecutionChain_RendersTree_AndNodeClickFiltersGrid()
|
public async Task DrillInToExecutionChain_RendersTree_AndNodeClickFiltersGrid()
|
||||||
{
|
{
|
||||||
|
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
|
||||||
|
|
||||||
// Audit Log ParentExecutionId feature, Task 10: the drawer's "View
|
// Audit Log ParentExecutionId feature, Task 10: the drawer's "View
|
||||||
// execution chain" action opens /audit/execution-tree?executionId={id}.
|
// execution chain" action opens /audit/execution-tree?executionId={id}.
|
||||||
// We seed a spawner row + a child row, open the child's drawer, click
|
// We seed a spawner row + a child row, open the child's drawer, click
|
||||||
// "View execution chain", assert the tree renders BOTH executions, then
|
// "View execution chain", assert the tree renders BOTH executions, then
|
||||||
// click the spawner node and assert the Audit Log grid filters to it.
|
// 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 runId = Guid.NewGuid().ToString("N");
|
||||||
var targetPrefix = $"playwright-test/exec-chain-tree/{runId}/";
|
var targetPrefix = $"playwright-test/exec-chain-tree/{runId}/";
|
||||||
var parentExecutionId = Guid.NewGuid();
|
var parentExecutionId = Guid.NewGuid();
|
||||||
@@ -519,9 +494,11 @@ public class AuditLogPageTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[SkippableFact]
|
||||||
public async Task DoubleClickTreeNode_OpensExecutionRowModal()
|
public async Task DoubleClickTreeNode_OpensExecutionRowModal()
|
||||||
{
|
{
|
||||||
|
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
|
||||||
|
|
||||||
// Execution-Tree Node Detail Modal feature, Task 5: double-clicking a
|
// Execution-Tree Node Detail Modal feature, Task 5: double-clicking a
|
||||||
// node on the /audit/execution-tree page opens ExecutionDetailModal —
|
// node on the /audit/execution-tree page opens ExecutionDetailModal —
|
||||||
// a modal listing that execution's audit rows, with click-through to
|
// 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
|
// 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
|
// a single-row detail), open the tree, double-click the node, walk
|
||||||
// list → row → detail, then close the modal.
|
// 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 runId = Guid.NewGuid().ToString("N");
|
||||||
var targetPrefix = $"playwright-test/exec-node-modal/{runId}/";
|
var targetPrefix = $"playwright-test/exec-node-modal/{runId}/";
|
||||||
var executionId = Guid.NewGuid();
|
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}");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user