From a89698712b77fd6d4745e82123dccb2758b42e63 Mon Sep 17 00:00:00 2001
From: Janki Salvi <117571355+js-jankisalvi@users.noreply.github.com>
Date: Thu, 28 Nov 2024 16:50:07 +0000
Subject: [PATCH 1/2] [ResponseOps][NewRuleForm] Update functional tests to use
new rule form for stack management (#198915)
## Summary
Meta issue https://github.com/elastic/kibana/issues/196235
This PR updates existing e2e tests to use the new rule form instead of
old rule flyout for `stack management > rules`
### Flaky test runner
https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/7488
https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/7530
### Checklist
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
---
.../src/rule_form/create_rule_form.tsx | 1 +
.../rule_form/rule_page/rule_page.test.tsx | 4 +-
.../src/rule_form/rule_page/rule_page.tsx | 2 +-
.../utils/get_initial_multi_consumer.ts | 20 +
.../test/functional/services/ml/alerting.ts | 2 +-
.../test/functional/services/rules/common.ts | 10 +-
.../discover/search_source_alert.ts | 10 +-
.../discover_ml_uptime/ml/alert_flyout.ts | 1 +
.../alert_create_flyout.ts | 347 +++++++++---------
.../connectors/opsgenie.ts | 47 ++-
.../triggers_actions_ui/connectors/slack.ts | 27 +-
.../apps/triggers_actions_ui/details.ts | 150 ++------
.../rules_list/rules_list.ts | 2 +-
.../functional_with_es_ssl/config.base.ts | 1 -
.../page_objects/triggers_actions_ui_page.ts | 18 +-
15 files changed, 290 insertions(+), 352 deletions(-)
diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/create_rule_form.tsx b/packages/kbn-alerts-ui-shared/src/rule_form/create_rule_form.tsx
index 8bdadc69a6f1a..b0d95a7d5c2c9 100644
--- a/packages/kbn-alerts-ui-shared/src/rule_form/create_rule_form.tsx
+++ b/packages/kbn-alerts-ui-shared/src/rule_form/create_rule_form.tsx
@@ -195,6 +195,7 @@ export const CreateRuleForm = (props: CreateRuleFormProps) => {
multiConsumerSelection,
validConsumers,
ruleType,
+ ruleTypes,
}),
}}
>
diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/rule_page/rule_page.test.tsx b/packages/kbn-alerts-ui-shared/src/rule_form/rule_page/rule_page.test.tsx
index 9523dad2a8a6f..710f046adb28a 100644
--- a/packages/kbn-alerts-ui-shared/src/rule_form/rule_page/rule_page.test.tsx
+++ b/packages/kbn-alerts-ui-shared/src/rule_form/rule_page/rule_page.test.tsx
@@ -152,7 +152,7 @@ describe('rulePage', () => {
render();
fireEvent.click(screen.getByTestId('rulePageFooterCancelButton'));
- expect(screen.getByTestId('ruleFormCancelModal')).toBeInTheDocument();
+ expect(screen.getByTestId('confirmRuleCloseModal')).toBeInTheDocument();
});
test('should not display discard changes modal id no changes are made in the form', () => {
@@ -181,6 +181,6 @@ describe('rulePage', () => {
render();
fireEvent.click(screen.getByTestId('rulePageFooterCancelButton'));
- expect(screen.queryByTestId('ruleFormCancelModal')).not.toBeInTheDocument();
+ expect(screen.queryByTestId('confirmRuleCloseModal')).not.toBeInTheDocument();
});
});
diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/rule_page/rule_page.tsx b/packages/kbn-alerts-ui-shared/src/rule_form/rule_page/rule_page.tsx
index bdb2838bc9963..de15ccaca441c 100644
--- a/packages/kbn-alerts-ui-shared/src/rule_form/rule_page/rule_page.tsx
+++ b/packages/kbn-alerts-ui-shared/src/rule_form/rule_page/rule_page.tsx
@@ -217,7 +217,7 @@ export const RulePage = (props: RulePageProps) => {
setIsCancelModalOpen(false)}
onConfirm={onCancel}
- data-test-subj="ruleFormCancelModal"
+ data-test-subj="confirmRuleCloseModal"
buttonColor="danger"
defaultFocusedButton="confirm"
title={RULE_FORM_CANCEL_MODAL_TITLE}
diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/utils/get_initial_multi_consumer.ts b/packages/kbn-alerts-ui-shared/src/rule_form/utils/get_initial_multi_consumer.ts
index ee80bf46b99c8..0f4ffe41d67da 100644
--- a/packages/kbn-alerts-ui-shared/src/rule_form/utils/get_initial_multi_consumer.ts
+++ b/packages/kbn-alerts-ui-shared/src/rule_form/utils/get_initial_multi_consumer.ts
@@ -11,6 +11,7 @@ import { AlertConsumers, RuleCreationValidConsumer } from '@kbn/rule-data-utils'
import { RuleTypeWithDescription } from '../../common/types';
import { MULTI_CONSUMER_RULE_TYPE_IDS } from '../constants';
import { FEATURE_NAME_MAP } from '../translations';
+import { getAuthorizedConsumers } from './get_authorized_consumers';
export const getValidatedMultiConsumer = ({
multiConsumerSelection,
@@ -33,10 +34,12 @@ export const getInitialMultiConsumer = ({
multiConsumerSelection,
validConsumers,
ruleType,
+ ruleTypes,
}: {
multiConsumerSelection?: RuleCreationValidConsumer | null;
validConsumers: RuleCreationValidConsumer[];
ruleType: RuleTypeWithDescription;
+ ruleTypes: RuleTypeWithDescription[];
}): RuleCreationValidConsumer | null => {
// If rule type doesn't support multi-consumer or no valid consumers exists,
// return nothing
@@ -54,6 +57,23 @@ export const getInitialMultiConsumer = ({
return AlertConsumers.OBSERVABILITY;
}
+ const selectedAvailableRuleType = ruleTypes.find((availableRuleType) => {
+ return availableRuleType.id === ruleType.id;
+ });
+
+ if (!selectedAvailableRuleType?.authorizedConsumers) {
+ return null;
+ }
+
+ const authorizedConsumers = getAuthorizedConsumers({
+ ruleType: selectedAvailableRuleType,
+ validConsumers,
+ });
+
+ if (authorizedConsumers.length === 1) {
+ return authorizedConsumers[0];
+ }
+
// User passed in null explicitly, won't set initial consumer
if (multiConsumerSelection === null) {
return null;
diff --git a/x-pack/test/functional/services/ml/alerting.ts b/x-pack/test/functional/services/ml/alerting.ts
index 74c6eb735ea34..9a42c09e8829f 100644
--- a/x-pack/test/functional/services/ml/alerting.ts
+++ b/x-pack/test/functional/services/ml/alerting.ts
@@ -28,7 +28,7 @@ export function MachineLearningAlertingProvider(
async selectAnomalyDetectionAlertType() {
await retry.tryForTime(5000, async () => {
await testSubjects.click('xpack.ml.anomaly_detection_alert-SelectOption');
- await testSubjects.existOrFail(`mlAnomalyAlertForm`, { timeout: 1000 });
+ await testSubjects.existOrFail(`mlAnomalyAlertForm`);
});
},
diff --git a/x-pack/test/functional/services/rules/common.ts b/x-pack/test/functional/services/rules/common.ts
index 934fdefef10ed..fcc1bf26099c5 100644
--- a/x-pack/test/functional/services/rules/common.ts
+++ b/x-pack/test/functional/services/rules/common.ts
@@ -27,7 +27,7 @@ export function RulesCommonServiceProvider({ getService, getPageObject }: FtrPro
},
async cancelRuleCreation() {
- await testSubjects.click('cancelSaveRuleButton');
+ await testSubjects.click('rulePageFooterCancelButton');
await testSubjects.existOrFail('confirmRuleCloseModal');
await testSubjects.click('confirmRuleCloseModal > confirmModalConfirmButton');
await testSubjects.missingOrFail('confirmRuleCloseModal');
@@ -43,8 +43,6 @@ export function RulesCommonServiceProvider({ getService, getPageObject }: FtrPro
await browser.refresh();
await this.clickCreateAlertButton();
await testSubjects.click(`.index-threshold-SelectOption`);
- await testSubjects.scrollIntoView('ruleNameInput');
- await testSubjects.setValue('ruleNameInput', alertName);
await testSubjects.scrollIntoView('selectIndexExpression');
await testSubjects.click('selectIndexExpression');
await comboBox.set('thresholdIndexesComboBox', 'k');
@@ -55,9 +53,6 @@ export function RulesCommonServiceProvider({ getService, getPageObject }: FtrPro
await fieldOptions[1].click();
});
await testSubjects.click('closePopover');
- // need this two out of popup clicks to close them
- const nameInput = await testSubjects.find('ruleNameInput');
- await nameInput.click();
await testSubjects.click('whenExpression');
await testSubjects.click('whenExpressionSelect');
@@ -74,6 +69,9 @@ export function RulesCommonServiceProvider({ getService, getPageObject }: FtrPro
const ofOptions = ofOptionsString.trim().split('\n');
expect(ofOptions.length > 0).to.be(true);
await comboBox.set('availableFieldsOptionsComboBox', ofOptions[0]);
+
+ await testSubjects.scrollIntoView('ruleDetailsNameInput');
+ await testSubjects.setValue('ruleDetailsNameInput', alertName);
},
};
}
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
index 8c176c61530b7..97d59de76ce4f 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/discover/search_source_alert.ts
@@ -470,7 +470,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await testSubjects.click('thresholdPopover');
await testSubjects.setValue('alertThresholdInput0', '1');
- await testSubjects.click('saveEditedRuleButton');
+ await testSubjects.click('rulePageFooterSaveButton');
await PageObjects.header.waitUntilLoadingHasFinished();
await openAlertResults(RULE_NAME);
@@ -622,8 +622,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
await retry.waitFor('rule name value is correct', async () => {
- await testSubjects.setValue('ruleNameInput', newAlert);
- const ruleName = await testSubjects.getAttribute('ruleNameInput', 'value');
+ await testSubjects.setValue('ruleDetailsNameInput', newAlert);
+ const ruleName = await testSubjects.getAttribute('ruleDetailsNameInput', 'value');
return ruleName === newAlert;
});
@@ -641,10 +641,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
);
await sourceDataViewOption.click();
- await testSubjects.click('saveRuleButton');
+ await testSubjects.click('rulePageFooterSaveButton');
await retry.waitFor('confirmation modal', async () => {
- return await testSubjects.exists('confirmModalConfirmButton');
+ return await testSubjects.exists('rulePageConfirmCreateRule');
});
await testSubjects.click('confirmModalConfirmButton');
diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/ml/alert_flyout.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/ml/alert_flyout.ts
index 58c72ef9d1a27..e76093c666ca1 100644
--- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/ml/alert_flyout.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/ml/alert_flyout.ts
@@ -134,6 +134,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await pageObjects.triggersActionsUI.setAlertName('ml-test-alert');
await pageObjects.triggersActionsUI.setAlertInterval(10, 's');
await pageObjects.triggersActionsUI.saveAlert();
+ await ml.navigation.navigateToAlertsAndAction();
await pageObjects.triggersActionsUI.clickOnAlertInAlertsList('ml-test-alert');
});
});
diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts
index 121bb753e434b..07e6aa841f8e2 100644
--- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts
@@ -47,6 +47,30 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
});
}
+ async function createWebhookConnector(connectorName: string) {
+ await pageObjects.common.navigateToApp('triggersActionsConnectors');
+ await testSubjects.click('connectorsTab');
+
+ await testSubjects.click('createConnectorButton');
+ await testSubjects.scrollIntoView('.webhook-card');
+ await testSubjects.click('.webhook-card');
+
+ await testSubjects.setValue('nameInput', connectorName);
+ await testSubjects.setValue('webhookUrlText', 'https://test.test');
+ await testSubjects.setValue('webhookUserInput', 'fakeuser');
+ await testSubjects.setValue('webhookPasswordInput', 'fakepassword');
+
+ await retry.try(async () => {
+ await find.clickByCssSelector(
+ '[data-test-subj="create-connector-flyout-save-btn"]:not(disabled)'
+ );
+ await testSubjects.click('create-connector-flyout-save-btn');
+ });
+
+ const toastTitle = await toasts.getTitleAndDismiss();
+ expect(toastTitle).to.eql(`Created '${connectorName}'`);
+ }
+
async function deleteConnectorByName(connectorName: string) {
const { body: connectors } = await supertest.get(`/api/actions/connectors`).expect(200);
const connector = connectors?.find((c: { name: string }) => c.name === connectorName);
@@ -62,7 +86,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
async function defineEsQueryAlert(alertName: string) {
await pageObjects.triggersActionsUI.clickCreateAlertButton();
await testSubjects.click(`.es-query-SelectOption`);
- await testSubjects.setValue('ruleNameInput', alertName);
+ await testSubjects.setValue('ruleDetailsNameInput', alertName);
await testSubjects.click('queryFormType_esQuery');
await testSubjects.click('selectIndexExpression');
await comboBox.set('thresholdIndexesComboBox', 'k');
@@ -74,20 +98,21 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
});
await testSubjects.click('closePopover');
// need this two out of popup clicks to close them
- const nameInput = await testSubjects.find('ruleNameInput');
+ const nameInput = await testSubjects.find('ruleDetailsNameInput');
await nameInput.click();
}
async function defineAPMErrorCountRule(ruleName: string) {
await pageObjects.triggersActionsUI.clickCreateAlertButton();
await testSubjects.click(`apm.error_rate-SelectOption`);
- await testSubjects.setValue('ruleNameInput', ruleName);
+ await testSubjects.setValue('ruleDetailsNameInput', ruleName);
}
async function defineAlwaysFiringAlert(alertName: string) {
await pageObjects.triggersActionsUI.clickCreateAlertButton();
await testSubjects.click('test.always-firing-SelectOption');
- await testSubjects.setValue('ruleNameInput', alertName);
+ await testSubjects.scrollIntoView('ruleDetailsNameInput');
+ await testSubjects.setValue('ruleDetailsNameInput', alertName);
}
async function discardNewRuleCreation() {
@@ -95,12 +120,16 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
}
// Failing: See https://github.com/elastic/kibana/issues/196153
- describe.skip('create alert', function () {
+ describe('create alert', function () {
let apmSynthtraceEsClient: ApmSynthtraceEsClient;
+ const webhookConnectorName = 'webhook-test';
before(async () => {
await esArchiver.load(
'test/api_integration/fixtures/es_archiver/index_patterns/constant_keyword'
);
+
+ await createWebhookConnector(webhookConnectorName);
+
const version = (await apmSynthtraceKibanaClient.installApmPackage()).version;
apmSynthtraceEsClient = await getApmSynthtraceEsClient({
client: esClient,
@@ -137,10 +166,12 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
});
after(async () => {
- await apmSynthtraceEsClient.clean();
+ await apmSynthtraceEsClient?.clean();
await esArchiver.unload(
'test/api_integration/fixtures/es_archiver/index_patterns/constant_keyword'
);
+
+ await deleteConnectorByName(webhookConnectorName);
});
beforeEach(async () => {
@@ -153,24 +184,25 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
const ruleName = generateUniqueKey();
await rules.common.defineIndexThresholdAlert(ruleName);
- // create webhook connector
- await testSubjects.click('.webhook-alerting-ActionTypeSelectOption');
- await testSubjects.click('createActionConnectorButton-0');
- await testSubjects.setValue('nameInput', 'webhook-test');
- await testSubjects.setValue('webhookUrlText', 'https://test.test');
- await testSubjects.setValue('webhookUserInput', 'fakeuser');
- await testSubjects.setValue('webhookPasswordInput', 'fakepassword');
-
- // save rule
- await find.clickByCssSelector('[data-test-subj="saveActionButtonModal"]:not(disabled)');
+ // add webhook connector 1
+ await testSubjects.click('ruleActionsAddActionButton');
+ await testSubjects.existOrFail('ruleActionsConnectorsModal');
+ await find.clickByButtonText(webhookConnectorName);
await find.setValueByClass('kibanaCodeEditor', 'myUniqueKey');
- await testSubjects.click('saveRuleButton');
+
+ await testSubjects.click('rulePageFooterSaveButton');
// add new action and remove first one
- await testSubjects.click('ruleSidebarEditAction');
- await testSubjects.click('.webhook-alerting-ActionTypeSelectOption');
+ await testSubjects.click('openEditRuleFlyoutButton');
+
+ // add webhook connector 2
+ await testSubjects.click('ruleActionsAddActionButton');
+ await testSubjects.existOrFail('ruleActionsConnectorsModal');
+ await find.clickByButtonText(webhookConnectorName);
+ await find.setValueByClass('kibanaCodeEditor', 'myUniqueKey1');
+
await find.clickByCssSelector(
- '[data-test-subj="alertActionAccordion-0"] [aria-label="Delete"]'
+ '[data-test-subj="ruleActionsItem"] [data-test-subj="ruleActionsItemDeleteButton"]'
);
// check that the removed action is the right one
@@ -184,7 +216,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
// Additional cleanup step to prevent
// FLAKY: https://github.com/elastic/kibana/issues/167443
// FLAKY: https://github.com/elastic/kibana/issues/167444
- await deleteConnectorByName('webhook-test');
});
it('should create an alert', async () => {
@@ -198,29 +229,9 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await testSubjects.setValue('filterKuery', 'group: group-0');
expect(await filterKueryInput.elementHasClass('euiFieldSearch-isInvalid')).to.eql(false);
- await testSubjects.click('.slack-alerting-ActionTypeSelectOption');
- await testSubjects.click('addNewActionConnectorButton-.slack');
- const slackConnectorName = generateUniqueKey();
- await testSubjects.setValue('nameInput', slackConnectorName);
- await testSubjects.setValue('slackWebhookUrlInput', 'https://test.com');
- await find.clickByCssSelector('[data-test-subj="saveActionButtonModal"]:not(disabled)');
- const createdConnectorToastTitle = await toasts.getTitleAndDismiss();
- expect(createdConnectorToastTitle).to.eql(`Created '${slackConnectorName}'`);
- await testSubjects.click('notifyWhenSelect');
- await testSubjects.click('onThrottleInterval');
- await testSubjects.setValue('throttleInput', '10');
-
- // Alerts search bar (conditional actions)
- await testSubjects.click('alertsFilterQueryToggle');
-
- await pageObjects.header.waitUntilLoadingHasFinished();
- await testSubjects.click('addFilter');
- await testSubjects.click('filterFieldSuggestionList');
- await comboBox.set('filterFieldSuggestionList', '_id');
- await comboBox.set('filterOperatorList', 'is not');
- await testSubjects.setValue('filterParams', 'fake-rule-id');
- await testSubjects.click('saveFilter');
- await testSubjects.setValue('queryInput', '_id: *');
+ await testSubjects.click('ruleActionsAddActionButton');
+ await testSubjects.existOrFail('ruleActionsConnectorsModal');
+ await find.clickByButtonText('Slack#xyztest');
const messageTextArea = await find.byCssSelector('[data-test-subj="messageTextArea"]');
expect(await messageTextArea.getAttribute('value')).to.eql(
@@ -246,9 +257,29 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
'test message {{alert.actionGroup}} some additional text {{rule.id}}'
);
- await testSubjects.click('saveRuleButton');
+ await find.clickByButtonText('Settings');
+ await testSubjects.click('notifyWhenSelect');
+ await testSubjects.click('onThrottleInterval');
+ await testSubjects.setValue('throttleInput', '10');
+
+ // Alerts search bar (conditional actions)
+ await testSubjects.click('alertsFilterQueryToggle');
+
+ await pageObjects.header.waitUntilLoadingHasFinished();
+ await testSubjects.click('addFilter');
+ await testSubjects.click('filterFieldSuggestionList');
+ await comboBox.set('filterFieldSuggestionList', '_id');
+ await comboBox.set('filterOperatorList', 'is not');
+ await testSubjects.setValue('filterParams', 'fake-rule-id');
+ await testSubjects.click('saveFilter');
+ await testSubjects.setValue('queryInput', '_id: *');
+
+ await testSubjects.click('rulePageFooterSaveButton');
const toastTitle = await toasts.getTitleAndDismiss();
expect(toastTitle).to.eql(`Created rule "${alertName}"`);
+
+ await pageObjects.common.navigateToApp('triggersActions');
+ await testSubjects.click('rulesTab');
await pageObjects.triggersActionsUI.searchAlerts(alertName);
const searchResultsAfterSave = await pageObjects.triggersActionsUI.getAlertsList();
const searchResultAfterSave = searchResultsAfterSave[0];
@@ -275,14 +306,35 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await testSubjects.setValue('filterKuery', 'group: group-0');
expect(await filterKueryInput.elementHasClass('euiFieldSearch-isInvalid')).to.eql(false);
- await testSubjects.click('.slack-alerting-ActionTypeSelectOption');
- await testSubjects.click('addNewActionConnectorButton-.slack');
- const slackConnectorName = generateUniqueKey();
- await testSubjects.setValue('nameInput', slackConnectorName);
- await testSubjects.setValue('slackWebhookUrlInput', 'https://test.com');
- await find.clickByCssSelector('[data-test-subj="saveActionButtonModal"]:not(disabled)');
- const createdConnectorToastTitle = await toasts.getTitleAndDismiss();
- expect(createdConnectorToastTitle).to.eql(`Created '${slackConnectorName}'`);
+ await testSubjects.click('ruleActionsAddActionButton');
+ await testSubjects.existOrFail('ruleActionsConnectorsModal');
+ await find.clickByButtonText('Slack#xyztest');
+
+ const messageTextArea = await find.byCssSelector('[data-test-subj="messageTextArea"]');
+ expect(await messageTextArea.getAttribute('value')).to.eql(
+ `Rule {{rule.name}} is active for group {{context.group}}:
+
+- Value: {{context.value}}
+- Conditions Met: {{context.conditions}} over {{rule.params.timeWindowSize}}{{rule.params.timeWindowUnit}}
+- Timestamp: {{context.date}}`
+ );
+ await testSubjects.setValue('messageTextArea', 'test message ');
+ await testSubjects.click('messageAddVariableButton');
+ await testSubjects.click('variableMenuButton-alert.actionGroup');
+ expect(await messageTextArea.getAttribute('value')).to.eql(
+ 'test message {{alert.actionGroup}}'
+ );
+ await messageTextArea.type(' some additional text ');
+
+ await testSubjects.click('messageAddVariableButton');
+ await testSubjects.setValue('messageVariablesSelectableSearch', 'rule.id');
+ await testSubjects.click('variableMenuButton-rule.id');
+
+ expect(await messageTextArea.getAttribute('value')).to.eql(
+ 'test message {{alert.actionGroup}} some additional text {{rule.id}}'
+ );
+
+ await find.clickByButtonText('Settings');
await testSubjects.click('notifyWhenSelect');
await testSubjects.click('onThrottleInterval');
await testSubjects.setValue('throttleInput', '10');
@@ -314,32 +366,12 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await testSubjects.click('saveFilter');
await testSubjects.setValue('queryInput', '_id: *');
- const messageTextArea = await find.byCssSelector('[data-test-subj="messageTextArea"]');
- expect(await messageTextArea.getAttribute('value')).to.eql(
- `Rule {{rule.name}} is active for group {{context.group}}:
-
-- Value: {{context.value}}
-- Conditions Met: {{context.conditions}} over {{rule.params.timeWindowSize}}{{rule.params.timeWindowUnit}}
-- Timestamp: {{context.date}}`
- );
- await testSubjects.setValue('messageTextArea', 'test message ');
- await testSubjects.click('messageAddVariableButton');
- await testSubjects.click('variableMenuButton-alert.actionGroup');
- expect(await messageTextArea.getAttribute('value')).to.eql(
- 'test message {{alert.actionGroup}}'
- );
- await messageTextArea.type(' some additional text ');
-
- await testSubjects.click('messageAddVariableButton');
- await testSubjects.setValue('messageVariablesSelectableSearch', 'rule.id');
- await testSubjects.click('variableMenuButton-rule.id');
-
- expect(await messageTextArea.getAttribute('value')).to.eql(
- 'test message {{alert.actionGroup}} some additional text {{rule.id}}'
- );
- await testSubjects.click('saveRuleButton');
+ await testSubjects.click('rulePageFooterSaveButton');
const toastTitle = await toasts.getTitleAndDismiss();
expect(toastTitle).to.eql(`Created rule "${alertName}"`);
+
+ await pageObjects.common.navigateToApp('triggersActions');
+ await testSubjects.click('rulesTab');
await pageObjects.triggersActionsUI.searchAlerts(alertName);
const searchResultsAfterSave = await pageObjects.triggersActionsUI.getAlertsList();
const searchResultAfterSave = searchResultsAfterSave[0];
@@ -366,14 +398,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await testSubjects.setValue('filterKuery', 'group: group-0');
expect(await filterKueryInput.elementHasClass('euiFieldSearch-isInvalid')).to.eql(false);
- await testSubjects.click('.slack-alerting-ActionTypeSelectOption');
- await testSubjects.click('addNewActionConnectorButton-.slack');
- const slackConnectorName = generateUniqueKey();
- await testSubjects.setValue('nameInput', slackConnectorName);
- await testSubjects.setValue('slackWebhookUrlInput', 'https://test.com');
- await find.clickByCssSelector('[data-test-subj="saveActionButtonModal"]:not(disabled)');
- const createdConnectorToastTitle = await toasts.getTitleAndDismiss();
- expect(createdConnectorToastTitle).to.eql(`Created '${slackConnectorName}'`);
+ await testSubjects.click('ruleActionsAddActionButton');
+ await testSubjects.existOrFail('ruleActionsConnectorsModal');
+ await find.clickByButtonText('Slack#xyztest');
+
+ await find.clickByButtonText('Settings');
await testSubjects.click('notifyWhenSelect');
await testSubjects.click('onThrottleInterval');
await testSubjects.setValue('throttleInput', '10');
@@ -384,19 +413,19 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
const filter = `{
"bool": {
- "filter": [{ "term": { "kibana.alert.rule.consumer": "*" } }]
+ "filter": [{ "term": { "kibana.alert.rule.name": "${alertName}" } }]
}
}`;
- await filterBar.addDslFilter(filter, true);
-
- await testSubjects.click('saveRuleButton');
+ await filterBar.addDslFilter(filter);
+ await testSubjects.click('rulePageFooterSaveButton');
const toastTitle = await toasts.getTitleAndDismiss();
expect(toastTitle).to.eql(`Created rule "${alertName}"`);
- await testSubjects.click('editActionHoverButton');
+ await testSubjects.click('openEditRuleFlyoutButton');
await pageObjects.header.waitUntilLoadingHasFinished();
+ await find.clickByButtonText('Settings');
await testSubjects.scrollIntoView('globalQueryBar');
await filterBar.hasFilter('query', filter, true);
@@ -410,37 +439,36 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
const alertName = generateUniqueKey();
await defineAlwaysFiringAlert(alertName);
- // create Slack connector and attach an action using it
- await testSubjects.click('.slack-alerting-ActionTypeSelectOption');
- await testSubjects.click('addNewActionConnectorButton-.slack');
- const slackConnectorName = generateUniqueKey();
- await testSubjects.setValue('nameInput', slackConnectorName);
- await testSubjects.setValue('slackWebhookUrlInput', 'https://test.com');
- await find.clickByCssSelector('[data-test-subj="saveActionButtonModal"]:not(disabled)');
- const createdConnectorToastTitle = await toasts.getTitleAndDismiss();
- expect(createdConnectorToastTitle).to.eql(`Created '${slackConnectorName}'`);
+ await testSubjects.click('ruleActionsAddActionButton');
+ await testSubjects.existOrFail('ruleActionsConnectorsModal');
+ await find.clickByButtonText('Slack#xyztest');
+
await testSubjects.setValue('messageTextArea', 'test message ');
await (
await find.byCssSelector(
- '[data-test-subj="alertActionAccordion-0"] [data-test-subj="messageTextArea"]'
+ '[data-test-subj="ruleActionsItem"] [data-test-subj="messageTextArea"]'
)
).type('some text ');
+ await find.clickByButtonText('Settings');
+ await testSubjects.click('ruleActionsSettingsSelectActionGroup');
+ await testSubjects.click('addNewActionConnectorActionGroup-recovered');
- await testSubjects.click('addAlertActionButton');
- await testSubjects.click('.slack-alerting-ActionTypeSelectOption');
- await testSubjects.setValue('messageTextArea', 'test message ');
+ await testSubjects.click('ruleActionsAddActionButton');
+ await testSubjects.existOrFail('ruleActionsConnectorsModal');
+ await find.clickByButtonText('Slack#xyztest');
+
+ const actionItems = await find.allByCssSelector('[data-test-subj="ruleActionsItem"]');
await (
- await find.byCssSelector(
- '[data-test-subj="alertActionAccordion-1"] [data-test-subj="messageTextArea"]'
- )
+ await actionItems[1].findByCssSelector('[data-test-subj="messageTextArea"]')
).type('some text ');
- await testSubjects.click('addNewActionConnectorActionGroup-1');
- await testSubjects.click('addNewActionConnectorActionGroup-1-option-other');
-
- await testSubjects.click('saveRuleButton');
+ await testSubjects.click('rulePageFooterSaveButton');
const toastTitle = await toasts.getTitleAndDismiss();
expect(toastTitle).to.eql(`Created rule "${alertName}"`);
+
+ await pageObjects.common.navigateToApp('triggersActions');
+ await testSubjects.click('rulesTab');
+
await pageObjects.triggersActionsUI.searchAlerts(alertName);
const searchResultsAfterSave = await pageObjects.triggersActionsUI.getAlertsList();
const searchResultAfterSave = searchResultsAfterSave[0];
@@ -459,20 +487,24 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
const alertName = generateUniqueKey();
await defineAlwaysFiringAlert(alertName);
- await testSubjects.click('saveRuleButton');
- await testSubjects.existOrFail('confirmRuleSaveModal');
- await testSubjects.click('confirmRuleSaveModal > confirmModalCancelButton');
+ await testSubjects.click('rulePageFooterSaveButton');
+ await testSubjects.existOrFail('rulePageConfirmCreateRule');
+ await testSubjects.click('rulePageConfirmCreateRule > confirmModalCancelButton');
await testSubjects.missingOrFail('confirmRuleSaveModal');
- await find.existsByCssSelector('[data-test-subj="saveRuleButton"]:not(disabled)');
+ await find.existsByCssSelector('[data-test-subj="rulePageFooterSaveButton"]:not(disabled)');
- await testSubjects.click('saveRuleButton');
- await testSubjects.existOrFail('confirmRuleSaveModal');
- await testSubjects.click('confirmRuleSaveModal > confirmModalConfirmButton');
- await testSubjects.missingOrFail('confirmRuleSaveModal');
+ await testSubjects.click('rulePageFooterSaveButton');
+ await testSubjects.existOrFail('rulePageConfirmCreateRule');
+ await testSubjects.click('rulePageConfirmCreateRule > confirmModalConfirmButton');
+ await testSubjects.missingOrFail('rulePageConfirmCreateRule');
const toastTitle = await toasts.getTitleAndDismiss();
expect(toastTitle).to.eql(`Created rule "${alertName}"`);
await new Promise((resolve) => setTimeout(resolve, 1000));
+
+ await pageObjects.common.navigateToApp('triggersActions');
+ await testSubjects.click('rulesTab');
+
await pageObjects.triggersActionsUI.searchAlerts(alertName);
const searchResultsAfterSave = await pageObjects.triggersActionsUI.getAlertsList();
const searchResultAfterSave = searchResultsAfterSave[0];
@@ -490,13 +522,13 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
it('should show discard confirmation before closing flyout without saving', async () => {
await pageObjects.triggersActionsUI.clickCreateAlertButton();
await testSubjects.click(`.es-query-SelectOption`);
- await testSubjects.click('cancelSaveRuleButton');
+ await testSubjects.click('rulePageFooterCancelButton');
await testSubjects.missingOrFail('confirmRuleCloseModal');
await pageObjects.triggersActionsUI.clickCreateAlertButton();
await testSubjects.click(`.es-query-SelectOption`);
- await testSubjects.setValue('ruleNameInput', 'alertName');
- await testSubjects.click('cancelSaveRuleButton');
+ await testSubjects.setValue('ruleDetailsNameInput', 'alertName');
+ await testSubjects.click('rulePageFooterCancelButton');
await testSubjects.existOrFail('confirmRuleCloseModal');
await testSubjects.click('confirmRuleCloseModal > confirmModalCancelButton');
await testSubjects.missingOrFail('confirmRuleCloseModal');
@@ -521,7 +553,14 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await testSubjects.missingOrFail('testQuerySuccess');
await testSubjects.existOrFail('testQueryError');
await testSubjects.setValue('queryJsonEditor', '');
- await discardNewRuleCreation();
+
+ await testSubjects.click('rulePageFooterCancelButton');
+
+ const confirmRuleCloseModalExists = await testSubjects.exists('confirmRuleCloseModal');
+ if (confirmRuleCloseModalExists) {
+ await testSubjects.click('confirmRuleCloseModal > confirmModalConfirmButton');
+ await testSubjects.missingOrFail('confirmRuleCloseModal');
+ }
});
// Related issue that this test is trying to prevent:
@@ -554,65 +593,23 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await testSubjects.existOrFail('testQuerySuccess');
await testSubjects.missingOrFail('testQueryError');
- await discardNewRuleCreation();
- });
-
- it('should not do a type override when adding a second action', async () => {
- // create a new rule
- const ruleName = generateUniqueKey();
- await rules.common.defineIndexThresholdAlert(ruleName);
-
- // add server log action
- await testSubjects.click('.server-log-alerting-ActionTypeSelectOption');
- expect(
- await find.existsByCssSelector(
- '[data-test-subj="comboBoxSearchInput"][value="Serverlog#xyz"]'
- )
- ).to.eql(true);
- expect(
- await find.existsByCssSelector(
- '[data-test-subj="comboBoxSearchInput"][value="webhook-test"]'
- )
- ).to.eql(false);
-
- // click on add new action
- await testSubjects.click('addAlertActionButton');
- await find.existsByCssSelector('[data-test-subj="Serverlog#xyz"]');
-
- // create webhook connector
- await testSubjects.click('.webhook-alerting-ActionTypeSelectOption');
- await testSubjects.click('createActionConnectorButton-1');
- await testSubjects.setValue('nameInput', 'webhook-test');
- await testSubjects.setValue('webhookUrlText', 'https://test.test');
- await testSubjects.setValue('webhookUserInput', 'fakeuser');
- await testSubjects.setValue('webhookPasswordInput', 'fakepassword');
- await testSubjects.click('saveActionButtonModal');
-
- // checking the new one first to avoid flakiness. If the value is checked before the new one is added
- // it might return a false positive
- expect(
- await find.existsByCssSelector(
- '[data-test-subj="comboBoxSearchInput"][value="webhook-test"]'
- )
- ).to.eql(true);
- // If it was overridden, the value would change to be empty
- expect(
- await find.existsByCssSelector(
- '[data-test-subj="comboBoxSearchInput"][value="Serverlog#xyz"]'
- )
- ).to.eql(true);
+ await testSubjects.click('rulePageFooterCancelButton');
- await deleteConnectorByName('webhook-test');
+ const confirmRuleCloseModalExists = await testSubjects.exists('confirmRuleCloseModal');
+ if (confirmRuleCloseModalExists) {
+ await testSubjects.click('confirmRuleCloseModal > confirmModalConfirmButton');
+ await testSubjects.missingOrFail('confirmRuleCloseModal');
+ }
});
it('should add filter', async () => {
const ruleName = generateUniqueKey();
await defineAlwaysFiringAlert(ruleName);
- await testSubjects.click('saveRuleButton');
- await testSubjects.existOrFail('confirmRuleSaveModal');
- await testSubjects.click('confirmRuleSaveModal > confirmModalConfirmButton');
- await testSubjects.missingOrFail('confirmRuleSaveModal');
+ await testSubjects.click('rulePageFooterSaveButton');
+ await testSubjects.existOrFail('rulePageConfirmCreateRule');
+ await testSubjects.click('rulePageConfirmCreateRule > confirmModalConfirmButton');
+ await testSubjects.missingOrFail('rulePageConfirmCreateRule');
const toastTitle = await toasts.getTitleAndDismiss();
expect(toastTitle).to.eql(`Created rule "${ruleName}"`);
@@ -625,7 +622,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
}
}`;
- await filterBar.addDslFilter(filter, true);
+ await filterBar.addDslFilter(filter);
await filterBar.hasFilter('query', filter, true);
diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors/opsgenie.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors/opsgenie.ts
index 6656103b6a89a..c4eb6a7dcd093 100644
--- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors/opsgenie.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors/opsgenie.ts
@@ -307,48 +307,58 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
});
it('should default to the create alert action', async () => {
+ await find.clickByButtonText('Message');
await testSubjects.existOrFail('messageInput');
expect(await testSubjects.getAttribute('aliasInput', 'value')).to.eql(defaultAlias);
});
it('should default to the close alert action when setting the run when to recovered', async () => {
- await testSubjects.click('addNewActionConnectorActionGroup-0');
- await testSubjects.click('addNewActionConnectorActionGroup-0-option-recovered');
+ await find.clickByButtonText('Settings');
+ await testSubjects.click('ruleActionsSettingsSelectActionGroup');
+ await testSubjects.click('addNewActionConnectorActionGroup-recovered');
+ await find.clickByButtonText('Message');
expect(await testSubjects.getAttribute('aliasInput', 'value')).to.eql(defaultAlias);
await testSubjects.existOrFail('noteTextArea');
await testSubjects.missingOrFail('messageInput');
});
it('should not preserve the alias when switching run when to recover', async () => {
+ await find.clickByButtonText('Message');
await testSubjects.setValue('aliasInput', 'an alias');
- await testSubjects.click('addNewActionConnectorActionGroup-0');
- await testSubjects.click('addNewActionConnectorActionGroup-0-option-recovered');
- await testSubjects.missingOrFail('messageInput');
+ await find.clickByButtonText('Settings');
+ await testSubjects.click('ruleActionsSettingsSelectActionGroup');
+ await testSubjects.click('addNewActionConnectorActionGroup-recovered');
+ await find.clickByButtonText('Message');
+ await testSubjects.missingOrFail('messageInput');
expect(await testSubjects.getAttribute('aliasInput', 'value')).to.be(defaultAlias);
});
it('should not preserve the alias when switching run when to threshold met', async () => {
- await testSubjects.click('addNewActionConnectorActionGroup-0');
- await testSubjects.click('addNewActionConnectorActionGroup-0-option-recovered');
- await testSubjects.missingOrFail('messageInput');
+ await find.clickByButtonText('Settings');
+ await testSubjects.click('ruleActionsSettingsSelectActionGroup');
+ await testSubjects.click('addNewActionConnectorActionGroup-recovered');
+ await find.clickByButtonText('Message');
+ await testSubjects.missingOrFail('messageInput');
await testSubjects.setValue('aliasInput', 'an alias');
- await testSubjects.click('addNewActionConnectorActionGroup-0');
- await testSubjects.click('addNewActionConnectorActionGroup-0-option-threshold met');
- await testSubjects.exists('messageInput');
+ await find.clickByButtonText('Settings');
+ await testSubjects.click('ruleActionsSettingsSelectActionGroup');
+ await testSubjects.click('addNewActionConnectorActionGroup-threshold met');
+
+ await find.clickByButtonText('Message');
+ await testSubjects.exists('messageInput');
expect(await testSubjects.getAttribute('aliasInput', 'value')).to.be(defaultAlias);
});
it('should show the message is required error when clicking the save button', async () => {
- await testSubjects.click('saveRuleButton');
- const messageError = await find.byClassName('euiFormErrorText');
-
- expect(await messageError.getVisibleText()).to.eql('Message is required.');
+ expect(
+ await (await testSubjects.find('rulePageFooterSaveButton')).getAttribute('disabled')
+ ).to.be('true');
});
});
@@ -360,8 +370,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
};
const selectOpsgenieConnectorInRuleAction = async (name: string) => {
- await testSubjects.click('.opsgenie-alerting-ActionTypeSelectOption');
- await testSubjects.selectValue('comboBoxInput', name);
+ await testSubjects.click('ruleActionsAddActionButton');
+ await testSubjects.existOrFail('ruleActionsConnectorsModal');
+ await find.clickByButtonText(name);
+
+ await find.clickByButtonText('Settings');
await rules.common.setNotifyThrottleInput();
};
diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors/slack.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors/slack.ts
index 026608ecf0e08..a7ea6aef95c8a 100644
--- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors/slack.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors/slack.ts
@@ -14,6 +14,7 @@ import { createSlackConnectorAndObjectRemover, getConnectorByName } from './util
export default ({ getPageObjects, getService }: FtrProviderContext) => {
const testSubjects = getService('testSubjects');
const pageObjects = getPageObjects(['common', 'triggersActionsUI', 'header']);
+ const find = getService('find');
const retry = getService('retry');
const supertest = getService('supertest');
const actions = getService('actions');
@@ -119,10 +120,14 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
return response.body.data[0].id;
};
- const selectSlackConnectorInRuleAction = async ({ connectorId }: { connectorId: string }) => {
- await testSubjects.click('.slack-alerting-ActionTypeSelectOption'); // "Slack" in connector list
- await testSubjects.click('selectActionConnector-.slack-0');
- await testSubjects.click(`dropdown-connector-${connectorId}`);
+ const selectSlackConnectorInRuleAction = async ({
+ connectorName,
+ }: {
+ connectorName: string;
+ }) => {
+ await testSubjects.click('ruleActionsAddActionButton');
+ await testSubjects.existOrFail('ruleActionsConnectorsModal');
+ await find.clickByButtonText(connectorName);
};
before(async () => {
@@ -149,9 +154,14 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
const ruleName = await setupRule();
await selectSlackConnectorInRuleAction({
- connectorId: webhookAction.id,
+ connectorName: webhookConnectorName,
});
- await testSubjects.click('saveRuleButton');
+ await testSubjects.click('rulePageFooterSaveButton');
+ const toastTitle = await toasts.getTitleAndDismiss();
+ expect(toastTitle).to.eql(`Created rule "${ruleName}"`);
+
+ await pageObjects.common.navigateToApp('triggersActions');
+ await testSubjects.click('rulesTab');
await pageObjects.triggersActionsUI.searchAlerts(ruleName);
const ruleId = await getRuleIdByName(ruleName);
@@ -166,9 +176,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
tags: '',
},
]);
-
- const toastTitle = await toasts.getTitleAndDismiss();
- expect(toastTitle).to.eql(`Created rule "${ruleName}"`);
});
/* FUTURE ENGINEER
@@ -179,7 +186,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
it.skip('should save webapi type slack connectors', async () => {
await setupRule();
await selectSlackConnectorInRuleAction({
- connectorId: webApiAction.id,
+ connectorName: webhookConnectorName,
});
await testSubjects.click('saveRuleButton');
diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts
index 04a5d97017124..56150e5693a39 100644
--- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts
@@ -23,7 +23,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
const retry = getService('retry');
const find = getService('find');
const supertest = getService('supertest');
- const comboBox = getService('comboBox');
const objectRemover = new ObjectRemover(supertest);
const toasts = getService('toasts');
@@ -187,7 +186,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
const editButton = await testSubjects.find('ruleIntervalToastEditButton');
await editButton.click();
- await testSubjects.click('cancelSaveEditedRuleButton');
+ await testSubjects.click('rulePageFooterCancelButton');
});
it('should disable the rule', async () => {
@@ -375,14 +374,14 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await editButton.click();
expect(await testSubjects.exists('hasActionsDisabled')).to.eql(false);
- await testSubjects.setValue('ruleNameInput', updatedRuleName, {
+ await testSubjects.setValue('ruleDetailsNameInput', updatedRuleName, {
clearWithKeyboard: true,
});
- await find.clickByCssSelector('[data-test-subj="saveEditedRuleButton"]:not(disabled)');
+ await find.clickByCssSelector('[data-test-subj="rulePageFooterSaveButton"]:not(disabled)');
const toastTitle = await toasts.getTitleAndDismiss();
- expect(toastTitle).to.eql(`Updated '${updatedRuleName}'`);
+ expect(toastTitle).to.eql(`Updated "${updatedRuleName}"`);
await retry.tryForTime(30 * 1000, async () => {
const headingText = await pageObjects.ruleDetailsUI.getHeadingText();
@@ -407,18 +406,18 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
const editButton = await testSubjects.find('openEditRuleFlyoutButton');
await editButton.click();
- await testSubjects.setValue('ruleNameInput', uuidv4(), {
+ await testSubjects.setValue('ruleDetailsNameInput', uuidv4(), {
clearWithKeyboard: true,
});
- await testSubjects.click('cancelSaveEditedRuleButton');
+ await testSubjects.click('rulePageFooterCancelButton');
await testSubjects.existOrFail('confirmRuleCloseModal');
await testSubjects.click('confirmRuleCloseModal > confirmModalConfirmButton');
- await find.waitForDeletedByCssSelector('[data-test-subj="cancelSaveEditedRuleButton"]');
+ await find.waitForDeletedByCssSelector('[data-test-subj="rulePageFooterCancelButton"]');
await editButton.click();
- const nameInputAfterCancel = await testSubjects.find('ruleNameInput');
+ const nameInputAfterCancel = await testSubjects.find('ruleDetailsNameInput');
const textAfterCancel = await nameInputAfterCancel.getAttribute('value');
expect(textAfterCancel).to.eql(updatedRuleName);
});
@@ -482,127 +481,26 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await editButton.click();
expect(await testSubjects.exists('hasActionsDisabled')).to.eql(false);
- expect(await testSubjects.exists('addNewActionConnectorActionGroup-0')).to.eql(false);
- expect(await testSubjects.exists('alertActionAccordion-0')).to.eql(true);
+ const headerText = await find.byCssSelector('[data-test-subj="ruleActionsItem"] h2');
- expect(await testSubjects.exists('selectActionConnector-.slack-0')).to.eql(true);
- // click the super selector the reveal the options
- await testSubjects.click('selectActionConnector-.slack-0');
- // click the available option (my-slack1 is a preconfigured connector created before this test runs)
- await testSubjects.click('dropdown-connector-my-slack1');
- expect(await testSubjects.exists('addNewActionConnectorActionGroup-0')).to.eql(true);
- });
-
- it('should show and update deleted connectors when there are no existing connectors of the same type', async () => {
- const connector = await createConnectorManualCleanup({
- name: `index-${testRunUuid}-${0}`,
- connector_type_id: '.index',
- config: {
- index: `index-${testRunUuid}-${0}`,
- },
- secrets: {},
- });
-
- await pageObjects.common.navigateToApp('triggersActions');
- const alert = await createAlwaysFiringRule({
- name: testRunUuid,
- actions: [
- {
- group: 'default',
- id: connector.id,
- params: { level: 'info', message: ' {{context.message}}' },
- frequency: {
- summary: false,
- notify_when: RuleNotifyWhen.THROTTLE,
- throttle: '1m',
- },
- },
- {
- group: 'other',
- id: connector.id,
- params: { level: 'info', message: ' {{context.message}}' },
- frequency: {
- summary: false,
- notify_when: RuleNotifyWhen.THROTTLE,
- throttle: '1m',
- },
- },
- ],
- });
-
- // refresh to see alert
- await browser.refresh();
- await pageObjects.header.waitUntilLoadingHasFinished();
-
- // verify content
- await testSubjects.existOrFail('rulesList');
-
- // delete connector
- await pageObjects.common.navigateToApp('triggersActionsConnectors');
- await pageObjects.triggersActionsUI.searchConnectors(connector.name);
- await testSubjects.click('deleteConnector');
- await testSubjects.existOrFail('deleteIdsConfirmation');
- await testSubjects.click('deleteIdsConfirmation > confirmModalConfirmButton');
- await testSubjects.missingOrFail('deleteIdsConfirmation');
-
- const toastTitle = await toasts.getTitleAndDismiss();
- expect(toastTitle).to.eql('Deleted 1 connector');
-
- // Wait to ensure the table is finished loading
- await pageObjects.triggersActionsUI.tableFinishedLoading();
-
- // click on first rule
- await pageObjects.common.navigateToApp('triggersActions');
- await pageObjects.triggersActionsUI.clickOnAlertInAlertsList(alert.name);
-
- const editButton = await testSubjects.find('openEditRuleFlyoutButton');
- await editButton.click();
- expect(await testSubjects.exists('hasActionsDisabled')).to.eql(false);
-
- expect(await testSubjects.exists('addNewActionConnectorActionGroup-0')).to.eql(false);
- expect(await testSubjects.exists('alertActionAccordion-0')).to.eql(true);
- expect(await testSubjects.exists('addNewActionConnectorActionGroup-1')).to.eql(false);
- expect(await testSubjects.exists('alertActionAccordion-1')).to.eql(true);
-
- await testSubjects.click('createActionConnectorButton-0');
- await testSubjects.existOrFail('connectorAddModal');
- await testSubjects.setValue('nameInput', 'new connector');
- await retry.try(async () => {
- // At times we find the driver controlling the ComboBox in tests
- // can select the wrong item, this ensures we always select the correct index
- await comboBox.set('connectorIndexesComboBox', 'test-index');
- expect(
- await comboBox.isOptionSelected(
- await testSubjects.find('connectorIndexesComboBox'),
- 'test-index'
- )
- ).to.be(true);
- });
- await testSubjects.click('connectorAddModal > saveActionButtonModal');
- await testSubjects.missingOrFail('deleteIdsConfirmation');
+ expect(await headerText.getVisibleText()).to.eql('Unable to find connector');
- expect(await testSubjects.exists('addNewActionConnectorActionGroup-0')).to.eql(true);
- expect(await testSubjects.exists('addNewActionConnectorActionGroup-1')).to.eql(true);
+ await testSubjects.click('ruleActionsAddActionButton');
+ await testSubjects.existOrFail('ruleActionsConnectorsModal');
- // delete connector
- await pageObjects.common.navigateToApp('triggersActions');
- // refresh to see alert
- await browser.refresh();
- await pageObjects.header.waitUntilLoadingHasFinished();
+ // click the available option (my-slack1 is a preconfigured connector created before this test runs)
+ await find.clickByButtonText('Slack#xyztest');
- // verify content
- await testSubjects.existOrFail('rulesList');
+ const ruleActionItems = await testSubjects.findAll('ruleActionsItem');
+ expect(ruleActionItems.length).to.eql(2);
- await pageObjects.common.navigateToApp('triggersActionsConnectors');
- await pageObjects.triggersActionsUI.searchConnectors('new connector');
- await testSubjects.click('deleteConnector');
- await testSubjects.existOrFail('deleteIdsConfirmation');
- await testSubjects.click('deleteIdsConfirmation > confirmModalConfirmButton');
- await testSubjects.missingOrFail('deleteIdsConfirmation');
+ expect(await ruleActionItems[0].getVisibleText()).to.contain('Slack');
+ expect(await ruleActionItems[1].getVisibleText()).to.contain('Slack');
});
});
- describe('Edit rule with legacy rule-level notify values', function () {
+ // bug with legacy notify_when values https://github.com/elastic/kibana/issues/199494
+ describe.skip('Edit rule with legacy rule-level notify values', function () {
const testRunUuid = uuidv4();
afterEach(async () => {
@@ -643,20 +541,22 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
const editButton = await testSubjects.find('openEditRuleFlyoutButton');
await editButton.click();
+
+ await find.clickByButtonText('Settings');
const notifyWhenSelect = await testSubjects.find('notifyWhenSelect');
expect(await notifyWhenSelect.getVisibleText()).to.eql('On custom action intervals');
const throttleInput = await testSubjects.find('throttleInput');
const throttleUnitInput = await testSubjects.find('throttleUnitInput');
expect(await throttleInput.getAttribute('value')).to.be('2');
expect(await throttleUnitInput.getAttribute('value')).to.be('d');
- await testSubjects.setValue('ruleNameInput', updatedRuleName, {
+ await testSubjects.setValue('ruleDetailsNameInput', updatedRuleName, {
clearWithKeyboard: true,
});
- await find.clickByCssSelector('[data-test-subj="saveEditedRuleButton"]:not(disabled)');
+ await find.clickByCssSelector('[data-test-subj="rulePageFooterSaveButton"]:not(disabled)');
const toastTitle = await toasts.getTitleAndDismiss();
- expect(toastTitle).to.eql(`Updated '${updatedRuleName}'`);
+ expect(toastTitle).to.eql(`Updated '${rule.name}'`);
});
});
diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rules_list/rules_list.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rules_list/rules_list.ts
index 70f9d672b94a1..a9de637cd691a 100644
--- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rules_list/rules_list.ts
+++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/rules_list/rules_list.ts
@@ -449,7 +449,7 @@ export default ({ getPageObjects, getPageObject, getService }: FtrProviderContex
const infoIcon = await testSubjects.find('ruleInterval-config-icon-0');
await infoIcon.click();
- await testSubjects.click('cancelSaveEditedRuleButton');
+ await testSubjects.click('rulePageFooterCancelButton');
});
it('should delete all selection', async () => {
diff --git a/x-pack/test/functional_with_es_ssl/config.base.ts b/x-pack/test/functional_with_es_ssl/config.base.ts
index 2abf100f2823f..bcc6e00b9a979 100644
--- a/x-pack/test/functional_with_es_ssl/config.base.ts
+++ b/x-pack/test/functional_with_es_ssl/config.base.ts
@@ -85,7 +85,6 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
'stackAlertsPage',
'ruleTagFilter',
'ruleStatusFilter',
- 'isUsingRuleCreateFlyout',
])}`,
`--xpack.alerting.rules.minimumScheduleInterval.value="5s"`,
`--xpack.actions.enabledActionTypes=${JSON.stringify(enabledActionTypes)}`,
diff --git a/x-pack/test/functional_with_es_ssl/page_objects/triggers_actions_ui_page.ts b/x-pack/test/functional_with_es_ssl/page_objects/triggers_actions_ui_page.ts
index 1880400dc37c5..e56b9f71f169d 100644
--- a/x-pack/test/functional_with_es_ssl/page_objects/triggers_actions_ui_page.ts
+++ b/x-pack/test/functional_with_es_ssl/page_objects/triggers_actions_ui_page.ts
@@ -166,31 +166,33 @@ export function TriggersActionsPageProvider({ getService }: FtrProviderContext)
await rules.common.clickCreateAlertButton();
},
async setAlertName(value: string) {
- await testSubjects.setValue('ruleNameInput', value);
+ await testSubjects.setValue('ruleDetailsNameInput', value);
await this.assertAlertName(value);
},
async assertAlertName(expectedValue: string) {
- const actualValue = await testSubjects.getAttribute('ruleNameInput', 'value');
+ const actualValue = await testSubjects.getAttribute('ruleDetailsNameInput', 'value');
expect(actualValue).to.eql(expectedValue);
},
async setAlertInterval(value: number, unit?: 's' | 'm' | 'h' | 'd') {
- await testSubjects.setValue('intervalInput', value.toString());
+ await testSubjects.setValue('ruleScheduleNumberInput', value.toString());
if (unit) {
- await testSubjects.selectValue('intervalInputUnit', unit);
+ await testSubjects.selectValue('ruleScheduleUnitInput', unit);
}
await this.assertAlertInterval(value, unit);
},
async assertAlertInterval(expectedValue: number, expectedUnit?: 's' | 'm' | 'h' | 'd') {
- const actualValue = await testSubjects.getAttribute('intervalInput', 'value');
+ const actualValue = await testSubjects.getAttribute('ruleScheduleNumberInput', 'value');
expect(actualValue).to.eql(expectedValue);
if (expectedUnit) {
- const actualUnitValue = await testSubjects.getAttribute('intervalInputUnit', 'value');
+ const actualUnitValue = await testSubjects.getAttribute('ruleScheduleUnitInput', 'value');
expect(actualUnitValue).to.eql(expectedUnit);
}
},
async saveAlert() {
- await testSubjects.click('saveRuleButton');
- const isConfirmationModalVisible = await testSubjects.isDisplayed('confirmRuleSaveModal');
+ await testSubjects.click('rulePageFooterSaveButton');
+ const isConfirmationModalVisible = await testSubjects.isDisplayed(
+ 'rulePageConfirmCreateRule'
+ );
expect(isConfirmationModalVisible).to.eql(true, 'Expect confirmation modal to be visible');
await testSubjects.click('confirmModalConfirmButton');
},
From 9724c46be1257a4287bb313a1cb85407bf0349e3 Mon Sep 17 00:00:00 2001
From: Jusheng Huang <117657272+viajes7@users.noreply.github.com>
Date: Fri, 29 Nov 2024 00:58:57 +0800
Subject: [PATCH 2/2] [ILM] fix remove the unnecessary toast notification
(#201524)
## Summary
Fixes #129647
After fixup:
---
.../sections/edit_policy/edit_policy.tsx | 35 ++++++++-----------
.../translations/translations/fr-FR.json | 1 -
.../translations/translations/ja-JP.json | 1 -
.../translations/translations/zh-CN.json | 1 -
4 files changed, 15 insertions(+), 23 deletions(-)
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx
index f254c7d525759..20ca1fbc82a2f 100644
--- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx
@@ -33,7 +33,6 @@ import {
useKibana,
useFormIsModified,
} from '../../../shared_imports';
-import { toasts } from '../../services/notification';
import { getPoliciesListPath, getPolicyViewPath } from '../../services/navigation';
import { UseField } from './form';
import { savePolicy } from './save_policy';
@@ -137,25 +136,21 @@ export const EditPolicy: React.FunctionComponent = () => {
const { data: policy, isValid } = await form.submit();
if (!isValid) {
- toasts.addDanger(
- i18n.translate('xpack.indexLifecycleMgmt.editPolicy.formErrorsMessage', {
- defaultMessage: 'Please fix the errors on this page.',
- })
- );
- } else {
- const name = getPolicyName();
- setHasSubmittedForm(true);
- const success = await savePolicy(
- {
- ...policy,
- name,
- },
- isNewPolicy || isClonedPolicy
- );
-
- if (success) {
- backToPolicyList(name);
- }
+ return;
+ }
+
+ const name = getPolicyName();
+ setHasSubmittedForm(true);
+ const success = await savePolicy(
+ {
+ ...policy,
+ name,
+ },
+ isNewPolicy || isClonedPolicy
+ );
+
+ if (success) {
+ backToPolicyList(name);
}
};
diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json
index 183b8724c2455..b22dd8b9c2f51 100644
--- a/x-pack/plugins/translations/translations/fr-FR.json
+++ b/x-pack/plugins/translations/translations/fr-FR.json
@@ -23702,7 +23702,6 @@
"xpack.indexLifecycleMgmt.editPolicy.forceMerge.enableExplanationText": "Réduisez le nombre de segments dans chaque partition d'index et nettoyez les documents supprimés.",
"xpack.indexLifecycleMgmt.editPolicy.forceMerge.enableText": "Forcer la fusion",
"xpack.indexLifecycleMgmt.editPolicy.forcemerge.numberOfSegmentsRequiredError": "Valeur obligatoire du nombre de segments.",
- "xpack.indexLifecycleMgmt.editPolicy.formErrorsMessage": "Veuillez corriger les erreurs sur cette page.",
"xpack.indexLifecycleMgmt.editPolicy.frozenPhase.activateFrozenPhaseSwitchLabel": "Activer la phase \"frozen\"",
"xpack.indexLifecycleMgmt.editPolicy.frozenPhase.frozenPhaseDescription": "Transférez les données au niveau \"frozen\" pour les conserver sur le long terme. Le niveau \"frozen\" représente le moyen le plus rentable de conserver vos données tout en permettant d'effectuer des recherches.",
"xpack.indexLifecycleMgmt.editPolicy.frozenPhase.frozenPhaseTitle": "Phase \"frozen\"",
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 045a68d9abdab..710bcd937efc4 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -23674,7 +23674,6 @@
"xpack.indexLifecycleMgmt.editPolicy.forceMerge.enableExplanationText": "各インデックスシャードのセグメント数を減らし、削除したドキュメントをクリーンアップします。",
"xpack.indexLifecycleMgmt.editPolicy.forceMerge.enableText": "強制結合",
"xpack.indexLifecycleMgmt.editPolicy.forcemerge.numberOfSegmentsRequiredError": "セグメント数の評価が必要です。",
- "xpack.indexLifecycleMgmt.editPolicy.formErrorsMessage": "このページのエラーを修正してください。",
"xpack.indexLifecycleMgmt.editPolicy.frozenPhase.activateFrozenPhaseSwitchLabel": "フローズンフェーズをアクティブ化",
"xpack.indexLifecycleMgmt.editPolicy.frozenPhase.frozenPhaseDescription": "長期間保持する場合はデータをフローズンティアに移動します。フローズンティアはデータを格納し、検索することもできる最も費用対効果が高い方法です。",
"xpack.indexLifecycleMgmt.editPolicy.frozenPhase.frozenPhaseTitle": "フローズンフェーズ",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index d747917e0339d..8d17a753111c6 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -23273,7 +23273,6 @@
"xpack.indexLifecycleMgmt.editPolicy.forceMerge.enableExplanationText": "减少每个索引分片中的分段数目,并清除删除的文档。",
"xpack.indexLifecycleMgmt.editPolicy.forceMerge.enableText": "强制合并",
"xpack.indexLifecycleMgmt.editPolicy.forcemerge.numberOfSegmentsRequiredError": "必须指定分段数的值。",
- "xpack.indexLifecycleMgmt.editPolicy.formErrorsMessage": "请修复此页面上的错误。",
"xpack.indexLifecycleMgmt.editPolicy.frozenPhase.activateFrozenPhaseSwitchLabel": "激活冻结阶段",
"xpack.indexLifecycleMgmt.editPolicy.frozenPhase.frozenPhaseDescription": "将数据移到冻层以长期保留。冻层提供最有成本效益的方法存储数据,并且仍能够搜索数据。",
"xpack.indexLifecycleMgmt.editPolicy.frozenPhase.frozenPhaseTitle": "冻结阶段",