From 78e67c2aab359e1234e19aa59c82e4fa0c0f74c5 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Tue, 10 Feb 2026 07:47:48 -0500 Subject: [PATCH] Migrate UI tests to Playwright dotta --- NEW/src/JdeScoping.Host/Program.cs | 2 +- .../JdeScoping.Ui.Tests/AuthApiSmokeTests.cs | 28 ++- .../ComponentLotSearchTests.cs | 28 ++- .../JdeScoping.Ui.Tests/DataSyncPageTests.cs | 40 +++- NEW/tests/JdeScoping.Ui.Tests/GlobalUsings.cs | 2 +- .../Helpers/UiAuthHelper.cs | 20 +- .../Helpers/UiNavigationHelper.cs | 6 +- .../Helpers/UiSearchFormHelper.cs | 24 +- .../JdeScoping.Ui.Tests.csproj | 48 ++-- .../JdeScoping.Ui.Tests/LoginPageTests.cs | 29 ++- .../RefreshStatusPageTests.cs | 35 ++- .../JdeScoping.Ui.Tests/SearchPageTests.cs | 22 +- .../SearchQueuePageTests.cs | 38 ++- .../SearchesDashboardPageTests.cs | 26 +- .../Support/PlaywrightFixture.cs | 13 +- .../Support/SearchFlowTestBase.cs | 20 +- .../Support/TestDataPaths.cs | 7 +- .../Support/UiSearchTypes.cs | 2 +- .../JdeScoping.Ui.Tests/Support/UiTestBase.cs | 4 +- .../Support/UiTestCollection.cs | 4 +- .../Support/UiTestSettings.cs | 5 +- .../TestData/test-data.json | 225 ++++++++++++++---- .../TimeSpanItemNumberSearchTests.cs | 29 ++- .../TimeSpanOperatorSearchTests.cs | 29 ++- .../TimeSpanPcExtractMisSearchTests.cs | 29 ++- .../TimeSpanPcItemSearchTests.cs | 30 ++- .../TimeSpanPcOperatorSearchTests.cs | 30 ++- .../TimeSpanPcPartOpSearchTests.cs | 30 ++- .../TimeSpanPcWoPartOpSearchTests.cs | 31 ++- .../TimeSpanProfitCenterSearchTests.cs | 29 ++- .../TimeSpanWcExtractMisSearchTests.cs | 29 ++- .../TimeSpanWcItemSearchTests.cs | 30 ++- .../TimeSpanWcOperatorSearchTests.cs | 30 ++- .../TimeSpanWcPartOpSearchTests.cs | 30 ++- .../TimeSpanWcWoPartOpSearchTests.cs | 31 ++- .../TimeSpanWorkCenterSearchTests.cs | 29 ++- .../WorkOrderSearchTests.cs | 28 ++- 37 files changed, 842 insertions(+), 230 deletions(-) diff --git a/NEW/src/JdeScoping.Host/Program.cs b/NEW/src/JdeScoping.Host/Program.cs index 9ae4d02..a0a5ade 100644 --- a/NEW/src/JdeScoping.Host/Program.cs +++ b/NEW/src/JdeScoping.Host/Program.cs @@ -62,7 +62,7 @@ try .AddDataAccess(builder.Configuration) // 1. Database access + search processing .AddInfrastructure(builder.Configuration) // 2. Infrastructure (JDE/CMS/Auth) .AddDataSyncServices(builder.Configuration) // 3. Data sync background service - .AddExcelIO(builder.Configuration) // 4. Result export + .AddExcelIO(builder.Configuration) // 4. Result export .AddWebApi(builder.Configuration); // 5. Web API (controllers, auth, SignalR) var app = builder.Build(); diff --git a/NEW/tests/JdeScoping.Ui.Tests/AuthApiSmokeTests.cs b/NEW/tests/JdeScoping.Ui.Tests/AuthApiSmokeTests.cs index 61dce19..9c4fca0 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/AuthApiSmokeTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/AuthApiSmokeTests.cs @@ -3,14 +3,31 @@ using System.Net.Http.Json; using System.Security.Cryptography; using System.Text; using System.Text.Json; -using JdeScoping.Core.Models; using JdeScoping.Core.Models.Auth; using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// API-level smoke tests for the authentication endpoint against the Docker host. +/// Validates the RSA public-key exchange, encrypted login, and session cookie flow. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public class AuthApiSmokeTests { + /// + /// Verifies the full login flow: fetch public key, encrypt credentials, POST login, and confirm session via /me. + /// + /// + /// Steps: + /// + /// Create an HttpClient with a CookieContainer for session tracking. + /// GET /api/auth/public-key and verify the PEM response. + /// RSA-encrypt a test login payload using the returned public key. + /// POST /api/auth/login with the encrypted payload and assert HTTP 200. + /// GET /api/auth/me and assert HTTP 200 (session is authenticated). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] public async Task AuthApi_Login_WorksAgainstDockerHost() @@ -23,16 +40,17 @@ public class AuthApiSmokeTests Assert.NotNull(key); Assert.Contains("BEGIN PUBLIC KEY", key!.PublicKeyPem); - var payload = JsonSerializer.Serialize(new LoginModel { Username = "testuser", Password = "testpass" }); + string payload = JsonSerializer.Serialize(new LoginModel { Username = "testuser", Password = "testpass" }); using var rsa = RSA.Create(); rsa.ImportFromPem(key.PublicKeyPem); - var encrypted = rsa.Encrypt(Encoding.UTF8.GetBytes(payload), RSAEncryptionPadding.OaepSHA256); + byte[] encrypted = rsa.Encrypt(Encoding.UTF8.GetBytes(payload), RSAEncryptionPadding.OaepSHA256); - var login = await client.PostAsJsonAsync("api/auth/login", new EncryptedLoginRequest(Convert.ToBase64String(encrypted))); + var login = await client.PostAsJsonAsync("api/auth/login", + new EncryptedLoginRequest(Convert.ToBase64String(encrypted))); Assert.Equal(HttpStatusCode.OK, login.StatusCode); var me = await client.GetAsync("api/auth/me"); Assert.Equal(HttpStatusCode.OK, me.StatusCode); } -} +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/ComponentLotSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/ComponentLotSearchTests.cs index 0164f07..5f6b8d0 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/ComponentLotSearchTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/ComponentLotSearchTests.cs @@ -2,16 +2,38 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the "Component Lot" search type (TC-020). +/// Validates search form interaction in smoke mode and full submission with workbook upload in strict mode. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class ComponentLotSearchTests(PlaywrightFixture fixture) : SearchFlowTestBase(fixture) { + /// + /// Verifies the Component Lot search form submits with an uploaded workbook filter (TC-020). + /// + /// + /// Steps (smoke mode stops after step 4; strict mode runs all steps): + /// + /// Navigate to the search page. + /// Enter the search name "MIGRATED-TC-020". + /// Select the "Component Lot" search type from the dropdown. + /// Verify the dropdown displays the selected type. + /// Upload "single_lot.xlsx" to the "Filter By Component Lot" panel (strict only). + /// Click Submit (strict only). + /// Assert no error notification is present (strict only). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] - public Task ComponentLot_SubmitsWithUploadedWorkbook() => - RunSearchSubmissionAsync( + public Task ComponentLot_SubmitsWithUploadedWorkbook() + { + return RunSearchSubmissionAsync( UiSearchTypes.ComponentLot, "MIGRATED-TC-020", uploads: [ ("Filter By Component Lot", "single_lot.xlsx") ]); -} + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/DataSyncPageTests.cs b/NEW/tests/JdeScoping.Ui.Tests/DataSyncPageTests.cs index f23f303..b0b8786 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/DataSyncPageTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/DataSyncPageTests.cs @@ -3,8 +3,26 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI smoke tests for the Data Sync Requests page. +/// Validates that the page loads and shows action buttons or redirects to search. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class DataSyncPageTests(PlaywrightFixture fixture) : UiTestBase(fixture) { + /// + /// Verifies the Data Sync page loads at /data-sync/requests and displays action buttons. + /// + /// + /// Steps: + /// + /// Navigate to the Data Sync Requests page. + /// Assert the URL ends with /data-sync/requests or /search (redirect). + /// If on the data sync page, assert "Data Sync Requests" heading is visible. + /// Assert "New Request" or "Reload Pipelines" button is visible. + /// If redirected, assert "Search Details" is visible. + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] public async Task DataSync_Loads() @@ -12,23 +30,27 @@ public sealed class DataSyncPageTests(PlaywrightFixture fixture) : UiTestBase(fi await RunAsync(async page => { await UiNavigationHelper.NavigateToDataSyncAsync(page); - var url = page.Url; - var onDataSync = url.EndsWith("/data-sync/requests", StringComparison.OrdinalIgnoreCase); - var redirectedToSearch = url.EndsWith("/search", StringComparison.OrdinalIgnoreCase); + string url = page.Url; + bool onDataSync = url.EndsWith("/data-sync/requests", StringComparison.OrdinalIgnoreCase); + bool redirectedToSearch = url.EndsWith("/search", StringComparison.OrdinalIgnoreCase); Assert.True(onDataSync || redirectedToSearch, $"Unexpected URL: {url}"); if (onDataSync) { - await Assertions.Expect(page.GetByText("Data Sync Requests")).ToBeVisibleAsync(new() { Timeout = 15_000 }); - var newRequestButton = page.GetByRole(Microsoft.Playwright.AriaRole.Button, new() { Name = "New Request" }); - var reloadButton = page.GetByRole(Microsoft.Playwright.AriaRole.Button, new() { Name = "Reload Pipelines" }); - var hasAnyControl = await newRequestButton.IsVisibleAsync() || await reloadButton.IsVisibleAsync(); + await Assertions.Expect(page.GetByText("Data Sync Requests")) + .ToBeVisibleAsync(new LocatorAssertionsToBeVisibleOptions { Timeout = 15_000 }); + var newRequestButton = + page.GetByRole(AriaRole.Button, new PageGetByRoleOptions { Name = "New Request" }); + var reloadButton = + page.GetByRole(AriaRole.Button, new PageGetByRoleOptions { Name = "Reload Pipelines" }); + bool hasAnyControl = await newRequestButton.IsVisibleAsync() || await reloadButton.IsVisibleAsync(); Assert.True(hasAnyControl, "Expected Data Sync action buttons to be visible."); } else { - await Assertions.Expect(page.GetByText("Search Details")).ToBeVisibleAsync(new() { Timeout = 15_000 }); + await Assertions.Expect(page.GetByText("Search Details")) + .ToBeVisibleAsync(new LocatorAssertionsToBeVisibleOptions { Timeout = 15_000 }); } }); } -} +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/GlobalUsings.cs b/NEW/tests/JdeScoping.Ui.Tests/GlobalUsings.cs index 1a4e89f..e64e483 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/GlobalUsings.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/GlobalUsings.cs @@ -1,2 +1,2 @@ global using Xunit; -global using Microsoft.Playwright; +global using Microsoft.Playwright; \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/Helpers/UiAuthHelper.cs b/NEW/tests/JdeScoping.Ui.Tests/Helpers/UiAuthHelper.cs index fadc449..49292b4 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/Helpers/UiAuthHelper.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/Helpers/UiAuthHelper.cs @@ -1,5 +1,3 @@ -using Microsoft.Playwright; - namespace JdeScoping.Ui.Tests.Helpers; internal static class UiAuthHelper @@ -7,11 +5,8 @@ internal static class UiAuthHelper public static async Task LoginAsync(IPage page, string username = "testuser", string password = "testpass") { var loginForm = page.GetByText("Authentication Required"); - var formVisible = await loginForm.IsVisibleAsync(); - if (!formVisible) - { - return; - } + bool formVisible = await loginForm.IsVisibleAsync(); + if (!formVisible) return; await page.Locator("input[name='Username']").FillAsync(username); await page.Locator("input[name='Password']").FillAsync(password); @@ -25,15 +20,12 @@ internal static class UiAuthHelper if (await loginForm.IsVisibleAsync()) { var notifications = page.Locator(".rz-notification"); - var count = await notifications.CountAsync(); + int count = await notifications.CountAsync(); var details = new List(); for (var i = 0; i < count; i++) { - var text = (await notifications.Nth(i).InnerTextAsync()).Trim(); - if (!string.IsNullOrWhiteSpace(text)) - { - details.Add(text); - } + string text = (await notifications.Nth(i).InnerTextAsync()).Trim(); + if (!string.IsNullOrWhiteSpace(text)) details.Add(text); } throw new InvalidOperationException( @@ -50,4 +42,4 @@ internal static class UiAuthHelper await page.WaitForLoadStateAsync(LoadState.NetworkIdle); } } -} +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/Helpers/UiNavigationHelper.cs b/NEW/tests/JdeScoping.Ui.Tests/Helpers/UiNavigationHelper.cs index a114986..c0a4095 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/Helpers/UiNavigationHelper.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/Helpers/UiNavigationHelper.cs @@ -1,5 +1,3 @@ -using Microsoft.Playwright; - namespace JdeScoping.Ui.Tests.Helpers; internal static class UiNavigationHelper @@ -98,9 +96,7 @@ internal static class UiNavigationHelper { var meResponse = await page.Context.APIRequest.GetAsync("/api/auth/me"); if (meResponse.Status != 200) - { throw new InvalidOperationException( $"UI test host did not establish authenticated session after login. /api/auth/me status={meResponse.Status}."); - } } -} +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/Helpers/UiSearchFormHelper.cs b/NEW/tests/JdeScoping.Ui.Tests/Helpers/UiSearchFormHelper.cs index b5b75cc..3255fc1 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/Helpers/UiSearchFormHelper.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/Helpers/UiSearchFormHelper.cs @@ -1,5 +1,3 @@ -using Microsoft.Playwright; - namespace JdeScoping.Ui.Tests.Helpers; internal static class UiSearchFormHelper @@ -7,12 +5,15 @@ internal static class UiSearchFormHelper public static async Task SelectSearchTypeAsync(IPage page, string searchType) { await page.Locator(".rz-dropdown").First.ClickAsync(); - await page.GetByRole(AriaRole.Option, new PageGetByRoleOptions { Name = searchType, Exact = true }).ClickAsync(); + await page.GetByRole(AriaRole.Option, new PageGetByRoleOptions { Name = searchType, Exact = true }) + .ClickAsync(); await page.WaitForTimeoutAsync(500); } - public static Task EnterSearchNameAsync(IPage page, string name) => - page.Locator("input[placeholder=' ']").First.FillAsync(name); + public static Task EnterSearchNameAsync(IPage page, string name) + { + return page.Locator("input[placeholder=' ']").First.FillAsync(name); + } public static async Task SetDateRangeAsync(IPage page, string minimumMmDdYyyy, string maximumMmDdYyyy) { @@ -27,10 +28,7 @@ internal static class UiSearchFormHelper await page.WaitForTimeoutAsync(500); var listItem = page.Locator(".rz-autocomplete-list .rz-autocomplete-list-item").First; - if (await listItem.IsVisibleAsync()) - { - await listItem.ClickAsync(); - } + if (await listItem.IsVisibleAsync()) await listItem.ClickAsync(); await panel.GetByRole(AriaRole.Button, new LocatorGetByRoleOptions { Name = "Add" }).ClickAsync(); await page.WaitForTimeoutAsync(250); @@ -51,13 +49,15 @@ internal static class UiSearchFormHelper State = WaitForSelectorState.Visible, Timeout = 10_000 }); - await page.Locator(".rz-dialog-wrapper button").GetByText("Submit", new LocatorGetByTextOptions { Exact = true }).ClickAsync(); + await page.Locator(".rz-dialog-wrapper button") + .GetByText("Submit", new LocatorGetByTextOptions { Exact = true }).ClickAsync(); await page.WaitForTimeoutAsync(1_000); } public static async Task AssertNoErrorNotificationAsync(IPage page) { var error = page.Locator(".rz-notification-error"); - await Assertions.Expect(error).Not.ToBeVisibleAsync(new LocatorAssertionsToBeVisibleOptions { Timeout = 5_000 }); + await Assertions.Expect(error).Not + .ToBeVisibleAsync(new LocatorAssertionsToBeVisibleOptions { Timeout = 5_000 }); } -} +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/JdeScoping.Ui.Tests.csproj b/NEW/tests/JdeScoping.Ui.Tests/JdeScoping.Ui.Tests.csproj index 628efcd..21ddbca 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/JdeScoping.Ui.Tests.csproj +++ b/NEW/tests/JdeScoping.Ui.Tests/JdeScoping.Ui.Tests.csproj @@ -1,32 +1,32 @@ - - net10.0 - enable - enable - false - true - + + net10.0 + enable + enable + false + true + - - - - - - - - + + + + + + + + - - - + + + - - - + + + - - - + + + diff --git a/NEW/tests/JdeScoping.Ui.Tests/LoginPageTests.cs b/NEW/tests/JdeScoping.Ui.Tests/LoginPageTests.cs index d2b31ac..59ff8a8 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/LoginPageTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/LoginPageTests.cs @@ -1,11 +1,30 @@ +using System.Text.RegularExpressions; using JdeScoping.Ui.Tests.Helpers; using JdeScoping.Ui.Tests.Support; -using System.Text.RegularExpressions; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the Login page. +/// Validates that the login form renders, credentials are accepted, and logout revokes the session. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class LoginPageTests(PlaywrightFixture fixture) : UiTestBase(fixture) { + /// + /// Verifies the login page renders, credentials authenticate the user, and logout revokes the session. + /// + /// + /// Steps: + /// + /// Navigate to the login page. + /// Assert the page title contains "Login - JDE Scoping Tool". + /// Submit test credentials via UiAuthHelper.LoginAsync. + /// Assert the user sees the Logout button or remains on the login view. + /// Invoke UiAuthHelper.LogoutAsync. + /// GET /api/auth/me and assert HTTP 401 (session revoked). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] public async Task LoginPage_AllowsLoginAndLogout() @@ -17,9 +36,9 @@ public sealed class LoginPageTests(PlaywrightFixture fixture) : UiTestBase(fixtu await UiAuthHelper.LoginAsync(page); var loggedOutView = page.GetByText("Authentication Required"); - var logoutButton = page.GetByRole(Microsoft.Playwright.AriaRole.Button, new() { Name = "Logout" }); - var authenticated = await logoutButton.IsVisibleAsync(); - var stillOnLogin = await loggedOutView.IsVisibleAsync(); + var logoutButton = page.GetByRole(AriaRole.Button, new PageGetByRoleOptions { Name = "Logout" }); + bool authenticated = await logoutButton.IsVisibleAsync(); + bool stillOnLogin = await loggedOutView.IsVisibleAsync(); Assert.True(authenticated || stillOnLogin); await UiAuthHelper.LogoutAsync(page); @@ -27,4 +46,4 @@ public sealed class LoginPageTests(PlaywrightFixture fixture) : UiTestBase(fixtu Assert.Equal(401, meAfterLogout.Status); }); } -} +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/RefreshStatusPageTests.cs b/NEW/tests/JdeScoping.Ui.Tests/RefreshStatusPageTests.cs index c3e3dac..db4f0d9 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/RefreshStatusPageTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/RefreshStatusPageTests.cs @@ -3,8 +3,25 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI smoke tests for the Cache Refresh Status page. +/// Validates that the page loads and shows the "Cache Refresh Status" heading or redirects to search. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class RefreshStatusPageTests(PlaywrightFixture fixture) : UiTestBase(fixture) { + /// + /// Verifies the Refresh Status page loads at /refresh-status and displays the expected heading. + /// + /// + /// Steps: + /// + /// Navigate to the Refresh Status page. + /// Assert the URL ends with /refresh-status or /search (redirect). + /// If on the refresh page, assert "Cache Refresh Status" heading is visible. + /// If redirected, assert "Search Details" is visible. + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] public async Task RefreshStatus_Loads() @@ -12,19 +29,17 @@ public sealed class RefreshStatusPageTests(PlaywrightFixture fixture) : UiTestBa await RunAsync(async page => { await UiNavigationHelper.NavigateToRefreshStatusAsync(page); - var url = page.Url; - var onRefreshStatus = url.EndsWith("/refresh-status", StringComparison.OrdinalIgnoreCase); - var redirectedToSearch = url.EndsWith("/search", StringComparison.OrdinalIgnoreCase); + string url = page.Url; + bool onRefreshStatus = url.EndsWith("/refresh-status", StringComparison.OrdinalIgnoreCase); + bool redirectedToSearch = url.EndsWith("/search", StringComparison.OrdinalIgnoreCase); Assert.True(onRefreshStatus || redirectedToSearch, $"Unexpected URL: {url}"); if (onRefreshStatus) - { - await Assertions.Expect(page.GetByText("Cache Refresh Status")).ToBeVisibleAsync(new() { Timeout = 15_000 }); - } + await Assertions.Expect(page.GetByText("Cache Refresh Status")) + .ToBeVisibleAsync(new LocatorAssertionsToBeVisibleOptions { Timeout = 15_000 }); else - { - await Assertions.Expect(page.GetByText("Search Details")).ToBeVisibleAsync(new() { Timeout = 15_000 }); - } + await Assertions.Expect(page.GetByText("Search Details")) + .ToBeVisibleAsync(new LocatorAssertionsToBeVisibleOptions { Timeout = 15_000 }); }); } -} +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/SearchPageTests.cs b/NEW/tests/JdeScoping.Ui.Tests/SearchPageTests.cs index 0487bbd..5666fa6 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/SearchPageTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/SearchPageTests.cs @@ -3,8 +3,25 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI smoke tests for the Search page. +/// Validates that the search form loads with primary controls visible and no error notifications. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class SearchPageTests(PlaywrightFixture fixture) : UiTestBase(fixture) { + /// + /// Verifies the search page loads and displays the "Search Details" heading, Submit button, and no errors. + /// + /// + /// Steps: + /// + /// Navigate to the search page. + /// Assert the "Search Details" text is visible. + /// Assert the Submit button is visible. + /// Assert no error notification is present. + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] public async Task SearchPage_LoadsAndShowsPrimaryControls() @@ -13,8 +30,9 @@ public sealed class SearchPageTests(PlaywrightFixture fixture) : UiTestBase(fixt { await UiNavigationHelper.NavigateToSearchPageAsync(page); await Assertions.Expect(page.GetByText("Search Details")).ToBeVisibleAsync(); - await Assertions.Expect(page.GetByRole(Microsoft.Playwright.AriaRole.Button, new() { Name = "Submit" }).First).ToBeVisibleAsync(); + await Assertions.Expect(page.GetByRole(AriaRole.Button, new PageGetByRoleOptions { Name = "Submit" }).First) + .ToBeVisibleAsync(); await UiSearchFormHelper.AssertNoErrorNotificationAsync(page); }); } -} +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/SearchQueuePageTests.cs b/NEW/tests/JdeScoping.Ui.Tests/SearchQueuePageTests.cs index f18a1f1..09044bc 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/SearchQueuePageTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/SearchQueuePageTests.cs @@ -1,9 +1,27 @@ using JdeScoping.Ui.Tests.Helpers; using JdeScoping.Ui.Tests.Support; + namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI smoke tests for the Search Queue page. +/// Validates that the queue page loads and shows a data grid, alert, or loading indicator. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class SearchQueuePageTests(PlaywrightFixture fixture) : UiTestBase(fixture) { + /// + /// Verifies the Search Queue page loads at /search/queue and displays queue content or a redirect. + /// + /// + /// Steps: + /// + /// Navigate to the Search Queue page. + /// Assert the URL ends with /search/queue or /search (redirect). + /// If on the queue page, assert "Search Queue" heading and grid/alert/loading indicator are visible. + /// If redirected, assert "Search Details" is visible. + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] public async Task SearchQueue_Loads() @@ -11,23 +29,25 @@ public sealed class SearchQueuePageTests(PlaywrightFixture fixture) : UiTestBase await RunAsync(async page => { await UiNavigationHelper.NavigateToQueueAsync(page); - var url = page.Url; - var onQueue = url.EndsWith("/search/queue", StringComparison.OrdinalIgnoreCase); - var redirectedToSearch = url.EndsWith("/search", StringComparison.OrdinalIgnoreCase); + string url = page.Url; + bool onQueue = url.EndsWith("/search/queue", StringComparison.OrdinalIgnoreCase); + bool redirectedToSearch = url.EndsWith("/search", StringComparison.OrdinalIgnoreCase); Assert.True(onQueue || redirectedToSearch, $"Unexpected URL: {url}"); if (onQueue) { - await Assertions.Expect(page.GetByText("Search Queue")).ToBeVisibleAsync(new() { Timeout = 15_000 }); - var hasGrid = await page.Locator(".rz-data-grid").First.IsVisibleAsync(); - var hasAlert = await page.Locator(".rz-alert").First.IsVisibleAsync(); - var hasLoading = await page.GetByText("Loading queue").IsVisibleAsync(); + await Assertions.Expect(page.GetByText("Search Queue")) + .ToBeVisibleAsync(new LocatorAssertionsToBeVisibleOptions { Timeout = 15_000 }); + bool hasGrid = await page.Locator(".rz-data-grid").First.IsVisibleAsync(); + bool hasAlert = await page.Locator(".rz-alert").First.IsVisibleAsync(); + bool hasLoading = await page.GetByText("Loading queue").IsVisibleAsync(); Assert.True(hasGrid || hasAlert || hasLoading, "Expected queue grid, alert, or loading indicator."); } else { - await Assertions.Expect(page.GetByText("Search Details")).ToBeVisibleAsync(new() { Timeout = 15_000 }); + await Assertions.Expect(page.GetByText("Search Details")) + .ToBeVisibleAsync(new LocatorAssertionsToBeVisibleOptions { Timeout = 15_000 }); } }); } -} +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/SearchesDashboardPageTests.cs b/NEW/tests/JdeScoping.Ui.Tests/SearchesDashboardPageTests.cs index eefa37c..a60d5c1 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/SearchesDashboardPageTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/SearchesDashboardPageTests.cs @@ -3,8 +3,24 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI smoke tests for the Searches Dashboard page. +/// Validates that the dashboard loads at the expected URL and shows a heading or data grid. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class SearchesDashboardPageTests(PlaywrightFixture fixture) : UiTestBase(fixture) { + /// + /// Verifies the Searches Dashboard page loads at /searches and displays a heading or data grid. + /// + /// + /// Steps: + /// + /// Navigate to the Searches Dashboard page. + /// Assert the URL ends with /searches, /search, or /. + /// Assert that "Searches Dashboard", "Search Details", or the Radzen data grid is visible. + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] public async Task SearchesDashboard_Loads() @@ -12,17 +28,17 @@ public sealed class SearchesDashboardPageTests(PlaywrightFixture fixture) : UiTe await RunAsync(async page => { await UiNavigationHelper.NavigateToSearchesDashboardAsync(page); - var url = page.Url; + string url = page.Url; Assert.True( url.EndsWith("/searches", StringComparison.OrdinalIgnoreCase) || url.EndsWith("/search", StringComparison.OrdinalIgnoreCase) || url.EndsWith("/", StringComparison.OrdinalIgnoreCase), $"Unexpected URL: {url}"); - var hasSearchesHeading = await page.GetByText("Searches Dashboard").IsVisibleAsync(); - var hasSearchDetails = await page.GetByText("Search Details").IsVisibleAsync(); - var hasGrid = await page.Locator(".rz-data-grid").First.IsVisibleAsync(); + bool hasSearchesHeading = await page.GetByText("Searches Dashboard").IsVisibleAsync(); + bool hasSearchDetails = await page.GetByText("Search Details").IsVisibleAsync(); + bool hasGrid = await page.Locator(".rz-data-grid").First.IsVisibleAsync(); Assert.True(hasSearchesHeading || hasSearchDetails || hasGrid); }); } -} +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/Support/PlaywrightFixture.cs b/NEW/tests/JdeScoping.Ui.Tests/Support/PlaywrightFixture.cs index 6174dca..16f5948 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/Support/PlaywrightFixture.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/Support/PlaywrightFixture.cs @@ -1,17 +1,15 @@ -using Microsoft.Playwright; - namespace JdeScoping.Ui.Tests.Support; public sealed class PlaywrightFixture : IAsyncLifetime { - private IPlaywright? _playwright; private IBrowser? _browser; + private IPlaywright? _playwright; public IBrowser Browser => _browser ?? throw new InvalidOperationException("Browser is not initialized."); public async Task InitializeAsync() { - _playwright = await Microsoft.Playwright.Playwright.CreateAsync(); + _playwright = await Playwright.CreateAsync(); _browser = await _playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions { Headless = UiTestSettings.Headless, @@ -21,11 +19,8 @@ public sealed class PlaywrightFixture : IAsyncLifetime public async Task DisposeAsync() { - if (_browser is not null) - { - await _browser.CloseAsync(); - } + if (_browser is not null) await _browser.CloseAsync(); _playwright?.Dispose(); } -} +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/Support/SearchFlowTestBase.cs b/NEW/tests/JdeScoping.Ui.Tests/Support/SearchFlowTestBase.cs index 22e3f53..238d4ad 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/Support/SearchFlowTestBase.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/Support/SearchFlowTestBase.cs @@ -5,7 +5,8 @@ namespace JdeScoping.Ui.Tests.Support; public abstract class SearchFlowTestBase(PlaywrightFixture fixture) : UiTestBase(fixture) { private static bool StrictMode => - string.Equals(Environment.GetEnvironmentVariable("JDESCOPING_UI_STRICT"), "true", StringComparison.OrdinalIgnoreCase); + string.Equals(Environment.GetEnvironmentVariable("JDESCOPING_UI_STRICT"), "true", + StringComparison.OrdinalIgnoreCase); protected Task RunSearchSubmissionAsync( string searchType, @@ -23,34 +24,23 @@ public abstract class SearchFlowTestBase(PlaywrightFixture fixture) : UiTestBase await Assertions.Expect(page.Locator(".rz-dropdown-label").First).ToContainTextAsync(searchType); if (!StrictMode) - { // Default mode is smoke-only against local docker where source systems can be offline. return; - } if (!string.IsNullOrWhiteSpace(minDate) && !string.IsNullOrWhiteSpace(maxDate)) - { await UiSearchFormHelper.SetDateRangeAsync(page, minDate, maxDate); - } if (autocompleteItems is not null) - { foreach (var item in autocompleteItems) - { await UiSearchFormHelper.AddAutocompleteItemAsync(page, item.PanelHeader, item.Value); - } - } if (uploads is not null) - { foreach (var upload in uploads) - { - await UiSearchFormHelper.UploadFileAsync(page, upload.PanelHeader, TestDataPaths.Get(upload.FileName)); - } - } + await UiSearchFormHelper.UploadFileAsync(page, upload.PanelHeader, + TestDataPaths.Get(upload.FileName)); await UiSearchFormHelper.SubmitSearchAsync(page); await UiSearchFormHelper.AssertNoErrorNotificationAsync(page); }); } -} +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/Support/TestDataPaths.cs b/NEW/tests/JdeScoping.Ui.Tests/Support/TestDataPaths.cs index 14ce098..2792581 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/Support/TestDataPaths.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/Support/TestDataPaths.cs @@ -2,5 +2,8 @@ namespace JdeScoping.Ui.Tests.Support; internal static class TestDataPaths { - public static string Get(string fileName) => Path.Combine(AppContext.BaseDirectory, "TestData", fileName); -} + public static string Get(string fileName) + { + return Path.Combine(AppContext.BaseDirectory, "TestData", fileName); + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/Support/UiSearchTypes.cs b/NEW/tests/JdeScoping.Ui.Tests/Support/UiSearchTypes.cs index 3e239f2..5f6c4fe 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/Support/UiSearchTypes.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/Support/UiSearchTypes.cs @@ -18,4 +18,4 @@ internal static class UiSearchTypes public const string TimeSpanItem = "Time Span + Item Number"; public const string TimeSpanWcOperator = "Time Span + Work Center + Operator"; public const string TimeSpanPcOperator = "Time Span + Profit Center + Operator"; -} +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/Support/UiTestBase.cs b/NEW/tests/JdeScoping.Ui.Tests/Support/UiTestBase.cs index e43c9c2..57455a1 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/Support/UiTestBase.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/Support/UiTestBase.cs @@ -1,5 +1,3 @@ -using Microsoft.Playwright; - namespace JdeScoping.Ui.Tests.Support; [Collection(UiTestCollection.Name)] @@ -26,4 +24,4 @@ public abstract class UiTestBase await action(page); } -} +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/Support/UiTestCollection.cs b/NEW/tests/JdeScoping.Ui.Tests/Support/UiTestCollection.cs index 96ff60b..3b2a49c 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/Support/UiTestCollection.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/Support/UiTestCollection.cs @@ -1,9 +1,7 @@ -using Xunit; - namespace JdeScoping.Ui.Tests.Support; [CollectionDefinition(Name)] public sealed class UiTestCollection : ICollectionFixture { public const string Name = "UiTests"; -} +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/Support/UiTestSettings.cs b/NEW/tests/JdeScoping.Ui.Tests/Support/UiTestSettings.cs index 810f98f..3adfb0b 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/Support/UiTestSettings.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/Support/UiTestSettings.cs @@ -7,5 +7,6 @@ internal static class UiTestSettings ?? "http://localhost:5294"; public static bool Headless => - !string.Equals(Environment.GetEnvironmentVariable("JDESCOPING_UI_HEADED"), "true", StringComparison.OrdinalIgnoreCase); -} + !string.Equals(Environment.GetEnvironmentVariable("JDESCOPING_UI_HEADED"), "true", + StringComparison.OrdinalIgnoreCase); +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/TestData/test-data.json b/NEW/tests/JdeScoping.Ui.Tests/TestData/test-data.json index fa3e836..132ce5e 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/TestData/test-data.json +++ b/NEW/tests/JdeScoping.Ui.Tests/TestData/test-data.json @@ -1,60 +1,195 @@ { "profitCenters": [ - { "code": "1AM", "description": "Profit Center 1AM" }, - { "code": "1BM", "description": "Profit Center 1BM" }, - { "code": "1CM", "description": "Profit Center 1CM" }, - { "code": "1PM", "description": "Profit Center 1PM" }, - { "code": "2DM", "description": "Profit Center 2DM" }, - { "code": "2SM", "description": "Profit Center 2SM" }, - { "code": "3TM", "description": "Profit Center 3TM" }, - { "code": "4IM", "description": "Profit Center 4IM" }, - { "code": "5SM", "description": "Profit Center 5SM" } + { + "code": "1AM", + "description": "Profit Center 1AM" + }, + { + "code": "1BM", + "description": "Profit Center 1BM" + }, + { + "code": "1CM", + "description": "Profit Center 1CM" + }, + { + "code": "1PM", + "description": "Profit Center 1PM" + }, + { + "code": "2DM", + "description": "Profit Center 2DM" + }, + { + "code": "2SM", + "description": "Profit Center 2SM" + }, + { + "code": "3TM", + "description": "Profit Center 3TM" + }, + { + "code": "4IM", + "description": "Profit Center 4IM" + }, + { + "code": "5SM", + "description": "Profit Center 5SM" + } ], "workCenters": [ - { "code": "WC001", "description": "Work Center 001" }, - { "code": "WC002", "description": "Work Center 002" }, - { "code": "WC003", "description": "Work Center 003" } + { + "code": "WC001", + "description": "Work Center 001" + }, + { + "code": "WC002", + "description": "Work Center 002" + }, + { + "code": "WC003", + "description": "Work Center 003" + } ], "operators": [ - { "userId": "ADAMSSN", "fullName": "Adams, S N" }, - { "userId": "AGNEWA", "fullName": "Agnew, A" }, - { "userId": "AGNEWL", "fullName": "Agnew, L" }, - { "userId": "ALASMARB", "fullName": "Alasmar, B" }, - { "userId": "ALEXIUCG", "fullName": "Alexiuc, G" }, - { "userId": "ALLENHY", "fullName": "Allen, H Y" }, - { "userId": "ALLENNI", "fullName": "Allen, N I" }, - { "userId": "ALURUM", "fullName": "Aluru, M" }, - { "userId": "ALVESM1", "fullName": "Alves, M" }, - { "userId": "APONTEVE", "fullName": "Aponte, V E" } + { + "userId": "ADAMSSN", + "fullName": "Adams, S N" + }, + { + "userId": "AGNEWA", + "fullName": "Agnew, A" + }, + { + "userId": "AGNEWL", + "fullName": "Agnew, L" + }, + { + "userId": "ALASMARB", + "fullName": "Alasmar, B" + }, + { + "userId": "ALEXIUCG", + "fullName": "Alexiuc, G" + }, + { + "userId": "ALLENHY", + "fullName": "Allen, H Y" + }, + { + "userId": "ALLENNI", + "fullName": "Allen, N I" + }, + { + "userId": "ALURUM", + "fullName": "Aluru, M" + }, + { + "userId": "ALVESM1", + "fullName": "Alves, M" + }, + { + "userId": "APONTEVE", + "fullName": "Aponte, V E" + } ], "workOrders": [ - { "workOrderNumber": "99059700", "itemNumber": "00598004702" }, - { "workOrderNumber": "99002260", "itemNumber": "82070000028" }, - { "workOrderNumber": "99002259", "itemNumber": "82070000027" }, - { "workOrderNumber": "99002258", "itemNumber": "82070000019" }, - { "workOrderNumber": "99002257", "itemNumber": "82070000018" }, - { "workOrderNumber": "99002256", "itemNumber": "82070000017" }, - { "workOrderNumber": "99002255", "itemNumber": "00855140333" }, - { "workOrderNumber": "99002254", "itemNumber": "00855480834" }, - { "workOrderNumber": "99002252", "itemNumber": "82070000016" }, - { "workOrderNumber": "99002251", "itemNumber": "00855910448" }, - { "workOrderNumber": "99002250", "itemNumber": "82070000015" }, - { "workOrderNumber": "99002249", "itemNumber": "00855480834" }, - { "workOrderNumber": "99002248", "itemNumber": "00855910446" }, - { "workOrderNumber": "99002247", "itemNumber": "00855910447" }, - { "workOrderNumber": "99002246", "itemNumber": "82900171601" } + { + "workOrderNumber": "99059700", + "itemNumber": "00598004702" + }, + { + "workOrderNumber": "99002260", + "itemNumber": "82070000028" + }, + { + "workOrderNumber": "99002259", + "itemNumber": "82070000027" + }, + { + "workOrderNumber": "99002258", + "itemNumber": "82070000019" + }, + { + "workOrderNumber": "99002257", + "itemNumber": "82070000018" + }, + { + "workOrderNumber": "99002256", + "itemNumber": "82070000017" + }, + { + "workOrderNumber": "99002255", + "itemNumber": "00855140333" + }, + { + "workOrderNumber": "99002254", + "itemNumber": "00855480834" + }, + { + "workOrderNumber": "99002252", + "itemNumber": "82070000016" + }, + { + "workOrderNumber": "99002251", + "itemNumber": "00855910448" + }, + { + "workOrderNumber": "99002250", + "itemNumber": "82070000015" + }, + { + "workOrderNumber": "99002249", + "itemNumber": "00855480834" + }, + { + "workOrderNumber": "99002248", + "itemNumber": "00855910446" + }, + { + "workOrderNumber": "99002247", + "itemNumber": "00855910447" + }, + { + "workOrderNumber": "99002246", + "itemNumber": "82900171601" + } ], "itemNumbers": [ - { "itemNumber": "00598004702", "description": "Item 598004702" }, - { "itemNumber": "82070000028", "description": "Item 82070000028" }, - { "itemNumber": "82070000027", "description": "Item 82070000027" }, - { "itemNumber": "00855140333", "description": "Item 855140333" }, - { "itemNumber": "00855480834", "description": "Item 855480834" } + { + "itemNumber": "00598004702", + "description": "Item 598004702" + }, + { + "itemNumber": "82070000028", + "description": "Item 82070000028" + }, + { + "itemNumber": "82070000027", + "description": "Item 82070000027" + }, + { + "itemNumber": "00855140333", + "description": "Item 855140333" + }, + { + "itemNumber": "00855480834", + "description": "Item 855480834" + } ], "componentLots": [ - { "lotNumber": "LOT001", "itemNumber": "00598004702" }, - { "lotNumber": "LOT002", "itemNumber": "82070000028" }, - { "lotNumber": "LOT003", "itemNumber": "82070000027" } + { + "lotNumber": "LOT001", + "itemNumber": "00598004702" + }, + { + "lotNumber": "LOT002", + "itemNumber": "82070000028" + }, + { + "lotNumber": "LOT003", + "itemNumber": "82070000027" + } ], "partOperations": [ { diff --git a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanItemNumberSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanItemNumberSearchTests.cs index 45a9acb..7b2cd26 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanItemNumberSearchTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanItemNumberSearchTests.cs @@ -2,12 +2,34 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the "Time Span + Item Number" search type (TC-140). +/// Validates search form interaction in smoke mode and full submission with workbook upload in strict mode. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class TimeSpanItemNumberSearchTests(PlaywrightFixture fixture) : SearchFlowTestBase(fixture) { + /// + /// Verifies the Time Span + Item Number search form submits with an uploaded workbook filter (TC-140). + /// + /// + /// Steps (smoke mode stops after step 4; strict mode runs all steps): + /// + /// Navigate to the search page. + /// Enter the search name "MIGRATED-TC-140". + /// Select the "Time Span + Item Number" search type from the dropdown. + /// Verify the dropdown displays the selected type. + /// Set the date range to 01/01/2019 – 12/31/2019 (strict only). + /// Upload "single_item.xlsx" to the "Filter by Item Number" panel (strict only). + /// Click Submit (strict only). + /// Assert no error notification is present (strict only). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] - public Task TimeSpanItemNumber_Submits() => - RunSearchSubmissionAsync( + public Task TimeSpanItemNumber_Submits() + { + return RunSearchSubmissionAsync( UiSearchTypes.TimeSpanItem, "MIGRATED-TC-140", "01/01/2019", @@ -16,4 +38,5 @@ public sealed class TimeSpanItemNumberSearchTests(PlaywrightFixture fixture) : S [ ("Filter by Item Number", "single_item.xlsx") ]); -} + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanOperatorSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanOperatorSearchTests.cs index 1e5b413..f236957 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanOperatorSearchTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanOperatorSearchTests.cs @@ -2,12 +2,34 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the "Time Span + Operator" search type (TC-050). +/// Validates search form interaction in smoke mode and full submission in strict mode. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class TimeSpanOperatorSearchTests(PlaywrightFixture fixture) : SearchFlowTestBase(fixture) { + /// + /// Verifies the Time Span + Operator search form submits with autocomplete filter (TC-050). + /// + /// + /// Steps (smoke mode stops after step 4; strict mode runs all steps): + /// + /// Navigate to the search page. + /// Enter the search name "MIGRATED-TC-050". + /// Select the "Time Span + Operator" search type from the dropdown. + /// Verify the dropdown displays the selected type. + /// Set the date range to 01/01/2019 – 12/31/2019 (strict only). + /// Add autocomplete value "ADAMSSN" to the "Filter by Operator" panel (strict only). + /// Click Submit (strict only). + /// Assert no error notification is present (strict only). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] - public Task TimeSpanOperator_Submits() => - RunSearchSubmissionAsync( + public Task TimeSpanOperator_Submits() + { + return RunSearchSubmissionAsync( UiSearchTypes.TimeSpanOperator, "MIGRATED-TC-050", "01/01/2019", @@ -15,4 +37,5 @@ public sealed class TimeSpanOperatorSearchTests(PlaywrightFixture fixture) : Sea [ ("Filter by Operator", "ADAMSSN") ]); -} + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcExtractMisSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcExtractMisSearchTests.cs index ca49567..8eb476a 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcExtractMisSearchTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcExtractMisSearchTests.cs @@ -2,12 +2,34 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the "Time Span + Profit Center + Extract MIS" search type (TC-090). +/// Validates search form interaction in smoke mode and full submission in strict mode. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class TimeSpanPcExtractMisSearchTests(PlaywrightFixture fixture) : SearchFlowTestBase(fixture) { + /// + /// Verifies the Time Span + Profit Center + Extract MIS search form submits with autocomplete filter (TC-090). + /// + /// + /// Steps (smoke mode stops after step 4; strict mode runs all steps): + /// + /// Navigate to the search page. + /// Enter the search name "MIGRATED-TC-090". + /// Select the "Time Span + Profit Center + Extract MIS" search type from the dropdown. + /// Verify the dropdown displays the selected type. + /// Set the date range to 01/01/2019 – 12/31/2019 (strict only). + /// Add autocomplete value "1AM" to the "Filter by Profit Center" panel (strict only). + /// Click Submit (strict only). + /// Assert no error notification is present (strict only). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] - public Task TimeSpanPcExtractMis_Submits() => - RunSearchSubmissionAsync( + public Task TimeSpanPcExtractMis_Submits() + { + return RunSearchSubmissionAsync( UiSearchTypes.TimeSpanPcExtractMis, "MIGRATED-TC-090", "01/01/2019", @@ -15,4 +37,5 @@ public sealed class TimeSpanPcExtractMisSearchTests(PlaywrightFixture fixture) : [ ("Filter by Profit Center", "1AM") ]); -} + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcItemSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcItemSearchTests.cs index 37316c4..291237b 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcItemSearchTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcItemSearchTests.cs @@ -2,12 +2,35 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the "Time Span + Profit Center + Item Number" search type (TC-060). +/// Validates search form interaction in smoke mode and full submission in strict mode. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class TimeSpanPcItemSearchTests(PlaywrightFixture fixture) : SearchFlowTestBase(fixture) { + /// + /// Verifies the Time Span + Profit Center + Item Number search form submits with autocomplete and upload (TC-060). + /// + /// + /// Steps (smoke mode stops after step 4; strict mode runs all steps): + /// + /// Navigate to the search page. + /// Enter the search name "MIGRATED-TC-060". + /// Select the "Time Span + Profit Center + Item Number" search type from the dropdown. + /// Verify the dropdown displays the selected type. + /// Set the date range to 01/01/2019 – 12/31/2019 (strict only). + /// Add autocomplete value "1AM" to the "Filter by Profit Center" panel (strict only). + /// Upload "single_item.xlsx" to the "Filter by Item Number" panel (strict only). + /// Click Submit (strict only). + /// Assert no error notification is present (strict only). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] - public Task TimeSpanPcItem_Submits() => - RunSearchSubmissionAsync( + public Task TimeSpanPcItem_Submits() + { + return RunSearchSubmissionAsync( UiSearchTypes.TimeSpanPcItem, "MIGRATED-TC-060", "01/01/2019", @@ -18,4 +41,5 @@ public sealed class TimeSpanPcItemSearchTests(PlaywrightFixture fixture) : Searc [ ("Filter by Item Number", "single_item.xlsx") ]); -} + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcOperatorSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcOperatorSearchTests.cs index c9bc793..80bd56b 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcOperatorSearchTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcOperatorSearchTests.cs @@ -2,12 +2,35 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the "Time Span + Profit Center + Operator" search type (TC-160). +/// Validates search form interaction in smoke mode and full submission in strict mode. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class TimeSpanPcOperatorSearchTests(PlaywrightFixture fixture) : SearchFlowTestBase(fixture) { + /// + /// Verifies the Time Span + Profit Center + Operator search form submits with autocomplete filters (TC-160). + /// + /// + /// Steps (smoke mode stops after step 4; strict mode runs all steps): + /// + /// Navigate to the search page. + /// Enter the search name "MIGRATED-TC-160". + /// Select the "Time Span + Profit Center + Operator" search type from the dropdown. + /// Verify the dropdown displays the selected type. + /// Set the date range to 01/01/2019 – 12/31/2019 (strict only). + /// Add autocomplete value "1AM" to the "Filter by Profit Center" panel (strict only). + /// Add autocomplete value "ADAMSSN" to the "Filter by Operator" panel (strict only). + /// Click Submit (strict only). + /// Assert no error notification is present (strict only). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] - public Task TimeSpanPcOperator_Submits() => - RunSearchSubmissionAsync( + public Task TimeSpanPcOperator_Submits() + { + return RunSearchSubmissionAsync( UiSearchTypes.TimeSpanPcOperator, "MIGRATED-TC-160", "01/01/2019", @@ -16,4 +39,5 @@ public sealed class TimeSpanPcOperatorSearchTests(PlaywrightFixture fixture) : S ("Filter by Profit Center", "1AM"), ("Filter by Operator", "ADAMSSN") ]); -} + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcPartOpSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcPartOpSearchTests.cs index 604309a..6fb40f5 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcPartOpSearchTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcPartOpSearchTests.cs @@ -2,12 +2,35 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the "Time Span + Profit Center + Item/Operation/MIS" search type (TC-070). +/// Validates search form interaction in smoke mode and full submission in strict mode. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class TimeSpanPcPartOpSearchTests(PlaywrightFixture fixture) : SearchFlowTestBase(fixture) { + /// + /// Verifies the Time Span + Profit Center + Item/Operation/MIS search form submits with autocomplete and upload (TC-070). + /// + /// + /// Steps (smoke mode stops after step 4; strict mode runs all steps): + /// + /// Navigate to the search page. + /// Enter the search name "MIGRATED-TC-070". + /// Select the "Time Span + Profit Center + Item/Operation/MIS" search type from the dropdown. + /// Verify the dropdown displays the selected type. + /// Set the date range to 01/01/2019 – 12/31/2019 (strict only). + /// Add autocomplete value "1AM" to the "Filter by Profit Center" panel (strict only). + /// Upload "single_operation.xlsx" to the "Filter By Item/Operation/MIS" panel (strict only). + /// Click Submit (strict only). + /// Assert no error notification is present (strict only). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] - public Task TimeSpanPcPartOp_Submits() => - RunSearchSubmissionAsync( + public Task TimeSpanPcPartOp_Submits() + { + return RunSearchSubmissionAsync( UiSearchTypes.TimeSpanPcPartOp, "MIGRATED-TC-070", "01/01/2019", @@ -18,4 +41,5 @@ public sealed class TimeSpanPcPartOpSearchTests(PlaywrightFixture fixture) : Sea [ ("Filter By Item/Operation/MIS", "single_operation.xlsx") ]); -} + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcWoPartOpSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcWoPartOpSearchTests.cs index 2abce56..0d3dcd9 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcWoPartOpSearchTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcWoPartOpSearchTests.cs @@ -2,12 +2,36 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the "Time Span + Profit Center + Work Order + Item/Operation/MIS" search type (TC-080). +/// Validates search form interaction in smoke mode and full submission in strict mode. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class TimeSpanPcWoPartOpSearchTests(PlaywrightFixture fixture) : SearchFlowTestBase(fixture) { + /// + /// Verifies the Time Span + PC + Work Order + Item/Op/MIS search form submits with autocomplete and uploads (TC-080). + /// + /// + /// Steps (smoke mode stops after step 4; strict mode runs all steps): + /// + /// Navigate to the search page. + /// Enter the search name "MIGRATED-TC-080". + /// Select the "Time Span + Profit Center + Work Order + Item/Operation/MIS" search type from the dropdown. + /// Verify the dropdown displays the selected type. + /// Set the date range to 01/01/2019 – 12/31/2019 (strict only). + /// Add autocomplete value "1AM" to the "Filter by Profit Center" panel (strict only). + /// Upload "single_workorder.xlsx" to the "Filter by Work Order" panel (strict only). + /// Upload "single_operation.xlsx" to the "Filter By Item/Operation/MIS" panel (strict only). + /// Click Submit (strict only). + /// Assert no error notification is present (strict only). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] - public Task TimeSpanPcWoPartOp_Submits() => - RunSearchSubmissionAsync( + public Task TimeSpanPcWoPartOp_Submits() + { + return RunSearchSubmissionAsync( UiSearchTypes.TimeSpanPcWoPartOp, "MIGRATED-TC-080", "01/01/2019", @@ -19,4 +43,5 @@ public sealed class TimeSpanPcWoPartOpSearchTests(PlaywrightFixture fixture) : S ("Filter by Work Order", "single_workorder.xlsx"), ("Filter By Item/Operation/MIS", "single_operation.xlsx") ]); -} + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanProfitCenterSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanProfitCenterSearchTests.cs index dfebe4b..36dce2f 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanProfitCenterSearchTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanProfitCenterSearchTests.cs @@ -2,12 +2,34 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the "Time Span + Profit Center" search type (TC-030). +/// Validates search form interaction in smoke mode and full submission in strict mode. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class TimeSpanProfitCenterSearchTests(PlaywrightFixture fixture) : SearchFlowTestBase(fixture) { + /// + /// Verifies the Time Span + Profit Center search form submits with autocomplete filter (TC-030). + /// + /// + /// Steps (smoke mode stops after step 4; strict mode runs all steps): + /// + /// Navigate to the search page. + /// Enter the search name "MIGRATED-TC-030". + /// Select the "Time Span + Profit Center" search type from the dropdown. + /// Verify the dropdown displays the selected type. + /// Set the date range to 01/01/2019 – 12/31/2019 (strict only). + /// Add autocomplete value "1AM" to the "Filter by Profit Center" panel (strict only). + /// Click Submit (strict only). + /// Assert no error notification is present (strict only). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] - public Task TimeSpanProfitCenter_Submits() => - RunSearchSubmissionAsync( + public Task TimeSpanProfitCenter_Submits() + { + return RunSearchSubmissionAsync( UiSearchTypes.TimeSpanProfitCenter, "MIGRATED-TC-030", "01/01/2019", @@ -15,4 +37,5 @@ public sealed class TimeSpanProfitCenterSearchTests(PlaywrightFixture fixture) : [ ("Filter by Profit Center", "1AM") ]); -} + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcExtractMisSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcExtractMisSearchTests.cs index ea92150..efe7a5d 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcExtractMisSearchTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcExtractMisSearchTests.cs @@ -2,12 +2,34 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the "Time Span + Work Center + Extract MIS" search type (TC-110). +/// Validates search form interaction in smoke mode and full submission in strict mode. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class TimeSpanWcExtractMisSearchTests(PlaywrightFixture fixture) : SearchFlowTestBase(fixture) { + /// + /// Verifies the Time Span + Work Center + Extract MIS search form submits with autocomplete filter (TC-110). + /// + /// + /// Steps (smoke mode stops after step 4; strict mode runs all steps): + /// + /// Navigate to the search page. + /// Enter the search name "MIGRATED-TC-110". + /// Select the "Time Span + Work Center + Extract MIS" search type from the dropdown. + /// Verify the dropdown displays the selected type. + /// Set the date range to 01/01/2019 – 12/31/2019 (strict only). + /// Add autocomplete value "0083AS" to the "Filter by Work Center" panel (strict only). + /// Click Submit (strict only). + /// Assert no error notification is present (strict only). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] - public Task TimeSpanWcExtractMis_Submits() => - RunSearchSubmissionAsync( + public Task TimeSpanWcExtractMis_Submits() + { + return RunSearchSubmissionAsync( UiSearchTypes.TimeSpanWcExtractMis, "MIGRATED-TC-110", "01/01/2019", @@ -15,4 +37,5 @@ public sealed class TimeSpanWcExtractMisSearchTests(PlaywrightFixture fixture) : [ ("Filter by Work Center", "0083AS") ]); -} + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcItemSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcItemSearchTests.cs index ef4c8ab..81366b4 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcItemSearchTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcItemSearchTests.cs @@ -2,12 +2,35 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the "Time Span + Work Center + Item Number" search type (TC-100). +/// Validates search form interaction in smoke mode and full submission in strict mode. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class TimeSpanWcItemSearchTests(PlaywrightFixture fixture) : SearchFlowTestBase(fixture) { + /// + /// Verifies the Time Span + Work Center + Item Number search form submits with autocomplete and upload (TC-100). + /// + /// + /// Steps (smoke mode stops after step 4; strict mode runs all steps): + /// + /// Navigate to the search page. + /// Enter the search name "MIGRATED-TC-100". + /// Select the "Time Span + Work Center + Item Number" search type from the dropdown. + /// Verify the dropdown displays the selected type. + /// Set the date range to 01/01/2019 – 12/31/2019 (strict only). + /// Add autocomplete value "0083AS" to the "Filter by Work Center" panel (strict only). + /// Upload "single_item.xlsx" to the "Filter by Item Number" panel (strict only). + /// Click Submit (strict only). + /// Assert no error notification is present (strict only). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] - public Task TimeSpanWcItem_Submits() => - RunSearchSubmissionAsync( + public Task TimeSpanWcItem_Submits() + { + return RunSearchSubmissionAsync( UiSearchTypes.TimeSpanWcItem, "MIGRATED-TC-100", "01/01/2019", @@ -18,4 +41,5 @@ public sealed class TimeSpanWcItemSearchTests(PlaywrightFixture fixture) : Searc [ ("Filter by Item Number", "single_item.xlsx") ]); -} + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcOperatorSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcOperatorSearchTests.cs index c7b7f1c..c2135cd 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcOperatorSearchTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcOperatorSearchTests.cs @@ -2,12 +2,35 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the "Time Span + Work Center + Operator" search type (TC-150). +/// Validates search form interaction in smoke mode and full submission in strict mode. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class TimeSpanWcOperatorSearchTests(PlaywrightFixture fixture) : SearchFlowTestBase(fixture) { + /// + /// Verifies the Time Span + Work Center + Operator search form submits with autocomplete filters (TC-150). + /// + /// + /// Steps (smoke mode stops after step 4; strict mode runs all steps): + /// + /// Navigate to the search page. + /// Enter the search name "MIGRATED-TC-150". + /// Select the "Time Span + Work Center + Operator" search type from the dropdown. + /// Verify the dropdown displays the selected type. + /// Set the date range to 01/01/2019 – 12/31/2019 (strict only). + /// Add autocomplete value "0083AS" to the "Filter by Work Center" panel (strict only). + /// Add autocomplete value "ADAMSSN" to the "Filter by Operator" panel (strict only). + /// Click Submit (strict only). + /// Assert no error notification is present (strict only). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] - public Task TimeSpanWcOperator_Submits() => - RunSearchSubmissionAsync( + public Task TimeSpanWcOperator_Submits() + { + return RunSearchSubmissionAsync( UiSearchTypes.TimeSpanWcOperator, "MIGRATED-TC-150", "01/01/2019", @@ -16,4 +39,5 @@ public sealed class TimeSpanWcOperatorSearchTests(PlaywrightFixture fixture) : S ("Filter by Work Center", "0083AS"), ("Filter by Operator", "ADAMSSN") ]); -} + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcPartOpSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcPartOpSearchTests.cs index 41d638f..693270c 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcPartOpSearchTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcPartOpSearchTests.cs @@ -2,12 +2,35 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the "Time Span + Work Center + Item/Operation/MIS" search type (TC-120). +/// Validates search form interaction in smoke mode and full submission in strict mode. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class TimeSpanWcPartOpSearchTests(PlaywrightFixture fixture) : SearchFlowTestBase(fixture) { + /// + /// Verifies the Time Span + Work Center + Item/Operation/MIS search form submits with autocomplete and upload (TC-120). + /// + /// + /// Steps (smoke mode stops after step 4; strict mode runs all steps): + /// + /// Navigate to the search page. + /// Enter the search name "MIGRATED-TC-120". + /// Select the "Time Span + Work Center + Item/Operation/MIS" search type from the dropdown. + /// Verify the dropdown displays the selected type. + /// Set the date range to 01/01/2019 – 12/31/2019 (strict only). + /// Add autocomplete value "0083AS" to the "Filter by Work Center" panel (strict only). + /// Upload "single_operation.xlsx" to the "Filter By Item/Operation/MIS" panel (strict only). + /// Click Submit (strict only). + /// Assert no error notification is present (strict only). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] - public Task TimeSpanWcPartOp_Submits() => - RunSearchSubmissionAsync( + public Task TimeSpanWcPartOp_Submits() + { + return RunSearchSubmissionAsync( UiSearchTypes.TimeSpanWcPartOp, "MIGRATED-TC-120", "01/01/2019", @@ -18,4 +41,5 @@ public sealed class TimeSpanWcPartOpSearchTests(PlaywrightFixture fixture) : Sea [ ("Filter By Item/Operation/MIS", "single_operation.xlsx") ]); -} + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcWoPartOpSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcWoPartOpSearchTests.cs index cd6dc95..7b616c5 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcWoPartOpSearchTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcWoPartOpSearchTests.cs @@ -2,12 +2,36 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the "Time Span + Work Center + Work Order + Item/Operation/MIS" search type (TC-130). +/// Validates search form interaction in smoke mode and full submission in strict mode. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class TimeSpanWcWoPartOpSearchTests(PlaywrightFixture fixture) : SearchFlowTestBase(fixture) { + /// + /// Verifies the Time Span + WC + Work Order + Item/Op/MIS search form submits with autocomplete and uploads (TC-130). + /// + /// + /// Steps (smoke mode stops after step 4; strict mode runs all steps): + /// + /// Navigate to the search page. + /// Enter the search name "MIGRATED-TC-130". + /// Select the "Time Span + Work Center + Work Order + Item/Operation/MIS" search type from the dropdown. + /// Verify the dropdown displays the selected type. + /// Set the date range to 01/01/2019 – 12/31/2019 (strict only). + /// Add autocomplete value "0083AS" to the "Filter by Work Center" panel (strict only). + /// Upload "single_workorder.xlsx" to the "Filter by Work Order" panel (strict only). + /// Upload "single_operation.xlsx" to the "Filter By Item/Operation/MIS" panel (strict only). + /// Click Submit (strict only). + /// Assert no error notification is present (strict only). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] - public Task TimeSpanWcWoPartOp_Submits() => - RunSearchSubmissionAsync( + public Task TimeSpanWcWoPartOp_Submits() + { + return RunSearchSubmissionAsync( UiSearchTypes.TimeSpanWcWoPartOp, "MIGRATED-TC-130", "01/01/2019", @@ -19,4 +43,5 @@ public sealed class TimeSpanWcWoPartOpSearchTests(PlaywrightFixture fixture) : S ("Filter by Work Order", "single_workorder.xlsx"), ("Filter By Item/Operation/MIS", "single_operation.xlsx") ]); -} + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWorkCenterSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWorkCenterSearchTests.cs index a255ffa..0999a11 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWorkCenterSearchTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWorkCenterSearchTests.cs @@ -2,12 +2,34 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the "Time Span + Work Center" search type (TC-040). +/// Validates search form interaction in smoke mode and full submission in strict mode. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class TimeSpanWorkCenterSearchTests(PlaywrightFixture fixture) : SearchFlowTestBase(fixture) { + /// + /// Verifies the Time Span + Work Center search form submits with autocomplete filter (TC-040). + /// + /// + /// Steps (smoke mode stops after step 4; strict mode runs all steps): + /// + /// Navigate to the search page. + /// Enter the search name "MIGRATED-TC-040". + /// Select the "Time Span + Work Center" search type from the dropdown. + /// Verify the dropdown displays the selected type. + /// Set the date range to 01/01/2019 – 12/31/2019 (strict only). + /// Add autocomplete value "0083AS" to the "Filter by Work Center" panel (strict only). + /// Click Submit (strict only). + /// Assert no error notification is present (strict only). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] - public Task TimeSpanWorkCenter_Submits() => - RunSearchSubmissionAsync( + public Task TimeSpanWorkCenter_Submits() + { + return RunSearchSubmissionAsync( UiSearchTypes.TimeSpanWorkCenter, "MIGRATED-TC-040", "01/01/2019", @@ -15,4 +37,5 @@ public sealed class TimeSpanWorkCenterSearchTests(PlaywrightFixture fixture) : S [ ("Filter by Work Center", "0083AS") ]); -} + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/WorkOrderSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/WorkOrderSearchTests.cs index d6fb29c..b051378 100644 --- a/NEW/tests/JdeScoping.Ui.Tests/WorkOrderSearchTests.cs +++ b/NEW/tests/JdeScoping.Ui.Tests/WorkOrderSearchTests.cs @@ -2,16 +2,38 @@ using JdeScoping.Ui.Tests.Support; namespace JdeScoping.Ui.Tests; +/// +/// Playwright UI tests for the "Work Order" search type (TC-010). +/// Validates search form interaction in smoke mode and full submission with workbook upload in strict mode. +/// Requires a running Docker host (Category: RequiresDockerHost). +/// public sealed class WorkOrderSearchTests(PlaywrightFixture fixture) : SearchFlowTestBase(fixture) { + /// + /// Verifies the Work Order search form submits with an uploaded workbook filter (TC-010). + /// + /// + /// Steps (smoke mode stops after step 4; strict mode runs all steps): + /// + /// Navigate to the search page. + /// Enter the search name "MIGRATED-TC-010". + /// Select the "Work Order" search type from the dropdown. + /// Verify the dropdown displays the selected type. + /// Upload "single_workorder.xlsx" to the "Filter by Work Order" panel (strict only). + /// Click Submit (strict only). + /// Assert no error notification is present (strict only). + /// + /// [Fact] [Trait("Category", "RequiresDockerHost")] - public Task WorkOrder_SubmitsWithUploadedWorkbook() => - RunSearchSubmissionAsync( + public Task WorkOrder_SubmitsWithUploadedWorkbook() + { + return RunSearchSubmissionAsync( UiSearchTypes.WorkOrder, "MIGRATED-TC-010", uploads: [ ("Filter by Work Order", "single_workorder.xlsx") ]); -} + } +} \ No newline at end of file