test(playwright): node-scope DataConnection kebab + target site node (review fix)
This commit is contained in:
+20
-11
@@ -39,23 +39,30 @@ public class DataConnectionCrudTests
|
|||||||
await Assertions.Expect(page.Locator("h4:has-text('Connections')")).ToBeVisibleAsync();
|
await Assertions.Expect(page.Locator("h4:has-text('Connections')")).ToBeVisibleAsync();
|
||||||
|
|
||||||
// Reveal all nodes so the new connection (a child of its site) is in the tree.
|
// Reveal all nodes so the new connection (a child of its site) is in the tree.
|
||||||
await page.Locator("button.btn-outline-secondary.btn-sm.dropdown-toggle:has-text('Bulk actions')")
|
// Scope the "Expand all" click to the Bulk-actions dropdown we just opened, so it
|
||||||
.ClickAsync();
|
// can't multi-match any other "Expand all" on the page.
|
||||||
await page.Locator(".dropdown-item:has-text('Expand all')").ClickAsync();
|
var bulkDropdown = page.Locator(".dropdown")
|
||||||
|
.Filter(new() { Has = page.Locator("button.dropdown-toggle:has-text('Bulk actions')") });
|
||||||
|
await bulkDropdown.Locator("button.dropdown-toggle:has-text('Bulk actions')").ClickAsync();
|
||||||
|
await bulkDropdown.Locator(".dropdown-menu .dropdown-item:has-text('Expand all')").ClickAsync();
|
||||||
|
|
||||||
var node = page.Locator("span.tv-label", new() { HasText = name });
|
var node = page.Locator("span.tv-label", new() { HasText = name });
|
||||||
await Assertions.Expect(node).ToBeVisibleAsync(new() { Timeout = 10_000 });
|
await Assertions.Expect(node).ToBeVisibleAsync(new() { Timeout = 10_000 });
|
||||||
|
|
||||||
|
// Scope ALL dropdown interaction to THIS node's own .dc-node-actions wrapper (the
|
||||||
|
// per-node div.dropdown in DataConnections.razor that holds the kebab + its menu),
|
||||||
|
// keyed by the unique aria-label. This avoids any reliance on Bootstrap's .show —
|
||||||
|
// multiple connection-node menus (or the TreeView's separate ContextMenu) can carry
|
||||||
|
// .show at once, which would multi-match under Playwright strict mode.
|
||||||
|
var nodeActions = page.Locator(".dc-node-actions")
|
||||||
|
.Filter(new() { Has = page.Locator($"button[aria-label='More actions for {name}']") });
|
||||||
|
|
||||||
// The kebab is opacity:0 until its row is hovered; hovering first makes the
|
// The kebab is opacity:0 until its row is hovered; hovering first makes the
|
||||||
// reveal deterministic, then a forced click sidesteps any residual flake.
|
// reveal deterministic, then a forced click sidesteps any residual flake.
|
||||||
await node.HoverAsync();
|
await node.HoverAsync();
|
||||||
await page.Locator($"button.dc-kebab[aria-label='More actions for {name}']")
|
await nodeActions.Locator("button.dc-kebab").ClickAsync(new() { Force = true });
|
||||||
.ClickAsync(new() { Force = true });
|
|
||||||
|
|
||||||
// Every connection node renders its own .text-danger "Delete" item, so scope the
|
await nodeActions.Locator(".dropdown-menu .dropdown-item.text-danger:has-text('Delete')")
|
||||||
// click to the one open menu. Bootstrap puts .show on the active node's
|
|
||||||
// ul.dropdown-menu (and auto-closes the others), making this match uniquely.
|
|
||||||
await page.Locator(".dropdown-menu.show .dropdown-item.text-danger:has-text('Delete')")
|
|
||||||
.ClickAsync();
|
.ClickAsync();
|
||||||
|
|
||||||
await Assertions.Expect(page.Locator(".modal-title:has-text('Delete Connection')")).ToBeVisibleAsync();
|
await Assertions.Expect(page.Locator(".modal-title:has-text('Delete Connection')")).ToBeVisibleAsync();
|
||||||
@@ -95,8 +102,10 @@ public class DataConnectionCrudTests
|
|||||||
var addButton = page.Locator("button.btn.btn-primary.btn-sm:has-text('+ Connection')");
|
var addButton = page.Locator("button.btn.btn-primary.btn-sm:has-text('+ Connection')");
|
||||||
await Assertions.Expect(addButton).ToBeDisabledAsync();
|
await Assertions.Expect(addButton).ToBeDisabledAsync();
|
||||||
|
|
||||||
// Selecting any site node (site-a exists on the live cluster) satisfies the gate.
|
// Selecting a site node (site-a exists on the live cluster) satisfies the gate.
|
||||||
await page.Locator("span.tv-label").First.ClickAsync();
|
// Site-level labels carry the extra `fw-semibold` class (connection labels don't),
|
||||||
|
// so this targets a SITE node specifically rather than any tree label.
|
||||||
|
await page.Locator("span.tv-label.fw-semibold").First.ClickAsync();
|
||||||
|
|
||||||
await Assertions.Expect(addButton).ToBeEnabledAsync();
|
await Assertions.Expect(addButton).ToBeEnabledAsync();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user