-
Notifications
You must be signed in to change notification settings - Fork 54
HMS-9726: Add filter type patch tests #1491
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,267 @@ | ||
| import { | ||
| test, | ||
| expect, | ||
| navigateToAdvisories, | ||
| navigateToPackages, | ||
| navigateToSystems, | ||
| closePopupsIfExist, | ||
| openConditionalFilter, | ||
| verifyFilterTypeExists, | ||
| applyFilterSubtype, | ||
| resetFilters, | ||
| waitForTableLoad, | ||
| getPublishDateCutoff, | ||
| parsePublishDateCell, | ||
| } from 'test-utils'; | ||
|
|
||
| /** | ||
| * Filter tests for Patch pages: Advisories, Packages, and Systems. | ||
| */ | ||
|
|
||
| test.describe('Patch Filters', () => { | ||
| test('Filter types on Advisory page', async ({ page, request, systems }) => { | ||
| const system = await systems.add('filter-advisory-test', 'base'); | ||
|
|
||
| // Fetch an advisory ID from the created system | ||
| const advisoriesResponse = await request | ||
| .get(`/api/patch/v3/systems/${system.id}/advisories?limit=1`) | ||
| .then((r) => r.json()); | ||
| const advisoryId = advisoriesResponse?.data?.[0]?.id ?? 'RHSA'; | ||
|
|
||
| await navigateToAdvisories(page); | ||
| await closePopupsIfExist(page); | ||
| await openConditionalFilter(page); | ||
|
|
||
| await test.step('Verify "Advisory" filter with search subtype', async () => { | ||
| await verifyFilterTypeExists(page, 'Advisory'); | ||
| await applyFilterSubtype(page, 'Advisory', { name: advisoryId, inputType: 'search' }); | ||
|
|
||
| // Assert exactly one data row exists (header + 1 row) and that it contains the advisory ID | ||
| const rows = page.getByRole('row'); | ||
| await expect(rows).toHaveCount(2); | ||
| await expect(rows.filter({ hasText: advisoryId })).toHaveCount(1); | ||
|
|
||
| await resetFilters(page); | ||
| }); | ||
|
|
||
| await test.step('Verify "Type" filter with all subtypes', async () => { | ||
| await verifyFilterTypeExists(page, 'Type'); | ||
|
|
||
| // Test each type filter and verify all results match | ||
| for (const typeValue of ['Security', 'Bugfix', 'Enhancement', 'Other']) { | ||
| await applyFilterSubtype(page, 'Type', { name: typeValue, inputType: 'checkbox' }); | ||
|
|
||
| // Get all cells in the Type column using data-label attribute | ||
| const typeCells = page.locator('td[data-label="Type"]'); | ||
| const cellCount = await typeCells.count(); | ||
|
|
||
| if (cellCount > 0) { | ||
| // Verify ALL Type column cells contain the filtered value | ||
| for (let i = 0; i < cellCount; i++) { | ||
| await expect(typeCells.nth(i)).toHaveText(typeValue); | ||
| } | ||
| } | ||
|
|
||
| await resetFilters(page); | ||
| } | ||
| }); | ||
|
|
||
| await test.step('Verify "Severity" filter with all subtypes', async () => { | ||
| await verifyFilterTypeExists(page, 'Severity'); | ||
|
|
||
| // Test each severity filter and verify all results match | ||
| for (const severityValue of ['None', 'Low', 'Moderate', 'Important', 'Critical']) { | ||
| await applyFilterSubtype(page, 'Severity', { name: severityValue, inputType: 'checkbox' }); | ||
|
|
||
| // Get all cells in the Severity column using data-label attribute | ||
| const severityCells = page.locator('td[data-label="Severity"]'); | ||
| const cellCount = await severityCells.count(); | ||
|
|
||
| if (cellCount > 0) { | ||
| // Verify ALL Severity column cells contain the filtered value | ||
| for (let i = 0; i < cellCount; i++) { | ||
| await expect(severityCells.nth(i)).toHaveText(severityValue); | ||
| } | ||
| } | ||
|
|
||
| await resetFilters(page); | ||
| } | ||
| }); | ||
|
|
||
| await test.step('Verify "Publish date" filter with all subtypes', async () => { | ||
| await verifyFilterTypeExists(page, 'Publish date'); | ||
|
|
||
| for (const dateValue of [ | ||
| 'Last 7 days', | ||
| 'Last 30 days', | ||
| 'Last 90 days', | ||
| 'Last year', | ||
| 'More than 1 year ago', | ||
| ]) { | ||
| await applyFilterSubtype(page, 'Publish date', { name: dateValue, inputType: 'option' }); | ||
|
|
||
| await expect(page.getByRole('grid', { name: 'Patch table view' })).toBeVisible(); | ||
|
|
||
| const { minDate, maxDate } = getPublishDateCutoff(dateValue); | ||
| const publishDateCells = page.locator('td[data-label="Publish date"]'); | ||
| const cellCount = await publishDateCells.count(); | ||
|
|
||
| if (cellCount > 0) { | ||
| for (let i = 0; i < cellCount; i++) { | ||
| const text = await publishDateCells.nth(i).textContent(); | ||
| const cellDate = parsePublishDateCell(text ?? ''); | ||
| if (cellDate) { | ||
| if (minDate !== undefined) { | ||
| // Cell shows date only; filter is "not older than X" so date must be >= cutoff | ||
| expect( | ||
| cellDate.getTime(), | ||
| `Publish date "${text}" should not be older than ${dateValue}`, | ||
| ).toBeGreaterThanOrEqual(minDate.getTime()); | ||
| } else if (maxDate !== undefined) { | ||
| // "More than 1 year ago" means date must be before the cutoff | ||
| expect( | ||
| cellDate.getTime(), | ||
| `Publish date "${text}" should be older than 1 year`, | ||
| ).toBeLessThanOrEqual(maxDate.getTime()); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| await resetFilters(page); | ||
| } | ||
| }); | ||
|
|
||
| await test.step('Verify "Reboot" filter with all subtypes', async () => { | ||
| await verifyFilterTypeExists(page, 'Reboot'); | ||
|
|
||
| // Test each reboot filter and verify all results match | ||
| for (const rebootValue of ['Required', 'Not required']) { | ||
| await applyFilterSubtype(page, 'Reboot', { name: rebootValue, inputType: 'checkbox' }); | ||
|
|
||
| // Get all cells in the Reboot column using data-label attribute | ||
| const rebootCells = page.locator('td[data-label="Reboot"]'); | ||
| const cellCount = await rebootCells.count(); | ||
|
|
||
| if (cellCount > 0) { | ||
| // Verify ALL Reboot column cells contain the filtered value | ||
| for (let i = 0; i < cellCount; i++) { | ||
| await expect(rebootCells.nth(i)).toHaveText(rebootValue); | ||
| } | ||
| } | ||
|
|
||
| await resetFilters(page); | ||
| } | ||
| }); | ||
| }); | ||
|
|
||
| test('Filter types on Packages page', async ({ page, systems }) => { | ||
| await systems.add('filter-packages-test', 'base'); | ||
|
|
||
| await navigateToPackages(page); | ||
| await closePopupsIfExist(page); | ||
| await waitForTableLoad(page); | ||
|
|
||
| // Use a package name from the table so the filter is guaranteed to match a visible row | ||
| const firstPackageCell = page.locator('td[data-label="Name"]').first(); | ||
| await firstPackageCell.waitFor({ state: 'visible' }); | ||
| const packageName = (await firstPackageCell.textContent())?.trim(); | ||
| expect(packageName, 'Packages table should have at least one row').toBeDefined(); | ||
|
|
||
| await openConditionalFilter(page); | ||
|
|
||
| await test.step('Verify "Package" filter exists', async () => { | ||
| await verifyFilterTypeExists(page, 'Package'); | ||
xbhouse marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }); | ||
|
|
||
| await test.step('Verify "Package" filter with search displays expected package', async () => { | ||
| await applyFilterSubtype(page, 'Package', { name: packageName!, inputType: 'search' }); | ||
|
|
||
| const rows = page.getByRole('row'); | ||
| await expect(rows).toHaveCount(2); | ||
| await expect(rows.filter({ hasText: packageName })).toHaveCount(1); | ||
|
|
||
| await resetFilters(page); | ||
| }); | ||
|
|
||
| await test.step('Verify "Patch status" filter with all subtypes', async () => { | ||
| await verifyFilterTypeExists(page, 'Patch status'); | ||
xbhouse marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // "Systems up to date": Packages default is "Systems with patches available". Uncheck it | ||
| // first, then check "Systems up to date" so only eq:0 is sent (API drops filter if both are sent). | ||
| await resetFilters(page); | ||
| await openConditionalFilter(page); | ||
| await applyFilterSubtype( | ||
| page, | ||
| 'Patch status', | ||
| { name: 'Systems with patches available', inputType: 'checkbox' }, | ||
| { verifyChip: false }, | ||
| ); | ||
| await openConditionalFilter(page); | ||
| await applyFilterSubtype(page, 'Patch status', { | ||
| name: 'Systems up to date', | ||
| inputType: 'checkbox', | ||
| }); | ||
|
|
||
| let applicableCells = page.locator('td[data-label="Applicable systems"]'); | ||
| let cellCount = await applicableCells.count(); | ||
| if (cellCount > 0) { | ||
| for (let i = 0; i < cellCount; i++) { | ||
| await expect(applicableCells.nth(i)).toHaveText('0'); | ||
| } | ||
| } | ||
|
|
||
| // "Systems with patches available": reset restores default (gt:0); no need to click again. | ||
| await resetFilters(page); | ||
|
|
||
| applicableCells = page.locator('td[data-label="Applicable systems"]'); | ||
| cellCount = await applicableCells.count(); | ||
| if (cellCount > 0) { | ||
| for (let i = 0; i < cellCount; i++) { | ||
| const text = (await applicableCells.nth(i).textContent())?.trim() ?? ''; | ||
| const num = parseInt(text, 10); | ||
| expect( | ||
| Number.isNaN(num) ? 0 : num, | ||
| 'Applicable systems should be > 0 for "Systems with patches available"', | ||
| ).toBeGreaterThan(0); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| await expect(page.getByRole('button', { name: 'Conditional filter toggle' })).toBeVisible(); | ||
| }); | ||
|
|
||
| test('Filter types on Systems page', async ({ page, systems }) => { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the filtered data for systems could be verified for most of these (maybe excluding Tags?)
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, improvements made, thank you
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry, by this comment i meant to verify the data displayed is expected when filtering in the following steps (similar to what you've done for advisories and packages). to test the tags filter, i think this would involve adding a new system archive with a tag (found some docs here that might be helpful)
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for delay, will get to this after PTO
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no worries, thank you for picking this up ❤️ reach out when you get back if you need any help |
||
| await systems.add('filter-systems-test', 'base'); | ||
|
|
||
| await navigateToSystems(page); | ||
| await closePopupsIfExist(page); | ||
| await openConditionalFilter(page); | ||
|
|
||
| await test.step('Verify "Operating system" filter exists', async () => { | ||
| await verifyFilterTypeExists(page, 'Operating system'); | ||
| }); | ||
|
|
||
| await test.step('Verify "Workspace" filter exists', async () => { | ||
| await verifyFilterTypeExists(page, 'Workspace'); | ||
| }); | ||
|
|
||
| await test.step('Verify "Tag" filter exists', async () => { | ||
| await verifyFilterTypeExists(page, 'Tag'); | ||
| }); | ||
|
|
||
| await test.step('Verify "System" filter exists', async () => { | ||
| await verifyFilterTypeExists(page, 'System', true); | ||
| }); | ||
|
|
||
| await test.step('Verify "Status" filter exists', async () => { | ||
| await verifyFilterTypeExists(page, 'Status', true); | ||
| }); | ||
|
|
||
| await test.step('Verify "Patch status" filter exists', async () => { | ||
| await verifyFilterTypeExists(page, 'Patch status'); | ||
| }); | ||
|
|
||
| await expect(page.getByRole('button', { name: 'Conditional filter toggle' })).toBeVisible(); | ||
| }); | ||
| }); | ||
Uh oh!
There was an error while loading. Please reload this page.