feat(centralui): ExecutionId column, filter and drill-in on the Audit Log page
This commit is contained in:
@@ -24,6 +24,9 @@ namespace ScadaLink.CentralUI.PlaywrightTests.Audit;
|
||||
/// link relies on; verified by reproducing the link target directly because
|
||||
/// seeding a notification visible to the report page requires the Akka query
|
||||
/// path, not just an INSERT).</item>
|
||||
/// <item><c>DrillInFromExecutionId_LandsOnAuditLogWithFilterContext</c> — the
|
||||
/// <c>?executionId=</c> drill-in (the drawer's "View this execution" action)
|
||||
/// auto-loads the grid filtered by ExecutionId.</item>
|
||||
/// <item><c>NotificationsPage_HasViewAuditHistoryLink_WhenNotificationsExist</c> —
|
||||
/// the report page wires drill-in links when notifications are present.</item>
|
||||
/// <item><c>ExportCsv_LinkIsVisibleAndDownloads</c> — Export CSV button gated on
|
||||
@@ -289,6 +292,64 @@ public class AuditLogPageTests
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DrillInFromExecutionId_LandsOnAuditLogWithFilterContext()
|
||||
{
|
||||
// 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();
|
||||
var eventId = Guid.NewGuid();
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
try
|
||||
{
|
||||
await AuditDataSeeder.InsertAuditEventAsync(
|
||||
eventId: eventId,
|
||||
occurredAtUtc: now,
|
||||
channel: "ApiOutbound",
|
||||
kind: "ApiCall",
|
||||
status: "Delivered",
|
||||
target: targetPrefix + "endpoint",
|
||||
executionId: executionId,
|
||||
httpStatus: 200,
|
||||
durationMs: 11);
|
||||
|
||||
var page = await _fixture.NewAuthenticatedPageAsync();
|
||||
|
||||
// The exact URL the drawer's "View this execution" button produces.
|
||||
await page.GotoAsync($"{PlaywrightFixture.BaseUrl}/audit/log?executionId={executionId}");
|
||||
await page.WaitForLoadStateAsync(LoadState.NetworkIdle);
|
||||
|
||||
Assert.Contains($"executionId={executionId}", page.Url);
|
||||
await Assertions.Expect(page.Locator("h1:has-text('Audit Log')")).ToBeVisibleAsync();
|
||||
await Assertions.Expect(page.Locator("[data-test='audit-filter-bar']")).ToBeVisibleAsync();
|
||||
await Assertions.Expect(page.Locator("[data-test='audit-results-grid']")).ToBeVisibleAsync();
|
||||
|
||||
// Auto-load: the query-string drill-in resolves the ?executionId=
|
||||
// filter on OnInitialized and the seeded row appears without an
|
||||
// Apply click.
|
||||
var seededRow = page.Locator($"[data-test='grid-row-{eventId}']");
|
||||
await Assertions.Expect(seededRow).ToBeVisibleAsync();
|
||||
|
||||
// The ExecutionId column renders the row's short-form value.
|
||||
var execCell = page.Locator($"[data-test='execution-id-{eventId}']");
|
||||
await Assertions.Expect(execCell).ToBeVisibleAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
await AuditDataSeeder.DeleteByTargetPrefixAsync(targetPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task NotificationsPage_RendersAuditDrillInLinkPattern()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user