diff --git a/NEW/Directory.Packages.props b/NEW/Directory.Packages.props new file mode 100644 index 0000000..17b13b3 --- /dev/null +++ b/NEW/Directory.Packages.props @@ -0,0 +1,78 @@ + + + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NEW/JdeScoping.slnx b/NEW/JdeScoping.slnx index 6c0e274..3a8b38c 100644 --- a/NEW/JdeScoping.slnx +++ b/NEW/JdeScoping.slnx @@ -28,6 +28,7 @@ + diff --git a/NEW/src/JdeScoping.Api/JdeScoping.Api.csproj b/NEW/src/JdeScoping.Api/JdeScoping.Api.csproj index 5b9b0c9..186ebad 100644 --- a/NEW/src/JdeScoping.Api/JdeScoping.Api.csproj +++ b/NEW/src/JdeScoping.Api/JdeScoping.Api.csproj @@ -18,8 +18,8 @@ - - + + diff --git a/NEW/src/JdeScoping.Client/JdeScoping.Client.csproj b/NEW/src/JdeScoping.Client/JdeScoping.Client.csproj index 2f3d35d..654ed9b 100644 --- a/NEW/src/JdeScoping.Client/JdeScoping.Client.csproj +++ b/NEW/src/JdeScoping.Client/JdeScoping.Client.csproj @@ -8,12 +8,12 @@ - - - - - - + + + + + + diff --git a/NEW/src/JdeScoping.Core/JdeScoping.Core.csproj b/NEW/src/JdeScoping.Core/JdeScoping.Core.csproj index f5d8d9a..0b77c77 100644 --- a/NEW/src/JdeScoping.Core/JdeScoping.Core.csproj +++ b/NEW/src/JdeScoping.Core/JdeScoping.Core.csproj @@ -7,15 +7,15 @@ - - - - - - - - - + + + + + + + + + diff --git a/NEW/src/JdeScoping.DataAccess/JdeScoping.DataAccess.csproj b/NEW/src/JdeScoping.DataAccess/JdeScoping.DataAccess.csproj index b2bfa0e..f81bc7d 100644 --- a/NEW/src/JdeScoping.DataAccess/JdeScoping.DataAccess.csproj +++ b/NEW/src/JdeScoping.DataAccess/JdeScoping.DataAccess.csproj @@ -7,17 +7,17 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/NEW/src/JdeScoping.DataSync.Dev/JdeScoping.DataSync.Dev.csproj b/NEW/src/JdeScoping.DataSync.Dev/JdeScoping.DataSync.Dev.csproj index dce71c4..0ce74db 100644 --- a/NEW/src/JdeScoping.DataSync.Dev/JdeScoping.DataSync.Dev.csproj +++ b/NEW/src/JdeScoping.DataSync.Dev/JdeScoping.DataSync.Dev.csproj @@ -12,7 +12,7 @@ - + diff --git a/NEW/src/JdeScoping.DataSync/JdeScoping.DataSync.csproj b/NEW/src/JdeScoping.DataSync/JdeScoping.DataSync.csproj index a3f71f8..8adac7c 100644 --- a/NEW/src/JdeScoping.DataSync/JdeScoping.DataSync.csproj +++ b/NEW/src/JdeScoping.DataSync/JdeScoping.DataSync.csproj @@ -17,14 +17,14 @@ - - - - - - - - + + + + + + + + diff --git a/NEW/src/JdeScoping.Database/JdeScoping.Database.csproj b/NEW/src/JdeScoping.Database/JdeScoping.Database.csproj index 46bd5b5..122336b 100644 --- a/NEW/src/JdeScoping.Database/JdeScoping.Database.csproj +++ b/NEW/src/JdeScoping.Database/JdeScoping.Database.csproj @@ -11,8 +11,8 @@ - - + + diff --git a/NEW/src/JdeScoping.ExcelIO/JdeScoping.ExcelIO.csproj b/NEW/src/JdeScoping.ExcelIO/JdeScoping.ExcelIO.csproj index 3655446..717802a 100644 --- a/NEW/src/JdeScoping.ExcelIO/JdeScoping.ExcelIO.csproj +++ b/NEW/src/JdeScoping.ExcelIO/JdeScoping.ExcelIO.csproj @@ -7,12 +7,12 @@ - - - - - - + + + + + + diff --git a/NEW/src/JdeScoping.Host/JdeScoping.Host.csproj b/NEW/src/JdeScoping.Host/JdeScoping.Host.csproj index 23b0dcb..d657d6d 100644 --- a/NEW/src/JdeScoping.Host/JdeScoping.Host.csproj +++ b/NEW/src/JdeScoping.Host/JdeScoping.Host.csproj @@ -12,12 +12,12 @@ - - - - - - + + + + + + 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/src/JdeScoping.Infrastructure/JdeScoping.Infrastructure.csproj b/NEW/src/JdeScoping.Infrastructure/JdeScoping.Infrastructure.csproj index f59f613..9a2d10f 100644 --- a/NEW/src/JdeScoping.Infrastructure/JdeScoping.Infrastructure.csproj +++ b/NEW/src/JdeScoping.Infrastructure/JdeScoping.Infrastructure.csproj @@ -7,14 +7,14 @@ - - - - - - - - + + + + + + + + diff --git a/NEW/src/Utils/JdeScoping.ConfigManager.Cli/JdeScoping.ConfigManager.Cli.csproj b/NEW/src/Utils/JdeScoping.ConfigManager.Cli/JdeScoping.ConfigManager.Cli.csproj index a7ab85b..25cad4b 100644 --- a/NEW/src/Utils/JdeScoping.ConfigManager.Cli/JdeScoping.ConfigManager.Cli.csproj +++ b/NEW/src/Utils/JdeScoping.ConfigManager.Cli/JdeScoping.ConfigManager.Cli.csproj @@ -8,12 +8,12 @@ - - - - - - + + + + + + diff --git a/NEW/src/Utils/JdeScoping.ConfigManager.Core/JdeScoping.ConfigManager.Core.csproj b/NEW/src/Utils/JdeScoping.ConfigManager.Core/JdeScoping.ConfigManager.Core.csproj index c953f94..2442538 100644 --- a/NEW/src/Utils/JdeScoping.ConfigManager.Core/JdeScoping.ConfigManager.Core.csproj +++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/JdeScoping.ConfigManager.Core.csproj @@ -6,12 +6,12 @@ - - - - - - + + + + + + diff --git a/NEW/src/Utils/JdeScoping.ConfigManager.Ui/JdeScoping.ConfigManager.Ui.csproj b/NEW/src/Utils/JdeScoping.ConfigManager.Ui/JdeScoping.ConfigManager.Ui.csproj index c051560..4060c33 100644 --- a/NEW/src/Utils/JdeScoping.ConfigManager.Ui/JdeScoping.ConfigManager.Ui.csproj +++ b/NEW/src/Utils/JdeScoping.ConfigManager.Ui/JdeScoping.ConfigManager.Ui.csproj @@ -12,18 +12,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/NEW/tests/JdeScoping.Api.IntegrationTests/JdeScoping.Api.IntegrationTests.csproj b/NEW/tests/JdeScoping.Api.IntegrationTests/JdeScoping.Api.IntegrationTests.csproj index 2d81f4d..e8ae092 100644 --- a/NEW/tests/JdeScoping.Api.IntegrationTests/JdeScoping.Api.IntegrationTests.csproj +++ b/NEW/tests/JdeScoping.Api.IntegrationTests/JdeScoping.Api.IntegrationTests.csproj @@ -16,14 +16,14 @@ - - - - - - - - + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/NEW/tests/JdeScoping.Api.Tests/JdeScoping.Api.Tests.csproj b/NEW/tests/JdeScoping.Api.Tests/JdeScoping.Api.Tests.csproj index b964046..39d707f 100644 --- a/NEW/tests/JdeScoping.Api.Tests/JdeScoping.Api.Tests.csproj +++ b/NEW/tests/JdeScoping.Api.Tests/JdeScoping.Api.Tests.csproj @@ -13,12 +13,12 @@ - - - - - - + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/NEW/tests/JdeScoping.Client.Tests/JdeScoping.Client.Tests.csproj b/NEW/tests/JdeScoping.Client.Tests/JdeScoping.Client.Tests.csproj index ae0028e..f6617c7 100644 --- a/NEW/tests/JdeScoping.Client.Tests/JdeScoping.Client.Tests.csproj +++ b/NEW/tests/JdeScoping.Client.Tests/JdeScoping.Client.Tests.csproj @@ -12,13 +12,13 @@ - - - - - - - + + + + + + + diff --git a/NEW/tests/JdeScoping.Core.Tests/JdeScoping.Core.Tests.csproj b/NEW/tests/JdeScoping.Core.Tests/JdeScoping.Core.Tests.csproj index 48dfa4b..4555652 100644 --- a/NEW/tests/JdeScoping.Core.Tests/JdeScoping.Core.Tests.csproj +++ b/NEW/tests/JdeScoping.Core.Tests/JdeScoping.Core.Tests.csproj @@ -8,12 +8,12 @@ - - - - - - + + + + + + diff --git a/NEW/tests/JdeScoping.DataAccess.Tests/JdeScoping.DataAccess.Tests.csproj b/NEW/tests/JdeScoping.DataAccess.Tests/JdeScoping.DataAccess.Tests.csproj index 348de2b..825b82d 100644 --- a/NEW/tests/JdeScoping.DataAccess.Tests/JdeScoping.DataAccess.Tests.csproj +++ b/NEW/tests/JdeScoping.DataAccess.Tests/JdeScoping.DataAccess.Tests.csproj @@ -9,17 +9,17 @@ - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - - - + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/NEW/tests/JdeScoping.DataSync.Dev.Tests/JdeScoping.DataSync.Dev.Tests.csproj b/NEW/tests/JdeScoping.DataSync.Dev.Tests/JdeScoping.DataSync.Dev.Tests.csproj index eba4d70..fb656a7 100644 --- a/NEW/tests/JdeScoping.DataSync.Dev.Tests/JdeScoping.DataSync.Dev.Tests.csproj +++ b/NEW/tests/JdeScoping.DataSync.Dev.Tests/JdeScoping.DataSync.Dev.Tests.csproj @@ -9,23 +9,23 @@ - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - - - + + + + + diff --git a/NEW/tests/JdeScoping.DataSync.Tests/JdeScoping.DataSync.Tests.csproj b/NEW/tests/JdeScoping.DataSync.Tests/JdeScoping.DataSync.Tests.csproj index 7dfd001..4fcf909 100644 --- a/NEW/tests/JdeScoping.DataSync.Tests/JdeScoping.DataSync.Tests.csproj +++ b/NEW/tests/JdeScoping.DataSync.Tests/JdeScoping.DataSync.Tests.csproj @@ -9,26 +9,26 @@ - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - - - - - - + + + + + + + + diff --git a/NEW/tests/JdeScoping.Database.Tests/JdeScoping.Database.Tests.csproj b/NEW/tests/JdeScoping.Database.Tests/JdeScoping.Database.Tests.csproj index eda758c..635e88b 100644 --- a/NEW/tests/JdeScoping.Database.Tests/JdeScoping.Database.Tests.csproj +++ b/NEW/tests/JdeScoping.Database.Tests/JdeScoping.Database.Tests.csproj @@ -9,14 +9,14 @@ - - - - - - - - + + + + + + + + diff --git a/NEW/tests/JdeScoping.ExcelIO.Tests/JdeScoping.ExcelIO.Tests.csproj b/NEW/tests/JdeScoping.ExcelIO.Tests/JdeScoping.ExcelIO.Tests.csproj index 3f2df8b..447d9bc 100644 --- a/NEW/tests/JdeScoping.ExcelIO.Tests/JdeScoping.ExcelIO.Tests.csproj +++ b/NEW/tests/JdeScoping.ExcelIO.Tests/JdeScoping.ExcelIO.Tests.csproj @@ -9,16 +9,16 @@ - - - - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/NEW/tests/JdeScoping.Host.Tests/JdeScoping.Host.Tests.csproj b/NEW/tests/JdeScoping.Host.Tests/JdeScoping.Host.Tests.csproj index 3ea3ade..6602de0 100644 --- a/NEW/tests/JdeScoping.Host.Tests/JdeScoping.Host.Tests.csproj +++ b/NEW/tests/JdeScoping.Host.Tests/JdeScoping.Host.Tests.csproj @@ -8,12 +8,12 @@ - - - - - - + + + + + + diff --git a/NEW/tests/JdeScoping.Infrastructure.Tests/JdeScoping.Infrastructure.Tests.csproj b/NEW/tests/JdeScoping.Infrastructure.Tests/JdeScoping.Infrastructure.Tests.csproj index b7ac024..c9b34fd 100644 --- a/NEW/tests/JdeScoping.Infrastructure.Tests/JdeScoping.Infrastructure.Tests.csproj +++ b/NEW/tests/JdeScoping.Infrastructure.Tests/JdeScoping.Infrastructure.Tests.csproj @@ -8,12 +8,12 @@ - - - - - - + + + + + + diff --git a/NEW/tests/JdeScoping.Ui.Tests/AuthApiSmokeTests.cs b/NEW/tests/JdeScoping.Ui.Tests/AuthApiSmokeTests.cs new file mode 100644 index 0000000..9c4fca0 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/AuthApiSmokeTests.cs @@ -0,0 +1,56 @@ +using System.Net; +using System.Net.Http.Json; +using System.Security.Cryptography; +using System.Text; +using System.Text.Json; +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() + { + var cookies = new CookieContainer(); + using var handler = new HttpClientHandler { CookieContainer = cookies }; + using var client = new HttpClient(handler) { BaseAddress = new Uri(UiTestSettings.BaseUrl) }; + + var key = await client.GetFromJsonAsync("api/auth/public-key"); + Assert.NotNull(key); + Assert.Contains("BEGIN PUBLIC KEY", key!.PublicKeyPem); + + string payload = JsonSerializer.Serialize(new LoginModel { Username = "testuser", Password = "testpass" }); + + using var rsa = RSA.Create(); + rsa.ImportFromPem(key.PublicKeyPem); + byte[] encrypted = rsa.Encrypt(Encoding.UTF8.GetBytes(payload), RSAEncryptionPadding.OaepSHA256); + + 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 new file mode 100644 index 0000000..5f6b8d0 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/ComponentLotSearchTests.cs @@ -0,0 +1,39 @@ +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() + { + 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 new file mode 100644 index 0000000..b0b8786 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/DataSyncPageTests.cs @@ -0,0 +1,56 @@ +using JdeScoping.Ui.Tests.Helpers; +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() + { + await RunAsync(async page => + { + await UiNavigationHelper.NavigateToDataSyncAsync(page); + 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 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 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 new file mode 100644 index 0000000..e64e483 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/GlobalUsings.cs @@ -0,0 +1,2 @@ +global using Xunit; +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 new file mode 100644 index 0000000..49292b4 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/Helpers/UiAuthHelper.cs @@ -0,0 +1,45 @@ +namespace JdeScoping.Ui.Tests.Helpers; + +internal static class UiAuthHelper +{ + public static async Task LoginAsync(IPage page, string username = "testuser", string password = "testpass") + { + var loginForm = page.GetByText("Authentication Required"); + bool formVisible = await loginForm.IsVisibleAsync(); + if (!formVisible) return; + + await page.Locator("input[name='Username']").FillAsync(username); + await page.Locator("input[name='Password']").FillAsync(password); + await page.Locator("button[type='submit']:has-text('LOGIN')").ClickAsync(); + + await page.WaitForLoadStateAsync(LoadState.NetworkIdle); + await page.WaitForTimeoutAsync(3_000); + await page.GotoAsync("/search"); + await page.WaitForLoadStateAsync(LoadState.NetworkIdle); + + if (await loginForm.IsVisibleAsync()) + { + var notifications = page.Locator(".rz-notification"); + int count = await notifications.CountAsync(); + var details = new List(); + for (var i = 0; i < count; i++) + { + string text = (await notifications.Nth(i).InnerTextAsync()).Trim(); + if (!string.IsNullOrWhiteSpace(text)) details.Add(text); + } + + throw new InvalidOperationException( + $"Login did not complete. URL={page.Url}. Notifications={string.Join(" | ", details)}"); + } + } + + public static async Task LogoutAsync(IPage page) + { + var logoutButton = page.GetByRole(AriaRole.Button, new PageGetByRoleOptions { Name = "Logout" }); + if (await logoutButton.IsVisibleAsync()) + { + await logoutButton.ClickAsync(); + 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 new file mode 100644 index 0000000..c0a4095 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/Helpers/UiNavigationHelper.cs @@ -0,0 +1,102 @@ +namespace JdeScoping.Ui.Tests.Helpers; + +internal static class UiNavigationHelper +{ + public static async Task NavigateToSearchPageAsync(IPage page) + { + await page.GotoAsync("/search"); + await page.WaitForLoadStateAsync(LoadState.NetworkIdle); + await UiAuthHelper.LoginAsync(page); + await EnsureAuthenticatedOrThrowAsync(page); + await WaitForBlazorReadyAsync(page); + } + + public static async Task NavigateToSearchesDashboardAsync(IPage page) + { + await page.GotoAsync("/searches"); + await page.WaitForLoadStateAsync(LoadState.NetworkIdle); + await UiAuthHelper.LoginAsync(page); + await EnsureAuthenticatedOrThrowAsync(page); + await WaitForBlazorReadyAsync(page); + } + + public static async Task NavigateToQueueAsync(IPage page) + { + await page.GotoAsync("/search/queue"); + await page.WaitForLoadStateAsync(LoadState.NetworkIdle); + await UiAuthHelper.LoginAsync(page); + await EnsureAuthenticatedOrThrowAsync(page); + await WaitForBlazorReadyAsync(page); + } + + public static async Task NavigateToRefreshStatusAsync(IPage page) + { + await page.GotoAsync("/refresh-status"); + await page.WaitForLoadStateAsync(LoadState.NetworkIdle); + await UiAuthHelper.LoginAsync(page); + await EnsureAuthenticatedOrThrowAsync(page); + await WaitForBlazorReadyAsync(page); + } + + public static async Task NavigateToDataSyncAsync(IPage page) + { + await page.GotoAsync("/data-sync/requests"); + await page.WaitForLoadStateAsync(LoadState.NetworkIdle); + await UiAuthHelper.LoginAsync(page); + await EnsureAuthenticatedOrThrowAsync(page); + await WaitForBlazorReadyAsync(page); + } + + public static async Task NavigateToLoginAsync(IPage page) + { + await page.GotoAsync("/login"); + await page.WaitForLoadStateAsync(LoadState.NetworkIdle); + } + + private static async Task WaitForBlazorReadyAsync(IPage page) + { + var timeoutMs = 15_000; + try + { + await page.Locator(".rz-dropdown").First.WaitForAsync(new LocatorWaitForOptions + { + State = WaitForSelectorState.Visible, + Timeout = timeoutMs + }); + return; + } + catch (PlaywrightException) + { + // Try additional readiness markers. + } + + try + { + await page.Locator(".rz-data-grid").First.WaitForAsync(new LocatorWaitForOptions + { + State = WaitForSelectorState.Visible, + Timeout = timeoutMs + }); + return; + } + catch (PlaywrightException) + { + // Try text marker as final fallback. + } + + await page.GetByText("Search Details").First.WaitForAsync(new LocatorWaitForOptions + { + State = WaitForSelectorState.Visible, + Timeout = timeoutMs + }); + await page.WaitForTimeoutAsync(1_000); + } + + private static async Task EnsureAuthenticatedOrThrowAsync(IPage page) + { + 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 new file mode 100644 index 0000000..3255fc1 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/Helpers/UiSearchFormHelper.cs @@ -0,0 +1,63 @@ +namespace JdeScoping.Ui.Tests.Helpers; + +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.WaitForTimeoutAsync(500); + } + + 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) + { + await page.Locator("input[name='MinimumDt']").FillAsync(minimumMmDdYyyy); + await page.Locator("input[name='MaximumDt']").FillAsync(maximumMmDdYyyy); + } + + public static async Task AddAutocompleteItemAsync(IPage page, string panelHeader, string value) + { + var panel = page.Locator($".rz-card:has-text('{panelHeader}')"); + await panel.Locator(".rz-autocomplete input").First.FillAsync(value); + await page.WaitForTimeoutAsync(500); + + var listItem = page.Locator(".rz-autocomplete-list .rz-autocomplete-list-item").First; + if (await listItem.IsVisibleAsync()) await listItem.ClickAsync(); + + await panel.GetByRole(AriaRole.Button, new LocatorGetByRoleOptions { Name = "Add" }).ClickAsync(); + await page.WaitForTimeoutAsync(250); + } + + public static async Task UploadFileAsync(IPage page, string panelHeader, string filePath) + { + var panel = page.Locator($".rz-card:has-text('{panelHeader}')"); + await panel.Locator("input[type='file']").First.SetInputFilesAsync(filePath); + await page.WaitForTimeoutAsync(1_500); + } + + public static async Task SubmitSearchAsync(IPage page) + { + await page.GetByRole(AriaRole.Button, new PageGetByRoleOptions { Name = "Submit" }).First.ClickAsync(); + await page.GetByText("Confirm Submit").WaitForAsync(new LocatorWaitForOptions + { + State = WaitForSelectorState.Visible, + Timeout = 10_000 + }); + 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 }); + } +} \ 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 new file mode 100644 index 0000000..21ddbca --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/JdeScoping.Ui.Tests.csproj @@ -0,0 +1,32 @@ + + + + net10.0 + enable + enable + false + true + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NEW/tests/JdeScoping.Ui.Tests/LoginPageTests.cs b/NEW/tests/JdeScoping.Ui.Tests/LoginPageTests.cs new file mode 100644 index 0000000..59ff8a8 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/LoginPageTests.cs @@ -0,0 +1,49 @@ +using System.Text.RegularExpressions; +using JdeScoping.Ui.Tests.Helpers; +using JdeScoping.Ui.Tests.Support; + +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() + { + await RunAsync(async page => + { + await UiNavigationHelper.NavigateToLoginAsync(page); + await Assertions.Expect(page).ToHaveTitleAsync(new Regex("Login - JDE Scoping Tool")); + + await UiAuthHelper.LoginAsync(page); + var loggedOutView = page.GetByText("Authentication Required"); + 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); + var meAfterLogout = await page.Context.APIRequest.GetAsync("/api/auth/me"); + Assert.Equal(401, meAfterLogout.Status); + }); + } +} \ No newline at end of file diff --git a/NEW/tests/JdeScoping.Ui.Tests/README.md b/NEW/tests/JdeScoping.Ui.Tests/README.md new file mode 100644 index 0000000..d7681a2 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/README.md @@ -0,0 +1,29 @@ +# JdeScoping.Ui.Tests + +Playwright-for-.NET UI tests migrated from the legacy TypeScript Playwright suite. + +## Preconditions + +- Docker host container is already running via `/Users/dohertj2/Desktop/JdeScopingTool/NEW/deploy/docker/deploy-host.sh` +- App reachable at `http://localhost:5294` (or set `JDESCOPING_UI_BASE_URL`) + +## First-time setup + +```bash +cd /Users/dohertj2/Desktop/JdeScopingTool/NEW/tests/JdeScoping.Ui.Tests +dotnet build +pwsh bin/Debug/net10.0/playwright.ps1 install chromium +``` + +## Run tests + +```bash +cd /Users/dohertj2/Desktop/JdeScopingTool/NEW +dotnet test tests/JdeScoping.Ui.Tests/JdeScoping.Ui.Tests.csproj --filter "Category=RequiresDockerHost" +``` + +Run headed mode: + +```bash +JDESCOPING_UI_HEADED=true dotnet test tests/JdeScoping.Ui.Tests/JdeScoping.Ui.Tests.csproj +``` diff --git a/NEW/tests/JdeScoping.Ui.Tests/RefreshStatusPageTests.cs b/NEW/tests/JdeScoping.Ui.Tests/RefreshStatusPageTests.cs new file mode 100644 index 0000000..db4f0d9 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/RefreshStatusPageTests.cs @@ -0,0 +1,45 @@ +using JdeScoping.Ui.Tests.Helpers; +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() + { + await RunAsync(async page => + { + await UiNavigationHelper.NavigateToRefreshStatusAsync(page); + 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 LocatorAssertionsToBeVisibleOptions { Timeout = 15_000 }); + else + 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 new file mode 100644 index 0000000..5666fa6 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/SearchPageTests.cs @@ -0,0 +1,38 @@ +using JdeScoping.Ui.Tests.Helpers; +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() + { + await RunAsync(async page => + { + await UiNavigationHelper.NavigateToSearchPageAsync(page); + await Assertions.Expect(page.GetByText("Search Details")).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 new file mode 100644 index 0000000..09044bc --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/SearchQueuePageTests.cs @@ -0,0 +1,53 @@ +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() + { + await RunAsync(async page => + { + await UiNavigationHelper.NavigateToQueueAsync(page); + 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 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 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 new file mode 100644 index 0000000..a60d5c1 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/SearchesDashboardPageTests.cs @@ -0,0 +1,44 @@ +using JdeScoping.Ui.Tests.Helpers; +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() + { + await RunAsync(async page => + { + await UiNavigationHelper.NavigateToSearchesDashboardAsync(page); + string url = page.Url; + Assert.True( + url.EndsWith("/searches", StringComparison.OrdinalIgnoreCase) || + url.EndsWith("/search", StringComparison.OrdinalIgnoreCase) || + url.EndsWith("/", StringComparison.OrdinalIgnoreCase), + $"Unexpected URL: {url}"); + + 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 new file mode 100644 index 0000000..16f5948 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/Support/PlaywrightFixture.cs @@ -0,0 +1,26 @@ +namespace JdeScoping.Ui.Tests.Support; + +public sealed class PlaywrightFixture : IAsyncLifetime +{ + private IBrowser? _browser; + private IPlaywright? _playwright; + + public IBrowser Browser => _browser ?? throw new InvalidOperationException("Browser is not initialized."); + + public async Task InitializeAsync() + { + _playwright = await Playwright.CreateAsync(); + _browser = await _playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions + { + Headless = UiTestSettings.Headless, + Args = ["--no-sandbox", "--disable-dev-shm-usage"] + }); + } + + public async Task DisposeAsync() + { + 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 new file mode 100644 index 0000000..238d4ad --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/Support/SearchFlowTestBase.cs @@ -0,0 +1,46 @@ +using JdeScoping.Ui.Tests.Helpers; + +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); + + protected Task RunSearchSubmissionAsync( + string searchType, + string testName, + string? minDate = null, + string? maxDate = null, + (string PanelHeader, string Value)[]? autocompleteItems = null, + (string PanelHeader, string FileName)[]? uploads = null) + { + return RunAsync(async page => + { + await UiNavigationHelper.NavigateToSearchPageAsync(page); + await UiSearchFormHelper.EnterSearchNameAsync(page, testName); + await UiSearchFormHelper.SelectSearchTypeAsync(page, searchType); + 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.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 new file mode 100644 index 0000000..2792581 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/Support/TestDataPaths.cs @@ -0,0 +1,9 @@ +namespace JdeScoping.Ui.Tests.Support; + +internal static class TestDataPaths +{ + 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 new file mode 100644 index 0000000..5f6c4fe --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/Support/UiSearchTypes.cs @@ -0,0 +1,21 @@ +namespace JdeScoping.Ui.Tests.Support; + +internal static class UiSearchTypes +{ + public const string WorkOrder = "Work Order"; + public const string ComponentLot = "Component Lot"; + public const string TimeSpanProfitCenter = "Time Span + Profit Center"; + public const string TimeSpanWorkCenter = "Time Span + Work Center"; + public const string TimeSpanOperator = "Time Span + Operator"; + public const string TimeSpanPcItem = "Time Span + Profit Center + Item Number"; + public const string TimeSpanPcPartOp = "Time Span + Profit Center + Item/Operation/MIS"; + public const string TimeSpanPcWoPartOp = "Time Span + Profit Center + Work Order + Item/Operation/MIS"; + public const string TimeSpanPcExtractMis = "Time Span + Profit Center + Extract MIS"; + public const string TimeSpanWcItem = "Time Span + Work Center + Item Number"; + public const string TimeSpanWcExtractMis = "Time Span + Work Center + Extract MIS"; + public const string TimeSpanWcPartOp = "Time Span + Work Center + Item/Operation/MIS"; + public const string TimeSpanWcWoPartOp = "Time Span + Work Center + Work Order + Item/Operation/MIS"; + 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 new file mode 100644 index 0000000..57455a1 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/Support/UiTestBase.cs @@ -0,0 +1,27 @@ +namespace JdeScoping.Ui.Tests.Support; + +[Collection(UiTestCollection.Name)] +public abstract class UiTestBase +{ + private readonly PlaywrightFixture _fixture; + + protected UiTestBase(PlaywrightFixture fixture) + { + _fixture = fixture; + } + + protected async Task RunAsync(Func action) + { + await using var context = await _fixture.Browser.NewContextAsync(new BrowserNewContextOptions + { + BaseURL = UiTestSettings.BaseUrl, + IgnoreHTTPSErrors = true + }); + + var page = await context.NewPageAsync(); + page.SetDefaultTimeout(30_000); + page.SetDefaultNavigationTimeout(120_000); + + 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 new file mode 100644 index 0000000..3b2a49c --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/Support/UiTestCollection.cs @@ -0,0 +1,7 @@ +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 new file mode 100644 index 0000000..3adfb0b --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/Support/UiTestSettings.cs @@ -0,0 +1,12 @@ +namespace JdeScoping.Ui.Tests.Support; + +internal static class UiTestSettings +{ + public static string BaseUrl => + Environment.GetEnvironmentVariable("JDESCOPING_UI_BASE_URL") + ?? "http://localhost:5294"; + + public static bool Headless => + !string.Equals(Environment.GetEnvironmentVariable("JDESCOPING_UI_HEADED"), "true", + StringComparison.OrdinalIgnoreCase); +} \ No newline at end of file diff --git a/TestScripts/playwright/test-data/empty_file.xlsx b/NEW/tests/JdeScoping.Ui.Tests/TestData/empty_file.xlsx similarity index 100% rename from TestScripts/playwright/test-data/empty_file.xlsx rename to NEW/tests/JdeScoping.Ui.Tests/TestData/empty_file.xlsx diff --git a/TestScripts/playwright/test-data/invalid_format.txt b/NEW/tests/JdeScoping.Ui.Tests/TestData/invalid_format.txt similarity index 100% rename from TestScripts/playwright/test-data/invalid_format.txt rename to NEW/tests/JdeScoping.Ui.Tests/TestData/invalid_format.txt diff --git a/TestScripts/playwright/test-data/invalid_workorders.xlsx b/NEW/tests/JdeScoping.Ui.Tests/TestData/invalid_workorders.xlsx similarity index 100% rename from TestScripts/playwright/test-data/invalid_workorders.xlsx rename to NEW/tests/JdeScoping.Ui.Tests/TestData/invalid_workorders.xlsx diff --git a/TestScripts/playwright/test-data/max_workorders.xlsx b/NEW/tests/JdeScoping.Ui.Tests/TestData/max_workorders.xlsx similarity index 100% rename from TestScripts/playwright/test-data/max_workorders.xlsx rename to NEW/tests/JdeScoping.Ui.Tests/TestData/max_workorders.xlsx diff --git a/TestScripts/playwright/test-data/multiple_items.xlsx b/NEW/tests/JdeScoping.Ui.Tests/TestData/multiple_items.xlsx similarity index 100% rename from TestScripts/playwright/test-data/multiple_items.xlsx rename to NEW/tests/JdeScoping.Ui.Tests/TestData/multiple_items.xlsx diff --git a/TestScripts/playwright/test-data/multiple_lots.xlsx b/NEW/tests/JdeScoping.Ui.Tests/TestData/multiple_lots.xlsx similarity index 100% rename from TestScripts/playwright/test-data/multiple_lots.xlsx rename to NEW/tests/JdeScoping.Ui.Tests/TestData/multiple_lots.xlsx diff --git a/TestScripts/playwright/test-data/multiple_operations.xlsx b/NEW/tests/JdeScoping.Ui.Tests/TestData/multiple_operations.xlsx similarity index 100% rename from TestScripts/playwright/test-data/multiple_operations.xlsx rename to NEW/tests/JdeScoping.Ui.Tests/TestData/multiple_operations.xlsx diff --git a/TestScripts/playwright/test-data/multiple_workorders.xlsx b/NEW/tests/JdeScoping.Ui.Tests/TestData/multiple_workorders.xlsx similarity index 100% rename from TestScripts/playwright/test-data/multiple_workorders.xlsx rename to NEW/tests/JdeScoping.Ui.Tests/TestData/multiple_workorders.xlsx diff --git a/TestScripts/playwright/test-data/single_item.xlsx b/NEW/tests/JdeScoping.Ui.Tests/TestData/single_item.xlsx similarity index 100% rename from TestScripts/playwright/test-data/single_item.xlsx rename to NEW/tests/JdeScoping.Ui.Tests/TestData/single_item.xlsx diff --git a/TestScripts/playwright/test-data/single_lot.xlsx b/NEW/tests/JdeScoping.Ui.Tests/TestData/single_lot.xlsx similarity index 100% rename from TestScripts/playwright/test-data/single_lot.xlsx rename to NEW/tests/JdeScoping.Ui.Tests/TestData/single_lot.xlsx diff --git a/TestScripts/playwright/test-data/single_operation.xlsx b/NEW/tests/JdeScoping.Ui.Tests/TestData/single_operation.xlsx similarity index 100% rename from TestScripts/playwright/test-data/single_operation.xlsx rename to NEW/tests/JdeScoping.Ui.Tests/TestData/single_operation.xlsx diff --git a/TestScripts/playwright/test-data/single_workorder.xlsx b/NEW/tests/JdeScoping.Ui.Tests/TestData/single_workorder.xlsx similarity index 100% rename from TestScripts/playwright/test-data/single_workorder.xlsx rename to NEW/tests/JdeScoping.Ui.Tests/TestData/single_workorder.xlsx diff --git a/TestScripts/playwright/test-data/special_chars_workorders.xlsx b/NEW/tests/JdeScoping.Ui.Tests/TestData/special_chars_workorders.xlsx similarity index 100% rename from TestScripts/playwright/test-data/special_chars_workorders.xlsx rename to NEW/tests/JdeScoping.Ui.Tests/TestData/special_chars_workorders.xlsx diff --git a/NEW/tests/JdeScoping.Ui.Tests/TestData/test-data.json b/NEW/tests/JdeScoping.Ui.Tests/TestData/test-data.json new file mode 100644 index 0000000..132ce5e --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/TestData/test-data.json @@ -0,0 +1,281 @@ +{ + "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" + } + ], + "workCenters": [ + { + "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" + } + ], + "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" + } + ], + "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" + } + ], + "componentLots": [ + { + "lotNumber": "LOT001", + "itemNumber": "00598004702" + }, + { + "lotNumber": "LOT002", + "itemNumber": "82070000028" + }, + { + "lotNumber": "LOT003", + "itemNumber": "82070000027" + } + ], + "partOperations": [ + { + "itemNumber": "00598004702", + "operationNumber": "100", + "misNumber": "MIS001", + "misRevision": "A" + }, + { + "itemNumber": "00598004702", + "operationNumber": "200", + "misNumber": "MIS002", + "misRevision": "B" + }, + { + "itemNumber": "82070000028", + "operationNumber": "100", + "misNumber": "MIS003", + "misRevision": "A" + } + ], + "dateRanges": { + "recent": { + "min": "2020-01-01", + "max": "2020-09-01", + "description": "Recent data range" + }, + "midRange": { + "min": "2018-01-01", + "max": "2019-12-31", + "description": "Mid-range data" + }, + "historical": { + "min": "2016-01-01", + "max": "2017-12-31", + "description": "Historical data" + }, + "sameDay": { + "min": "2020-06-15", + "max": "2020-06-15", + "description": "Single day range" + }, + "startBoundary": { + "min": "1905-01-20", + "max": "1905-12-31", + "description": "Start of data range" + }, + "endBoundary": { + "min": "2020-08-01", + "max": "2020-09-01", + "description": "End of data range" + } + }, + "invalidData": { + "workOrders": { + "invalidFormat": "ABC123XYZ", + "specialChars": "99059700!@#", + "empty": "", + "whitespace": " " + }, + "profitCenters": { + "invalid": "INVALID", + "specialChars": "1AM!@#", + "empty": "", + "tooLong": "1AMEXTRALONG" + }, + "dates": { + "invalidFormat": "31-12-2020", + "future": { + "min": "2025-01-01", + "max": "2025-12-31" + }, + "reversed": { + "min": "2020-09-01", + "max": "2020-01-01" + } + } + }, + "testCredentials": { + "validUser": { + "username": "testuser", + "password": "testpass" + }, + "invalidUser": { + "username": "invaliduser", + "password": "wrongpassword" + } + } +} diff --git a/NEW/tests/JdeScoping.Ui.Tests/TimeSpanItemNumberSearchTests.cs b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanItemNumberSearchTests.cs new file mode 100644 index 0000000..7b2cd26 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanItemNumberSearchTests.cs @@ -0,0 +1,42 @@ +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() + { + return RunSearchSubmissionAsync( + UiSearchTypes.TimeSpanItem, + "MIGRATED-TC-140", + "01/01/2019", + "12/31/2019", + uploads: + [ + ("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 new file mode 100644 index 0000000..f236957 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanOperatorSearchTests.cs @@ -0,0 +1,41 @@ +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() + { + return RunSearchSubmissionAsync( + UiSearchTypes.TimeSpanOperator, + "MIGRATED-TC-050", + "01/01/2019", + "12/31/2019", + [ + ("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 new file mode 100644 index 0000000..8eb476a --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcExtractMisSearchTests.cs @@ -0,0 +1,41 @@ +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() + { + return RunSearchSubmissionAsync( + UiSearchTypes.TimeSpanPcExtractMis, + "MIGRATED-TC-090", + "01/01/2019", + "12/31/2019", + [ + ("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 new file mode 100644 index 0000000..291237b --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcItemSearchTests.cs @@ -0,0 +1,45 @@ +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() + { + return RunSearchSubmissionAsync( + UiSearchTypes.TimeSpanPcItem, + "MIGRATED-TC-060", + "01/01/2019", + "12/31/2019", + [ + ("Filter by Profit Center", "1AM") + ], + [ + ("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 new file mode 100644 index 0000000..80bd56b --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcOperatorSearchTests.cs @@ -0,0 +1,43 @@ +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() + { + return RunSearchSubmissionAsync( + UiSearchTypes.TimeSpanPcOperator, + "MIGRATED-TC-160", + "01/01/2019", + "12/31/2019", + [ + ("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 new file mode 100644 index 0000000..6fb40f5 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcPartOpSearchTests.cs @@ -0,0 +1,45 @@ +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() + { + return RunSearchSubmissionAsync( + UiSearchTypes.TimeSpanPcPartOp, + "MIGRATED-TC-070", + "01/01/2019", + "12/31/2019", + [ + ("Filter by Profit Center", "1AM") + ], + [ + ("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 new file mode 100644 index 0000000..0d3dcd9 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanPcWoPartOpSearchTests.cs @@ -0,0 +1,47 @@ +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() + { + return RunSearchSubmissionAsync( + UiSearchTypes.TimeSpanPcWoPartOp, + "MIGRATED-TC-080", + "01/01/2019", + "12/31/2019", + [ + ("Filter by Profit Center", "1AM") + ], + [ + ("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 new file mode 100644 index 0000000..36dce2f --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanProfitCenterSearchTests.cs @@ -0,0 +1,41 @@ +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() + { + return RunSearchSubmissionAsync( + UiSearchTypes.TimeSpanProfitCenter, + "MIGRATED-TC-030", + "01/01/2019", + "12/31/2019", + [ + ("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 new file mode 100644 index 0000000..efe7a5d --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcExtractMisSearchTests.cs @@ -0,0 +1,41 @@ +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() + { + return RunSearchSubmissionAsync( + UiSearchTypes.TimeSpanWcExtractMis, + "MIGRATED-TC-110", + "01/01/2019", + "12/31/2019", + [ + ("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 new file mode 100644 index 0000000..81366b4 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcItemSearchTests.cs @@ -0,0 +1,45 @@ +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() + { + return RunSearchSubmissionAsync( + UiSearchTypes.TimeSpanWcItem, + "MIGRATED-TC-100", + "01/01/2019", + "12/31/2019", + [ + ("Filter by Work Center", "0083AS") + ], + [ + ("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 new file mode 100644 index 0000000..c2135cd --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcOperatorSearchTests.cs @@ -0,0 +1,43 @@ +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() + { + return RunSearchSubmissionAsync( + UiSearchTypes.TimeSpanWcOperator, + "MIGRATED-TC-150", + "01/01/2019", + "12/31/2019", + [ + ("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 new file mode 100644 index 0000000..693270c --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcPartOpSearchTests.cs @@ -0,0 +1,45 @@ +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() + { + return RunSearchSubmissionAsync( + UiSearchTypes.TimeSpanWcPartOp, + "MIGRATED-TC-120", + "01/01/2019", + "12/31/2019", + [ + ("Filter by Work Center", "0083AS") + ], + [ + ("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 new file mode 100644 index 0000000..7b616c5 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWcWoPartOpSearchTests.cs @@ -0,0 +1,47 @@ +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() + { + return RunSearchSubmissionAsync( + UiSearchTypes.TimeSpanWcWoPartOp, + "MIGRATED-TC-130", + "01/01/2019", + "12/31/2019", + [ + ("Filter by Work Center", "0083AS") + ], + [ + ("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 new file mode 100644 index 0000000..0999a11 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/TimeSpanWorkCenterSearchTests.cs @@ -0,0 +1,41 @@ +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() + { + return RunSearchSubmissionAsync( + UiSearchTypes.TimeSpanWorkCenter, + "MIGRATED-TC-040", + "01/01/2019", + "12/31/2019", + [ + ("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 new file mode 100644 index 0000000..b051378 --- /dev/null +++ b/NEW/tests/JdeScoping.Ui.Tests/WorkOrderSearchTests.cs @@ -0,0 +1,39 @@ +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() + { + return RunSearchSubmissionAsync( + UiSearchTypes.WorkOrder, + "MIGRATED-TC-010", + uploads: + [ + ("Filter by Work Order", "single_workorder.xlsx") + ]); + } +} \ No newline at end of file diff --git a/NEW/tests/Utils/JdeScoping.ConfigManager.Cli.Tests/JdeScoping.ConfigManager.Cli.Tests.csproj b/NEW/tests/Utils/JdeScoping.ConfigManager.Cli.Tests/JdeScoping.ConfigManager.Cli.Tests.csproj index 5d9f0c2..bdcfe1e 100644 --- a/NEW/tests/Utils/JdeScoping.ConfigManager.Cli.Tests/JdeScoping.ConfigManager.Cli.Tests.csproj +++ b/NEW/tests/Utils/JdeScoping.ConfigManager.Cli.Tests/JdeScoping.ConfigManager.Cli.Tests.csproj @@ -13,10 +13,10 @@ - - - - - + + + + + diff --git a/NEW/tests/Utils/JdeScoping.ConfigManager.Core.Tests/JdeScoping.ConfigManager.Core.Tests.csproj b/NEW/tests/Utils/JdeScoping.ConfigManager.Core.Tests/JdeScoping.ConfigManager.Core.Tests.csproj index 52b1841..86b4ffe 100644 --- a/NEW/tests/Utils/JdeScoping.ConfigManager.Core.Tests/JdeScoping.ConfigManager.Core.Tests.csproj +++ b/NEW/tests/Utils/JdeScoping.ConfigManager.Core.Tests/JdeScoping.ConfigManager.Core.Tests.csproj @@ -12,10 +12,10 @@ - - - - - + + + + + diff --git a/NEW/tests/Utils/JdeScoping.ConfigManager.Ui.Tests/JdeScoping.ConfigManager.Ui.Tests.csproj b/NEW/tests/Utils/JdeScoping.ConfigManager.Ui.Tests/JdeScoping.ConfigManager.Ui.Tests.csproj index 7a14e49..3f9c43c 100644 --- a/NEW/tests/Utils/JdeScoping.ConfigManager.Ui.Tests/JdeScoping.ConfigManager.Ui.Tests.csproj +++ b/NEW/tests/Utils/JdeScoping.ConfigManager.Ui.Tests/JdeScoping.ConfigManager.Ui.Tests.csproj @@ -13,12 +13,12 @@ - - - - - - - + + + + + + + diff --git a/TestScripts/playwright/README.md b/TestScripts/deprecated/playwright/README.md similarity index 100% rename from TestScripts/playwright/README.md rename to TestScripts/deprecated/playwright/README.md diff --git a/TestScripts/playwright/debug-screenshot.png b/TestScripts/deprecated/playwright/debug-screenshot.png similarity index 100% rename from TestScripts/playwright/debug-screenshot.png rename to TestScripts/deprecated/playwright/debug-screenshot.png diff --git a/TestScripts/playwright/fixtures/test.fixture.ts b/TestScripts/deprecated/playwright/fixtures/test.fixture.ts similarity index 100% rename from TestScripts/playwright/fixtures/test.fixture.ts rename to TestScripts/deprecated/playwright/fixtures/test.fixture.ts diff --git a/TestScripts/playwright/helpers/auth.helper.ts b/TestScripts/deprecated/playwright/helpers/auth.helper.ts similarity index 100% rename from TestScripts/playwright/helpers/auth.helper.ts rename to TestScripts/deprecated/playwright/helpers/auth.helper.ts diff --git a/TestScripts/playwright/helpers/autocomplete.helper.ts b/TestScripts/deprecated/playwright/helpers/autocomplete.helper.ts similarity index 100% rename from TestScripts/playwright/helpers/autocomplete.helper.ts rename to TestScripts/deprecated/playwright/helpers/autocomplete.helper.ts diff --git a/TestScripts/playwright/helpers/date-picker.helper.ts b/TestScripts/deprecated/playwright/helpers/date-picker.helper.ts similarity index 100% rename from TestScripts/playwright/helpers/date-picker.helper.ts rename to TestScripts/deprecated/playwright/helpers/date-picker.helper.ts diff --git a/TestScripts/playwright/helpers/file-upload.helper.ts b/TestScripts/deprecated/playwright/helpers/file-upload.helper.ts similarity index 100% rename from TestScripts/playwright/helpers/file-upload.helper.ts rename to TestScripts/deprecated/playwright/helpers/file-upload.helper.ts diff --git a/TestScripts/playwright/helpers/index.ts b/TestScripts/deprecated/playwright/helpers/index.ts similarity index 100% rename from TestScripts/playwright/helpers/index.ts rename to TestScripts/deprecated/playwright/helpers/index.ts diff --git a/TestScripts/playwright/helpers/navigation.helper.ts b/TestScripts/deprecated/playwright/helpers/navigation.helper.ts similarity index 100% rename from TestScripts/playwright/helpers/navigation.helper.ts rename to TestScripts/deprecated/playwright/helpers/navigation.helper.ts diff --git a/TestScripts/playwright/helpers/radzen.helper.ts b/TestScripts/deprecated/playwright/helpers/radzen.helper.ts similarity index 100% rename from TestScripts/playwright/helpers/radzen.helper.ts rename to TestScripts/deprecated/playwright/helpers/radzen.helper.ts diff --git a/TestScripts/playwright/helpers/search-type.helper.ts b/TestScripts/deprecated/playwright/helpers/search-type.helper.ts similarity index 100% rename from TestScripts/playwright/helpers/search-type.helper.ts rename to TestScripts/deprecated/playwright/helpers/search-type.helper.ts diff --git a/TestScripts/playwright/helpers/validation.helper.ts b/TestScripts/deprecated/playwright/helpers/validation.helper.ts similarity index 100% rename from TestScripts/playwright/helpers/validation.helper.ts rename to TestScripts/deprecated/playwright/helpers/validation.helper.ts diff --git a/TestScripts/playwright/package-lock.json b/TestScripts/deprecated/playwright/package-lock.json similarity index 100% rename from TestScripts/playwright/package-lock.json rename to TestScripts/deprecated/playwright/package-lock.json diff --git a/TestScripts/playwright/package.json b/TestScripts/deprecated/playwright/package.json similarity index 100% rename from TestScripts/playwright/package.json rename to TestScripts/deprecated/playwright/package.json diff --git a/TestScripts/playwright/playwright-report/index.html b/TestScripts/deprecated/playwright/playwright-report/index.html similarity index 100% rename from TestScripts/playwright/playwright-report/index.html rename to TestScripts/deprecated/playwright/playwright-report/index.html diff --git a/TestScripts/playwright/playwright.config.ts b/TestScripts/deprecated/playwright/playwright.config.ts similarity index 100% rename from TestScripts/playwright/playwright.config.ts rename to TestScripts/deprecated/playwright/playwright.config.ts diff --git a/TestScripts/playwright/scripts/create-test-excel.js b/TestScripts/deprecated/playwright/scripts/create-test-excel.js similarity index 100% rename from TestScripts/playwright/scripts/create-test-excel.js rename to TestScripts/deprecated/playwright/scripts/create-test-excel.js diff --git a/TestScripts/deprecated/playwright/test-data/empty_file.xlsx b/TestScripts/deprecated/playwright/test-data/empty_file.xlsx new file mode 100644 index 0000000..097cb81 Binary files /dev/null and b/TestScripts/deprecated/playwright/test-data/empty_file.xlsx differ diff --git a/TestScripts/deprecated/playwright/test-data/invalid_format.txt b/TestScripts/deprecated/playwright/test-data/invalid_format.txt new file mode 100644 index 0000000..3df86f3 --- /dev/null +++ b/TestScripts/deprecated/playwright/test-data/invalid_format.txt @@ -0,0 +1,2 @@ +This is not a valid Excel file +Just plain text \ No newline at end of file diff --git a/TestScripts/deprecated/playwright/test-data/invalid_workorders.xlsx b/TestScripts/deprecated/playwright/test-data/invalid_workorders.xlsx new file mode 100644 index 0000000..c0e5a0d Binary files /dev/null and b/TestScripts/deprecated/playwright/test-data/invalid_workorders.xlsx differ diff --git a/TestScripts/deprecated/playwright/test-data/max_workorders.xlsx b/TestScripts/deprecated/playwright/test-data/max_workorders.xlsx new file mode 100644 index 0000000..9d6a4c4 Binary files /dev/null and b/TestScripts/deprecated/playwright/test-data/max_workorders.xlsx differ diff --git a/TestScripts/deprecated/playwright/test-data/multiple_items.xlsx b/TestScripts/deprecated/playwright/test-data/multiple_items.xlsx new file mode 100644 index 0000000..0326409 Binary files /dev/null and b/TestScripts/deprecated/playwright/test-data/multiple_items.xlsx differ diff --git a/TestScripts/deprecated/playwright/test-data/multiple_lots.xlsx b/TestScripts/deprecated/playwright/test-data/multiple_lots.xlsx new file mode 100644 index 0000000..5ecc266 Binary files /dev/null and b/TestScripts/deprecated/playwright/test-data/multiple_lots.xlsx differ diff --git a/TestScripts/deprecated/playwright/test-data/multiple_operations.xlsx b/TestScripts/deprecated/playwright/test-data/multiple_operations.xlsx new file mode 100644 index 0000000..395ef6d Binary files /dev/null and b/TestScripts/deprecated/playwright/test-data/multiple_operations.xlsx differ diff --git a/TestScripts/deprecated/playwright/test-data/multiple_workorders.xlsx b/TestScripts/deprecated/playwright/test-data/multiple_workorders.xlsx new file mode 100644 index 0000000..5f1b2af Binary files /dev/null and b/TestScripts/deprecated/playwright/test-data/multiple_workorders.xlsx differ diff --git a/TestScripts/deprecated/playwright/test-data/single_item.xlsx b/TestScripts/deprecated/playwright/test-data/single_item.xlsx new file mode 100644 index 0000000..6ba8707 Binary files /dev/null and b/TestScripts/deprecated/playwright/test-data/single_item.xlsx differ diff --git a/TestScripts/deprecated/playwright/test-data/single_lot.xlsx b/TestScripts/deprecated/playwright/test-data/single_lot.xlsx new file mode 100644 index 0000000..909b0e2 Binary files /dev/null and b/TestScripts/deprecated/playwright/test-data/single_lot.xlsx differ diff --git a/TestScripts/deprecated/playwright/test-data/single_operation.xlsx b/TestScripts/deprecated/playwright/test-data/single_operation.xlsx new file mode 100644 index 0000000..999ecbe Binary files /dev/null and b/TestScripts/deprecated/playwright/test-data/single_operation.xlsx differ diff --git a/TestScripts/deprecated/playwright/test-data/single_workorder.xlsx b/TestScripts/deprecated/playwright/test-data/single_workorder.xlsx new file mode 100644 index 0000000..a71dc24 Binary files /dev/null and b/TestScripts/deprecated/playwright/test-data/single_workorder.xlsx differ diff --git a/TestScripts/deprecated/playwright/test-data/special_chars_workorders.xlsx b/TestScripts/deprecated/playwright/test-data/special_chars_workorders.xlsx new file mode 100644 index 0000000..9363abb Binary files /dev/null and b/TestScripts/deprecated/playwright/test-data/special_chars_workorders.xlsx differ diff --git a/TestScripts/playwright/test-data/test-data.json b/TestScripts/deprecated/playwright/test-data/test-data.json similarity index 100% rename from TestScripts/playwright/test-data/test-data.json rename to TestScripts/deprecated/playwright/test-data/test-data.json diff --git a/TestScripts/playwright/test-results/.last-run.json b/TestScripts/deprecated/playwright/test-results/.last-run.json similarity index 100% rename from TestScripts/playwright/test-results/.last-run.json rename to TestScripts/deprecated/playwright/test-results/.last-run.json diff --git a/TestScripts/playwright/tests/component-lot.spec.ts b/TestScripts/deprecated/playwright/tests/component-lot.spec.ts similarity index 100% rename from TestScripts/playwright/tests/component-lot.spec.ts rename to TestScripts/deprecated/playwright/tests/component-lot.spec.ts diff --git a/TestScripts/playwright/tests/data-sync.spec.ts b/TestScripts/deprecated/playwright/tests/data-sync.spec.ts similarity index 100% rename from TestScripts/playwright/tests/data-sync.spec.ts rename to TestScripts/deprecated/playwright/tests/data-sync.spec.ts diff --git a/TestScripts/playwright/tests/login.spec.ts b/TestScripts/deprecated/playwright/tests/login.spec.ts similarity index 100% rename from TestScripts/playwright/tests/login.spec.ts rename to TestScripts/deprecated/playwright/tests/login.spec.ts diff --git a/TestScripts/playwright/tests/refresh-status.spec.ts b/TestScripts/deprecated/playwright/tests/refresh-status.spec.ts similarity index 100% rename from TestScripts/playwright/tests/refresh-status.spec.ts rename to TestScripts/deprecated/playwright/tests/refresh-status.spec.ts diff --git a/TestScripts/playwright/tests/search-page.spec.ts b/TestScripts/deprecated/playwright/tests/search-page.spec.ts similarity index 100% rename from TestScripts/playwright/tests/search-page.spec.ts rename to TestScripts/deprecated/playwright/tests/search-page.spec.ts diff --git a/TestScripts/playwright/tests/search-queue.spec.ts b/TestScripts/deprecated/playwright/tests/search-queue.spec.ts similarity index 100% rename from TestScripts/playwright/tests/search-queue.spec.ts rename to TestScripts/deprecated/playwright/tests/search-queue.spec.ts diff --git a/TestScripts/playwright/tests/searches-dashboard.spec.ts b/TestScripts/deprecated/playwright/tests/searches-dashboard.spec.ts similarity index 100% rename from TestScripts/playwright/tests/searches-dashboard.spec.ts rename to TestScripts/deprecated/playwright/tests/searches-dashboard.spec.ts diff --git a/TestScripts/playwright/tests/timespan-item-number.spec.ts b/TestScripts/deprecated/playwright/tests/timespan-item-number.spec.ts similarity index 100% rename from TestScripts/playwright/tests/timespan-item-number.spec.ts rename to TestScripts/deprecated/playwright/tests/timespan-item-number.spec.ts diff --git a/TestScripts/playwright/tests/timespan-operator.spec.ts b/TestScripts/deprecated/playwright/tests/timespan-operator.spec.ts similarity index 100% rename from TestScripts/playwright/tests/timespan-operator.spec.ts rename to TestScripts/deprecated/playwright/tests/timespan-operator.spec.ts diff --git a/TestScripts/playwright/tests/timespan-pc-extractmis.spec.ts b/TestScripts/deprecated/playwright/tests/timespan-pc-extractmis.spec.ts similarity index 100% rename from TestScripts/playwright/tests/timespan-pc-extractmis.spec.ts rename to TestScripts/deprecated/playwright/tests/timespan-pc-extractmis.spec.ts diff --git a/TestScripts/playwright/tests/timespan-pc-item.spec.ts b/TestScripts/deprecated/playwright/tests/timespan-pc-item.spec.ts similarity index 100% rename from TestScripts/playwright/tests/timespan-pc-item.spec.ts rename to TestScripts/deprecated/playwright/tests/timespan-pc-item.spec.ts diff --git a/TestScripts/playwright/tests/timespan-pc-operator.spec.ts b/TestScripts/deprecated/playwright/tests/timespan-pc-operator.spec.ts similarity index 100% rename from TestScripts/playwright/tests/timespan-pc-operator.spec.ts rename to TestScripts/deprecated/playwright/tests/timespan-pc-operator.spec.ts diff --git a/TestScripts/playwright/tests/timespan-pc-partop.spec.ts b/TestScripts/deprecated/playwright/tests/timespan-pc-partop.spec.ts similarity index 100% rename from TestScripts/playwright/tests/timespan-pc-partop.spec.ts rename to TestScripts/deprecated/playwright/tests/timespan-pc-partop.spec.ts diff --git a/TestScripts/playwright/tests/timespan-pc-wo-partop.spec.ts b/TestScripts/deprecated/playwright/tests/timespan-pc-wo-partop.spec.ts similarity index 100% rename from TestScripts/playwright/tests/timespan-pc-wo-partop.spec.ts rename to TestScripts/deprecated/playwright/tests/timespan-pc-wo-partop.spec.ts diff --git a/TestScripts/playwright/tests/timespan-profit-center.spec.ts b/TestScripts/deprecated/playwright/tests/timespan-profit-center.spec.ts similarity index 100% rename from TestScripts/playwright/tests/timespan-profit-center.spec.ts rename to TestScripts/deprecated/playwright/tests/timespan-profit-center.spec.ts diff --git a/TestScripts/playwright/tests/timespan-wc-extractmis.spec.ts b/TestScripts/deprecated/playwright/tests/timespan-wc-extractmis.spec.ts similarity index 100% rename from TestScripts/playwright/tests/timespan-wc-extractmis.spec.ts rename to TestScripts/deprecated/playwright/tests/timespan-wc-extractmis.spec.ts diff --git a/TestScripts/playwright/tests/timespan-wc-item.spec.ts b/TestScripts/deprecated/playwright/tests/timespan-wc-item.spec.ts similarity index 100% rename from TestScripts/playwright/tests/timespan-wc-item.spec.ts rename to TestScripts/deprecated/playwright/tests/timespan-wc-item.spec.ts diff --git a/TestScripts/playwright/tests/timespan-wc-operator.spec.ts b/TestScripts/deprecated/playwright/tests/timespan-wc-operator.spec.ts similarity index 100% rename from TestScripts/playwright/tests/timespan-wc-operator.spec.ts rename to TestScripts/deprecated/playwright/tests/timespan-wc-operator.spec.ts diff --git a/TestScripts/playwright/tests/timespan-wc-partop.spec.ts b/TestScripts/deprecated/playwright/tests/timespan-wc-partop.spec.ts similarity index 100% rename from TestScripts/playwright/tests/timespan-wc-partop.spec.ts rename to TestScripts/deprecated/playwright/tests/timespan-wc-partop.spec.ts diff --git a/TestScripts/playwright/tests/timespan-wc-wo-partop.spec.ts b/TestScripts/deprecated/playwright/tests/timespan-wc-wo-partop.spec.ts similarity index 100% rename from TestScripts/playwright/tests/timespan-wc-wo-partop.spec.ts rename to TestScripts/deprecated/playwright/tests/timespan-wc-wo-partop.spec.ts diff --git a/TestScripts/playwright/tests/timespan-work-center.spec.ts b/TestScripts/deprecated/playwright/tests/timespan-work-center.spec.ts similarity index 100% rename from TestScripts/playwright/tests/timespan-work-center.spec.ts rename to TestScripts/deprecated/playwright/tests/timespan-work-center.spec.ts diff --git a/TestScripts/playwright/tests/work-order.spec.ts b/TestScripts/deprecated/playwright/tests/work-order.spec.ts similarity index 100% rename from TestScripts/playwright/tests/work-order.spec.ts rename to TestScripts/deprecated/playwright/tests/work-order.spec.ts