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, clearDateRange, TestDateRanges } from '../helpers/date-picker.helper'; import { addProfitCenter, addProfitCenters, clearAutocompleteItems, profitCenterConfig, getAutocompleteItemCount, removeAutocompleteItem, isAutocompletePanelVisible, } from '../helpers/autocomplete.helper'; import { assertNoErrorNotification, hasSuccessNotification } from '../helpers/radzen.helper'; import { hasValidationErrors, submitAndExpectError, ValidationMessages } from '../helpers/validation.helper'; /** * Test suite for Search Type 30: Time Span + Profit Center * * This search type allows users to search by a date range combined with * one or more profit center (branch) codes. * * Filters Enabled: Timespan, Profit Center */ test.describe('Search Type 30: Time Span + Profit Center', () => { test.beforeEach(async ({ page }) => { await navigateToSearchPage(page); }); // ============================================================================ // POSITIVE TEST CASES // ============================================================================ test.describe('Positive Tests', () => { test('TC-030-P01: Single profit center with standard date range', async ({ page }) => { // Select search type await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); // Verify filter panel is visible await expect(page.locator('text=Filter by Profit Center')).toBeVisible(); await expect(page.locator('text=Filter by Time Span')).toBeVisible(); // Enter search name await enterSearchName(page, 'TC-030-P01 Single Profit Center'); // Set date range await setDateRange(page, '2020-01-01', '2020-09-01'); // Add profit center await addProfitCenter(page, '1AM'); // Verify profit center appears in the list const itemCount = await getAutocompleteItemCount(page, profitCenterConfig); expect(itemCount).toBe(1); // Submit search await clickSubmitSearch(page); await confirmSubmitSearch(page); // Verify no error notification await assertNoErrorNotification(page); }); test('TC-030-P02: Multiple profit centers search', async ({ page }) => { await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); await enterSearchName(page, 'TC-030-P02 Multiple Profit Centers'); // Set date range await setDateRange(page, '2019-01-01', '2019-12-31'); // Add multiple profit centers await addProfitCenters(page, ['1AM', '1PM', '2DM']); // Verify all profit centers appear in the list const itemCount = await getAutocompleteItemCount(page, profitCenterConfig); expect(itemCount).toBe(3); // Submit search await clickSubmitSearch(page); await confirmSubmitSearch(page); await assertNoErrorNotification(page); }); test('TC-030-P03: All profit centers search', async ({ page }) => { await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); await enterSearchName(page, 'TC-030-P03 All Profit Centers'); // Set date range await setDateRange(page, '2018-01-01', '2018-12-31'); // Add all profit centers const allProfitCenters = ['1AM', '1BM', '1CM', '1PM', '2DM', '2SM', '3TM', '4IM', '5SM']; await addProfitCenters(page, allProfitCenters); // Verify all profit centers appear in the list const itemCount = await getAutocompleteItemCount(page, profitCenterConfig); expect(itemCount).toBe(9); // Submit search await clickSubmitSearch(page); await confirmSubmitSearch(page); await assertNoErrorNotification(page); }); test('TC-030-P04: Minimum date range (same day)', async ({ page }) => { await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); await enterSearchName(page, 'TC-030-P04 Same Day Range'); // Set same day date range await setDateRange(page, TestDateRanges.SAME_DAY.min, TestDateRanges.SAME_DAY.max); // Add profit center await addProfitCenter(page, '1PM'); // Submit search await clickSubmitSearch(page); await confirmSubmitSearch(page); await assertNoErrorNotification(page); }); test('TC-030-P05: Boundary date - start of data range', async ({ page }) => { await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); await enterSearchName(page, 'TC-030-P05 Start Boundary'); // Set earliest date boundary (1905-01-20 to 1905-12-31) await setDateRange(page, TestDateRanges.START_BOUNDARY.min, TestDateRanges.START_BOUNDARY.max); // Add profit center await addProfitCenter(page, '1AM'); // Submit search await clickSubmitSearch(page); await confirmSubmitSearch(page); await assertNoErrorNotification(page); }); test('TC-030-P06: Boundary date - end of data range', async ({ page }) => { await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); await enterSearchName(page, 'TC-030-P06 End Boundary'); // Set latest date boundary (2020-08-01 to 2020-09-01) await setDateRange(page, TestDateRanges.END_BOUNDARY.min, TestDateRanges.END_BOUNDARY.max); // Add profit center await addProfitCenter(page, '1CM'); // Submit search await clickSubmitSearch(page); await confirmSubmitSearch(page); await assertNoErrorNotification(page); }); test('TC-030-P07: Historical date range search', async ({ page }) => { await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); await enterSearchName(page, 'TC-030-P07 Historical Search'); // Set historical date range (2016-01-01 to 2017-12-31) await setDateRange(page, TestDateRanges.HISTORICAL.min, TestDateRanges.HISTORICAL.max); // Add profit center await addProfitCenter(page, '2SM'); // Submit search await clickSubmitSearch(page); await confirmSubmitSearch(page); await assertNoErrorNotification(page); }); test('TC-030-P08: Profit center remove and re-add', async ({ page }) => { await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); await enterSearchName(page, 'TC-030-P08 PC Remove Re-add'); // Set date range await setDateRange(page, '2019-01-01', '2019-12-31'); // Add profit centers await addProfitCenter(page, '1AM'); await addProfitCenter(page, '1BM'); // Verify both are added let itemCount = await getAutocompleteItemCount(page, profitCenterConfig); expect(itemCount).toBe(2); // Remove first profit center (1AM) await removeAutocompleteItem(page, profitCenterConfig, 0); // Verify only one remains itemCount = await getAutocompleteItemCount(page, profitCenterConfig); expect(itemCount).toBe(1); // Add another profit center await addProfitCenter(page, '1CM'); // Verify two profit centers in list (1BM and 1CM) itemCount = await getAutocompleteItemCount(page, profitCenterConfig); expect(itemCount).toBe(2); // Submit search await clickSubmitSearch(page); await confirmSubmitSearch(page); await assertNoErrorNotification(page); }); }); // ============================================================================ // NEGATIVE TEST CASES // ============================================================================ test.describe('Negative Tests', () => { test('TC-030-N01: Missing search name', async ({ page }) => { await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); // Do NOT enter search name // Set valid date range await setDateRange(page, '2020-01-01', '2020-09-01'); // Add profit center await addProfitCenter(page, '1AM'); // Attempt to submit await submitAndExpectError(page); // Verify user remains on the page await expect(page.locator('text=Filter by Profit Center')).toBeVisible(); }); test('TC-030-N02: No search type selected', async ({ page }) => { // Enter search name without selecting search type await enterSearchName(page, 'TC-030-N02 No Type'); // Verify filter panels are not visible (search type not selected) const profitCenterPanelVisible = await isAutocompletePanelVisible(page, profitCenterConfig); expect(profitCenterPanelVisible).toBe(false); // Attempt to submit await submitAndExpectError(page); }); test('TC-030-N03: Missing minimum date', async ({ page }) => { await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); await enterSearchName(page, 'TC-030-N03 Missing Min Date'); // Only set maximum date await setMaxDate(page, '2020-09-01'); // Add profit center await addProfitCenter(page, '1AM'); // Attempt to submit await submitAndExpectError(page); }); test('TC-030-N04: Missing maximum date', async ({ page }) => { await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); await enterSearchName(page, 'TC-030-N04 Missing Max Date'); // Only set minimum date await setMinDate(page, '2020-01-01'); // Add profit center await addProfitCenter(page, '1AM'); // Attempt to submit await submitAndExpectError(page); }); test('TC-030-N05: Empty profit center list', async ({ page }) => { await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); await enterSearchName(page, 'TC-030-N05 Empty Profit Centers'); // Set valid date range await setDateRange(page, '2020-01-01', '2020-09-01'); // Do NOT add any profit centers // Verify profit center list is empty const itemCount = await getAutocompleteItemCount(page, profitCenterConfig); expect(itemCount).toBe(0); // Attempt to submit await submitAndExpectError(page); }); test('TC-030-N06: Invalid date range (min > max)', async ({ page }) => { await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); await enterSearchName(page, 'TC-030-N06 Invalid Date Range'); // Set invalid date range (min date after max date) await setDateRange(page, TestDateRanges.INVALID_REVERSED.min, TestDateRanges.INVALID_REVERSED.max); // Add profit center await addProfitCenter(page, '1AM'); // Attempt to submit await submitAndExpectError(page); }); test('TC-030-N07: Invalid profit center code', async ({ page }) => { await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); await enterSearchName(page, 'TC-030-N07 Invalid PC Code'); // Set valid date range await setDateRange(page, '2020-01-01', '2020-09-01'); // Try to add invalid profit center // The autocomplete should not find any matches for "INVALID" const panel = page.locator(`.rz-card:has-text("${profitCenterConfig.panelHeader}")`); const autocomplete = panel.locator('.rz-autocomplete input'); await autocomplete.fill('INVALID'); // Wait for autocomplete to search await page.waitForTimeout(500); // Verify no autocomplete suggestions appear const dropdown = page.locator('.rz-autocomplete-list'); const dropdownVisible = await dropdown.isVisible({ timeout: 2000 }).catch(() => false); // If dropdown is not visible or empty, the invalid code is rejected if (dropdownVisible) { const items = dropdown.locator('.rz-autocomplete-list-item'); const count = await items.count(); expect(count).toBe(0); } // Verify profit center list is still empty const itemCount = await getAutocompleteItemCount(page, profitCenterConfig); expect(itemCount).toBe(0); }); test('TC-030-N08: Future date range', async ({ page }) => { await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); await enterSearchName(page, 'TC-030-N08 Future Dates'); // Set future date range await setDateRange(page, TestDateRanges.FUTURE.min, TestDateRanges.FUTURE.max); // Add profit center await addProfitCenter(page, '1AM'); // Submit search - may be accepted but will return no results // or may show validation warning await clickSubmitSearch(page); // Check if there's a validation error or if it proceeds const hasErrors = await hasValidationErrors(page); if (!hasErrors) { // If accepted, confirm the submission await confirmSubmitSearch(page); await assertNoErrorNotification(page); } // If there are validation errors, that's also acceptable behavior }); test('TC-030-N09: Invalid date format', async ({ page }) => { await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); await enterSearchName(page, 'TC-030-N09 Invalid Date Format'); // Try to enter invalid date format directly // The Radzen date picker should prevent or reject invalid formats const minDateInput = page.locator('input[name="MinimumDt"]'); await minDateInput.fill('31-12-2020'); // Invalid format await setMaxDate(page, '2020-09-01'); // Add profit center await addProfitCenter(page, '1AM'); // Attempt to submit - should fail validation await submitAndExpectError(page); }); test('TC-030-N10: Profit center with special characters', async ({ page }) => { await selectSearchType(page, SearchTypes.TIMESPAN_PROFIT_CENTER); await enterSearchName(page, 'TC-030-N10 PC Special Chars'); // Set valid date range await setDateRange(page, '2020-01-01', '2020-09-01'); // Try to add profit center with special characters const panel = page.locator(`.rz-card:has-text("${profitCenterConfig.panelHeader}")`); const autocomplete = panel.locator('.rz-autocomplete input'); await autocomplete.fill('1AM!@#'); // Wait for autocomplete to search await page.waitForTimeout(500); // Verify no autocomplete suggestions appear for invalid input const dropdown = page.locator('.rz-autocomplete-list'); const dropdownVisible = await dropdown.isVisible({ timeout: 2000 }).catch(() => false); if (dropdownVisible) { const items = dropdown.locator('.rz-autocomplete-list-item'); const count = await items.count(); expect(count).toBe(0); } // Verify profit center list is still empty const itemCount = await getAutocompleteItemCount(page, profitCenterConfig); expect(itemCount).toBe(0); }); }); });