mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[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
This commit is contained in:
parent
99a413506f
commit
a89698712b
15 changed files with 291 additions and 353 deletions
|
@ -195,6 +195,7 @@ export const CreateRuleForm = (props: CreateRuleFormProps) => {
|
|||
multiConsumerSelection,
|
||||
validConsumers,
|
||||
ruleType,
|
||||
ruleTypes,
|
||||
}),
|
||||
}}
|
||||
>
|
||||
|
|
|
@ -152,7 +152,7 @@ describe('rulePage', () => {
|
|||
render(<RulePage onCancel={onCancel} onSave={onSave} />);
|
||||
|
||||
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(<RulePage onCancel={onCancel} onSave={onSave} />);
|
||||
|
||||
fireEvent.click(screen.getByTestId('rulePageFooterCancelButton'));
|
||||
expect(screen.queryByTestId('ruleFormCancelModal')).not.toBeInTheDocument();
|
||||
expect(screen.queryByTestId('confirmRuleCloseModal')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -217,7 +217,7 @@ export const RulePage = (props: RulePageProps) => {
|
|||
<EuiConfirmModal
|
||||
onCancel={() => setIsCancelModalOpen(false)}
|
||||
onConfirm={onCancel}
|
||||
data-test-subj="ruleFormCancelModal"
|
||||
data-test-subj="confirmRuleCloseModal"
|
||||
buttonColor="danger"
|
||||
defaultFocusedButton="confirm"
|
||||
title={RULE_FORM_CANCEL_MODAL_TITLE}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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`);
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -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);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
await testSubjects.click('rulePageFooterCancelButton');
|
||||
|
||||
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 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);
|
||||
|
||||
|
|
|
@ -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 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 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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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 headerText.getVisibleText()).to.eql('Unable to find connector');
|
||||
|
||||
await testSubjects.click('ruleActionsAddActionButton');
|
||||
await testSubjects.existOrFail('ruleActionsConnectorsModal');
|
||||
|
||||
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);
|
||||
});
|
||||
await find.clickByButtonText('Slack#xyztest');
|
||||
|
||||
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: {},
|
||||
});
|
||||
const ruleActionItems = await testSubjects.findAll('ruleActionsItem');
|
||||
expect(ruleActionItems.length).to.eql(2);
|
||||
|
||||
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 testSubjects.exists('addNewActionConnectorActionGroup-0')).to.eql(true);
|
||||
expect(await testSubjects.exists('addNewActionConnectorActionGroup-1')).to.eql(true);
|
||||
|
||||
// delete connector
|
||||
await pageObjects.common.navigateToApp('triggersActions');
|
||||
// refresh to see alert
|
||||
await browser.refresh();
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
|
||||
// verify content
|
||||
await testSubjects.existOrFail('rulesList');
|
||||
|
||||
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}'`);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -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 () => {
|
||||
|
|
|
@ -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)}`,
|
||||
|
|
|
@ -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');
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue