test(playwright): Audit Log non-API-no-cURL + drawer-close edge cases (Wave 4)

This commit is contained in:
Joseph Doherty
2026-06-07 04:02:01 -04:00
parent eea68b97f6
commit f5535ad5c1
@@ -765,4 +765,116 @@ public class AuditLogPageTests
// The audit results grid never rendered for the unauthorized user.
Assert.Equal(0, await page.Locator("[data-test='audit-results-grid']").CountAsync());
}
[SkippableFact]
public async Task NonApiRow_Drawer_OmitsCopyAsCurl()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
// The Copy-as-cURL action is gated on AuditEventDetail.IsApiChannel, which
// returns true only for ApiOutbound/ApiInbound. A DbOutbound row's drawer
// must therefore render WITHOUT the cURL button — the negative of
// CopyAsCurlButton_IsVisibleAndClickableForApiInbound. We seed one
// DbOutbound row, open its drawer, and assert the drawer is open AND the
// cURL button is absent.
var runId = Guid.NewGuid().ToString("N");
var targetPrefix = $"playwright-test/wave4-audit2/{runId}/";
var dbId = Guid.NewGuid();
var now = DateTime.UtcNow;
try
{
await AuditDataSeeder.InsertAuditEventAsync(
eventId: dbId,
occurredAtUtc: now,
channel: "DbOutbound",
kind: "DbWrite",
status: "Delivered",
target: targetPrefix + "dbrow",
durationMs: 17);
var page = await _fixture.NewAuthenticatedPageAsync();
await page.GotoAsync($"{PlaywrightFixture.BaseUrl}/audit/log");
await page.WaitForLoadStateAsync(LoadState.NetworkIdle);
// Filter to the seeded row (contains-match), then Apply to populate the
// grid — it stays empty until the user filters.
await page.FillAsync("#audit-target", targetPrefix + "dbrow");
await page.ClickAsync("[data-test='filter-apply']");
await page.WaitForLoadStateAsync(LoadState.NetworkIdle);
var row = page.Locator($"[data-test='grid-row-{dbId}']");
await Assertions.Expect(row).ToBeVisibleAsync();
await row.ClickAsync();
// The drawer opens for the DbOutbound row, but the cURL action — gated
// on IsApiChannel — is absent.
await Assertions.Expect(page.Locator("[data-test='audit-drilldown-drawer']")).ToBeVisibleAsync();
await Assertions.Expect(page.Locator("[data-test='copy-as-curl']")).ToHaveCountAsync(0);
}
finally
{
await AuditDataSeeder.DeleteByTargetPrefixAsync(targetPrefix);
}
}
[SkippableFact]
public async Task Drawer_CloseControls_DismissTheDrawer()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
// The drawer offers two wired close paths — the header X
// ([data-test='drawer-close']) and the footer Close button
// ([data-test='drawer-close-footer']), both bound to HandleClose. We open
// the drawer, dismiss via the X, re-open, then dismiss via the footer,
// asserting the drawer is gone (count 0) after each.
// Escape-to-close is NOT wired on AuditDrilldownDrawer (only
// ExecutionDetailModal has a keydown handler); covering the X and
// footer-Close paths that ARE wired.
var runId = Guid.NewGuid().ToString("N");
var targetPrefix = $"playwright-test/wave4-audit2c/{runId}/";
var apiId = Guid.NewGuid();
var now = DateTime.UtcNow;
try
{
await AuditDataSeeder.InsertAuditEventAsync(
eventId: apiId,
occurredAtUtc: now,
channel: "ApiOutbound",
kind: "ApiCall",
status: "Delivered",
target: targetPrefix + "row",
httpStatus: 200,
durationMs: 42);
var page = await _fixture.NewAuthenticatedPageAsync();
await page.GotoAsync($"{PlaywrightFixture.BaseUrl}/audit/log");
await page.WaitForLoadStateAsync(LoadState.NetworkIdle);
await page.FillAsync("#audit-target", targetPrefix + "row");
await page.ClickAsync("[data-test='filter-apply']");
await page.WaitForLoadStateAsync(LoadState.NetworkIdle);
var row = page.Locator($"[data-test='grid-row-{apiId}']");
var drawer = page.Locator("[data-test='audit-drilldown-drawer']");
// Open, then dismiss via the header X.
await Assertions.Expect(row).ToBeVisibleAsync();
await row.ClickAsync();
await Assertions.Expect(drawer).ToBeVisibleAsync();
await page.ClickAsync("[data-test='drawer-close']");
await Assertions.Expect(drawer).ToHaveCountAsync(0);
// Re-open, then dismiss via the footer Close button.
await row.ClickAsync();
await Assertions.Expect(drawer).ToBeVisibleAsync();
await page.ClickAsync("[data-test='drawer-close-footer']");
await Assertions.Expect(drawer).ToHaveCountAsync(0);
}
finally
{
await AuditDataSeeder.DeleteByTargetPrefixAsync(targetPrefix);
}
}
}