[RAC] [Observability] Add functional tests covering the alert workflow status (#111788)

This commit is contained in:
Felix Stürmer 2021-09-16 16:05:50 +02:00 committed by GitHub
parent 13074f1296
commit 2282d53458
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 166 additions and 17 deletions

View file

@ -277,6 +277,7 @@ function ObservabilityActions({
iconType="boxesHorizontal" iconType="boxesHorizontal"
aria-label="More" aria-label="More"
onClick={() => toggleActionsPopover(eventId)} onClick={() => toggleActionsPopover(eventId)}
data-test-subj="alerts-table-row-action-more"
/> />
} }
isOpen={openActionsPopoverId === eventId} isOpen={openActionsPopoverId === eventId}

View file

@ -28,7 +28,7 @@ describe('StatusFilter', () => {
const props = { onChange, status }; const props = { onChange, status };
const { getByTestId } = render(<WorkflowStatusFilter {...props} />); const { getByTestId } = render(<WorkflowStatusFilter {...props} />);
const button = getByTestId(`WorkflowStatusFilter ${status} button`); const button = getByTestId(`workflow-status-filter-${status}-button`);
const input = button.querySelector('input') as Element; const input = button.querySelector('input') as Element;
Simulate.change(input); Simulate.change(input);

View file

@ -21,7 +21,7 @@ const options: Array<EuiButtonGroupOptionProps & { id: AlertWorkflowStatus }> =
label: i18n.translate('xpack.observability.alerts.workflowStatusFilter.openButtonLabel', { label: i18n.translate('xpack.observability.alerts.workflowStatusFilter.openButtonLabel', {
defaultMessage: 'Open', defaultMessage: 'Open',
}), }),
'data-test-subj': 'WorkflowStatusFilter open button', 'data-test-subj': 'workflow-status-filter-open-button',
}, },
{ {
id: 'acknowledged', id: 'acknowledged',
@ -31,14 +31,14 @@ const options: Array<EuiButtonGroupOptionProps & { id: AlertWorkflowStatus }> =
defaultMessage: 'Acknowledged', defaultMessage: 'Acknowledged',
} }
), ),
'data-test-subj': 'WorkflowStatusFilter acknowledged button', 'data-test-subj': 'workflow-status-filter-acknowledged-button',
}, },
{ {
id: 'closed', id: 'closed',
label: i18n.translate('xpack.observability.alerts.workflowStatusFilter.closedButtonLabel', { label: i18n.translate('xpack.observability.alerts.workflowStatusFilter.closedButtonLabel', {
defaultMessage: 'Closed', defaultMessage: 'Closed',
}), }),
'data-test-subj': 'WorkflowStatusFilter closed button', 'data-test-subj': 'workflow-status-filter-closed-button',
}, },
]; ];

View file

@ -6,6 +6,7 @@
*/ */
import querystring from 'querystring'; import querystring from 'querystring';
import { chunk } from 'lodash';
import { FtrProviderContext } from '../../ftr_provider_context'; import { FtrProviderContext } from '../../ftr_provider_context';
import { WebElementWrapper } from '../../../../../test/functional/services/lib/web_element_wrapper'; import { WebElementWrapper } from '../../../../../test/functional/services/lib/web_element_wrapper';
@ -16,12 +17,18 @@ const DATE_WITH_DATA = {
}; };
const ALERTS_FLYOUT_SELECTOR = 'alertsFlyout'; const ALERTS_FLYOUT_SELECTOR = 'alertsFlyout';
const ALERTS_TABLE_CONTAINER_SELECTOR = 'events-viewer-panel';
const ACTION_COLUMN_INDEX = 1;
type WorkflowStatus = 'open' | 'acknowledged' | 'closed';
export function ObservabilityAlertsProvider({ getPageObjects, getService }: FtrProviderContext) { export function ObservabilityAlertsProvider({ getPageObjects, getService }: FtrProviderContext) {
const testSubjects = getService('testSubjects'); const testSubjects = getService('testSubjects');
const flyoutService = getService('flyout'); const flyoutService = getService('flyout');
const pageObjects = getPageObjects(['common']); const pageObjects = getPageObjects(['common']);
const retry = getService('retry'); const retry = getService('retry');
const toasts = getService('toasts');
const navigateToTimeWithData = async () => { const navigateToTimeWithData = async () => {
return await pageObjects.common.navigateToUrlWithBrowserHistory( return await pageObjects.common.navigateToUrlWithBrowserHistory(
@ -31,13 +38,29 @@ export function ObservabilityAlertsProvider({ getPageObjects, getService }: FtrP
); );
}; };
const getTableColumnHeaders = async () => {
const table = await testSubjects.find(ALERTS_TABLE_CONTAINER_SELECTOR);
const tableHeaderRow = await testSubjects.findDescendant('dataGridHeader', table);
const columnHeaders = await tableHeaderRow.findAllByXpath('./div');
return columnHeaders;
};
const getTableCells = async () => { const getTableCells = async () => {
// NOTE: This isn't ideal, but EuiDataGrid doesn't really have the concept of "rows" // NOTE: This isn't ideal, but EuiDataGrid doesn't really have the concept of "rows"
return await testSubjects.findAll('dataGridRowCell'); return await testSubjects.findAll('dataGridRowCell');
}; };
const getTableCellsInRows = async () => {
const columnHeaders = await getTableColumnHeaders();
if (columnHeaders.length <= 0) {
return [];
}
const cells = await getTableCells();
return chunk(cells, columnHeaders.length);
};
const getTableOrFail = async () => { const getTableOrFail = async () => {
return await testSubjects.existOrFail('events-viewer-panel'); return await testSubjects.existOrFail(ALERTS_TABLE_CONTAINER_SELECTOR);
}; };
const getNoDataStateOrFail = async () => { const getNoDataStateOrFail = async () => {
@ -109,21 +132,55 @@ export function ObservabilityAlertsProvider({ getPageObjects, getService }: FtrP
return await testSubjects.findAllDescendant('alertsFlyoutDescriptionListDescription', flyout); return await testSubjects.findAllDescendant('alertsFlyoutDescriptionListDescription', flyout);
}; };
const openActionsMenuForRow = async (rowIndex: number) => {
const rows = await getTableCellsInRows();
const actionsOverflowButton = await testSubjects.findDescendant(
'alerts-table-row-action-more',
rows[rowIndex][ACTION_COLUMN_INDEX]
);
await actionsOverflowButton.click();
};
const setWorkflowStatusForRow = async (rowIndex: number, workflowStatus: WorkflowStatus) => {
await openActionsMenuForRow(rowIndex);
if (workflowStatus === 'closed') {
await testSubjects.click('close-alert-status');
} else {
await testSubjects.click(`${workflowStatus}-alert-status`);
}
// wait for a confirmation toast (the css index is 1-based)
await toasts.getToastElement(1);
await toasts.dismissAllToasts();
};
const setWorkflowStatusFilter = async (workflowStatus: WorkflowStatus) => {
const buttonGroupButton = await testSubjects.find(
`workflow-status-filter-${workflowStatus}-button`
);
await buttonGroupButton.click();
};
return { return {
clearQueryBar, clearQueryBar,
typeInQueryBar,
submitQuery,
getTableCells,
getTableOrFail,
getNoDataStateOrFail,
openAlertsFlyout,
getAlertsFlyout,
getAlertsFlyoutTitle,
closeAlertsFlyout, closeAlertsFlyout,
navigateToTimeWithData, getAlertsFlyout,
getAlertsFlyoutOrFail,
getAlertsFlyoutViewInAppButtonOrFail,
getAlertsFlyoutDescriptionListTitles,
getAlertsFlyoutDescriptionListDescriptions, getAlertsFlyoutDescriptionListDescriptions,
getAlertsFlyoutDescriptionListTitles,
getAlertsFlyoutOrFail,
getAlertsFlyoutTitle,
getAlertsFlyoutViewInAppButtonOrFail,
getNoDataStateOrFail,
getTableCells,
getTableCellsInRows,
getTableColumnHeaders,
getTableOrFail,
navigateToTimeWithData,
openAlertsFlyout,
setWorkflowStatusForRow,
setWorkflowStatusFilter,
submitQuery,
typeInQueryBar,
}; };
} }

View file

@ -0,0 +1,90 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../../ftr_provider_context';
export default ({ getService }: FtrProviderContext) => {
const esArchiver = getService('esArchiver');
describe('alert workflow status', function () {
this.tags('includeFirefox');
const observability = getService('observability');
const retry = getService('retry');
before(async () => {
await esArchiver.load('x-pack/test/functional/es_archives/observability/alerts');
await observability.alerts.navigateToTimeWithData();
});
after(async () => {
await esArchiver.unload('x-pack/test/functional/es_archives/observability/alerts');
});
it('is filtered to only show "open" alerts by default', async () => {
await retry.try(async () => {
const tableRows = await observability.alerts.getTableCellsInRows();
expect(tableRows.length).to.be(12);
});
});
it('can be set to "acknowledged" using the row menu', async () => {
await observability.alerts.setWorkflowStatusForRow(0, 'acknowledged');
await retry.try(async () => {
const tableRows = await observability.alerts.getTableCellsInRows();
expect(tableRows.length).to.be(11);
});
});
it('can be filtered to only show "acknowledged" alerts using the filter button', async () => {
await observability.alerts.setWorkflowStatusFilter('acknowledged');
await retry.try(async () => {
const tableRows = await observability.alerts.getTableCellsInRows();
expect(tableRows.length).to.be(3);
});
});
it('can be set to "closed" using the row menu', async () => {
await observability.alerts.setWorkflowStatusForRow(0, 'closed');
await retry.try(async () => {
const tableRows = await observability.alerts.getTableCellsInRows();
expect(tableRows.length).to.be(2);
});
});
it('can be filtered to only show "closed" alerts using the filter button', async () => {
await observability.alerts.setWorkflowStatusFilter('closed');
await retry.try(async () => {
const tableRows = await observability.alerts.getTableCellsInRows();
expect(tableRows.length).to.be(4);
});
});
it('can be set to "open" using the row menu', async () => {
await observability.alerts.setWorkflowStatusForRow(0, 'open');
await retry.try(async () => {
const tableRows = await observability.alerts.getTableCellsInRows();
expect(tableRows.length).to.be(3);
});
});
it('can be filtered to only show "open" alerts using the filter button', async () => {
await observability.alerts.setWorkflowStatusFilter('open');
await retry.try(async () => {
const tableRows = await observability.alerts.getTableCellsInRows();
expect(tableRows.length).to.be(12);
});
});
});
};

View file

@ -12,5 +12,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
this.tags('ciGroup6'); this.tags('ciGroup6');
loadTestFile(require.resolve('./feature_controls')); loadTestFile(require.resolve('./feature_controls'));
loadTestFile(require.resolve('./alerts')); loadTestFile(require.resolve('./alerts'));
loadTestFile(require.resolve('./alerts/workflow_status'));
}); });
} }