test(playwright): DebugViewTree — tolerate empty alarm forest (TreeView renders EmptyContent, not role=tree, when no alarms)

This commit is contained in:
Joseph Doherty
2026-06-17 16:08:37 -04:00
parent e7660134f2
commit 59e094ada3
@@ -37,14 +37,14 @@ namespace ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Deployment;
/// </para> /// </para>
/// ///
/// <para> /// <para>
/// <b>Why the tree assertion is robust regardless of seeded alarms</b> — the /// <b>Why the alarms-tab assertion is tolerant</b> — the
/// <see cref="TreeView{T}"/> always renders its <c>&lt;ul role="tree"&gt;</c> root /// <see cref="TreeView{T}"/> renders its <c>&lt;ul role="tree"&gt;</c> root ONLY
/// (with an <c>EmptyContent</c> "No alarms." / "No attributes." slot when the /// when the forest is non-empty; when empty it renders the <c>EmptyContent</c>
/// forest is empty), so asserting a <c>[role="tree"]</c> inside the active pane /// slot ("No alarms.") with no <c>[role="tree"]</c> element. The seeded
/// holds whether or not the fixture instance happens to carry a configured alarm /// <see cref="DeploymentFixture"/> instance has no configured alarms, so the
/// or composition members. The test therefore does NOT depend on heavy alarm /// alarms pane shows the empty hint. The Attributes pane always has data (one
/// seeding: it proves the Alarms tab switches the visible pane and that pane hosts /// attribute is seeded), so its <c>[role="tree"]</c> assertion remains strict.
/// a tree, which is the structural contract of the tabs+trees rework. /// The populated alarm tree is covered by bUnit tests (DebugViewAlarmTableTests).
/// </para> /// </para>
/// </summary> /// </summary>
[Collection("Playwright")] [Collection("Playwright")]
@@ -116,9 +116,18 @@ public class DebugViewTreeTests : IClassFixture<DeploymentFixture>
await Assertions.Expect(alarmTab).ToHaveAttributeAsync("aria-selected", "true"); await Assertions.Expect(alarmTab).ToHaveAttributeAsync("aria-selected", "true");
await Assertions.Expect(alarmPane).ToBeVisibleAsync(new() { Timeout = 10_000 }); await Assertions.Expect(alarmPane).ToBeVisibleAsync(new() { Timeout = 10_000 });
await Assertions.Expect(attrPane).ToBeHiddenAsync(); await Assertions.Expect(attrPane).ToBeHiddenAsync();
// The TreeView always renders its <ul role="tree"> root (EmptyContent slot when // TreeView renders <ul role="tree"> ONLY when the forest is non-empty; when empty it
// the forest is empty), so this holds whether or not the instance carries alarms. // renders the EmptyContent slot ("No alarms.") instead. The seeded DeploymentFixture
await Assertions.Expect(alarmPane.Locator("[role='tree']")).ToHaveCountAsync(1); // instance has no configured alarms, so the alarms forest is empty and the pane shows
// the empty hint rather than a tree. The populated alarm tree is covered by bUnit
// tests (DebugViewAlarmTableTests). Here we prove the tab switch works and the pane
// renders something valid — either a tree (if alarms exist) or the empty hint.
var alarmTreeCount = await alarmPane.Locator("[role='tree']").CountAsync();
if (alarmTreeCount == 0)
{
// No alarms configured on the seeded instance → TreeView shows EmptyContent.
await Assertions.Expect(alarmPane).ToContainTextAsync("No alarms.");
}
// Disconnect tears the card down and re-enables the selectors. // Disconnect tears the card down and re-enables the selectors.
await page.Locator("button.btn-outline-danger.btn-sm:has-text('Disconnect')").ClickAsync(); await page.Locator("button.btn-outline-danger.btn-sm:has-text('Disconnect')").ClickAsync();