using Microsoft.Playwright; namespace LANCommander.Server.UI.Tests.Pages; /// /// Page object for the admin dashboard and navigation. /// public class AdminDashboardPage { private readonly IPage _page; public AdminDashboardPage(IPage page) { _page = page; } public async Task IsDisplayedAsync() { return await _page.GetByText("Dashboard").First.IsVisibleAsync(); } public async Task GetPageTitleAsync() { return await _page.TitleAsync(); } // Navigation helpers public async Task NavigateToGamesAsync() { await _page.GetByRole(AriaRole.Link, new() { Name = "Games" }).ClickAsync(); await _page.WaitForURLAsync("**/Games", new() { Timeout = 10000 }); // Wait for Blazor to render the page content await _page.WaitForSelectorAsync("text=Add Game", new() { Timeout = 10000 }); } public async Task NavigateToSettingsGeneralAsync() { // Navigate directly to the route rather than expanding the Settings SubMenu flyout. // The nested submenu expansion depends on the Blazor Server circuit being responsive // and is unreliable in CI; a direct navigation still exercises routing + auth. await _page.GotoAsync("/Settings/General"); await _page.WaitForURLAsync("**/Settings/General", new() { Timeout = 10000 }); // Wait for Blazor to render the settings content await _page.WaitForSelectorAsync("text=Use SSL", new() { Timeout = 10000 }); } public async Task NavigateToRedistributablesAsync() { await _page.GetByRole(AriaRole.Link, new() { Name = "Redistributables" }).ClickAsync(); await _page.WaitForURLAsync("**/Redistributables", new() { Timeout = 10000 }); } public async Task NavigateToServersAsync() { await _page.GetByRole(AriaRole.Link, new() { Name = "Servers", Exact = true }).ClickAsync(); await _page.WaitForURLAsync("**/Servers", new() { Timeout = 10000 }); } public async Task NavigateToIssuesAsync() { await _page.GetByRole(AriaRole.Link, new() { Name = "Issues" }).ClickAsync(); await _page.WaitForURLAsync("**/Issues", new() { Timeout = 10000 }); } public async Task NavigateToFilesAsync() { await _page.GetByRole(AriaRole.Link, new() { Name = "Files" }).ClickAsync(); await _page.WaitForURLAsync("**/Files", new() { Timeout = 10000 }); } public async Task NavigateToToolsAsync() { await _page.GetByRole(AriaRole.Link, new() { Name = "Tools", Exact = true }).ClickAsync(); await _page.WaitForURLAsync("**/Tools", new() { Timeout = 10000 }); } /// /// Gets the visible menu items from the sidebar navigation. /// public async Task> GetMainMenuItemsAsync() { // Wait for sidebar menu items to render await _page.GetByRole(AriaRole.Complementary) .Locator("[role='menuitem']") .First .WaitForAsync(new() { Timeout = 10000 }); var menuItems = _page.GetByRole(AriaRole.Complementary).Locator("[role='menuitem']"); var count = await menuItems.CountAsync(); var items = new List(); for (int i = 0; i < count; i++) { var text = await menuItems.Nth(i).TextContentAsync(); if (!string.IsNullOrWhiteSpace(text)) items.Add(text.Trim()); } return items; } }