From 441bd9c12404343f4e66b50e5588fb4f8d8d1de7 Mon Sep 17 00:00:00 2001 From: Karen Grigoryan Date: Wed, 16 Oct 2024 20:30:23 +0200 Subject: [PATCH 1/2] [Security Solution][Data Quality Dashboard] fix tests and potential tests timing out on ci addresses #196216 --- .../historical_results_list/index.test.tsx | 2 +- .../index_check_flyout/historical_results/index.test.tsx | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/historical_results_list/index.test.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/historical_results_list/index.test.tsx index 78feadadc4d13..a635f2ee2c95d 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/historical_results_list/index.test.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/historical_results_list/index.test.tsx @@ -216,6 +216,6 @@ describe('HistoricalResultsList', () => { for (const accordionToggleButton of allAccordionToggles) { expect(accordionToggleButton).toHaveAttribute('aria-expanded', 'true'); } - }); + }, 10000); }); }); diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/index.test.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/index.test.tsx index 7c0b13f094030..857fa248f03ca 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/index.test.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/index.test.tsx @@ -207,7 +207,7 @@ describe('HistoricalResults', () => { endDate: 'now', }) ); - }); + }, 10000); }); }); @@ -236,7 +236,7 @@ describe('HistoricalResults', () => { const wrapper = screen.getByTestId('historicalResultsPagination'); expect(within(wrapper).getByText('Rows per page: 10')).toBeInTheDocument(); - }); + }, 10000); }); describe('when rows per page are clicked', () => { @@ -267,7 +267,7 @@ describe('HistoricalResults', () => { expect(screen.getByText('10 rows')).toBeInTheDocument(); expect(screen.getByText('25 rows')).toBeInTheDocument(); expect(screen.getByText('50 rows')).toBeInTheDocument(); - }); + }, 10000); }); describe('when total results are more than or equal 1 page', () => { @@ -410,7 +410,7 @@ describe('HistoricalResults', () => { size: 25, }) ); - }); + }, 10000); }); }); From 9f63b9b20cd50330f7abd58bfdb11b6e2427c71a Mon Sep 17 00:00:00 2001 From: Karen Grigoryan Date: Thu, 31 Oct 2024 13:51:03 +0100 Subject: [PATCH 2/2] improve(test): Remove accessibility selectors in slow tests - Refactored test cases to use `data-test-subj` attributes for 10x faster element selection - Added missing `data-test-subj` attributes in components to facilitate the prev point --- .../indices_details/index.test.tsx | 37 ++--- .../pattern/historical_results_tour/index.tsx | 3 + .../indices_details/pattern/index.test.tsx | 152 +++++++----------- .../indices_details/pattern/index.tsx | 4 +- .../historical_results_list/index.test.tsx | 43 ++--- .../historical_results_list/index.tsx | 2 +- .../historical_results/index.test.tsx | 89 +++++----- .../historical_results/index.tsx | 10 +- .../pattern/index_check_flyout/index.test.tsx | 65 +++----- .../pattern/index_check_flyout/index.tsx | 13 +- .../pattern/summary_table/utils/columns.tsx | 2 + 11 files changed, 190 insertions(+), 230 deletions(-) diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/index.test.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/index.test.tsx index b3d296c5a30db..44f51a50cc027 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/index.test.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/index.test.tsx @@ -95,23 +95,20 @@ describe('IndicesDetails', () => { describe('tour', () => { test('it renders the tour wrapping view history button of first row of first non-empty pattern', async () => { const wrapper = await screen.findByTestId('historicalResultsTour'); - const button = within(wrapper).getByRole('button', { name: 'View history' }); - expect(button).toBeInTheDocument(); + const button = within(wrapper).getByTestId( + 'viewHistoryAction-.internal.alerts-security.alerts-default-000001' + ); expect(button).toHaveAttribute('data-tour-element', patterns[1]); - expect( - screen.getByRole('dialog', { name: 'Introducing data quality history' }) - ).toBeInTheDocument(); + expect(screen.getByTestId('historicalResultsTourPanel')).toHaveTextContent( + 'Introducing data quality history' + ); }); describe('when the tour is dismissed', () => { test('it hides the tour and persists in localStorage', async () => { - const wrapper = await screen.findByRole('dialog', { - name: 'Introducing data quality history', - }); - - const button = within(wrapper).getByRole('button', { name: 'Close' }); - + const wrapper = screen.getByTestId('historicalResultsTourPanel'); + const button = within(wrapper).getByText('Close'); await userEvent.click(button); await waitFor(() => expect(screen.queryByTestId('historicalResultsTour')).toBeNull()); @@ -127,24 +124,22 @@ describe('IndicesDetails', () => { const firstNonEmptyPatternAccordionWrapper = await screen.findByTestId( `${patterns[1]}PatternPanel` ); - const accordionToggle = within(firstNonEmptyPatternAccordionWrapper).getByRole('button', { - name: /Pass/, - }); + const accordionToggle = within(firstNonEmptyPatternAccordionWrapper).getByTestId( + 'indexResultBadge' + ); await userEvent.click(accordionToggle); const secondPatternAccordionWrapper = screen.getByTestId(`${patterns[2]}PatternPanel`); const historicalResultsWrapper = await within(secondPatternAccordionWrapper).findByTestId( 'historicalResultsTour' ); - const button = within(historicalResultsWrapper).getByRole('button', { - name: 'View history', - }); + const button = within(historicalResultsWrapper).getByTestId( + `viewHistoryAction-${patternIndexNames[patterns[2]][0]}` + ); expect(button).toHaveAttribute('data-tour-element', patterns[2]); - expect( - screen.getByRole('dialog', { name: 'Introducing data quality history' }) - ).toBeInTheDocument(); - }, 10000); + expect(screen.getByTestId('historicalResultsTourPanel')).toBeInTheDocument(); + }); }); }); }); diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/historical_results_tour/index.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/historical_results_tour/index.tsx index 5e63379d17375..c35dce5da868e 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/historical_results_tour/index.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/historical_results_tour/index.tsx @@ -67,6 +67,9 @@ export const HistoricalResultsTour: FC = ({ repositionOnScroll anchor={anchorElement} zIndex={zIndex} + panelProps={{ + 'data-test-subj': 'historicalResultsTourPanel', + }} footerAction={[ {CLOSE} diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index.test.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index.test.tsx index eb6116c3276f9..8f8ed7d702d2f 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index.test.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index.test.tsx @@ -23,6 +23,7 @@ import { ERROR_LOADING_METADATA_TITLE, LOADING_STATS } from './translations'; import { useHistoricalResults } from './hooks/use_historical_results'; import { getHistoricalResultStub } from '../../../stub/get_historical_result_stub'; import userEvent from '@testing-library/user-event'; +import { HISTORY_TAB_ID, LATEST_CHECK_TAB_ID } from './constants'; const pattern = 'auditbeat-*'; @@ -94,11 +95,10 @@ describe('pattern', () => { ); - const accordionToggle = screen.getByRole('button', { - name: 'Fail auditbeat-* hot (1) unmanaged (2) Incompatible fields 4 Indices checked 3 Indices 3 Size 17.9MB Docs 19,127', - }); - - expect(accordionToggle).toBeInTheDocument(); + const accordionToggle = screen.getByTestId('patternAccordionButton-auditbeat-*'); + expect(accordionToggle).toHaveTextContent( + 'Failauditbeat-*hot (1)unmanaged (2)Incompatible fields4Indices checked3Indices3Size17.9MBDocs19,127' + ); expect(accordionToggle).toHaveAttribute('aria-expanded', 'true'); expect(screen.getByTestId('summaryTable')).toBeInTheDocument(); }); @@ -139,9 +139,10 @@ describe('pattern', () => { ); - const accordionToggle = await screen.findByRole('button', { - name: 'auditbeat-* Incompatible fields 0 Indices checked 0 Indices 0 Size 0B Docs 0', - }); + const accordionToggle = screen.getByTestId('patternAccordionButton-auditbeat-*'); + expect(accordionToggle).toHaveTextContent( + 'auditbeat-*Incompatible fields0Indices checked0Indices0Size0BDocs0' + ); expect(onAccordionToggle).toHaveBeenCalledTimes(1); @@ -186,10 +187,7 @@ describe('pattern', () => { ); - const accordionToggle = screen.getByRole('button', { - name: 'Fail auditbeat-* hot (1) unmanaged (2) Incompatible fields 4 Indices checked 3 Indices 3 Size 17.9MB Docs 19,127', - }); - + const accordionToggle = screen.getByTestId('patternAccordionButton-auditbeat-*'); expect(onAccordionToggle).toHaveBeenCalledTimes(1); await userEvent.click(accordionToggle); @@ -234,9 +232,7 @@ describe('pattern', () => { ); - const accordionToggle = screen.getByRole('button', { - name: 'Fail auditbeat-* hot (1) unmanaged (2) Incompatible fields 4 Indices checked 3 Indices 3 Size 17.9MB Docs 19,127', - }); + const accordionToggle = screen.getByTestId('patternAccordionButton-auditbeat-*'); expect(onAccordionToggle).toHaveBeenCalledTimes(1); expect(onAccordionToggle).toHaveBeenCalledWith(pattern, true, false); @@ -484,14 +480,11 @@ describe('pattern', () => { ); - const rows = screen.getAllByRole('row'); - const firstBodyRow = within(rows[1]); - expect(screen.queryByTestId('indexCheckFlyout')).not.toBeInTheDocument(); - const checkNowButton = firstBodyRow.getByRole('button', { - name: 'Check now', - }); + const checkNowButton = screen.getByTestId( + 'checkNowAction-.ds-auditbeat-8.6.1-2023.02.07-000001' + ); await userEvent.click(checkNowButton); @@ -505,12 +498,11 @@ describe('pattern', () => { indexName, pattern, }); - expect(screen.getByTestId('indexCheckFlyout')).toBeInTheDocument(); - expect(screen.getByRole('tab', { name: 'Latest Check' })).toHaveAttribute( + expect(screen.getByTestId(`indexCheckFlyoutTab-${LATEST_CHECK_TAB_ID}`)).toHaveAttribute( 'aria-selected', 'true' ); - expect(screen.getByRole('tab', { name: 'History' })).toHaveAttribute( + expect(screen.getByTestId(`indexCheckFlyoutTab-${HISTORY_TAB_ID}`)).toHaveAttribute( 'aria-selected', 'false' ); @@ -566,15 +558,11 @@ describe('pattern', () => { ); - const rows = screen.getAllByRole('row'); - const firstBodyRow = within(rows[1]); - expect(screen.queryByTestId('indexCheckFlyout')).not.toBeInTheDocument(); - const viewHistoryButton = firstBodyRow.getByRole('button', { - name: 'View history', - }); - + const viewHistoryButton = screen.getByTestId( + 'viewHistoryAction-.ds-auditbeat-8.6.1-2023.02.07-000001' + ); await userEvent.click(viewHistoryButton); // assert @@ -583,12 +571,11 @@ describe('pattern', () => { abortController: expect.any(AbortController), indexName, }); - expect(screen.getByTestId('indexCheckFlyout')).toBeInTheDocument(); - expect(screen.getByRole('tab', { name: 'Latest Check' })).toHaveAttribute( + expect(screen.getByTestId(`indexCheckFlyoutTab-${LATEST_CHECK_TAB_ID}`)).toHaveAttribute( 'aria-selected', 'false' ); - expect(screen.getByRole('tab', { name: 'History' })).toHaveAttribute( + expect(screen.getByTestId(`indexCheckFlyoutTab-${HISTORY_TAB_ID}`)).toHaveAttribute( 'aria-selected', 'true' ); @@ -644,24 +631,21 @@ describe('pattern', () => { ); - const rows = screen.getAllByRole('row'); - const firstBodyRow = within(rows[1]); - + // assert expect(screen.queryByTestId('indexCheckFlyout')).not.toBeInTheDocument(); - const viewHistoryButton = firstBodyRow.getByRole('button', { - name: 'View history', - }); + const viewHistoryButton = screen.getByTestId( + 'viewHistoryAction-.ds-auditbeat-8.6.1-2023.02.07-000001' + ); + // act await userEvent.click(viewHistoryButton); - - const closeButton = screen.getByRole('button', { name: 'Close this dialog' }); - + const closeButton = screen.getByTestId('euiFlyoutCloseButton'); await userEvent.click(closeButton); // assert expect(screen.queryByTestId('indexCheckFlyout')).not.toBeInTheDocument(); - }, 15000); + }); }); describe('when chartSelectedIndex is set', () => { @@ -718,15 +702,15 @@ describe('pattern', () => { indexName, pattern, }); - expect(screen.getByTestId('indexCheckFlyout')).toBeInTheDocument(); - expect(screen.getByRole('tab', { name: 'Latest Check' })).toHaveAttribute( + expect(screen.getByTestId(`indexCheckFlyoutTab-${LATEST_CHECK_TAB_ID}`)).toHaveAttribute( 'aria-selected', 'true' ); - expect(screen.getByRole('tab', { name: 'History' })).toHaveAttribute( + expect(screen.getByTestId(`indexCheckFlyoutTab-${HISTORY_TAB_ID}`)).toHaveAttribute( 'aria-selected', 'false' ); + expect(screen.getByTestId('latestResults')).toBeInTheDocument(); expect(screen.queryByTestId('historicalResults')).not.toBeInTheDocument(); }); @@ -766,19 +750,13 @@ describe('pattern', () => { ); - const rows = screen.getAllByRole('row'); - // skipping the first row which is the header - const firstBodyRow = within(rows[1]); - - const tourWrapper = await firstBodyRow.findByTestId('historicalResultsTour'); + const tourWrapper = await screen.findByTestId('historicalResultsTour'); expect( - within(tourWrapper).getByRole('button', { name: 'View history' }) + within(tourWrapper).getByTestId('viewHistoryAction-.ds-auditbeat-8.6.1-2023.02.07-000001') ).toBeInTheDocument(); - expect( - screen.getByRole('dialog', { name: 'Introducing data quality history' }) - ).toBeInTheDocument(); + expect(screen.getByTestId('historicalResultsTourPanel')).toBeInTheDocument(); }); describe('when accordion is collapsed', () => { @@ -815,14 +793,11 @@ describe('pattern', () => { expect(await screen.findByTestId('historicalResultsTour')).toBeInTheDocument(); - const accordionToggle = screen.getByRole('button', { - name: 'Fail auditbeat-* hot (1) unmanaged (2) Incompatible fields 4 Indices checked 3 Indices 3 Size 17.9MB Docs 19,127', - }); - + const accordionToggle = screen.getByTestId('patternAccordionButton-auditbeat-*'); await userEvent.click(accordionToggle); expect(screen.queryByTestId('historicalResultsTour')).not.toBeInTheDocument(); - }, 10000); + }); }); describe('when the tour close button is clicked', () => { @@ -859,11 +834,8 @@ describe('pattern', () => { ); - const tourDialog = await screen.findByRole('dialog', { - name: 'Introducing data quality history', - }); - - const closeButton = within(tourDialog).getByRole('button', { name: 'Close' }); + const tourDialog = await screen.findByTestId('historicalResultsTourPanel'); + const closeButton = within(tourDialog).getByText('Close'); await userEvent.click(closeButton); @@ -905,28 +877,24 @@ describe('pattern', () => { ); - const tourDialog = await screen.findByRole('dialog', { - name: 'Introducing data quality history', - }); - - const tryItButton = within(tourDialog).getByRole('button', { name: 'Try it' }); + const tourDialog = await screen.findByTestId('historicalResultsTourPanel'); + const tryItButton = within(tourDialog).getByText('Try it'); await userEvent.click(tryItButton); expect(onDismissTour).toHaveBeenCalledTimes(1); - expect(screen.getByTestId('indexCheckFlyout')).toBeInTheDocument(); - expect(screen.getByRole('tab', { name: 'Latest Check' })).toHaveAttribute( + expect(screen.getByTestId(`indexCheckFlyoutTab-${LATEST_CHECK_TAB_ID}`)).toHaveAttribute( 'aria-selected', 'false' ); - expect(screen.getByRole('tab', { name: 'History' })).toHaveAttribute( + expect(screen.getByTestId(`indexCheckFlyoutTab-${HISTORY_TAB_ID}`)).toHaveAttribute( 'aria-selected', 'true' ); }); }); - describe('when latest latest check flyout tab is opened', () => { + describe('when latest check flyout tab is opened', () => { it('hides the tour in listview and shows in flyout', async () => { (useIlmExplain as jest.Mock).mockReturnValue({ error: null, @@ -960,41 +928,41 @@ describe('pattern', () => { ); - const rows = screen.getAllByRole('row'); - // skipping the first row which is the header - const firstBodyRow = within(rows[1]); + const summaryTableWrapper = within(screen.getByTestId('summaryTable')); - expect(await firstBodyRow.findByTestId('historicalResultsTour')).toBeInTheDocument(); expect( - screen.getByRole('dialog', { name: 'Introducing data quality history' }) + await summaryTableWrapper.findByTestId('historicalResultsTour') ).toBeInTheDocument(); + expect(screen.queryByTestId('historicalResultsTourPanel')).toBeInTheDocument(); - const checkNowButton = firstBodyRow.getByRole('button', { - name: 'Check now', - }); + const checkNowButton = summaryTableWrapper.getByTestId( + 'checkNowAction-.ds-auditbeat-8.6.1-2023.02.07-000001' + ); await userEvent.click(checkNowButton); - expect(screen.getByTestId('indexCheckFlyout')).toBeInTheDocument(); - expect(screen.getByRole('tab', { name: 'Latest Check' })).toHaveAttribute( + expect(screen.getByTestId(`indexCheckFlyoutTab-${LATEST_CHECK_TAB_ID}`)).toHaveAttribute( 'aria-selected', 'true' ); - expect(screen.getByRole('tab', { name: 'History' })).toHaveAttribute( + expect(screen.getByTestId(`indexCheckFlyoutTab-${HISTORY_TAB_ID}`)).toHaveAttribute( 'aria-selected', 'false' ); - expect(firstBodyRow.queryByTestId('historicalResultsTour')).not.toBeInTheDocument(); + expect( + summaryTableWrapper.queryByTestId('historicalResultsTour') + ).not.toBeInTheDocument(); - const tabWrapper = await screen.findByRole('tab', { name: 'History' }); - await waitFor(() => + const tabWrapper = await screen.findByTestId(`indexCheckFlyoutTab-${HISTORY_TAB_ID}`); + await waitFor(() => { expect( tabWrapper.closest('[data-test-subj="historicalResultsTour"]') - ).toBeInTheDocument() - ); + ).toBeInTheDocument(); + expect(screen.queryByTestId('historicalResultsTourPanel')).toBeInTheDocument(); + }); expect(onDismissTour).not.toHaveBeenCalled(); - }, 10000); + }); }); }); diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index.tsx index a51f521eca169..fd0100bc1192e 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index.tsx @@ -322,7 +322,9 @@ const PatternComponent: React.FC = ({ id={patternComponentAccordionId} forceState={isAccordionOpen ? 'open' : 'closed'} onToggle={handleAccordionToggle} - buttonElement="div" + buttonProps={{ + 'data-test-subj': `patternAccordionButton-${pattern}`, + }} buttonContent={ { - return TOGGLE_HISTORICAL_RESULT_CHECKED_AT(getFormattedCheckTime(checkedAt)); -}; - describe('HistoricalResultsList', () => { it('should render individual historical result accordions with result outcome text, formatted check time and amount of incompatible fields', () => { const indexName = 'test'; @@ -65,13 +60,13 @@ describe('HistoricalResultsList', () => { ); expect( - screen.getByLabelText(getAccordionToggleLabel(historicalResultFail.checkedAt)) + screen.getByTestId(`historicalResultAccordionButton-${historicalResultFail.checkedAt}`) ).toHaveTextContent( `Fail${getFormattedCheckTime(historicalResultFail.checkedAt)}1 Incompatible field` ); expect( - screen.getByLabelText(getAccordionToggleLabel(historicalResultPass.checkedAt)) + screen.getByTestId(`historicalResultAccordionButton-${historicalResultPass.checkedAt}`) ).toHaveTextContent( `Pass${getFormattedCheckTime(historicalResultPass.checkedAt)}0 Incompatible fields` ); @@ -97,9 +92,9 @@ describe('HistoricalResultsList', () => { ); - const accordionToggleButton = screen.getByRole('button', { - name: TOGGLE_HISTORICAL_RESULT_CHECKED_AT(getFormattedCheckTime(historicalResult.checkedAt)), - }); + const accordionToggleButton = screen.getByTestId( + `historicalResultAccordionButton-${historicalResult.checkedAt}` + ); expect(accordionToggleButton).toBeInTheDocument(); @@ -127,11 +122,9 @@ describe('HistoricalResultsList', () => { ); - const accordionToggleButton = screen.getByRole('button', { - name: TOGGLE_HISTORICAL_RESULT_CHECKED_AT( - getFormattedCheckTime(historicalResult.checkedAt) - ), - }); + const accordionToggleButton = screen.getByTestId( + `historicalResultAccordionButton-${historicalResult.checkedAt}` + ); expect(accordionToggleButton).toBeInTheDocument(); @@ -139,15 +132,11 @@ describe('HistoricalResultsList', () => { expect(accordionToggleButton).toHaveAttribute('aria-expanded', 'true'); - const accordionToggleDiv = screen.getByLabelText( - getAccordionToggleLabel(historicalResult.checkedAt) - ); - - expect(accordionToggleDiv).toHaveTextContent( + expect(accordionToggleButton).toHaveTextContent( `Fail${getFormattedCheckTime(historicalResult.checkedAt)}` ); - expect(accordionToggleDiv).not.toHaveTextContent('1 Incompatible field'); + expect(accordionToggleButton).not.toHaveTextContent('1 Incompatible field'); }); }); @@ -198,9 +187,9 @@ describe('HistoricalResultsList', () => { ); for (const result of results) { - const accordionToggleButton = screen.getByRole('button', { - name: TOGGLE_HISTORICAL_RESULT_CHECKED_AT(getFormattedCheckTime(result.checkedAt)), - }); + const accordionToggleButton = screen.getByTestId( + `historicalResultAccordionButton-${result.checkedAt}` + ); expect(accordionToggleButton).toBeInTheDocument(); @@ -209,13 +198,11 @@ describe('HistoricalResultsList', () => { await act(async () => userEvent.click(accordionToggleButton)); } - const allAccordionToggles = screen.getAllByRole('button', { - name: /Toggle historical result checked at/, - }); + const allAccordionToggles = screen.getAllByTestId(/historicalResultAccordionButton-.*/); for (const accordionToggleButton of allAccordionToggles) { expect(accordionToggleButton).toHaveAttribute('aria-expanded', 'true'); } - }, 10000); + }); }); }); diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/historical_results_list/index.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/historical_results_list/index.tsx index cabe0b26f8bac..4032f72389d58 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/historical_results_list/index.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/historical_results_list/index.tsx @@ -53,11 +53,11 @@ export const HistoricalResultsListComponent: FC = ({ indexName }) => { { setAccordionState((prevState) => ({ diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/index.test.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/index.test.tsx index 857fa248f03ca..9a74d5ffaa3f7 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/index.test.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/index.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { HistoricalResults } from '.'; -import { screen, render, within, act } from '@testing-library/react'; +import { screen, render, within, act, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { @@ -16,11 +16,7 @@ import { TestHistoricalResultsProvider, } from '../../../../../mock/test_providers/test_providers'; import { getHistoricalResultStub } from '../../../../../stub/get_historical_result_stub'; -import { - ERROR_LOADING_HISTORICAL_RESULTS, - FILTER_RESULTS_BY_OUTCOME, - LOADING_HISTORICAL_RESULTS, -} from './translations'; +import { ERROR_LOADING_HISTORICAL_RESULTS, LOADING_HISTORICAL_RESULTS } from './translations'; import { generateHistoricalResultsStub } from '../../../../../stub/generate_historical_results_stub'; describe('HistoricalResults', () => { @@ -44,7 +40,7 @@ describe('HistoricalResults', () => { ); - expect(screen.getByRole('status', { name: '2 checks' })).toBeInTheDocument(); + expect(screen.getByTestId('historicalResultsTotalChecks')).toBeInTheDocument(); expect(screen.getByTestId('historicalResultsList')).toBeInTheDocument(); }); @@ -69,10 +65,8 @@ describe('HistoricalResults', () => { ); - expect( - screen.getByRole('radiogroup', { name: FILTER_RESULTS_BY_OUTCOME }) - ).toBeInTheDocument(); - const outcomeFilterAll = screen.getByRole('radio', { name: 'All' }); + expect(screen.getByTestId('historicalResultsOutcomeFilterGroup')).toBeInTheDocument(); + const outcomeFilterAll = screen.getByTestId('historicalResultsOutcomeFilterAll'); expect(outcomeFilterAll).toBeInTheDocument(); expect(outcomeFilterAll).toHaveAttribute('aria-checked', 'true'); @@ -102,7 +96,7 @@ describe('HistoricalResults', () => { ); - const outcomeFilter = screen.getByRole('radio', { name: outcome }); + const outcomeFilter = screen.getByTestId(`historicalResultsOutcomeFilter${outcome}`); await act(async () => outcomeFilter.click()); const fetchQueryOpts = { @@ -145,14 +139,15 @@ describe('HistoricalResults', () => { ); const superDatePicker = screen.getByTestId('historicalResultsDatePicker'); - expect(superDatePicker).toBeInTheDocument(); expect( - within(superDatePicker).getByRole('button', { name: 'Date quick select' }) + within(superDatePicker).getByTestId('superDatePickerToggleQuickMenuButton') ).toBeInTheDocument(); expect( - within(superDatePicker).getByRole('button', { name: 'Last 30 days' }) + within(superDatePicker).getByTestId('superDatePickerShowDatesButton') + ).toHaveTextContent('Last 30 days'); + expect( + within(superDatePicker).getByTestId('superDatePickerApplyTimeButton') ).toBeInTheDocument(); - expect(within(superDatePicker).getByRole('button', { name: 'Refresh' })).toBeInTheDocument(); }); describe('when new date is selected', () => { @@ -181,14 +176,14 @@ describe('HistoricalResults', () => { const superDatePicker = screen.getByTestId('historicalResultsDatePicker'); await act(async () => { - const dateQuickSelect = within(superDatePicker).getByRole('button', { - name: 'Date quick select', - }); + const dateQuickSelect = within(superDatePicker).getByTestId( + 'superDatePickerToggleQuickMenuButton' + ); await userEvent.click(dateQuickSelect); }); await act(async () => { - const monthToDateButton = screen.getByRole('button', { name: 'Month to date' }); + const monthToDateButton = screen.getByTestId('superDatePickerCommonlyUsed_Month_to date'); await userEvent.click(monthToDateButton); }); @@ -207,7 +202,7 @@ describe('HistoricalResults', () => { endDate: 'now', }) ); - }, 10000); + }); }); }); @@ -215,7 +210,7 @@ describe('HistoricalResults', () => { describe('by default', () => { it('should show rows per page: 10 by default', () => { const indexName = 'test'; - const results = generateHistoricalResultsStub(indexName, 20); + const results = generateHistoricalResultsStub(indexName, 11); render( @@ -235,14 +230,16 @@ describe('HistoricalResults', () => { const wrapper = screen.getByTestId('historicalResultsPagination'); - expect(within(wrapper).getByText('Rows per page: 10')).toBeInTheDocument(); - }, 10000); + expect(within(wrapper).getByTestId('tablePaginationPopoverButton')).toHaveTextContent( + 'Rows per page: 10' + ); + }); }); describe('when rows per page are clicked', () => { it('should show 10, 25, 50 rows per page options', async () => { const indexName = 'test'; - const results = generateHistoricalResultsStub(indexName, 20); + const results = generateHistoricalResultsStub(indexName, 11); render( @@ -262,18 +259,20 @@ describe('HistoricalResults', () => { const wrapper = screen.getByTestId('historicalResultsPagination'); - await act(async () => userEvent.click(within(wrapper).getByText('Rows per page: 10'))); + await act(async () => + userEvent.click(within(wrapper).getByTestId('tablePaginationPopoverButton')) + ); - expect(screen.getByText('10 rows')).toBeInTheDocument(); - expect(screen.getByText('25 rows')).toBeInTheDocument(); - expect(screen.getByText('50 rows')).toBeInTheDocument(); - }, 10000); + expect(screen.getByTestId('tablePagination-10-rows')).toBeInTheDocument(); + expect(screen.getByTestId('tablePagination-25-rows')).toBeInTheDocument(); + expect(screen.getByTestId('tablePagination-50-rows')).toBeInTheDocument(); + }); }); describe('when total results are more than or equal 1 page', () => { it('should render pagination', () => { const indexName = 'test'; - const results = generateHistoricalResultsStub(indexName, 20); + const results = generateHistoricalResultsStub(indexName, 11); render( @@ -292,14 +291,12 @@ describe('HistoricalResults', () => { ); const wrapper = screen.getByTestId('historicalResultsPagination'); - - expect(within(wrapper).getByText('Rows per page: 10')).toBeInTheDocument(); - expect(within(wrapper).getByRole('list')).toBeInTheDocument(); + expect(within(wrapper).getByTestId('historicalResultsTablePagination')).toBeInTheDocument(); }); }); describe('when total results are less than 1 page', () => { - it('should not render pagination', () => { + it('should not render pagination', async () => { const indexName = 'test'; const results = generateHistoricalResultsStub(indexName, 9); render( @@ -319,14 +316,16 @@ describe('HistoricalResults', () => { ); - expect(screen.queryByTestId('historicalResultsPagination')).not.toBeInTheDocument(); + await waitFor(() => { + expect(screen.queryByTestId('historicalResultsPagination')).not.toBeInTheDocument(); + }); }); }); describe('when new page is clicked', () => { it('should invoke fetchHistoricalResults with new from and remaining fetch query opts', async () => { const indexName = 'test'; - const results = generateHistoricalResultsStub(indexName, 20); + const results = generateHistoricalResultsStub(indexName, 11); const fetchHistoricalResults = jest.fn(); render( @@ -346,9 +345,9 @@ describe('HistoricalResults', () => { ); - const nextPageButton = screen.getByLabelText('Page 2 of 2'); - expect(nextPageButton).toHaveRole('button'); - await act(async () => nextPageButton.click()); + const wrapper = screen.getByTestId('historicalResultsPagination'); + + await act(() => userEvent.click(within(wrapper).getByTestId('pagination-button-1'))); const fetchQueryOpts = { abortController: expect.any(AbortController), @@ -370,7 +369,7 @@ describe('HistoricalResults', () => { describe('when items per page is changed', () => { it('should invoke fetchHistoricalResults with new size, from: 0 and remaining fetch query opts', async () => { const indexName = 'test'; - const results = generateHistoricalResultsStub(indexName, 20); + const results = generateHistoricalResultsStub(indexName, 11); const fetchHistoricalResults = jest.fn(); render( @@ -392,9 +391,11 @@ describe('HistoricalResults', () => { const wrapper = screen.getByTestId('historicalResultsPagination'); - await act(async () => userEvent.click(within(wrapper).getByText('Rows per page: 10'))); + await act(() => + userEvent.click(within(wrapper).getByTestId('tablePaginationPopoverButton')) + ); - await act(async () => userEvent.click(screen.getByText('25 rows'))); + await act(() => userEvent.click(screen.getByTestId('tablePagination-25-rows'))); const fetchQueryOpts = { abortController: expect.any(AbortController), @@ -410,7 +411,7 @@ describe('HistoricalResults', () => { size: 25, }) ); - }, 10000); + }); }); }); diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/index.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/index.tsx index 66fc6b100de13..3e12768efe39d 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/index.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/historical_results/index.tsx @@ -112,10 +112,15 @@ export const HistoricalResultsComponent: FC = ({ indexName }) => {
- + @@ -124,6 +129,7 @@ export const HistoricalResultsComponent: FC = ({ indexName }) => { @@ -132,6 +138,7 @@ export const HistoricalResultsComponent: FC = ({ indexName }) => { @@ -156,6 +163,7 @@ export const HistoricalResultsComponent: FC = ({ indexName }) => { aria-live="polite" // because it's not inferred in accessibility tree aria-label={totalChecksText} + data-test-subj="historicalResultsTotalChecks" aria-describedby={historicalResultsListId} > {totalChecksText} diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/index.test.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/index.test.tsx index e73fd4c2d610d..a41e7d67e7682 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/index.test.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/index.test.tsx @@ -20,6 +20,7 @@ import { auditbeatWithAllResults } from '../../../../mock/pattern_rollup/mock_au import { mockStats } from '../../../../mock/stats/mock_stats'; import { mockHistoricalResult } from '../../../../mock/historical_results/mock_historical_results_response'; import { getFormattedCheckTime } from './utils/get_formatted_check_time'; +import { HISTORY_TAB_ID, LATEST_CHECK_TAB_ID } from '../constants'; describe('IndexCheckFlyout', () => { beforeEach(() => { @@ -55,7 +56,7 @@ describe('IndexCheckFlyout', () => { }); it('should render heading section correctly with formatted latest check time', () => { - expect(screen.getByRole('heading', { level: 2 })).toHaveTextContent( + expect(screen.getByTestId('indexCheckFlyoutHeading')).toHaveTextContent( 'auditbeat-custom-index-1' ); expect(screen.getByTestId('latestCheckedAt')).toHaveTextContent( @@ -66,12 +67,12 @@ describe('IndexCheckFlyout', () => { }); it('should render tabs correctly, with latest check preselected', () => { - expect(screen.getByRole('tab', { name: 'Latest Check' })).toHaveAttribute( + expect(screen.getByTestId(`indexCheckFlyoutTab-${LATEST_CHECK_TAB_ID}`)).toHaveAttribute( 'aria-selected', 'true' ); - expect(screen.getByRole('tab', { name: 'Latest Check' })).not.toBeDisabled(); - expect(screen.getByRole('tab', { name: 'History' })).not.toBeDisabled(); + expect(screen.getByTestId(`indexCheckFlyoutTab-${LATEST_CHECK_TAB_ID}`)).not.toBeDisabled(); + expect(screen.getByTestId(`indexCheckFlyoutTab-${HISTORY_TAB_ID}`)).not.toBeDisabled(); }); it('should render the correct index properties panel', () => { @@ -80,7 +81,7 @@ describe('IndexCheckFlyout', () => { }); it('should render footer with check now button', () => { - expect(screen.getByRole('button', { name: 'Check now' })).toBeInTheDocument(); + expect(screen.getByTestId('indexCheckFlyoutCheckNowButton')).toBeInTheDocument(); }); }); @@ -107,7 +108,7 @@ describe('IndexCheckFlyout', () => { ); - const closeButton = screen.getByRole('button', { name: 'Close this dialog' }); + const closeButton = screen.getByTestId('euiFlyoutCloseButton'); await userEvent.click(closeButton); expect(onClose).toHaveBeenCalled(); @@ -141,7 +142,7 @@ describe('IndexCheckFlyout', () => { ); - const checkNowButton = screen.getByRole('button', { name: 'Check now' }); + const checkNowButton = screen.getByTestId('indexCheckFlyoutCheckNowButton'); await userEvent.click(checkNowButton); expect(checkIndex).toHaveBeenCalledWith({ @@ -189,16 +190,12 @@ describe('IndexCheckFlyout', () => { ); - expect(screen.getByRole('tab', { name: 'Latest Check' })).toHaveAttribute( - 'aria-selected', - 'true' - ); - expect(screen.getByRole('tab', { name: 'History' })).not.toHaveAttribute( - 'aria-selected', - 'true' - ); + const latestCheckTab = screen.getByTestId(`indexCheckFlyoutTab-${LATEST_CHECK_TAB_ID}`); + expect(latestCheckTab).toHaveAttribute('aria-selected', 'true'); + + const historyTab = screen.getByTestId(`indexCheckFlyoutTab-${HISTORY_TAB_ID}`); + expect(historyTab).toHaveAttribute('aria-selected', 'false'); - const historyTab = screen.getByRole('tab', { name: 'History' }); await userEvent.click(historyTab); expect(fetchHistoricalResults).toHaveBeenCalledWith({ @@ -206,11 +203,8 @@ describe('IndexCheckFlyout', () => { abortController: expect.any(AbortController), }); - expect(screen.getByRole('tab', { name: 'History' })).toHaveAttribute('aria-selected', 'true'); - expect(screen.getByRole('tab', { name: 'Latest Check' })).not.toHaveAttribute( - 'aria-selected', - 'true' - ); + expect(historyTab).toHaveAttribute('aria-selected', 'true'); + expect(latestCheckTab).toHaveAttribute('aria-selected', 'false'); expect(screen.getByTestId('historicalResults')).toBeInTheDocument(); }); @@ -240,17 +234,15 @@ describe('IndexCheckFlyout', () => { ); - const historyTab = screen.getByRole('tab', { name: 'History' }); - const latestCheckTab = screen.getByRole('tab', { name: 'Latest Check' }); + const historyTab = screen.getByTestId(`indexCheckFlyoutTab-${HISTORY_TAB_ID}`); + const latestCheckTab = screen.getByTestId(`indexCheckFlyoutTab-${LATEST_CHECK_TAB_ID}`); expect(historyTab).toHaveAttribute('data-tour-element', `${pattern}-history-tab`); expect(latestCheckTab).not.toHaveAttribute('data-tour-element', `${pattern}-history-tab`); await waitFor(() => expect(historyTab.closest('[data-test-subj="historicalResultsTour"]')).toBeInTheDocument() ); - expect( - screen.getByRole('dialog', { name: 'Introducing data quality history' }) - ).toBeInTheDocument(); + expect(screen.getByTestId('historicalResultsTourPanel')).toBeInTheDocument(); }); describe('when the tour close button is clicked', () => { @@ -276,11 +268,8 @@ describe('IndexCheckFlyout', () => { ); - const dialogWrapper = await screen.findByRole('dialog', { - name: 'Introducing data quality history', - }); - - const closeButton = within(dialogWrapper).getByRole('button', { name: 'Close' }); + const dialogWrapper = await screen.findByTestId('historicalResultsTourPanel'); + const closeButton = within(dialogWrapper).getByText('Close'); await userEvent.click(closeButton); expect(onDismissTour).toHaveBeenCalled(); @@ -310,15 +299,13 @@ describe('IndexCheckFlyout', () => { ); - const dialogWrapper = await screen.findByRole('dialog', { - name: 'Introducing data quality history', - }); + const dialogWrapper = await screen.findByTestId('historicalResultsTourPanel'); - const tryItButton = within(dialogWrapper).getByRole('button', { name: 'Try it' }); + const tryItButton = within(dialogWrapper).getByText('Try it'); await userEvent.click(tryItButton); expect(onDismissTour).toHaveBeenCalled(); - expect(screen.getByRole('tab', { name: 'History' })).toHaveAttribute( + expect(screen.getByTestId(`indexCheckFlyoutTab-${HISTORY_TAB_ID}`)).toHaveAttribute( 'aria-selected', 'true' ); @@ -350,7 +337,7 @@ describe('IndexCheckFlyout', () => { ); - const historyTab = screen.getByRole('tab', { name: 'History' }); + const historyTab = screen.getByTestId(`indexCheckFlyoutTab-${HISTORY_TAB_ID}`); await userEvent.click(historyTab); expect(onDismissTour).toHaveBeenCalled(); @@ -384,9 +371,7 @@ describe('IndexCheckFlyout', () => { expect(screen.queryByTestId('historicalResultsTour')).not.toBeInTheDocument() ); - expect( - screen.queryByRole('dialog', { name: 'Introducing data quality history' }) - ).not.toBeInTheDocument(); + expect(screen.queryByTestId('historicalResultsTourPanel')).not.toBeInTheDocument(); }); }); }); diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/index.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/index.tsx index b6dcf850d15b0..3bb20323ca1c4 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/index.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index_check_flyout/index.tsx @@ -171,6 +171,7 @@ export const IndexCheckFlyoutComponent: React.FC = ({ tabs.map((tab, index) => { return ( handleTabClick(tab.id)} isSelected={tab.id === selectedTabId} key={index} @@ -199,7 +200,9 @@ export const IndexCheckFlyoutComponent: React.FC = ({ {partitionedFieldMetadata?.incompatible != null && ( )} -

{indexName}

+

+ {indexName} +

{indexResult != null && indexResult.checkedAt != null && ( @@ -236,7 +239,13 @@ export const IndexCheckFlyoutComponent: React.FC = ({ - + {CHECK_NOW} diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/summary_table/utils/columns.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/summary_table/utils/columns.tsx index 832ba71d26af8..4e9bcf641ac16 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/summary_table/utils/columns.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/summary_table/utils/columns.tsx @@ -126,6 +126,7 @@ export const getSummaryTableColumns = ({ onCheckNowAction(item.indexName)} /> @@ -141,6 +142,7 @@ export const getSummaryTableColumns = ({ onViewHistoryAction(item.indexName)} {...(isFirstIndexName && { [HISTORICAL_RESULTS_TOUR_SELECTOR_KEY]: pattern,