[8.16] [Security Solution][Data Quality Dashboard] fix tests and potential tests timing out on ci (#196591) (#200549)

# Backport

This will backport the following commits from `main` to `8.16`:
- [[Security Solution][Data Quality Dashboard] fix tests and potential
tests timing out on ci
(#196591)](https://github.com/elastic/kibana/pull/196591)

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Karen
Grigoryan","email":"karen.grigoryan@elastic.co"},"sourceCommit":{"committedDate":"2024-11-01T18:59:41Z","message":"[Security
Solution][Data Quality Dashboard] fix tests and potential tests timing
out on ci (#196591)\n\naddresses #196216\r\n\r\nRemoving accessibility
selectors to ensure 10x speed of tests with\r\ndata-test-subj
locators.","sha":"b5a705e54cd9c657064cc67f8cf1b72f4324d3ab","branchLabelMapping":{"^v9.0.0$":"main","^v8.17.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","Team:Threat
Hunting","Team:Threat
Hunting:Explore","backport:prev-minor","v8.17.0"],"number":196591,"url":"https://github.com/elastic/kibana/pull/196591","mergeCommit":{"message":"[Security
Solution][Data Quality Dashboard] fix tests and potential tests timing
out on ci (#196591)\n\naddresses #196216\r\n\r\nRemoving accessibility
selectors to ensure 10x speed of tests with\r\ndata-test-subj
locators.","sha":"b5a705e54cd9c657064cc67f8cf1b72f4324d3ab"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","labelRegex":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/196591","number":196591,"mergeCommit":{"message":"[Security
Solution][Data Quality Dashboard] fix tests and potential tests timing
out on ci (#196591)\n\naddresses #196216\r\n\r\nRemoving accessibility
selectors to ensure 10x speed of tests with\r\ndata-test-subj
locators.","sha":"b5a705e54cd9c657064cc67f8cf1b72f4324d3ab"}},{"branch":"8.x","label":"v8.17.0","labelRegex":"^v8.17.0$","isSourceBranch":false,"url":"https://github.com/elastic/kibana/pull/198717","number":198717,"state":"MERGED","mergeCommit":{"sha":"273a1eef0fb2f3c717f9fff8be2097892b8b8b90","message":"[8.x]
[Security Solution][Data Quality Dashboard] fix tests and potential
tests timing out on ci (#196591) (#198717)\n\n# Backport\n\nThis will
backport the following commits from `main` to `8.x`:\n- [[Security
Solution][Data Quality Dashboard] fix tests and potential\ntests timing
out on
ci\n(#196591)](https://github.com/elastic/kibana/pull/196591)\n\n<!---
Backport version: 9.4.3 -->\n\n### Questions ?\nPlease refer to the
[Backport
tool\ndocumentation](https://github.com/sqren/backport)\n\n<!--BACKPORT
[{\"author\":{\"name\":\"Karen\nGrigoryan\",\"email\":\"karen.grigoryan@elastic.co\"},\"sourceCommit\":{\"committedDate\":\"2024-11-01T18:59:41Z\",\"message\":\"[Security\nSolution][Data
Quality Dashboard] fix tests and potential tests timing\nout on ci
(#196591)\\n\\naddresses #196216\\r\\n\\r\\nRemoving
accessibility\nselectors to ensure 10x speed of tests
with\\r\\ndata-test-subj\nlocators.\",\"sha\":\"b5a705e54cd9c657064cc67f8cf1b72f4324d3ab\",\"branchLabelMapping\":{\"^v9.0.0$\":\"main\",\"^v8.17.0$\":\"8.x\",\"^v(\\\\d+).(\\\\d+).\\\\d+$\":\"$1.$2\"}},\"sourcePullRequest\":{\"labels\":[\"release_note:skip\",\"v9.0.0\",\"Team:Threat\nHunting\",\"Team:Threat\nHunting:Explore\",\"backport:prev-minor\"],\"title\":\"[Security\nSolution][Data
Quality Dashboard] fix tests and potential tests timing\nout
on\nci\",\"number\":196591,\"url\":\"https://github.com/elastic/kibana/pull/196591\",\"mergeCommit\":{\"message\":\"[Security\nSolution][Data
Quality Dashboard] fix tests and potential tests timing\nout on ci
(#196591)\\n\\naddresses #196216\\r\\n\\r\\nRemoving
accessibility\nselectors to ensure 10x speed of tests
with\\r\\ndata-test-subj\nlocators.\",\"sha\":\"b5a705e54cd9c657064cc67f8cf1b72f4324d3ab\"}},\"sourceBranch\":\"main\",\"suggestedTargetBranches\":[],\"targetPullRequestStates\":[{\"branch\":\"main\",\"label\":\"v9.0.0\",\"branchLabelMappingKey\":\"^v9.0.0$\",\"isSourceBranch\":true,\"state\":\"MERGED\",\"url\":\"https://github.com/elastic/kibana/pull/196591\",\"number\":196591,\"mergeCommit\":{\"message\":\"[Security\nSolution][Data
Quality Dashboard] fix tests and potential tests timing\nout on ci
(#196591)\\n\\naddresses #196216\\r\\n\\r\\nRemoving
accessibility\nselectors to ensure 10x speed of tests
with\\r\\ndata-test-subj\nlocators.\",\"sha\":\"b5a705e54cd9c657064cc67f8cf1b72f4324d3ab\"}}]}]\nBACKPORT-->\n\nCo-authored-by:
Karen Grigoryan <karen.grigoryan@elastic.co>"}}]}] BACKPORT-->
This commit is contained in:
Karen Grigoryan 2024-11-18 15:04:07 +01:00 committed by GitHub
parent d91cdcb308
commit d23bd9913b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 185 additions and 225 deletions

View file

@ -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();
});
});
});
});

View file

@ -67,6 +67,9 @@ export const HistoricalResultsTour: FC<Props> = ({
repositionOnScroll
anchor={anchorElement}
zIndex={zIndex}
panelProps={{
'data-test-subj': 'historicalResultsTourPanel',
}}
footerAction={[
<EuiButtonEmpty size="xs" color="text" onClick={onDismissTour}>
{CLOSE}

View file

@ -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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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);
});
});
});

View file

@ -322,7 +322,9 @@ const PatternComponent: React.FC<Props> = ({
id={patternComponentAccordionId}
forceState={isAccordionOpen ? 'open' : 'closed'}
onToggle={handleAccordionToggle}
buttonElement="div"
buttonProps={{
'data-test-subj': `patternAccordionButton-${pattern}`,
}}
buttonContent={
<PatternSummary
incompatible={getTotalPatternIncompatible(patternRollup?.results)}

View file

@ -18,16 +18,11 @@ import { HistoricalResultsList } from '.';
import {
CHANGE_YOUR_SEARCH_CRITERIA_OR_RUN,
NO_RESULTS_MATCH_YOUR_SEARCH_CRITERIA,
TOGGLE_HISTORICAL_RESULT_CHECKED_AT,
} from './translations';
import { getFormattedCheckTime } from '../../utils/get_formatted_check_time';
import { getHistoricalResultStub } from '../../../../../../stub/get_historical_result_stub';
import userEvent from '@testing-library/user-event';
const getAccordionToggleLabel = (checkedAt: number) => {
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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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,9 +198,7 @@ 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');

View file

@ -53,11 +53,11 @@ export const HistoricalResultsListComponent: FC<Props> = ({ indexName }) => {
<EuiSpacer size="m" />
<StyledAccordion
id={historicalResultsAccordionId}
buttonElement="div"
buttonProps={{
'aria-label': TOGGLE_HISTORICAL_RESULT_CHECKED_AT(
getFormattedCheckTime(result.checkedAt)
),
'data-test-subj': `historicalResultAccordionButton-${result.checkedAt}`,
}}
onToggle={(isOpen) => {
setAccordionState((prevState) => ({

View file

@ -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', () => {
</TestExternalProviders>
);
expect(screen.getByRole('status', { name: '2 checks' })).toBeInTheDocument();
expect(screen.getByTestId('historicalResultsTotalChecks')).toBeInTheDocument();
expect(screen.getByTestId('historicalResultsList')).toBeInTheDocument();
});
@ -69,10 +65,8 @@ describe('HistoricalResults', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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);
});
@ -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(
<TestExternalProviders>
<TestDataQualityProviders>
@ -235,14 +230,16 @@ describe('HistoricalResults', () => {
const wrapper = screen.getByTestId('historicalResultsPagination');
expect(within(wrapper).getByText('Rows per page: 10')).toBeInTheDocument();
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(
<TestExternalProviders>
<TestDataQualityProviders>
@ -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();
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(
<TestExternalProviders>
<TestDataQualityProviders>
@ -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', () => {
</TestExternalProviders>
);
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(
<TestExternalProviders>
@ -346,9 +345,9 @@ describe('HistoricalResults', () => {
</TestExternalProviders>
);
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(
<TestExternalProviders>
@ -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),

View file

@ -112,10 +112,15 @@ export const HistoricalResultsComponent: FC<Props> = ({ indexName }) => {
<div data-test-subj="historicalResults">
<EuiFlexGroup justifyContent="spaceBetween">
<StyledFilterGroupFlexItem grow={false}>
<EuiFilterGroup role="radiogroup" aria-label={FILTER_RESULTS_BY_OUTCOME}>
<EuiFilterGroup
data-test-subj="historicalResultsOutcomeFilterGroup"
role="radiogroup"
aria-label={FILTER_RESULTS_BY_OUTCOME}
>
<EuiFilterButton
hasActiveFilters={isShowAll}
role="radio"
data-test-subj="historicalResultsOutcomeFilterAll"
aria-checked={isShowAll}
onClick={handleDefaultOutcome}
>
@ -124,6 +129,7 @@ export const HistoricalResultsComponent: FC<Props> = ({ indexName }) => {
<EuiFilterButton
hasActiveFilters={isShowPass}
role="radio"
data-test-subj="historicalResultsOutcomeFilterPass"
aria-checked={isShowPass}
onClick={handlePassOutcome}
>
@ -132,6 +138,7 @@ export const HistoricalResultsComponent: FC<Props> = ({ indexName }) => {
<EuiFilterButton
hasActiveFilters={isShowFail}
role="radio"
data-test-subj="historicalResultsOutcomeFilterFail"
aria-checked={isShowFail}
onClick={handleFailOutcome}
>
@ -156,6 +163,7 @@ export const HistoricalResultsComponent: FC<Props> = ({ indexName }) => {
aria-live="polite"
// because it's not inferred in accessibility tree
aria-label={totalChecksText}
data-test-subj="historicalResultsTotalChecks"
aria-describedby={historicalResultsListId}
>
{totalChecksText}

View file

@ -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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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', () => {
</TestExternalProviders>
);
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();
});
});
});

View file

@ -171,6 +171,7 @@ export const IndexCheckFlyoutComponent: React.FC<Props> = ({
tabs.map((tab, index) => {
return (
<EuiTab
data-test-subj={`indexCheckFlyoutTab-${tab.id}`}
onClick={() => handleTabClick(tab.id)}
isSelected={tab.id === selectedTabId}
key={index}
@ -199,7 +200,9 @@ export const IndexCheckFlyoutComponent: React.FC<Props> = ({
{partitionedFieldMetadata?.incompatible != null && (
<IndexResultBadge incompatible={partitionedFieldMetadata.incompatible.length} />
)}
<h2 id={indexCheckFlyoutTitleId}>{indexName}</h2>
<h2 data-test-subj="indexCheckFlyoutHeading" id={indexCheckFlyoutTitleId}>
{indexName}
</h2>
</EuiFlexGroup>
</EuiTitle>
{indexResult != null && indexResult.checkedAt != null && (
@ -236,7 +239,13 @@ export const IndexCheckFlyoutComponent: React.FC<Props> = ({
<EuiFlyoutFooter>
<EuiFlexGroup justifyContent="flexEnd">
<EuiFlexItem grow={false}>
<EuiButton iconType="refresh" isLoading={isChecking} onClick={handleCheckNow} fill>
<EuiButton
data-test-subj="indexCheckFlyoutCheckNowButton"
iconType="refresh"
isLoading={isChecking}
onClick={handleCheckNow}
fill
>
{CHECK_NOW}
</EuiButton>
</EuiFlexItem>

View file

@ -126,6 +126,7 @@ export const getSummaryTableColumns = ({
<EuiButtonIcon
iconType="refresh"
aria-label={CHECK_NOW}
data-test-subj={`checkNowAction-${item.indexName}`}
onClick={() => onCheckNowAction(item.indexName)}
/>
</EuiToolTip>
@ -141,6 +142,7 @@ export const getSummaryTableColumns = ({
<EuiButtonIcon
iconType="clockCounter"
aria-label={i18n.VIEW_HISTORY}
data-test-subj={`viewHistoryAction-${item.indexName}`}
onClick={() => onViewHistoryAction(item.indexName)}
{...(isFirstIndexName && {
[HISTORICAL_RESULTS_TOUR_SELECTOR_KEY]: pattern,