From 4f9108273c3bbdf03af26a8a0d2b7a571311751a Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Thu, 19 Oct 2023 00:26:55 +0200 Subject: [PATCH] [Security Solution] Unskip rules bulk actions Serverless Cypress tests (#168307) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Addresses:** https://github.com/elastic/kibana/issues/161540 ## Summary This PR unskips rules bulk actions Serverless Cypress tests (besides role based `bulk_edit_rules_actions.cy.ts`) - `bulk_duplicate_rules.cy.ts` - `bulk_edit_rules.cy.ts` - `bulk_edit_rules_data_view.cy.ts` ## Flaky test runner `detection_response/rule_management/rule_actions/bulk_actions` folder [150 runs](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/3596) 🟢 --- .../bulk_actions/bulk_duplicate_rules.cy.ts | 150 ++-- .../bulk_actions/bulk_edit_rules.cy.ts | 843 +++++++++--------- .../bulk_edit_rules_actions.cy.ts | 335 ++++--- .../bulk_edit_rules_data_view.cy.ts | 5 +- 4 files changed, 659 insertions(+), 674 deletions(-) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_duplicate_rules.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_duplicate_rules.cy.ts index 02a77d227a4c5..f14ced2ea02cf 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_duplicate_rules.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_duplicate_rules.cy.ts @@ -53,89 +53,83 @@ const EXPIRED_EXCEPTION_ITEM_NAME = 'Sample exception item'; const NON_EXPIRED_EXCEPTION_ITEM_NAME = 'Sample exception item with future expiration'; -// TODO: https://github.com/elastic/kibana/issues/161540 -// Flaky on serverless -describe( - 'Detection rules, bulk duplicate', - { tags: ['@ess', '@serverless', '@skipInServerless'] }, - () => { - before(() => { - cleanKibana(); +describe('Detection rules, bulk duplicate', { tags: ['@ess', '@serverless'] }, () => { + before(() => { + cleanKibana(); + }); + + beforeEach(() => { + login(); + // Make sure persisted rules table state is cleared + resetRulesTableState(); + deleteAlertsAndRules(); + cy.task('esArchiverResetKibana'); + createRule( + getNewRule({ name: RULE_NAME, ...defaultRuleData, rule_id: '1', enabled: false }) + ).then((response) => { + createRuleExceptionItem(response.body.id, [ + { + description: 'Exception item for rule default exception list', + entries: [ + { + field: 'user.name', + operator: 'included', + type: 'match', + value: 'some value', + }, + ], + name: EXPIRED_EXCEPTION_ITEM_NAME, + type: 'simple', + expire_time: expiredDate, + }, + { + description: 'Exception item for rule default exception list', + entries: [ + { + field: 'user.name', + operator: 'included', + type: 'match', + value: 'some value', + }, + ], + name: NON_EXPIRED_EXCEPTION_ITEM_NAME, + type: 'simple', + expire_time: futureDate, + }, + ]); }); - beforeEach(() => { - login(); - // Make sure persisted rules table state is cleared - resetRulesTableState(); - deleteAlertsAndRules(); - cy.task('esArchiverResetKibana'); - createRule( - getNewRule({ name: RULE_NAME, ...defaultRuleData, rule_id: '1', enabled: false }) - ).then((response) => { - createRuleExceptionItem(response.body.id, [ - { - description: 'Exception item for rule default exception list', - entries: [ - { - field: 'user.name', - operator: 'included', - type: 'match', - value: 'some value', - }, - ], - name: EXPIRED_EXCEPTION_ITEM_NAME, - type: 'simple', - expire_time: expiredDate, - }, - { - description: 'Exception item for rule default exception list', - entries: [ - { - field: 'user.name', - operator: 'included', - type: 'match', - value: 'some value', - }, - ], - name: NON_EXPIRED_EXCEPTION_ITEM_NAME, - type: 'simple', - expire_time: futureDate, - }, - ]); - }); - - visitRulesManagementTable(); - disableAutoRefresh(); - }); + visitRulesManagementTable(); + disableAutoRefresh(); + }); + + it('Duplicates rules', () => { + selectAllRules(); + duplicateSelectedRulesWithoutExceptions(); + expectManagementTableRules([`${RULE_NAME} [Duplicate]`]); + }); - it('Duplicates rules', () => { + describe('With exceptions', () => { + it('Duplicates rules with expired exceptions', () => { selectAllRules(); - duplicateSelectedRulesWithoutExceptions(); + duplicateSelectedRulesWithExceptions(); expectManagementTableRules([`${RULE_NAME} [Duplicate]`]); + goToRuleDetailsOf(`${RULE_NAME} [Duplicate]`); + goToExceptionsTab(); + assertExceptionItemsExists(EXCEPTION_CARD_ITEM_NAME, [NON_EXPIRED_EXCEPTION_ITEM_NAME]); + viewExpiredExceptionItems(); + assertExceptionItemsExists(EXCEPTION_CARD_ITEM_NAME, [EXPIRED_EXCEPTION_ITEM_NAME]); }); - describe('With exceptions', () => { - it('Duplicates rules with expired exceptions', () => { - selectAllRules(); - duplicateSelectedRulesWithExceptions(); - expectManagementTableRules([`${RULE_NAME} [Duplicate]`]); - goToRuleDetailsOf(`${RULE_NAME} [Duplicate]`); - goToExceptionsTab(); - assertExceptionItemsExists(EXCEPTION_CARD_ITEM_NAME, [NON_EXPIRED_EXCEPTION_ITEM_NAME]); - viewExpiredExceptionItems(); - assertExceptionItemsExists(EXCEPTION_CARD_ITEM_NAME, [EXPIRED_EXCEPTION_ITEM_NAME]); - }); - - it('Duplicates rules with exceptions, excluding expired exceptions', () => { - selectAllRules(); - duplicateSelectedRulesWithNonExpiredExceptions(); - expectManagementTableRules([`${RULE_NAME} [Duplicate]`]); - goToRuleDetailsOf(`${RULE_NAME} [Duplicate]`); - goToExceptionsTab(); - assertExceptionItemsExists(EXCEPTION_CARD_ITEM_NAME, [NON_EXPIRED_EXCEPTION_ITEM_NAME]); - viewExpiredExceptionItems(); - assertNumberOfExceptionItemsExists(0); - }); + it('Duplicates rules with exceptions, excluding expired exceptions', () => { + selectAllRules(); + duplicateSelectedRulesWithNonExpiredExceptions(); + expectManagementTableRules([`${RULE_NAME} [Duplicate]`]); + goToRuleDetailsOf(`${RULE_NAME} [Duplicate]`); + goToExceptionsTab(); + assertExceptionItemsExists(EXCEPTION_CARD_ITEM_NAME, [NON_EXPIRED_EXCEPTION_ITEM_NAME]); + viewExpiredExceptionItems(); + assertNumberOfExceptionItemsExists(0); }); - } -); + }); +}); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules.cy.ts index 8d551b655fca4..74448f32dcf5e 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules.cy.ts @@ -117,563 +117,558 @@ const defaultRuleData = { timeline_id: '495ad7a7-316e-4544-8a0f-9c098daee76e', }; -// TODO: https://github.com/elastic/kibana/issues/161540 -describe( - 'Detection rules, bulk edit', - { tags: ['@ess', '@serverless', '@brokenInServerless'] }, - () => { - before(() => { - cleanKibana(); - }); - beforeEach(() => { - login(); - // Make sure persisted rules table state is cleared - resetRulesTableState(); - deleteAlertsAndRules(); - preventPrebuiltRulesPackageInstallation(); // Make sure prebuilt rules aren't pulled from Fleet API - cy.task('esArchiverResetKibana'); - createRule(getNewRule({ name: RULE_NAME, ...defaultRuleData, rule_id: '1', enabled: false })); - createRule( - getEqlRule({ ...defaultRuleData, rule_id: '2', name: 'New EQL Rule', enabled: false }) - ); - createRule( - getMachineLearningRule({ - name: 'New ML Rule Test', - tags: ['test-default-tag-1', 'test-default-tag-2'], - enabled: false, - }) - ); - createRule( - getNewThreatIndicatorRule({ - ...defaultRuleData, - rule_id: '4', - name: 'Threat Indicator Rule Test', - enabled: false, - }) - ); - createRule( - getNewThresholdRule({ - ...defaultRuleData, - rule_id: '5', - name: 'Threshold Rule', - enabled: false, - }) - ); - createRule( - getNewTermsRule({ - ...defaultRuleData, - rule_id: '6', - name: 'New Terms Rule', - enabled: false, - }) - ); - - visitRulesManagementTable(); - disableAutoRefresh(); - }); - - describe('Prerequisites', () => { - const PREBUILT_RULES = [ - createRuleAssetSavedObject({ - name: 'Prebuilt rule 1', - rule_id: 'rule_1', - }), - createRuleAssetSavedObject({ - name: 'Prebuilt rule 2', - rule_id: 'rule_2', - }), - ]; - - it('No rules selected', () => { - openBulkActionsMenu(); - - // when no rule selected all bulk edit options should be disabled - cy.get(TAGS_RULE_BULK_MENU_ITEM).should('be.disabled'); - cy.get(INDEX_PATTERNS_RULE_BULK_MENU_ITEM).should('be.disabled'); - cy.get(APPLY_TIMELINE_RULE_BULK_MENU_ITEM).should('be.disabled'); - }); - - it('Only prebuilt rules selected', () => { - createAndInstallMockedPrebuiltRules(PREBUILT_RULES); - - // select Elastic(prebuilt) rules, check if we can't proceed further, as Elastic rules are not editable - filterByElasticRules(); - selectAllRulesOnPage(); - clickApplyTimelineTemplatesMenuItem(); - - getRulesManagementTableRows().then((rows) => { - // check modal window for Elastic rule that can't be edited - checkPrebuiltRulesCannotBeModified(rows.length); - - // the confirm button closes modal - cy.get(MODAL_CONFIRMATION_BTN).should('have.text', 'Close').click(); - cy.get(MODAL_CONFIRMATION_BODY).should('not.exist'); - }); - }); +describe('Detection rules, bulk edit', { tags: ['@ess', '@serverless'] }, () => { + before(() => { + cleanKibana(); + }); + beforeEach(() => { + login(); + // Make sure persisted rules table state is cleared + resetRulesTableState(); + deleteAlertsAndRules(); + preventPrebuiltRulesPackageInstallation(); // Make sure prebuilt rules aren't pulled from Fleet API + cy.task('esArchiverResetKibana'); + createRule(getNewRule({ name: RULE_NAME, ...defaultRuleData, rule_id: '1', enabled: false })); + createRule( + getEqlRule({ ...defaultRuleData, rule_id: '2', name: 'New EQL Rule', enabled: false }) + ); + createRule( + getMachineLearningRule({ + name: 'New ML Rule Test', + tags: ['test-default-tag-1', 'test-default-tag-2'], + enabled: false, + }) + ); + createRule( + getNewThreatIndicatorRule({ + ...defaultRuleData, + rule_id: '4', + name: 'Threat Indicator Rule Test', + enabled: false, + }) + ); + createRule( + getNewThresholdRule({ + ...defaultRuleData, + rule_id: '5', + name: 'Threshold Rule', + enabled: false, + }) + ); + createRule( + getNewTermsRule({ + ...defaultRuleData, + rule_id: '6', + name: 'New Terms Rule', + enabled: false, + }) + ); - it('Prebuilt and custom rules selected: user proceeds with custom rules editing', () => { - getRulesManagementTableRows().then((existedRulesRows) => { - createAndInstallMockedPrebuiltRules(PREBUILT_RULES); + visitRulesManagementTable(); + disableAutoRefresh(); + }); - // modal window should show how many rules can be edit, how many not - selectAllRules(); - clickAddTagsMenuItem(); + describe('Prerequisites', () => { + const PREBUILT_RULES = [ + createRuleAssetSavedObject({ + name: 'Prebuilt rule 1', + rule_id: 'rule_1', + }), + createRuleAssetSavedObject({ + name: 'Prebuilt rule 2', + rule_id: 'rule_2', + }), + ]; + + it('No rules selected', () => { + openBulkActionsMenu(); + + // when no rule selected all bulk edit options should be disabled + cy.get(TAGS_RULE_BULK_MENU_ITEM).should('be.disabled'); + cy.get(INDEX_PATTERNS_RULE_BULK_MENU_ITEM).should('be.disabled'); + cy.get(APPLY_TIMELINE_RULE_BULK_MENU_ITEM).should('be.disabled'); + }); - waitForMixedRulesBulkEditModal(existedRulesRows.length); + it('Only prebuilt rules selected', () => { + createAndInstallMockedPrebuiltRules(PREBUILT_RULES); - getAvailablePrebuiltRulesCount().then((availablePrebuiltRulesCount) => { - checkPrebuiltRulesCannotBeModified(availablePrebuiltRulesCount); - }); + // select Elastic(prebuilt) rules, check if we can't proceed further, as Elastic rules are not editable + filterByElasticRules(); + selectAllRulesOnPage(); + clickApplyTimelineTemplatesMenuItem(); - // user can proceed with custom rule editing - cy.get(MODAL_CONFIRMATION_BTN) - .should('have.text', `Edit ${existedRulesRows.length} custom rules`) - .click(); + getRulesManagementTableRows().then((rows) => { + // check modal window for Elastic rule that can't be edited + checkPrebuiltRulesCannotBeModified(rows.length); - // action should finish - typeTags(['test-tag']); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: existedRulesRows.length }); - }); + // the confirm button closes modal + cy.get(MODAL_CONFIRMATION_BTN).should('have.text', 'Close').click(); + cy.get(MODAL_CONFIRMATION_BODY).should('not.exist'); }); + }); - it('Prebuilt and custom rules selected: user cancels action', () => { + it('Prebuilt and custom rules selected: user proceeds with custom rules editing', () => { + getRulesManagementTableRows().then((existedRulesRows) => { createAndInstallMockedPrebuiltRules(PREBUILT_RULES); - getRulesManagementTableRows().then((rows) => { - // modal window should show how many rules can be edit, how many not - selectAllRules(); - clickAddTagsMenuItem(); - waitForMixedRulesBulkEditModal(rows.length); + // modal window should show how many rules can be edit, how many not + selectAllRules(); + clickAddTagsMenuItem(); - checkPrebuiltRulesCannotBeModified(PREBUILT_RULES.length); + waitForMixedRulesBulkEditModal(existedRulesRows.length); - // user cancels action and modal disappears - cancelConfirmationModal(); + getAvailablePrebuiltRulesCount().then((availablePrebuiltRulesCount) => { + checkPrebuiltRulesCannotBeModified(availablePrebuiltRulesCount); }); - }); - it('should not lose rules selection after edit action', () => { - const rulesToUpdate = [RULE_NAME, 'New EQL Rule', 'New Terms Rule'] as const; - // Switch to 5 rules per page, to have few pages in pagination(ideal way to test auto refresh and selection of few items) - setRowsPerPageTo(5); - // and make the rules order isn't changing (set sorting by rule name) over time if rules are run - sortByTableColumn('Rule'); - selectRulesByName(rulesToUpdate); + // user can proceed with custom rule editing + cy.get(MODAL_CONFIRMATION_BTN) + .should('have.text', `Edit ${existedRulesRows.length} custom rules`) + .click(); - // open add tags form and add 2 new tags - openBulkEditAddTagsForm(); - typeTags(['new-tag-1']); + // action should finish + typeTags(['test-tag']); submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rulesToUpdate.length }); - - testMultipleSelectedRulesLabel(rulesToUpdate.length); - // check if first four(rulesCount) rules still selected and tags are updated - for (const ruleName of rulesToUpdate) { - getRuleRow(ruleName).find(EUI_CHECKBOX).should('be.checked'); - getRuleRow(ruleName) - .find(RULES_TAGS_POPOVER_BTN) - .each(($el) => { - testTagsBadge($el, prePopulatedTags.concat(['new-tag-1'])); - }); - } + waitForBulkEditActionToFinish({ updatedCount: existedRulesRows.length }); }); }); - describe('Tags actions', () => { - it('Display list of tags in tags select', () => { + it('Prebuilt and custom rules selected: user cancels action', () => { + createAndInstallMockedPrebuiltRules(PREBUILT_RULES); + + getRulesManagementTableRows().then((rows) => { + // modal window should show how many rules can be edit, how many not selectAllRules(); + clickAddTagsMenuItem(); + waitForMixedRulesBulkEditModal(rows.length); - openBulkEditAddTagsForm(); - openTagsSelect(); + checkPrebuiltRulesCannotBeModified(PREBUILT_RULES.length); - cy.get(EUI_FILTER_SELECT_ITEM) - .should('have.length', prePopulatedTags.length) - .each(($el, index) => { - cy.wrap($el).should('have.text', prePopulatedTags[index]); - }); + // user cancels action and modal disappears + cancelConfirmationModal(); }); + }); - it('Add tags to custom rules', () => { - getRulesManagementTableRows().then((rows) => { - const tagsToBeAdded = ['tag-to-add-1', 'tag-to-add-2']; - const resultingTags = [...prePopulatedTags, ...tagsToBeAdded]; - - // check if only pre-populated tags exist in the tags filter - checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); - - selectAllRules(); + it('should not lose rules selection after edit action', () => { + const rulesToUpdate = [RULE_NAME, 'New EQL Rule', 'New Terms Rule'] as const; + // Switch to 5 rules per page, to have few pages in pagination(ideal way to test auto refresh and selection of few items) + setRowsPerPageTo(5); + // and make the rules order isn't changing (set sorting by rule name) over time if rules are run + sortByTableColumn('Rule'); + selectRulesByName(rulesToUpdate); + + // open add tags form and add 2 new tags + openBulkEditAddTagsForm(); + typeTags(['new-tag-1']); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rulesToUpdate.length }); + + testMultipleSelectedRulesLabel(rulesToUpdate.length); + // check if first four(rulesCount) rules still selected and tags are updated + for (const ruleName of rulesToUpdate) { + getRuleRow(ruleName).find(EUI_CHECKBOX).should('be.checked'); + getRuleRow(ruleName) + .find(RULES_TAGS_POPOVER_BTN) + .each(($el) => { + testTagsBadge($el, prePopulatedTags.concat(['new-tag-1'])); + }); + } + }); + }); - // open add tags form and add 2 new tags - openBulkEditAddTagsForm(); - typeTags(tagsToBeAdded); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); + describe('Tags actions', () => { + it('Display list of tags in tags select', () => { + selectAllRules(); - // check if all rules have been updated with new tags - testAllTagsBadges(resultingTags); + openBulkEditAddTagsForm(); + openTagsSelect(); - // check that new tags were added to tags filter - // tags in tags filter sorted alphabetically - const resultingTagsInFilter = [...resultingTags].sort(); - checkTagsInTagsFilter(resultingTagsInFilter, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); + cy.get(EUI_FILTER_SELECT_ITEM) + .should('have.length', prePopulatedTags.length) + .each(($el, index) => { + cy.wrap($el).should('have.text', prePopulatedTags[index]); }); - }); + }); - it('Display success toast after adding tags', () => { - getRulesManagementTableRows().then((rows) => { - const tagsToBeAdded = ['tag-to-add-1', 'tag-to-add-2']; + it('Add tags to custom rules', () => { + getRulesManagementTableRows().then((rows) => { + const tagsToBeAdded = ['tag-to-add-1', 'tag-to-add-2']; + const resultingTags = [...prePopulatedTags, ...tagsToBeAdded]; - // check if only pre-populated tags exist in the tags filter - checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); + // check if only pre-populated tags exist in the tags filter + checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); - selectAllRules(); + selectAllRules(); - // open add tags form and add 2 new tags - openBulkEditAddTagsForm(); - typeTags(tagsToBeAdded); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); - }); - }); + // open add tags form and add 2 new tags + openBulkEditAddTagsForm(); + typeTags(tagsToBeAdded); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); - it('Overwrite tags in custom rules', () => { - getRulesManagementTableRows().then((rows) => { - const tagsToOverwrite = ['overwrite-tag-1']; + // check if all rules have been updated with new tags + testAllTagsBadges(resultingTags); - // check if only pre-populated tags exist in the tags filter - checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); + // check that new tags were added to tags filter + // tags in tags filter sorted alphabetically + const resultingTagsInFilter = [...resultingTags].sort(); + checkTagsInTagsFilter(resultingTagsInFilter, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); + }); + }); - selectAllRules(); + it('Display success toast after adding tags', () => { + getRulesManagementTableRows().then((rows) => { + const tagsToBeAdded = ['tag-to-add-1', 'tag-to-add-2']; - // open add tags form, check overwrite tags and warning message, type tags - openBulkEditAddTagsForm(); - checkOverwriteTagsCheckbox(); + // check if only pre-populated tags exist in the tags filter + checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); - cy.get(RULES_BULK_EDIT_TAGS_WARNING).should( - 'have.text', - `You’re about to overwrite tags for ${rows.length} selected rules, press Save to apply changes.` - ); + selectAllRules(); - typeTags(tagsToOverwrite); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); + // open add tags form and add 2 new tags + openBulkEditAddTagsForm(); + typeTags(tagsToBeAdded); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); + }); + }); - // check if all rules have been updated with new tags - testAllTagsBadges(tagsToOverwrite); + it('Overwrite tags in custom rules', () => { + getRulesManagementTableRows().then((rows) => { + const tagsToOverwrite = ['overwrite-tag-1']; - // check that only new tags are in the tag filter - checkTagsInTagsFilter(tagsToOverwrite, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); - }); - }); + // check if only pre-populated tags exist in the tags filter + checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); - it('Delete tags from custom rules', () => { - getRulesManagementTableRows().then((rows) => { - const tagsToDelete = prePopulatedTags.slice(0, 1); - const resultingTags = prePopulatedTags.slice(1); + selectAllRules(); - // check if only pre-populated tags exist in the tags filter - checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); + // open add tags form, check overwrite tags and warning message, type tags + openBulkEditAddTagsForm(); + checkOverwriteTagsCheckbox(); - selectAllRules(); + cy.get(RULES_BULK_EDIT_TAGS_WARNING).should( + 'have.text', + `You’re about to overwrite tags for ${rows.length} selected rules, press Save to apply changes.` + ); - // open add tags form, check overwrite tags, type tags - openBulkEditDeleteTagsForm(); - typeTags(tagsToDelete); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); + typeTags(tagsToOverwrite); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); - // check tags has been removed from all rules - testAllTagsBadges(resultingTags); + // check if all rules have been updated with new tags + testAllTagsBadges(tagsToOverwrite); - // check that tags were removed from the tag filter - checkTagsInTagsFilter(resultingTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); - }); + // check that only new tags are in the tag filter + checkTagsInTagsFilter(tagsToOverwrite, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); }); }); - describe('Index patterns', () => { - it('Index pattern action applied to custom rules, including machine learning: user proceeds with edit of custom non machine learning rule', () => { - getRulesManagementTableRows().then((rows) => { - const indexPattersToBeAdded = ['index-to-add-1-*', 'index-to-add-2-*']; - const resultingIndexPatterns = [...prePopulatedIndexPatterns, ...indexPattersToBeAdded]; + it('Delete tags from custom rules', () => { + getRulesManagementTableRows().then((rows) => { + const tagsToDelete = prePopulatedTags.slice(0, 1); + const resultingTags = prePopulatedTags.slice(1); - selectAllRules(); - clickAddIndexPatternsMenuItem(); + // check if only pre-populated tags exist in the tags filter + checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); - // confirm editing custom rules, that are not Machine Learning - checkMachineLearningRulesCannotBeModified(expectedNumberOfMachineLearningRulesToBeEdited); - cy.get(MODAL_CONFIRMATION_BTN).click(); + selectAllRules(); - typeIndexPatterns(indexPattersToBeAdded); - submitBulkEditForm(); + // open add tags form, check overwrite tags, type tags + openBulkEditDeleteTagsForm(); + typeTags(tagsToDelete); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); - waitForBulkEditActionToFinish({ - updatedCount: rows.length - expectedNumberOfMachineLearningRulesToBeEdited, - }); + // check tags has been removed from all rules + testAllTagsBadges(resultingTags); - // check if rule has been updated - goToRuleDetailsOf(RULE_NAME); - hasIndexPatterns(resultingIndexPatterns.join('')); - }); + // check that tags were removed from the tag filter + checkTagsInTagsFilter(resultingTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); }); + }); + }); + + describe('Index patterns', () => { + it('Index pattern action applied to custom rules, including machine learning: user proceeds with edit of custom non machine learning rule', () => { + getRulesManagementTableRows().then((rows) => { + const indexPattersToBeAdded = ['index-to-add-1-*', 'index-to-add-2-*']; + const resultingIndexPatterns = [...prePopulatedIndexPatterns, ...indexPattersToBeAdded]; - it('Index pattern action applied to custom rules, including machine learning: user cancels action', () => { selectAllRules(); clickAddIndexPatternsMenuItem(); // confirm editing custom rules, that are not Machine Learning checkMachineLearningRulesCannotBeModified(expectedNumberOfMachineLearningRulesToBeEdited); + cy.get(MODAL_CONFIRMATION_BTN).click(); - // user cancels action and modal disappears - cancelConfirmationModal(); - }); - - it('Add index patterns to custom rules', () => { - getRulesManagementTableRows().then((rows) => { - const indexPattersToBeAdded = ['index-to-add-1-*', 'index-to-add-2-*']; - const resultingIndexPatterns = [...prePopulatedIndexPatterns, ...indexPattersToBeAdded]; - - // select only rules that are not ML - selectRulesByName([ - RULE_NAME, - 'New EQL Rule', - 'Threat Indicator Rule Test', - 'Threshold Rule', - 'New Terms Rule', - ]); - - openBulkEditAddIndexPatternsForm(); - typeIndexPatterns(indexPattersToBeAdded); - submitBulkEditForm(); - - waitForBulkEditActionToFinish({ - updatedCount: rows.length - expectedNumberOfMachineLearningRulesToBeEdited, - }); + typeIndexPatterns(indexPattersToBeAdded); + submitBulkEditForm(); - // check if rule has been updated - goToRuleDetailsOf(RULE_NAME); - hasIndexPatterns(resultingIndexPatterns.join('')); + waitForBulkEditActionToFinish({ + updatedCount: rows.length - expectedNumberOfMachineLearningRulesToBeEdited, }); - }); - it('Display success toast after editing the index pattern', () => { - getRulesManagementTableRows().then((rows) => { - const indexPattersToBeAdded = ['index-to-add-1-*', 'index-to-add-2-*']; - - // select only rules that are not ML - selectRulesByName([ - RULE_NAME, - 'New EQL Rule', - 'Threat Indicator Rule Test', - 'Threshold Rule', - 'New Terms Rule', - ]); - - openBulkEditAddIndexPatternsForm(); - typeIndexPatterns(indexPattersToBeAdded); - submitBulkEditForm(); - - waitForBulkEditActionToFinish({ - updatedCount: rows.length - expectedNumberOfMachineLearningRulesToBeEdited, - }); - }); + // check if rule has been updated + goToRuleDetailsOf(RULE_NAME); + hasIndexPatterns(resultingIndexPatterns.join('')); }); + }); + + it('Index pattern action applied to custom rules, including machine learning: user cancels action', () => { + selectAllRules(); + clickAddIndexPatternsMenuItem(); + + // confirm editing custom rules, that are not Machine Learning + checkMachineLearningRulesCannotBeModified(expectedNumberOfMachineLearningRulesToBeEdited); + + // user cancels action and modal disappears + cancelConfirmationModal(); + }); - it('Overwrite index patterns in custom rules', () => { - const rulesToSelect = [ + it('Add index patterns to custom rules', () => { + getRulesManagementTableRows().then((rows) => { + const indexPattersToBeAdded = ['index-to-add-1-*', 'index-to-add-2-*']; + const resultingIndexPatterns = [...prePopulatedIndexPatterns, ...indexPattersToBeAdded]; + + // select only rules that are not ML + selectRulesByName([ RULE_NAME, 'New EQL Rule', 'Threat Indicator Rule Test', 'Threshold Rule', 'New Terms Rule', - ] as const; - const indexPattersToWrite = ['index-to-write-1-*', 'index-to-write-2-*']; - - // select only rules that are not ML - selectRulesByName(rulesToSelect); + ]); openBulkEditAddIndexPatternsForm(); - - // check overwrite index patterns checkbox, ensure warning message is displayed and type index patterns - checkOverwriteIndexPatternsCheckbox(); - cy.get(RULES_BULK_EDIT_INDEX_PATTERNS_WARNING).should( - 'have.text', - `You’re about to overwrite index patterns for ${rulesToSelect.length} selected rules, press Save to apply changes.` - ); - - typeIndexPatterns(indexPattersToWrite); + typeIndexPatterns(indexPattersToBeAdded); submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rulesToSelect.length }); + waitForBulkEditActionToFinish({ + updatedCount: rows.length - expectedNumberOfMachineLearningRulesToBeEdited, + }); // check if rule has been updated goToRuleDetailsOf(RULE_NAME); - hasIndexPatterns(indexPattersToWrite.join('')); + hasIndexPatterns(resultingIndexPatterns.join('')); }); + }); + + it('Display success toast after editing the index pattern', () => { + getRulesManagementTableRows().then((rows) => { + const indexPattersToBeAdded = ['index-to-add-1-*', 'index-to-add-2-*']; - it('Delete index patterns from custom rules', () => { - const rulesToSelect = [ + // select only rules that are not ML + selectRulesByName([ RULE_NAME, 'New EQL Rule', 'Threat Indicator Rule Test', 'Threshold Rule', 'New Terms Rule', - ] as const; - const indexPatternsToDelete = prePopulatedIndexPatterns.slice(0, 1); - const resultingIndexPatterns = prePopulatedIndexPatterns.slice(1); - - // select only not ML rules - selectRulesByName(rulesToSelect); + ]); - openBulkEditDeleteIndexPatternsForm(); - typeIndexPatterns(indexPatternsToDelete); + openBulkEditAddIndexPatternsForm(); + typeIndexPatterns(indexPattersToBeAdded); submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rulesToSelect.length }); - - // check if rule has been updated - goToRuleDetailsOf(RULE_NAME); - hasIndexPatterns(resultingIndexPatterns.join('')); + waitForBulkEditActionToFinish({ + updatedCount: rows.length - expectedNumberOfMachineLearningRulesToBeEdited, + }); }); + }); - it('Delete all index patterns from custom rules', () => { - const rulesToSelect = [ - RULE_NAME, - 'New EQL Rule', - 'Threat Indicator Rule Test', - 'Threshold Rule', - 'New Terms Rule', - ] as const; + it('Overwrite index patterns in custom rules', () => { + const rulesToSelect = [ + RULE_NAME, + 'New EQL Rule', + 'Threat Indicator Rule Test', + 'Threshold Rule', + 'New Terms Rule', + ] as const; + const indexPattersToWrite = ['index-to-write-1-*', 'index-to-write-2-*']; + + // select only rules that are not ML + selectRulesByName(rulesToSelect); + + openBulkEditAddIndexPatternsForm(); + + // check overwrite index patterns checkbox, ensure warning message is displayed and type index patterns + checkOverwriteIndexPatternsCheckbox(); + cy.get(RULES_BULK_EDIT_INDEX_PATTERNS_WARNING).should( + 'have.text', + `You’re about to overwrite index patterns for ${rulesToSelect.length} selected rules, press Save to apply changes.` + ); - // select only rules that are not ML - selectRulesByName(rulesToSelect); + typeIndexPatterns(indexPattersToWrite); + submitBulkEditForm(); - openBulkEditDeleteIndexPatternsForm(); - typeIndexPatterns(prePopulatedIndexPatterns); - submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rulesToSelect.length }); - // error toast should be displayed that that rules edit failed - waitForBulkEditActionToFinish({ failedCount: rulesToSelect.length }); + // check if rule has been updated + goToRuleDetailsOf(RULE_NAME); + hasIndexPatterns(indexPattersToWrite.join('')); + }); - // on error toast button click display error that index patterns can't be empty - clickErrorToastBtn(); - cy.contains(MODAL_ERROR_BODY, "Index patterns can't be empty"); - }); + it('Delete index patterns from custom rules', () => { + const rulesToSelect = [ + RULE_NAME, + 'New EQL Rule', + 'Threat Indicator Rule Test', + 'Threshold Rule', + 'New Terms Rule', + ] as const; + const indexPatternsToDelete = prePopulatedIndexPatterns.slice(0, 1); + const resultingIndexPatterns = prePopulatedIndexPatterns.slice(1); + + // select only not ML rules + selectRulesByName(rulesToSelect); + + openBulkEditDeleteIndexPatternsForm(); + typeIndexPatterns(indexPatternsToDelete); + submitBulkEditForm(); + + waitForBulkEditActionToFinish({ updatedCount: rulesToSelect.length }); + + // check if rule has been updated + goToRuleDetailsOf(RULE_NAME); + hasIndexPatterns(resultingIndexPatterns.join('')); }); - describe('Timeline templates', () => { - beforeEach(() => { - loadPrepackagedTimelineTemplates(); - }); + it('Delete all index patterns from custom rules', () => { + const rulesToSelect = [ + RULE_NAME, + 'New EQL Rule', + 'Threat Indicator Rule Test', + 'Threshold Rule', + 'New Terms Rule', + ] as const; - it('Apply timeline template to custom rules', () => { - getRulesManagementTableRows().then((rows) => { - const timelineTemplateName = 'Generic Endpoint Timeline'; + // select only rules that are not ML + selectRulesByName(rulesToSelect); - selectAllRules(); + openBulkEditDeleteIndexPatternsForm(); + typeIndexPatterns(prePopulatedIndexPatterns); + submitBulkEditForm(); - // open Timeline template form, check warning, select timeline template - clickApplyTimelineTemplatesMenuItem(); - cy.get(RULES_BULK_EDIT_TIMELINE_TEMPLATES_WARNING).contains( - `You're about to apply changes to ${rows.length} selected rules. If you previously applied Timeline templates to these rules, they will be overwritten or (if you select 'None') reset to none.` - ); - selectTimelineTemplate(timelineTemplateName); + // error toast should be displayed that that rules edit failed + waitForBulkEditActionToFinish({ failedCount: rulesToSelect.length }); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); + // on error toast button click display error that index patterns can't be empty + clickErrorToastBtn(); + cy.contains(MODAL_ERROR_BODY, "Index patterns can't be empty"); + }); + }); - // check if timeline template has been updated to selected one - goToRuleDetailsOf(RULE_NAME); - getDetails(TIMELINE_TEMPLATE_DETAILS).should('have.text', timelineTemplateName); - }); + describe('Timeline templates', () => { + beforeEach(() => { + loadPrepackagedTimelineTemplates(); + }); + + it('Apply timeline template to custom rules', () => { + getRulesManagementTableRows().then((rows) => { + const timelineTemplateName = 'Generic Endpoint Timeline'; + + selectAllRules(); + + // open Timeline template form, check warning, select timeline template + clickApplyTimelineTemplatesMenuItem(); + cy.get(RULES_BULK_EDIT_TIMELINE_TEMPLATES_WARNING).contains( + `You're about to apply changes to ${rows.length} selected rules. If you previously applied Timeline templates to these rules, they will be overwritten or (if you select 'None') reset to none.` + ); + selectTimelineTemplate(timelineTemplateName); + + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); + + // check if timeline template has been updated to selected one + goToRuleDetailsOf(RULE_NAME); + getDetails(TIMELINE_TEMPLATE_DETAILS).should('have.text', timelineTemplateName); }); + }); - it('Reset timeline template to None for custom rules', () => { - getRulesManagementTableRows().then((rows) => { - const noneTimelineTemplate = 'None'; + it('Reset timeline template to None for custom rules', () => { + getRulesManagementTableRows().then((rows) => { + const noneTimelineTemplate = 'None'; - selectAllRules(); + selectAllRules(); - // open Timeline template form, submit form without picking timeline template as None is selected by default - clickApplyTimelineTemplatesMenuItem(); + // open Timeline template form, submit form without picking timeline template as None is selected by default + clickApplyTimelineTemplatesMenuItem(); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); - // check if timeline template has been updated to selected one, by opening rule that have had timeline prior to editing - goToRuleDetailsOf(RULE_NAME); - getDetails(TIMELINE_TEMPLATE_DETAILS).should('have.text', noneTimelineTemplate); - }); + // check if timeline template has been updated to selected one, by opening rule that have had timeline prior to editing + goToRuleDetailsOf(RULE_NAME); + getDetails(TIMELINE_TEMPLATE_DETAILS).should('have.text', noneTimelineTemplate); }); }); + }); - describe('Schedule', () => { - it('Default values are applied to bulk edit schedule fields', () => { - getRulesManagementTableRows().then((rows) => { - selectAllRules(); - clickUpdateScheduleMenuItem(); + describe('Schedule', () => { + it('Default values are applied to bulk edit schedule fields', () => { + getRulesManagementTableRows().then((rows) => { + selectAllRules(); + clickUpdateScheduleMenuItem(); - assertUpdateScheduleWarningExists(rows.length); + assertUpdateScheduleWarningExists(rows.length); - assertDefaultValuesAreAppliedToScheduleFields({ - interval: 5, - lookback: 1, - }); + assertDefaultValuesAreAppliedToScheduleFields({ + interval: 5, + lookback: 1, }); }); + }); - it('Updates schedule for custom rules', () => { - getRulesManagementTableRows().then((rows) => { - selectAllRules(); - clickUpdateScheduleMenuItem(); + it('Updates schedule for custom rules', () => { + getRulesManagementTableRows().then((rows) => { + selectAllRules(); + clickUpdateScheduleMenuItem(); - assertUpdateScheduleWarningExists(rows.length); + assertUpdateScheduleWarningExists(rows.length); - typeScheduleInterval('20'); - setScheduleIntervalTimeUnit('Hours'); + typeScheduleInterval('20'); + setScheduleIntervalTimeUnit('Hours'); - typeScheduleLookback('10'); - setScheduleLookbackTimeUnit('Minutes'); + typeScheduleLookback('10'); + setScheduleLookbackTimeUnit('Minutes'); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); - goToRuleDetailsOf(RULE_NAME); + goToRuleDetailsOf(RULE_NAME); - assertRuleScheduleValues({ - interval: '20h', - lookback: '10m', - }); + assertRuleScheduleValues({ + interval: '20h', + lookback: '10m', }); }); + }); - it('Validates invalid inputs when scheduling for custom rules', () => { - getRulesManagementTableRows().then((rows) => { - selectAllRules(); - clickUpdateScheduleMenuItem(); + it('Validates invalid inputs when scheduling for custom rules', () => { + getRulesManagementTableRows().then((rows) => { + selectAllRules(); + clickUpdateScheduleMenuItem(); - // Validate invalid values are corrected to minimumValue - for 0 and negative values - typeScheduleInterval('0'); - setScheduleIntervalTimeUnit('Hours'); + // Validate invalid values are corrected to minimumValue - for 0 and negative values + typeScheduleInterval('0'); + setScheduleIntervalTimeUnit('Hours'); - typeScheduleLookback('-5'); - setScheduleLookbackTimeUnit('Seconds'); + typeScheduleLookback('-5'); + setScheduleLookbackTimeUnit('Seconds'); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); - goToRuleDetailsOf(RULE_NAME); + goToRuleDetailsOf(RULE_NAME); - assertRuleScheduleValues({ - interval: '1h', - lookback: '1s', - }); + assertRuleScheduleValues({ + interval: '1h', + lookback: '1s', }); }); }); - } -); + }); +}); // ES|QL rule type is supported only in ESS environment // Adding 2 use cases only for this rule type, while it is disabled on serverless diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts index 1d59135012a9d..48acff836f0a4 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts @@ -74,82 +74,79 @@ const ruleNameToAssert = 'Custom rule name with actions'; const expectedExistingSlackMessage = 'Existing slack action'; const expectedSlackMessage = 'Slack action test message'; -// TODO: https://github.com/elastic/kibana/issues/161540 -describe( - 'Detection rules, bulk edit of rule actions', - { tags: ['@ess', '@serverless', '@brokenInServerless'] }, - () => { - beforeEach(() => { - cleanKibana(); - login(); - deleteAlertsAndRules(); - deleteConnectors(); - cy.task('esArchiverResetKibana'); - - createSlackConnector().then(({ body }) => { - const actions: RuleActionArray = [ - { - id: body.id, - action_type_id: '.slack', - group: 'default', - params: { - message: expectedExistingSlackMessage, - }, - frequency: { - summary: true, - throttle: null, - notifyWhen: 'onActiveAlert', - }, +describe('Detection rules, bulk edit of rule actions', { tags: ['@ess', '@serverless'] }, () => { + beforeEach(() => { + cleanKibana(); + login(); + deleteAlertsAndRules(); + deleteConnectors(); + cy.task('esArchiverResetKibana'); + + createSlackConnector().then(({ body }) => { + const actions: RuleActionArray = [ + { + id: body.id, + action_type_id: '.slack', + group: 'default', + params: { + message: expectedExistingSlackMessage, }, - ]; - - createRule( - getNewRule({ - rule_id: '1', - name: ruleNameToAssert, - max_signals: 500, - actions, - enabled: false, - }) - ); - }); + frequency: { + summary: true, + throttle: null, + notifyWhen: 'onActiveAlert', + }, + }, + ]; - createRule(getEqlRule({ rule_id: '2', name: 'New EQL Rule', enabled: false })); createRule( - getMachineLearningRule({ rule_id: '3', name: 'New ML Rule Test', enabled: false }) - ); - createRule( - getNewThreatIndicatorRule({ - rule_id: '4', - name: 'Threat Indicator Rule Test', + getNewRule({ + rule_id: '1', + name: ruleNameToAssert, + max_signals: 500, + actions, enabled: false, }) ); - createRule(getNewThresholdRule({ rule_id: '5', name: 'Threshold Rule', enabled: false })); - createRule(getNewTermsRule({ rule_id: '6', name: 'New Terms Rule', enabled: false })); - createRule( - getNewRule({ saved_id: 'mocked', rule_id: '7', name: 'New Rule Test', enabled: false }) - ); - - createSlackConnector(); - - // Prevent prebuilt rules package installation and mock two prebuilt rules - preventPrebuiltRulesPackageInstallation(); - - const RULE_1 = createRuleAssetSavedObject({ - name: 'Test rule 1', - rule_id: 'rule_1', - }); - const RULE_2 = createRuleAssetSavedObject({ - name: 'Test rule 2', - rule_id: 'rule_2', - }); + }); - createAndInstallMockedPrebuiltRules([RULE_1, RULE_2]); + createRule(getEqlRule({ rule_id: '2', name: 'New EQL Rule', enabled: false })); + createRule(getMachineLearningRule({ rule_id: '3', name: 'New ML Rule Test', enabled: false })); + createRule( + getNewThreatIndicatorRule({ + rule_id: '4', + name: 'Threat Indicator Rule Test', + enabled: false, + }) + ); + createRule(getNewThresholdRule({ rule_id: '5', name: 'Threshold Rule', enabled: false })); + createRule(getNewTermsRule({ rule_id: '6', name: 'New Terms Rule', enabled: false })); + createRule( + getNewRule({ saved_id: 'mocked', rule_id: '7', name: 'New Rule Test', enabled: false }) + ); + + createSlackConnector(); + + // Prevent prebuilt rules package installation and mock two prebuilt rules + preventPrebuiltRulesPackageInstallation(); + + const RULE_1 = createRuleAssetSavedObject({ + name: 'Test rule 1', + rule_id: 'rule_1', }); + const RULE_2 = createRuleAssetSavedObject({ + name: 'Test rule 2', + rule_id: 'rule_2', + }); + + createAndInstallMockedPrebuiltRules([RULE_1, RULE_2]); + }); - context('Restricted action privileges', () => { - it("User with no privileges can't add rule actions", () => { + context('Restricted action privileges', () => { + it( + "User with no privileges can't add rule actions", + { tags: ['@ess', '@skipInServerless'] }, + () => { login(ROLES.hunter_no_actions); visitRulesManagementTable(ROLES.hunter_no_actions); @@ -171,129 +168,129 @@ describe( openBulkActionsMenu(); cy.get(ADD_RULE_ACTIONS_MENU_ITEM).should('be.disabled'); - }); - }); + } + ); + }); - context('All actions privileges', () => { - beforeEach(() => { - login(); - visitRulesManagementTable(); - disableAutoRefresh(); - - expectManagementTableRules([ - ruleNameToAssert, - 'New EQL Rule', - 'New ML Rule Test', - 'Threat Indicator Rule Test', - 'Threshold Rule', - 'New Terms Rule', - 'New Rule Test', - 'Test rule 1', - 'Test rule 2', - ]); - }); + context('All actions privileges', () => { + beforeEach(() => { + login(); + visitRulesManagementTable(); + disableAutoRefresh(); + + expectManagementTableRules([ + ruleNameToAssert, + 'New EQL Rule', + 'New ML Rule Test', + 'Threat Indicator Rule Test', + 'Threshold Rule', + 'New Terms Rule', + 'New Rule Test', + 'Test rule 1', + 'Test rule 2', + ]); + }); - it('Add a rule action to rules (existing connector)', () => { - const expectedActionFrequency: RuleActionCustomFrequency = { - throttle: 1, - throttleUnit: 'd', - }; + it('Add a rule action to rules (existing connector)', () => { + const expectedActionFrequency: RuleActionCustomFrequency = { + throttle: 1, + throttleUnit: 'd', + }; - excessivelyInstallAllPrebuiltRules(); + excessivelyInstallAllPrebuiltRules(); - getRulesManagementTableRows().then((rows) => { - // select both custom and prebuilt rules - selectAllRules(); - openBulkEditRuleActionsForm(); + getRulesManagementTableRows().then((rows) => { + // select both custom and prebuilt rules + selectAllRules(); + openBulkEditRuleActionsForm(); - // ensure rule actions info callout displayed on the form - cy.get(RULES_BULK_EDIT_ACTIONS_INFO).should('be.visible'); + // ensure rule actions info callout displayed on the form + cy.get(RULES_BULK_EDIT_ACTIONS_INFO).should('be.visible'); - addSlackRuleAction(expectedSlackMessage); - pickSummaryOfAlertsOption(); - pickCustomFrequencyOption(expectedActionFrequency); + addSlackRuleAction(expectedSlackMessage); + pickSummaryOfAlertsOption(); + pickCustomFrequencyOption(expectedActionFrequency); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); - // check if rule has been updated - goToEditRuleActionsSettingsOf(ruleNameToAssert); + // check if rule has been updated + goToEditRuleActionsSettingsOf(ruleNameToAssert); - assertSelectedSummaryOfAlertsOption(); - assertSelectedCustomFrequencyOption(expectedActionFrequency, 1); - assertSlackRuleAction(expectedExistingSlackMessage, 0); - assertSlackRuleAction(expectedSlackMessage, 1); - // ensure there is no third action - cy.get(actionFormSelector(2)).should('not.exist'); - }); + assertSelectedSummaryOfAlertsOption(); + assertSelectedCustomFrequencyOption(expectedActionFrequency, 1); + assertSlackRuleAction(expectedExistingSlackMessage, 0); + assertSlackRuleAction(expectedSlackMessage, 1); + // ensure there is no third action + cy.get(actionFormSelector(2)).should('not.exist'); }); + }); - it('Overwrite rule actions in rules', () => { - excessivelyInstallAllPrebuiltRules(); - - getRulesManagementTableRows().then((rows) => { - // select both custom and prebuilt rules - selectAllRules(); - openBulkEditRuleActionsForm(); - - addSlackRuleAction(expectedSlackMessage); - pickSummaryOfAlertsOption(); - pickPerRuleRunFrequencyOption(); - - // check overwrite box, ensure warning is displayed - checkOverwriteRuleActionsCheckbox(); - cy.get(RULES_BULK_EDIT_ACTIONS_WARNING).contains( - `You're about to overwrite rule actions for ${rows.length} selected rules` - ); - - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); - - // check if rule has been updated - goToEditRuleActionsSettingsOf(ruleNameToAssert); - - assertSelectedSummaryOfAlertsOption(); - assertSelectedPerRuleRunFrequencyOption(); - assertSlackRuleAction(expectedSlackMessage); - // ensure existing action was overwritten - cy.get(actionFormSelector(1)).should('not.exist'); - }); - }); + it('Overwrite rule actions in rules', () => { + excessivelyInstallAllPrebuiltRules(); - it('Add a rule action to rules (new connector)', () => { - const rulesToSelect = [ - ruleNameToAssert, - 'New EQL Rule', - 'New ML Rule Test', - 'Threat Indicator Rule Test', - 'Threshold Rule', - 'New Terms Rule', - 'New Rule Test', - ] as const; - const expectedActionFrequency: RuleActionCustomFrequency = { - throttle: 2, - throttleUnit: 'h', - }; - const expectedEmail = 'test@example.com'; - const expectedSubject = 'Subject'; - - selectRulesByName(rulesToSelect); + getRulesManagementTableRows().then((rows) => { + // select both custom and prebuilt rules + selectAllRules(); openBulkEditRuleActionsForm(); - addEmailConnectorAndRuleAction(expectedEmail, expectedSubject); + addSlackRuleAction(expectedSlackMessage); pickSummaryOfAlertsOption(); - pickCustomFrequencyOption(expectedActionFrequency); + pickPerRuleRunFrequencyOption(); + + // check overwrite box, ensure warning is displayed + checkOverwriteRuleActionsCheckbox(); + cy.get(RULES_BULK_EDIT_ACTIONS_WARNING).contains( + `You're about to overwrite rule actions for ${rows.length} selected rules` + ); submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rulesToSelect.length }); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); // check if rule has been updated goToEditRuleActionsSettingsOf(ruleNameToAssert); assertSelectedSummaryOfAlertsOption(); - assertSelectedCustomFrequencyOption(expectedActionFrequency, 1); - assertEmailRuleAction(expectedEmail, expectedSubject); + assertSelectedPerRuleRunFrequencyOption(); + assertSlackRuleAction(expectedSlackMessage); + // ensure existing action was overwritten + cy.get(actionFormSelector(1)).should('not.exist'); }); }); - } -); + + it('Add a rule action to rules (new connector)', () => { + const rulesToSelect = [ + ruleNameToAssert, + 'New EQL Rule', + 'New ML Rule Test', + 'Threat Indicator Rule Test', + 'Threshold Rule', + 'New Terms Rule', + 'New Rule Test', + ] as const; + const expectedActionFrequency: RuleActionCustomFrequency = { + throttle: 2, + throttleUnit: 'h', + }; + const expectedEmail = 'test@example.com'; + const expectedSubject = 'Subject'; + + selectRulesByName(rulesToSelect); + openBulkEditRuleActionsForm(); + + addEmailConnectorAndRuleAction(expectedEmail, expectedSubject); + pickSummaryOfAlertsOption(); + pickCustomFrequencyOption(expectedActionFrequency); + + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rulesToSelect.length }); + + // check if rule has been updated + goToEditRuleActionsSettingsOf(ruleNameToAssert); + + assertSelectedSummaryOfAlertsOption(); + assertSelectedCustomFrequencyOption(expectedActionFrequency, 1); + assertEmailRuleAction(expectedEmail, expectedSubject); + }); + }); +}); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_data_view.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_data_view.cy.ts index b5c696da0c5ac..21c4558ce15e9 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_data_view.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_data_view.cy.ts @@ -53,10 +53,9 @@ const DATA_VIEW_ID = 'auditbeat'; const expectedIndexPatterns = ['index-1-*', 'index-2-*']; -// TODO: https://github.com/elastic/kibana/issues/161540 describe( 'Bulk editing index patterns of rules with a data view only', - { tags: ['@ess', '@serverless', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless'] }, () => { const TESTED_CUSTOM_QUERY_RULE_DATA = getNewRule({ index: undefined, @@ -244,7 +243,7 @@ describe( describe( 'Bulk editing index patterns of rules with index patterns and rules with a data view', - { tags: ['@ess', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless'] }, () => { const TESTED_CUSTOM_QUERY_RULE_DATA_WITH_DATAVIEW = getNewRule({ name: 'with dataview',