/** * Playwright E2E tests for Search Type 130: * Time Span + Work Center + Work Order + Item/Operation/MIS * * This search type allows users to search for work order data within a specific * date range, filtered by work center, work order number, and part operation details. * * Filters Enabled: * - Timespan (Start Date, End Date) * - Work Center (autocomplete) * - Work Order (file upload) * - Item/Operation/MIS (Part Operations - file upload) */ import { test, expect } from '@playwright/test'; import { navigateToSearchPage } from '../helpers/navigation.helper'; import { selectSearchType, SearchTypes, enterSearchName, clickSubmitSearch, confirmSubmitSearch } from '../helpers/search-type.helper'; import { setDateRange, setMinDate, setMaxDate, clearMinDate, clearMaxDate, TestDateRanges } from '../helpers/date-picker.helper'; import { addWorkCenter, addWorkCenters, workCenterConfig, getAutocompleteItemCount, isAutocompletePanelVisible } from '../helpers/autocomplete.helper'; import { uploadFile, workOrderConfig, partOperationConfig, getTestFile, TestFiles, getUploadedItemCount, isFileUploadPanelVisible } from '../helpers/file-upload.helper'; import { assertNoErrorNotification, hasErrorNotification } from '../helpers/radzen.helper'; import { hasValidationErrors, submitAndExpectError, ValidationMessages } from '../helpers/validation.helper'; // Test data constants for Type 130 const TYPE_130_NAME = SearchTypes.TIMESPAN_WC_WO_PARTOP; // Valid work centers from test documentation const VALID_WORK_CENTERS = ['0083AS', '0278AS', '0424AS', '0586AS', '0696AS', '1010AS', '1011AS', '10595CA', '11275CA', '11350CA']; // Standard date ranges for testing const STANDARD_DATE_RANGE = { min: '2018-01-01', max: '2020-09-01' }; const RECENT_DATE_RANGE = TestDateRanges.RECENT; const HISTORICAL_DATE_RANGE = TestDateRanges.HISTORICAL; const NARROW_DATE_RANGE = { min: '2020-06-01', max: '2020-06-30' }; const INVALID_DATE_RANGE = TestDateRanges.INVALID_REVERSED; test.describe('Search Type 130: Time Span + Work Center + Work Order + Item/Operation/MIS', () => { test.beforeEach(async ({ page }) => { await navigateToSearchPage(page); }); test.describe('Positive Test Cases', () => { test('TC-130-P01: Single values for all filters', async ({ page }) => { // Step 1: Enter search name await enterSearchName(page, 'TC-130-P01 Single Values'); // Step 2: Select search type await selectSearchType(page, TYPE_130_NAME); // Verify all filter panels are visible expect(await isAutocompletePanelVisible(page, workCenterConfig)).toBe(true); expect(await isFileUploadPanelVisible(page, workOrderConfig)).toBe(true); expect(await isFileUploadPanelVisible(page, partOperationConfig)).toBe(true); // Step 3: Set date range await setDateRange(page, STANDARD_DATE_RANGE.min, STANDARD_DATE_RANGE.max); // Step 4: Add single work center await addWorkCenter(page, '1010AS'); expect(await getAutocompleteItemCount(page, workCenterConfig)).toBe(1); // Step 5: Upload single work order file await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); // Step 6: Upload single part operation file await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); // Step 7: Submit search await clickSubmitSearch(page); await confirmSubmitSearch(page); // Verify no error notification await assertNoErrorNotification(page); }); test('TC-130-P02: Multiple work centers', async ({ page }) => { await enterSearchName(page, 'TC-130-P02 Multiple Work Centers'); await selectSearchType(page, TYPE_130_NAME); await setDateRange(page, '2019-01-01', STANDARD_DATE_RANGE.max); // Add multiple work centers await addWorkCenters(page, ['0083AS', '1010AS', '1011AS']); expect(await getAutocompleteItemCount(page, workCenterConfig)).toBe(3); await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); await clickSubmitSearch(page); await confirmSubmitSearch(page); await assertNoErrorNotification(page); }); test('TC-130-P03: Multiple work orders', async ({ page }) => { await enterSearchName(page, 'TC-130-P03 Multiple Work Orders'); await selectSearchType(page, TYPE_130_NAME); await setDateRange(page, STANDARD_DATE_RANGE.min, '2019-12-31'); await addWorkCenter(page, '0424AS'); // Upload multiple work orders await uploadFile(page, workOrderConfig, getTestFile(TestFiles.MULTIPLE_WORKORDERS)); const woCount = await getUploadedItemCount(page, workOrderConfig); expect(woCount).toBeGreaterThan(1); await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); await clickSubmitSearch(page); await confirmSubmitSearch(page); await assertNoErrorNotification(page); }); test('TC-130-P04: Multiple part operations', async ({ page }) => { await enterSearchName(page, 'TC-130-P04 Multiple Part Ops'); await selectSearchType(page, TYPE_130_NAME); await setDateRange(page, STANDARD_DATE_RANGE.min, STANDARD_DATE_RANGE.max); await addWorkCenter(page, '0586AS'); await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); // Upload multiple part operations await uploadFile(page, partOperationConfig, getTestFile(TestFiles.MULTIPLE_OPERATIONS)); const opCount = await getUploadedItemCount(page, partOperationConfig); expect(opCount).toBeGreaterThan(1); await clickSubmitSearch(page); await confirmSubmitSearch(page); await assertNoErrorNotification(page); }); test('TC-130-P05: All filters with multiple values', async ({ page }) => { await enterSearchName(page, 'TC-130-P05 All Multiple Values'); await selectSearchType(page, TYPE_130_NAME); await setDateRange(page, STANDARD_DATE_RANGE.min, STANDARD_DATE_RANGE.max); // Multiple work centers await addWorkCenters(page, ['1010AS', '11275CA']); expect(await getAutocompleteItemCount(page, workCenterConfig)).toBe(2); // Multiple work orders await uploadFile(page, workOrderConfig, getTestFile(TestFiles.MULTIPLE_WORKORDERS)); // Multiple part operations await uploadFile(page, partOperationConfig, getTestFile(TestFiles.MULTIPLE_OPERATIONS)); await clickSubmitSearch(page); await confirmSubmitSearch(page); await assertNoErrorNotification(page); }); test('TC-130-P06: Historical date range', async ({ page }) => { await enterSearchName(page, 'TC-130-P06 Historical Range'); await selectSearchType(page, TYPE_130_NAME); // Use historical date range await setDateRange(page, HISTORICAL_DATE_RANGE.min, HISTORICAL_DATE_RANGE.max); await addWorkCenter(page, '10595CA'); await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); await clickSubmitSearch(page); await confirmSubmitSearch(page); await assertNoErrorNotification(page); }); test('TC-130-P07: Narrow date range (same month)', async ({ page }) => { await enterSearchName(page, 'TC-130-P07 Narrow Date Range'); await selectSearchType(page, TYPE_130_NAME); // Use narrow date range (single month) await setDateRange(page, NARROW_DATE_RANGE.min, NARROW_DATE_RANGE.max); await addWorkCenter(page, '0696AS'); await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); await clickSubmitSearch(page); await confirmSubmitSearch(page); await assertNoErrorNotification(page); }); test('TC-130-P08: Recent date range', async ({ page }) => { await enterSearchName(page, 'TC-130-P08 Recent Date Range'); await selectSearchType(page, TYPE_130_NAME); // Use recent date range await setDateRange(page, RECENT_DATE_RANGE.min, RECENT_DATE_RANGE.max); await addWorkCenter(page, '0278AS'); await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); await clickSubmitSearch(page); await confirmSubmitSearch(page); await assertNoErrorNotification(page); }); test('TC-130-P09: All work centers with different formats', async ({ page }) => { await enterSearchName(page, 'TC-130-P09 Mixed Work Center Formats'); await selectSearchType(page, TYPE_130_NAME); await setDateRange(page, STANDARD_DATE_RANGE.min, STANDARD_DATE_RANGE.max); // Add work centers with different formats (AS vs CA suffix) await addWorkCenters(page, ['0083AS', '10595CA', '11275CA']); expect(await getAutocompleteItemCount(page, workCenterConfig)).toBe(3); await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); await clickSubmitSearch(page); await confirmSubmitSearch(page); await assertNoErrorNotification(page); }); test('TC-130-P10: Maximum work orders file', async ({ page }) => { await enterSearchName(page, 'TC-130-P10 Max Work Orders'); await selectSearchType(page, TYPE_130_NAME); await setDateRange(page, STANDARD_DATE_RANGE.min, STANDARD_DATE_RANGE.max); await addWorkCenter(page, '1011AS'); // Upload maximum work orders await uploadFile(page, workOrderConfig, getTestFile(TestFiles.MULTIPLE_WORKORDERS)); await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); await clickSubmitSearch(page); await confirmSubmitSearch(page); await assertNoErrorNotification(page); }); }); test.describe('Negative Test Cases', () => { test('TC-130-N01: Missing required date range', async ({ page }) => { await enterSearchName(page, 'TC-130-N01 No Dates'); await selectSearchType(page, TYPE_130_NAME); // Do NOT set any dates await clearMinDate(page); await clearMaxDate(page); await addWorkCenter(page, '1010AS'); await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); await submitAndExpectError(page); }); test('TC-130-N02: Missing work center', async ({ page }) => { await enterSearchName(page, 'TC-130-N02 No Work Center'); await selectSearchType(page, TYPE_130_NAME); await setDateRange(page, STANDARD_DATE_RANGE.min, STANDARD_DATE_RANGE.max); // Do NOT add work center await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); await submitAndExpectError(page); }); test('TC-130-N03: Missing work order', async ({ page }) => { await enterSearchName(page, 'TC-130-N03 No Work Order'); await selectSearchType(page, TYPE_130_NAME); await setDateRange(page, STANDARD_DATE_RANGE.min, STANDARD_DATE_RANGE.max); await addWorkCenter(page, '1010AS'); // Do NOT upload work order await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); await submitAndExpectError(page); }); test('TC-130-N04: Missing part operation', async ({ page }) => { await enterSearchName(page, 'TC-130-N04 No Part Op'); await selectSearchType(page, TYPE_130_NAME); await setDateRange(page, STANDARD_DATE_RANGE.min, STANDARD_DATE_RANGE.max); await addWorkCenter(page, '1010AS'); await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); // Do NOT upload part operation await submitAndExpectError(page); }); test('TC-130-N05: Start date after end date', async ({ page }) => { await enterSearchName(page, 'TC-130-N05 Invalid Date Range'); await selectSearchType(page, TYPE_130_NAME); // Set min date after max date await setDateRange(page, INVALID_DATE_RANGE.min, INVALID_DATE_RANGE.max); await addWorkCenter(page, '1010AS'); await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); await submitAndExpectError(page); }); test('TC-130-N06: Missing minimum date only', async ({ page }) => { await enterSearchName(page, 'TC-130-N06 Missing Min Date'); await selectSearchType(page, TYPE_130_NAME); // Only set max date await clearMinDate(page); await setMaxDate(page, STANDARD_DATE_RANGE.max); await addWorkCenter(page, '1010AS'); await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); await submitAndExpectError(page); }); test('TC-130-N07: Missing search name', async ({ page }) => { // Do NOT enter search name await selectSearchType(page, TYPE_130_NAME); await setDateRange(page, STANDARD_DATE_RANGE.min, STANDARD_DATE_RANGE.max); await addWorkCenter(page, '1010AS'); await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); await submitAndExpectError(page); }); test('TC-130-N08: Missing maximum date only', async ({ page }) => { await enterSearchName(page, 'TC-130-N08 Missing Max Date'); await selectSearchType(page, TYPE_130_NAME); // Only set min date await setMinDate(page, STANDARD_DATE_RANGE.min); await clearMaxDate(page); await addWorkCenter(page, '1010AS'); await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); await submitAndExpectError(page); }); test('TC-130-N09: Whitespace-only search name', async ({ page }) => { // Enter whitespace-only search name await enterSearchName(page, ' '); await selectSearchType(page, TYPE_130_NAME); await setDateRange(page, STANDARD_DATE_RANGE.min, STANDARD_DATE_RANGE.max); await addWorkCenter(page, '1010AS'); await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); await submitAndExpectError(page); }); test('TC-130-N10: Missing all required filters', async ({ page }) => { await enterSearchName(page, 'TC-130-N10 No Filters'); await selectSearchType(page, TYPE_130_NAME); // Do not set any filters await clearMinDate(page); await clearMaxDate(page); await submitAndExpectError(page); }); test('TC-130-N11: Empty work order file', async ({ page }) => { await enterSearchName(page, 'TC-130-N11 Empty WO File'); await selectSearchType(page, TYPE_130_NAME); await setDateRange(page, STANDARD_DATE_RANGE.min, STANDARD_DATE_RANGE.max); await addWorkCenter(page, '1010AS'); // Upload empty file await uploadFile(page, workOrderConfig, getTestFile(TestFiles.EMPTY_FILE)); await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); // Should either show error notification or validation error const hasError = await hasErrorNotification(page) || await hasValidationErrors(page); if (!hasError) { await submitAndExpectError(page); } }); test('TC-130-N12: Empty part operation file', async ({ page }) => { await enterSearchName(page, 'TC-130-N12 Empty Part Op File'); await selectSearchType(page, TYPE_130_NAME); await setDateRange(page, STANDARD_DATE_RANGE.min, STANDARD_DATE_RANGE.max); await addWorkCenter(page, '1010AS'); await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); // Upload empty file for part operations await uploadFile(page, partOperationConfig, getTestFile(TestFiles.EMPTY_FILE)); // Should either show error notification or validation error const hasError = await hasErrorNotification(page) || await hasValidationErrors(page); if (!hasError) { await submitAndExpectError(page); } }); }); test.describe('Filter Panel Visibility', () => { test('TC-130-V01: All filter panels visible when search type selected', async ({ page }) => { await selectSearchType(page, TYPE_130_NAME); // Verify all four filter panels are visible await expect(page.locator('text=Filter by Time Span')).toBeVisible(); await expect(page.locator('text=Filter by Work Center')).toBeVisible(); await expect(page.locator('text=Filter by Work Order')).toBeVisible(); await expect(page.locator('text=Filter By Item/Operation/MIS')).toBeVisible(); }); test('TC-130-V02: Date inputs are available in time span panel', async ({ page }) => { await selectSearchType(page, TYPE_130_NAME); // Verify date input fields exist const minDateInput = page.locator('input[name="MinimumDt"]'); const maxDateInput = page.locator('input[name="MaximumDt"]'); await expect(minDateInput).toBeVisible(); await expect(maxDateInput).toBeVisible(); }); test('TC-130-V03: Autocomplete available for work center', async ({ page }) => { await selectSearchType(page, TYPE_130_NAME); // Verify autocomplete component exists in work center panel const panel = page.locator(`.rz-card:has-text("${workCenterConfig.panelHeader}")`); const autocomplete = panel.locator('.rz-autocomplete'); await expect(autocomplete).toBeVisible(); }); test('TC-130-V04: File upload available for work order', async ({ page }) => { await selectSearchType(page, TYPE_130_NAME); // Verify file input exists in work order panel const panel = page.locator(`.rz-card:has-text("${workOrderConfig.panelHeader}")`); const fileInput = panel.locator('input[type="file"]'); await expect(fileInput).toBeAttached(); }); test('TC-130-V05: File upload available for part operation', async ({ page }) => { await selectSearchType(page, TYPE_130_NAME); // Verify file input exists in part operation panel const panel = page.locator(`.rz-card:has-text("${partOperationConfig.panelHeader}")`); const fileInput = panel.locator('input[type="file"]'); await expect(fileInput).toBeAttached(); }); }); test.describe('Template Downloads', () => { test('TC-130-T01: Download work order template', async ({ page }) => { await selectSearchType(page, TYPE_130_NAME); const panel = page.locator(`.rz-card:has-text("${workOrderConfig.panelHeader}")`); const downloadPromise = page.waitForEvent('download'); await panel.locator('button:has-text("Download Template")').click(); const download = await downloadPromise; expect(download.suggestedFilename()).toContain('.xlsx'); }); test('TC-130-T02: Download part operation template', async ({ page }) => { await selectSearchType(page, TYPE_130_NAME); const panel = page.locator(`.rz-card:has-text("${partOperationConfig.panelHeader}")`); const downloadPromise = page.waitForEvent('download'); await panel.locator('button:has-text("Download Template")').click(); const download = await downloadPromise; expect(download.suggestedFilename()).toContain('.xlsx'); }); }); test.describe('Data Grid Functionality', () => { test('TC-130-G01: Work order grid shows uploaded data', async ({ page }) => { await selectSearchType(page, TYPE_130_NAME); await uploadFile(page, workOrderConfig, getTestFile(TestFiles.SINGLE_WORKORDER)); // Verify data appears in grid (or no error if data not in DB) const count = await getUploadedItemCount(page, workOrderConfig); // Count can be 0 if work order not found in DB, but should not error await assertNoErrorNotification(page); }); test('TC-130-G02: Part operation grid shows uploaded data', async ({ page }) => { await selectSearchType(page, TYPE_130_NAME); await uploadFile(page, partOperationConfig, getTestFile(TestFiles.SINGLE_OPERATION)); // Verify data appears in grid (or no error if data not in DB) const count = await getUploadedItemCount(page, partOperationConfig); await assertNoErrorNotification(page); }); test('TC-130-G03: Work center grid shows added items', async ({ page }) => { await selectSearchType(page, TYPE_130_NAME); await addWorkCenter(page, '1010AS'); const count = await getAutocompleteItemCount(page, workCenterConfig); expect(count).toBe(1); }); }); });