Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion x-pack/plugins/translations/translations/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -20374,7 +20374,6 @@
"xpack.triggersActionsUI.sections.alertsList.alertStatusOk": "OK",
"xpack.triggersActionsUI.sections.alertsList.alertStatusPending": "保留中",
"xpack.triggersActionsUI.sections.alertsList.alertStatusUnknown": "不明",
"xpack.triggersActionsUI.sections.alertsList.attentionBannerTitle": "{totalStausesError} {totalStausesError, plural, one {{singleTitle}} other {# {multipleTitle}}}でエラーが見つかりました。",
"xpack.triggersActionsUI.sections.alertsList.bulkActionPopover.buttonTitle": "アラートを管理",
"xpack.triggersActionsUI.sections.alertsList.bulkActionPopover.deleteAllTitle": "削除",
"xpack.triggersActionsUI.sections.alertsList.bulkActionPopover.disableAllTitle": "無効にする",
Expand Down
1 change: 0 additions & 1 deletion x-pack/plugins/translations/translations/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -20394,7 +20394,6 @@
"xpack.triggersActionsUI.sections.alertsList.alertStatusOk": "确定",
"xpack.triggersActionsUI.sections.alertsList.alertStatusPending": "待处理",
"xpack.triggersActionsUI.sections.alertsList.alertStatusUnknown": "未知",
"xpack.triggersActionsUI.sections.alertsList.attentionBannerTitle": "在 {totalStausesError} 个 {totalStausesError, plural, one {{singleTitle}} other {# 个 {multipleTitle}}}中发现错误。",
"xpack.triggersActionsUI.sections.alertsList.bulkActionPopover.buttonTitle": "管理告警",
"xpack.triggersActionsUI.sections.alertsList.bulkActionPopover.deleteAllTitle": "删除",
"xpack.triggersActionsUI.sections.alertsList.bulkActionPopover.disableAllTitle": "禁用",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const ActionTypeFilter: React.FunctionComponent<ActionTypeFilterProps> =
numActiveFilters={selectedValues.length}
numFilters={selectedValues.length}
onClick={() => setIsPopoverOpen(!isPopoverOpen)}
data-test-subj="actionTypeFilterButton"
>
<FormattedMessage
id="xpack.triggersActionsUI.sections.alertsList.actionTypeFilterLabel"
Expand All @@ -61,6 +62,7 @@ export const ActionTypeFilter: React.FunctionComponent<ActionTypeFilterProps> =
}
}}
checked={selectedValues.includes(item.id) ? 'on' : undefined}
data-test-subj={`actionType${item.id}FilterOption`}
>
{item.name}
</EuiFilterSelectItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export const AlertStatusFilter: React.FunctionComponent<AlertStatusFilterProps>
numActiveFilters={selectedValues.length}
numFilters={selectedValues.length}
onClick={() => setIsPopoverOpen(!isPopoverOpen)}
data-test-subj="alertStatusFilterButton"
>
<FormattedMessage
id="xpack.triggersActionsUI.sections.alertsList.alertStatusFilterLabel"
Expand All @@ -78,6 +79,7 @@ export const AlertStatusFilter: React.FunctionComponent<AlertStatusFilterProps>
}
}}
checked={selectedValues.includes(item) ? 'on' : undefined}
data-test-subj={`alertStatus${item}FilerOption`}
>
<EuiHealth color={healthColor}>{alertsStatusesTranslationsMapping[item]}</EuiHealth>
</EuiFilterSelectItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,15 +437,14 @@ export const AlertsList: React.FunctionComponent = () => {
title={
<FormattedMessage
id="xpack.triggersActionsUI.sections.alertsList.attentionBannerTitle"
defaultMessage="Error found in {totalStausesError} {totalStausesError, plural, one {{singleTitle}} other {# {multipleTitle}}}."
defaultMessage="Error found in {totalStausesError, plural, one {# alert} other {# alerts}}."
values={{
totalStausesError: alertsStatusesTotal.error,
singleTitle: 'alert',
multipleTitle: 'alerts',
}}
/>
}
iconType="alert"
data-test-subj="alertsErrorBanner"
>
<EuiButton
type="primary"
Expand All @@ -471,7 +470,7 @@ export const AlertsList: React.FunctionComponent = () => {
<EuiSpacer size="m" />
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<EuiText size="s" color="subdued">
<EuiText size="s" color="subdued" data-test-subj="totalAlertsCount">
<FormattedMessage
id="xpack.triggersActionsUI.sections.alertsList.totalItemsCountDescription"
defaultMessage="Showing: {pageSize} of {totalItemCount} alerts."
Expand All @@ -483,42 +482,38 @@ export const AlertsList: React.FunctionComponent = () => {
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiHealth color="primary">
<EuiHealth color="primary" data-test-subj="totalActiveAlertsCount">
<FormattedMessage
id="xpack.triggersActionsUI.sections.alertsList.totalStausesActiveDescription"
defaultMessage="Active: {totalStausesActive}"
data-test-subj="totalStausesActive"
values={{
totalStausesActive: alertsStatusesTotal.active,
}}
/>
</EuiHealth>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiHealth color="danger">
<EuiHealth color="danger" data-test-subj="totalErrorAlertsCount">
<FormattedMessage
id="xpack.triggersActionsUI.sections.alertsList.totalStausesErrorDescription"
data-test-subj="totalStausesError"
defaultMessage="Error: {totalStausesError}"
values={{ totalStausesError: alertsStatusesTotal.error }}
/>
</EuiHealth>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiHealth color="subdued">
<EuiHealth color="subdued" data-test-subj="totalOkAlertsCount">
<FormattedMessage
id="xpack.triggersActionsUI.sections.alertsList.totalStausesOkDescription"
data-test-subj="totalStausesOk"
defaultMessage="Ok: {totalStausesOk}"
values={{ totalStausesOk: alertsStatusesTotal.ok }}
/>
</EuiHealth>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiHealth color="success">
<EuiHealth color="success" data-test-subj="totalPendingAlertsCount">
<FormattedMessage
id="xpack.triggersActionsUI.sections.alertsList.totalStausesPendingDescription"
data-test-subj="totalStausesPending"
defaultMessage="Pending: {totalStausesPending}"
values={{
totalStausesPending: alertsStatusesTotal.pending,
Expand All @@ -527,10 +522,9 @@ export const AlertsList: React.FunctionComponent = () => {
</EuiHealth>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiHealth color="warning">
<EuiHealth color="warning" data-test-subj="totalUnknownAlertsCount">
<FormattedMessage
id="xpack.triggersActionsUI.sections.alertsList.totalStausesUnknownDescription"
data-test-subj="totalStausesUnknown"
defaultMessage="Unknown: {totalStausesUnknown}"
values={{
totalStausesUnknown: alertsStatusesTotal.unknown,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const TypeFilter: React.FunctionComponent<TypeFilterProps> = ({
numActiveFilters={selectedValues.length}
numFilters={selectedValues.length}
onClick={() => setIsPopoverOpen(!isPopoverOpen)}
data-test-subj="alertTypeFilterButton"
>
<FormattedMessage
id="xpack.triggersActionsUI.sections.alertsList.typeFilterLabel"
Expand All @@ -63,6 +64,7 @@ export const TypeFilter: React.FunctionComponent<TypeFilterProps> = ({
}
}}
checked={selectedValues.includes(item.value) ? 'on' : undefined}
data-test-subj={`alertType${item.value}FilterOption`}
>
{item.name}
</EuiFilterSelectItem>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import uuid from 'uuid';
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';

function generateUniqueKey() {
return uuid.v4().replace(/-/g, '');
}

export default ({ getPageObjects, getService }: FtrProviderContext) => {
const testSubjects = getService('testSubjects');
const pageObjects = getPageObjects(['common', 'triggersActionsUI', 'header']);
const supertest = getService('supertest');
const find = getService('find');
const retry = getService('retry');

async function getAlertsByName(name: string) {
const {
body: { data: alerts },
} = await supertest.get(`/api/alerts/_find?search=${name}&search_fields=name`).expect(200);

return alerts;
}

async function deleteAlerts(alertIds: string[]) {
alertIds.forEach(async (alertId: string) => {
await supertest.delete(`/api/alerts/alert/${alertId}`).set('kbn-xsrf', 'foo').expect(204, '');
});
}

async function defineAlert(alertName: string) {
await pageObjects.triggersActionsUI.clickCreateAlertButton();
await testSubjects.setValue('alertNameInput', alertName);
await testSubjects.click('.index-threshold-SelectOption');
await testSubjects.click('selectIndexExpression');
const comboBox = await find.byCssSelector('#indexSelectSearchBox');
await comboBox.click();
await comboBox.type('k');
const filterSelectItem = await find.byCssSelector(`.euiFilterSelectItem`);
await filterSelectItem.click();
await testSubjects.click('thresholdAlertTimeFieldSelect');
await retry.try(async () => {
const fieldOptions = await find.allByCssSelector('#thresholdTimeField option');
expect(fieldOptions[1]).not.to.be(undefined);
await fieldOptions[1].click();
});
await testSubjects.click('closePopover');
// need this two out of popup clicks to close them
const nameInput = await testSubjects.find('alertNameInput');
await nameInput.click();
}

describe('create alert', function () {
before(async () => {
await pageObjects.common.navigateToApp('triggersActions');
await testSubjects.click('alertsTab');
});

it('should create an alert', async () => {
const alertName = generateUniqueKey();
await defineAlert(alertName);

await testSubjects.click('.slack-ActionTypeSelectOption');
await testSubjects.click('addNewActionConnectorButton-.slack');
const slackConnectorName = generateUniqueKey();
await testSubjects.setValue('nameInput', slackConnectorName);
await testSubjects.setValue('slackWebhookUrlInput', 'https://test');
await find.clickByCssSelector('[data-test-subj="saveActionButtonModal"]:not(disabled)');
const createdConnectorToastTitle = await pageObjects.common.closeToast();
expect(createdConnectorToastTitle).to.eql(`Created '${slackConnectorName}'`);
await testSubjects.setValue('messageTextArea', 'test message ');
await testSubjects.click('messageAddVariableButton');
await testSubjects.click('variableMenuButton-0');
const messageTextArea = await find.byCssSelector('[data-test-subj="messageTextArea"]');
expect(await messageTextArea.getAttribute('value')).to.eql('test message {{alertId}}');
await messageTextArea.type(' some additional text ');

await testSubjects.click('messageAddVariableButton');
await testSubjects.click('variableMenuButton-1');

expect(await messageTextArea.getAttribute('value')).to.eql(
'test message {{alertId}} some additional text {{alertInstanceId}}'
);

await testSubjects.click('saveAlertButton');
const toastTitle = await pageObjects.common.closeToast();
expect(toastTitle).to.eql(`Created alert "${alertName}"`);
await pageObjects.triggersActionsUI.searchAlerts(alertName);
const searchResultsAfterSave = await pageObjects.triggersActionsUI.getAlertsList();
expect(searchResultsAfterSave).to.eql([
{
name: alertName,
tagsText: '',
alertType: 'Index threshold',
interval: '1m',
},
]);

// clean up created alert
const alertsToDelete = await getAlertsByName(alertName);
await deleteAlerts(alertsToDelete.map((alertItem: { id: string }) => alertItem.id));
});

it('should show save confirmation before creating alert with no actions', async () => {
const alertName = generateUniqueKey();
await defineAlert(alertName);

await testSubjects.click('saveAlertButton');
await testSubjects.existOrFail('confirmAlertSaveModal');
await testSubjects.click('confirmAlertSaveModal > confirmModalCancelButton');
await testSubjects.missingOrFail('confirmAlertSaveModal');
await find.existsByCssSelector('[data-test-subj="saveAlertButton"]:not(disabled)');

await testSubjects.click('saveAlertButton');
await testSubjects.existOrFail('confirmAlertSaveModal');
await testSubjects.click('confirmAlertSaveModal > confirmModalConfirmButton');
await testSubjects.missingOrFail('confirmAlertSaveModal');

const toastTitle = await pageObjects.common.closeToast();
expect(toastTitle).to.eql(`Created alert "${alertName}"`);
await pageObjects.triggersActionsUI.searchAlerts(alertName);
const searchResultsAfterSave = await pageObjects.triggersActionsUI.getAlertsList();
expect(searchResultsAfterSave).to.eql([
{
name: alertName,
tagsText: '',
alertType: 'Index threshold',
interval: '1m',
},
]);

// clean up created alert
const alertsToDelete = await getAlertsByName(alertName);
await deleteAlerts(alertsToDelete.map((alertItem: { id: string }) => alertItem.id));
});
});
};
Loading