using Microsoft.Playwright; namespace ScadaLink.CentralUI.PlaywrightTests; [Collection("Playwright")] public class SiteCrudTests { private readonly PlaywrightFixture _fixture; public SiteCrudTests(PlaywrightFixture fixture) { _fixture = fixture; } [Fact] public async Task SitesPage_ShowsTable() { var page = await _fixture.NewAuthenticatedPageAsync(); await page.GotoAsync($"{PlaywrightFixture.BaseUrl}/admin/sites"); await page.WaitForLoadStateAsync(LoadState.NetworkIdle); await Expect(page.Locator("h4:has-text('Site Management')")).ToBeVisibleAsync(); await Expect(page.Locator("table")).ToBeVisibleAsync(); } [Fact] public async Task AddSiteButton_NavigatesToCreatePage() { var page = await _fixture.NewAuthenticatedPageAsync(); await page.GotoAsync($"{PlaywrightFixture.BaseUrl}/admin/sites"); await page.WaitForLoadStateAsync(LoadState.NetworkIdle); await page.ClickAsync("button:has-text('Add Site')"); await PlaywrightFixture.WaitForPathAsync(page, "/admin/sites/create"); var inputCount = await page.Locator("input").CountAsync(); Assert.True(inputCount >= 2, $"Expected at least 2 inputs, found {inputCount}"); } [Fact] public async Task CreatePage_BackButton_ReturnsToList() { var page = await _fixture.NewAuthenticatedPageAsync(); await page.GotoAsync($"{PlaywrightFixture.BaseUrl}/admin/sites/create"); await page.WaitForLoadStateAsync(LoadState.NetworkIdle); await page.ClickAsync("button:has-text('Back')"); await PlaywrightFixture.WaitForPathAsync(page, "/admin/sites", excludePath: "/create"); await Expect(page.Locator("h4:has-text('Site Management')")).ToBeVisibleAsync(); } [Fact] public async Task CreatePage_CancelButton_ReturnsToList() { var page = await _fixture.NewAuthenticatedPageAsync(); await page.GotoAsync($"{PlaywrightFixture.BaseUrl}/admin/sites/create"); await page.WaitForLoadStateAsync(LoadState.NetworkIdle); await page.ClickAsync("button:has-text('Cancel')"); await PlaywrightFixture.WaitForPathAsync(page, "/admin/sites", excludePath: "/create"); } [Fact] public async Task CreatePage_HasNodeSubsections() { var page = await _fixture.NewAuthenticatedPageAsync(); await page.GotoAsync($"{PlaywrightFixture.BaseUrl}/admin/sites/create"); await page.WaitForLoadStateAsync(LoadState.NetworkIdle); await Expect(page.Locator("h6:has-text('Node A')")).ToBeVisibleAsync(); await Expect(page.Locator("h6:has-text('Node B')")).ToBeVisibleAsync(); } [Fact] public async Task CreatePage_SaveWithoutName_ShowsError() { var page = await _fixture.NewAuthenticatedPageAsync(); await page.GotoAsync($"{PlaywrightFixture.BaseUrl}/admin/sites/create"); await page.WaitForLoadStateAsync(LoadState.NetworkIdle); await page.ClickAsync("button:has-text('Save')"); // Should stay on create page with validation error Assert.Contains("/admin/sites/create", page.Url); await Expect(page.Locator(".text-danger")).ToBeVisibleAsync(); } private static ILocatorAssertions Expect(ILocator locator) => Assertions.Expect(locator); }