test(playwright): InstanceConfigure alarm-override set-priority/clear round-trip; drop stale TODO
This commit is contained in:
+78
-1
@@ -166,5 +166,82 @@ public sealed class InstanceConfigureTests : IClassFixture<InstanceConfigureFixt
|
|||||||
await Assertions.Expect(errorAlert).ToContainTextAsync("not found");
|
await Assertions.Expect(errorAlert).ToContainTextAsync("not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(wave-N): alarm-override UI coverage — needs a template-with-alarm fixture (template alarms are not CLI-provisionable today).
|
/// <summary>
|
||||||
|
/// Alarm-override round-trip on the InstanceConfigure page's <b>Alarm Overrides</b> card: Edit the
|
||||||
|
/// fixture's non-locked HiLo alarm (<c>_cfg.AlarmName</c> = "HiHi"), set a priority override, Save →
|
||||||
|
/// one toast + an "overridden" badge, then verify the <c>InstanceAlarmOverride</c> actually persisted
|
||||||
|
/// via a CLI <c>instance get</c> read-back (not just the toast/badge), then Clear → badge gone +
|
||||||
|
/// override removed (re-verified via read-back).
|
||||||
|
///
|
||||||
|
/// <para>
|
||||||
|
/// Read-back path: the <c>instance get</c> document surfaces an <c>alarmOverrides</c> array whose
|
||||||
|
/// elements are <c>{ id, instanceId, alarmCanonicalName, priorityLevelOverride }</c> (camelCase,
|
||||||
|
/// empirically verified against the dev cluster — same instance-document path the
|
||||||
|
/// <see cref="SaveOverride_RoundTrips"/> test uses for <c>attributeOverrides</c>). For a direct
|
||||||
|
/// (non-composed) alarm, <c>alarmCanonicalName</c> equals the alarm name.
|
||||||
|
/// </para>
|
||||||
|
///
|
||||||
|
/// <para>
|
||||||
|
/// Setting only the PRIORITY field is the reliable "create override" delta — a Save with no
|
||||||
|
/// config-diff AND empty priority deletes the override instead. The fixture instance is SHARED, so
|
||||||
|
/// the test clears its own override in-body (badge gone + read-back empty) and again in a
|
||||||
|
/// <c>finally</c>, leaving the instance override-free as found.
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
[SkippableFact]
|
||||||
|
public async Task AlarmOverride_SetPriority_ThenClear_RoundTrips()
|
||||||
|
{
|
||||||
|
Skip.IfNot(_cfg.Available, ClusterAvailability.SkipReason);
|
||||||
|
|
||||||
|
var page = await _fixture.NewAuthenticatedPageAsync("multi-role", "password");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await page.GotoAsync($"{PlaywrightFixture.BaseUrl}/deployment/instances/{_cfg.InstanceId}/configure");
|
||||||
|
await page.WaitForLoadStateAsync(LoadState.NetworkIdle);
|
||||||
|
|
||||||
|
// The Alarm Overrides card renders one row per non-locked template alarm; web-first wait
|
||||||
|
// for the fixture alarm's row so we never race the post-load re-render. No override yet.
|
||||||
|
var row = page.Locator($"[data-test='alarm-override-row-{_cfg.AlarmName}']");
|
||||||
|
await Assertions.Expect(row).ToBeVisibleAsync(new() { Timeout = 15_000 });
|
||||||
|
await Assertions.Expect(row.Locator("[data-test='alarm-override-badge']")).ToHaveCountAsync(0);
|
||||||
|
|
||||||
|
// Edit → set a priority override → Save. FillAsync fires the input event, so the priority
|
||||||
|
// input's @bind:event="oninput" commits before the Save click (no extra change dispatch).
|
||||||
|
await row.Locator("[data-test='alarm-edit-btn']").ClickAsync();
|
||||||
|
var priorityInput = page.Locator("[data-test='alarm-priority-input']");
|
||||||
|
await Assertions.Expect(priorityInput).ToBeVisibleAsync(new() { Timeout = 15_000 });
|
||||||
|
await priorityInput.FillAsync("750");
|
||||||
|
await page.Locator("[data-test='alarm-save-override']").ClickAsync();
|
||||||
|
|
||||||
|
await Assertions.Expect(page.Locator(".toast")).ToHaveCountAsync(1, new() { Timeout = 15_000 });
|
||||||
|
await Assertions.Expect(row.Locator("[data-test='alarm-override-badge']"))
|
||||||
|
.ToBeVisibleAsync(new() { Timeout = 15_000 });
|
||||||
|
|
||||||
|
// Verify the InstanceAlarmOverride persisted via CLI read-back (not just the toast/badge).
|
||||||
|
using (var doc = await CliRunner.GetInstanceDocumentAsync(_cfg.InstanceId))
|
||||||
|
{
|
||||||
|
var overrides = doc.RootElement.GetProperty("alarmOverrides");
|
||||||
|
Assert.Contains(overrides.EnumerateArray(), o =>
|
||||||
|
o.GetProperty("alarmCanonicalName").GetString() == _cfg.AlarmName
|
||||||
|
&& o.GetProperty("priorityLevelOverride").GetInt32() == 750);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear is immediate (no confirm): the badge disappears and the override is removed.
|
||||||
|
await row.Locator("[data-test='alarm-clear-btn']").ClickAsync();
|
||||||
|
await Assertions.Expect(row.Locator("[data-test='alarm-override-badge']"))
|
||||||
|
.ToHaveCountAsync(0, new() { Timeout = 15_000 });
|
||||||
|
using (var doc = await CliRunner.GetInstanceDocumentAsync(_cfg.InstanceId))
|
||||||
|
{
|
||||||
|
var overrides = doc.RootElement.GetProperty("alarmOverrides");
|
||||||
|
Assert.DoesNotContain(overrides.EnumerateArray(), o =>
|
||||||
|
o.GetProperty("alarmCanonicalName").GetString() == _cfg.AlarmName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Belt-and-braces: leave the shared fixture instance override-free even if an assertion
|
||||||
|
// above threw after the Save (best-effort; never masks the test's own failure).
|
||||||
|
await CliRunner.DeleteInstanceAlarmOverrideAsync(_cfg.InstanceId, _cfg.AlarmName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user