using Microsoft.Playwright; namespace ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Deployment; /// /// Shared Topology-page navigation for the Playwright suites. The page loads lazily /// (bounded instance pages per branch, behind explicit "Load instances" loaders), so /// any test that addresses an area or instance row must first expand and load every /// branch. /// internal static class TopologyPageHelper { /// /// Navigates to the Topology page and returns a page whose tree is stable and /// fully expanded: it unchecks the #live-updates switch (stopping the 15s /// timer that would otherwise reload the tree and collapse expansions / tear down /// open dialogs and rename inputs), then clicks Expand all areas so nested /// area nodes are rendered and locatable. /// /// The Playwright fixture used to open an authenticated page. /// The authenticated page showing the fully-loaded Topology tree. public static async Task OpenStableTopologyAsync(PlaywrightFixture pw) => await OpenStableTopologyAsync(await pw.NewAuthenticatedPageAsync()); /// Navigates an existing authenticated to the fully-loaded Topology tree. /// An authenticated page. /// The same page, showing the fully-loaded Topology tree. public static async Task OpenStableTopologyAsync(IPage page) { await page.GotoAsync($"{PlaywrightFixture.BaseUrl}/deployment/topology"); await page.WaitForLoadStateAsync(LoadState.NetworkIdle); var live = page.Locator("#live-updates"); if (await live.IsCheckedAsync()) await live.UncheckAsync(); // stop the 15s tree reload // Lazy topology loads a bounded first page per branch. These small authoring // fixtures need their sites/areas loaded before addressing labels or instances. // "Expand all" re-renders over the SignalR circuit, so the click returns before the // newly-expanded branches (and their "Load instances" loaders) exist. Wait until no // collapsed branch remains before counting loaders — counting immediately raced the // render and returned an unexpanded tree whenever the round-trip lost. var collapsed = page.Locator("li[role='treeitem'][aria-expanded='false']"); for (var branch = 0; branch < 300; branch++) { await page.Locator("button[aria-label='Expand all areas']").ClickAsync(); await Assertions.Expect(collapsed).ToHaveCountAsync(0); var load = page.GetByRole(AriaRole.Button, new() { Name = "Load instances", Exact = true }); if (await load.CountAsync() == 0) return page; var pages = page.GetByText("Page 1", new() { Exact = true }); var count = await pages.CountAsync(); await load.First.ClickAsync(); await Assertions.Expect(pages).ToHaveCountAsync(count + 1); } throw new InvalidOperationException("Topology fixture exceeded 300 branches."); } }