diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx b/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx
index bca8c8095511..9b6e9e249346 100644
--- a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx
@@ -277,6 +277,7 @@ function ObservabilityActions({
iconType="boxesHorizontal"
aria-label="More"
onClick={() => toggleActionsPopover(eventId)}
+ data-test-subj="alerts-table-row-action-more"
/>
}
isOpen={openActionsPopoverId === eventId}
diff --git a/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.test.tsx b/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.test.tsx
index cc16f1c5a44a..f7441742ff38 100644
--- a/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.test.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.test.tsx
@@ -28,7 +28,7 @@ describe('StatusFilter', () => {
const props = { onChange, status };
const { getByTestId } = render();
- const button = getByTestId(`WorkflowStatusFilter ${status} button`);
+ const button = getByTestId(`workflow-status-filter-${status}-button`);
const input = button.querySelector('input') as Element;
Simulate.change(input);
diff --git a/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.tsx b/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.tsx
index 475ba17a9d2f..20073e9937b4 100644
--- a/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.tsx
@@ -21,7 +21,7 @@ const options: Array =
label: i18n.translate('xpack.observability.alerts.workflowStatusFilter.openButtonLabel', {
defaultMessage: 'Open',
}),
- 'data-test-subj': 'WorkflowStatusFilter open button',
+ 'data-test-subj': 'workflow-status-filter-open-button',
},
{
id: 'acknowledged',
@@ -31,14 +31,14 @@ const options: Array =
defaultMessage: 'Acknowledged',
}
),
- 'data-test-subj': 'WorkflowStatusFilter acknowledged button',
+ 'data-test-subj': 'workflow-status-filter-acknowledged-button',
},
{
id: 'closed',
label: i18n.translate('xpack.observability.alerts.workflowStatusFilter.closedButtonLabel', {
defaultMessage: 'Closed',
}),
- 'data-test-subj': 'WorkflowStatusFilter closed button',
+ 'data-test-subj': 'workflow-status-filter-closed-button',
},
];
diff --git a/x-pack/test/functional/services/observability/alerts.ts b/x-pack/test/functional/services/observability/alerts.ts
index ba7f952b30c6..8926d734d731 100644
--- a/x-pack/test/functional/services/observability/alerts.ts
+++ b/x-pack/test/functional/services/observability/alerts.ts
@@ -6,6 +6,7 @@
*/
import querystring from 'querystring';
+import { chunk } from 'lodash';
import { FtrProviderContext } from '../../ftr_provider_context';
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_TABLE_CONTAINER_SELECTOR = 'events-viewer-panel';
+
+const ACTION_COLUMN_INDEX = 1;
+
+type WorkflowStatus = 'open' | 'acknowledged' | 'closed';
export function ObservabilityAlertsProvider({ getPageObjects, getService }: FtrProviderContext) {
const testSubjects = getService('testSubjects');
const flyoutService = getService('flyout');
const pageObjects = getPageObjects(['common']);
const retry = getService('retry');
+ const toasts = getService('toasts');
const navigateToTimeWithData = async () => {
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 () => {
// NOTE: This isn't ideal, but EuiDataGrid doesn't really have the concept of "rows"
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 () => {
- return await testSubjects.existOrFail('events-viewer-panel');
+ return await testSubjects.existOrFail(ALERTS_TABLE_CONTAINER_SELECTOR);
};
const getNoDataStateOrFail = async () => {
@@ -109,21 +132,55 @@ export function ObservabilityAlertsProvider({ getPageObjects, getService }: FtrP
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 {
clearQueryBar,
- typeInQueryBar,
- submitQuery,
- getTableCells,
- getTableOrFail,
- getNoDataStateOrFail,
- openAlertsFlyout,
- getAlertsFlyout,
- getAlertsFlyoutTitle,
closeAlertsFlyout,
- navigateToTimeWithData,
- getAlertsFlyoutOrFail,
- getAlertsFlyoutViewInAppButtonOrFail,
- getAlertsFlyoutDescriptionListTitles,
+ getAlertsFlyout,
getAlertsFlyoutDescriptionListDescriptions,
+ getAlertsFlyoutDescriptionListTitles,
+ getAlertsFlyoutOrFail,
+ getAlertsFlyoutTitle,
+ getAlertsFlyoutViewInAppButtonOrFail,
+ getNoDataStateOrFail,
+ getTableCells,
+ getTableCellsInRows,
+ getTableColumnHeaders,
+ getTableOrFail,
+ navigateToTimeWithData,
+ openAlertsFlyout,
+ setWorkflowStatusForRow,
+ setWorkflowStatusFilter,
+ submitQuery,
+ typeInQueryBar,
};
}
diff --git a/x-pack/test/observability_functional/apps/observability/alerts/workflow_status.ts b/x-pack/test/observability_functional/apps/observability/alerts/workflow_status.ts
new file mode 100644
index 000000000000..d491e239c603
--- /dev/null
+++ b/x-pack/test/observability_functional/apps/observability/alerts/workflow_status.ts
@@ -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);
+ });
+ });
+ });
+};
diff --git a/x-pack/test/observability_functional/apps/observability/index.ts b/x-pack/test/observability_functional/apps/observability/index.ts
index fbb401a67b55..b823e1ee0869 100644
--- a/x-pack/test/observability_functional/apps/observability/index.ts
+++ b/x-pack/test/observability_functional/apps/observability/index.ts
@@ -12,5 +12,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
this.tags('ciGroup6');
loadTestFile(require.resolve('./feature_controls'));
loadTestFile(require.resolve('./alerts'));
+ loadTestFile(require.resolve('./alerts/workflow_status'));
});
}