diff --git a/x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules/installation_and_upgrade.md b/x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules/installation_and_upgrade.md
index 09198dd2d9ef8..b8ae0c85c82e6 100644
--- a/x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules/installation_and_upgrade.md
+++ b/x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules/installation_and_upgrade.md
@@ -431,7 +431,7 @@ And user should see a CTA that leads to the Rule Management page
### Rule installation workflow: filtering, sorting, pagination
-TODO: add scenarios
+TODO: add scenarios https://github.com/elastic/kibana/issues/166215
### Rule installation workflow: misc cases
@@ -515,7 +515,7 @@ And user should NOT see the Rule Updates table
### Rule upgrade workflow: filtering, sorting, pagination
-TODO: add scenarios
+TODO: add scenarios https://github.com/elastic/kibana/issues/166215
### Rule upgrade workflow: misc cases
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx
index 275dc1276cb5a..4376014ab110e 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/add_prebuilt_rules_table/use_add_prebuilt_rules_table_columns.tsx
@@ -42,6 +42,7 @@ const RuleName = ({ name, ruleId }: RuleNameProps) => {
onClick={() => {
openRulePreview(ruleId);
}}
+ data-test-subj="ruleName"
>
{name}
@@ -121,7 +122,14 @@ const createInstallButtonColumn = (
onClick={() => installOneRule(ruleId)}
data-test-subj={`installSinglePrebuiltRuleButton-${ruleId}`}
>
- {isRuleInstalling ? : i18n.INSTALL_RULE_BUTTON}
+ {isRuleInstalling ? (
+
+ ) : (
+ i18n.INSTALL_RULE_BUTTON
+ )}
);
},
diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_prebuilt_rules_table_columns.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_prebuilt_rules_table_columns.tsx
index 054d77cb5e441..3f72208dc51bf 100644
--- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_prebuilt_rules_table_columns.tsx
+++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/upgrade_prebuilt_rules_table/use_upgrade_prebuilt_rules_table_columns.tsx
@@ -40,6 +40,7 @@ const RuleName = ({ name, ruleId }: RuleNameProps) => {
onClick={() => {
openRulePreview(ruleId);
}}
+ data-test-subj="ruleName"
>
{name}
@@ -120,7 +121,14 @@ const createUpgradeButtonColumn = (
onClick={() => upgradeOneRule(ruleId)}
data-test-subj={`upgradeSinglePrebuiltRuleButton-${ruleId}`}
>
- {isRuleUpgrading ? : i18n.UPDATE_RULE_BUTTON}
+ {isRuleUpgrading ? (
+
+ ) : (
+ i18n.UPDATE_RULE_BUTTON
+ )}
);
},
diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_authorization.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_authorization.cy.ts
index 63e1aa776cd07..f95a4274a5181 100644
--- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_authorization.cy.ts
+++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_authorization.cy.ts
@@ -13,23 +13,30 @@ import {
import { ROLES } from '@kbn/security-solution-plugin/common/test';
import { createRuleAssetSavedObject } from '../../../helpers/rules';
-import { createAndInstallMockedPrebuiltRules } from '../../../tasks/api_calls/prebuilt_rules';
-import { resetRulesTableState, deleteAlertsAndRules } from '../../../tasks/common';
-import { login } from '../../../tasks/login';
+import {
+ createAndInstallMockedPrebuiltRules,
+ installPrebuiltRuleAssets,
+ preventPrebuiltRulesPackageInstallation,
+} from '../../../tasks/api_calls/prebuilt_rules';
import { visit } from '../../../tasks/navigation';
import { RULES_MANAGEMENT_URL } from '../../../urls/rules_management';
import {
ADD_ELASTIC_RULES_BTN,
getInstallSingleRuleButtonByRuleId,
getUpgradeSingleRuleButtonByRuleId,
+ GO_BACK_TO_RULES_TABLE_BUTTON,
INSTALL_ALL_RULES_BUTTON,
+ RULES_MANAGEMENT_TAB,
+ RULES_MANAGEMENT_TABLE,
RULES_UPDATES_TAB,
RULE_CHECKBOX,
UPGRADE_ALL_RULES_BUTTON,
} from '../../../screens/alerts_detection_rules';
+import { cleanKibana } from '../../../tasks/common';
+import { login } from '../../../tasks/login';
+// Rule to test update
const RULE_1_ID = 'rule_1';
-const RULE_2_ID = 'rule_2';
const OUTDATED_RULE_1 = createRuleAssetSavedObject({
name: 'Outdated rule 1',
rule_id: RULE_1_ID,
@@ -40,22 +47,25 @@ const UPDATED_RULE_1 = createRuleAssetSavedObject({
rule_id: RULE_1_ID,
version: 2,
});
-const OUTDATED_RULE_2 = createRuleAssetSavedObject({
- name: 'Outdated rule 2',
+
+// Rule to test installation
+const RULE_2_ID = 'rule_2';
+const RULE_2 = createRuleAssetSavedObject({
+ name: 'Rule 2',
rule_id: RULE_2_ID,
version: 1,
});
-const UPDATED_RULE_2 = createRuleAssetSavedObject({
- name: 'Updated rule 2',
- rule_id: RULE_2_ID,
- version: 2,
-});
const loadPageAsReadOnlyUser = (url: string) => {
login(ROLES.reader);
visit(url, { role: ROLES.reader });
};
+const loginPageAsWriteAuthorizedUser = (url: string) => {
+ login(ROLES.hunter);
+ visit(url);
+};
+
// TODO: https://github.com/elastic/kibana/issues/164451 We should find a way to make this spec work in Serverless
// TODO: https://github.com/elastic/kibana/issues/161540
describe(
@@ -63,29 +73,18 @@ describe(
{ tags: ['@ess', '@serverless', '@skipInServerless'] },
() => {
beforeEach(() => {
- login();
- resetRulesTableState();
- deleteAlertsAndRules();
- cy.task('esArchiverResetKibana');
- createAndInstallMockedPrebuiltRules({ rules: [OUTDATED_RULE_1, OUTDATED_RULE_2] });
+ preventPrebuiltRulesPackageInstallation();
+ cleanKibana();
});
describe('User with read privileges on Security Solution', () => {
- const RULE_1 = createRuleAssetSavedObject({
- name: 'Test rule 1',
- rule_id: 'rule_1',
- });
- const RULE_2 = createRuleAssetSavedObject({
- name: 'Test rule 2',
- rule_id: 'rule_2',
- });
- beforeEach(() => {
+ it('should not be able to install prebuilt rules', () => {
+ // Install one prebuilt rule asset to assert that user can't install it
+ installPrebuiltRuleAssets([RULE_2]);
+
// Now login with read-only user in preparation for test
- createAndInstallMockedPrebuiltRules({ rules: [RULE_1, RULE_2], installToKibana: false });
loadPageAsReadOnlyUser(RULES_MANAGEMENT_URL);
- });
- it('should not be able to install prebuilt rules', () => {
// Check that Add Elastic Rules button is disabled
cy.get(ADD_ELASTIC_RULES_BTN).should('be.disabled');
@@ -94,25 +93,21 @@ describe(
// installation buttons are disabled
cy.visit(`${APP_PATH}${RULES_ADD_PATH}`);
cy.get(INSTALL_ALL_RULES_BUTTON).should('be.disabled');
- cy.get(getInstallSingleRuleButtonByRuleId(RULE_1['security-rule'].rule_id)).should(
+ cy.get(getInstallSingleRuleButtonByRuleId(UPDATED_RULE_1['security-rule'].rule_id)).should(
'not.exist'
);
cy.get(RULE_CHECKBOX).should('not.exist');
});
- });
- describe('User with read privileges on Security Solution', () => {
- beforeEach(() => {
- /* Create a second version of the rule, making it available for update */
- createAndInstallMockedPrebuiltRules({
- rules: [UPDATED_RULE_1, UPDATED_RULE_2],
- installToKibana: false,
- });
+ it('should not be able to upgrade prebuilt rules', () => {
+ // Install one prebuilt rule asset to assert that user can't upgrade it
+ createAndInstallMockedPrebuiltRules([OUTDATED_RULE_1]);
+ // Create a new version of the rule to make it available for upgrade
+ installPrebuiltRuleAssets([UPDATED_RULE_1]);
+
// Now login with read-only user in preparation for test
loadPageAsReadOnlyUser(RULES_MANAGEMENT_URL);
- });
- it('should not be able to upgrade prebuilt rules', () => {
// Check that Rule Update tab is not shown
cy.get(RULES_UPDATES_TAB).should('not.exist');
@@ -121,11 +116,70 @@ describe(
// upgrade buttons are disabled
cy.visit(`${APP_PATH}${RULES_UPDATES}`);
cy.get(UPGRADE_ALL_RULES_BUTTON).should('be.disabled');
+
+ // Upgrade button and selection checkbox should not be visible
cy.get(getUpgradeSingleRuleButtonByRuleId(OUTDATED_RULE_1['security-rule'].rule_id)).should(
'not.exist'
);
cy.get(RULE_CHECKBOX).should('not.exist');
});
});
+
+ describe('User with write privileges on Security Solution', () => {
+ it('should be able to install prebuilt rules', () => {
+ // Install one prebuilt rule asset to assert that user can install it
+ installPrebuiltRuleAssets([RULE_2]);
+ loginPageAsWriteAuthorizedUser(RULES_MANAGEMENT_URL);
+
+ // Check that Add Elastic Rules button is enabled
+ cy.get(ADD_ELASTIC_RULES_BTN).should('not.be.disabled');
+
+ // Navigate to Add Elastic Rules page and assert that rules can be selected
+ // and all installation buttons are enabled
+ cy.get(ADD_ELASTIC_RULES_BTN).click();
+ cy.get(INSTALL_ALL_RULES_BUTTON).should('not.be.disabled');
+ cy.get(getInstallSingleRuleButtonByRuleId(RULE_2['security-rule'].rule_id)).should('exist');
+ cy.get(RULE_CHECKBOX).should('exist');
+
+ // Install all available prebuilt rules
+ cy.get(INSTALL_ALL_RULES_BUTTON).click();
+
+ // Rule shouldn't be available for installation anymore
+ cy.get(getInstallSingleRuleButtonByRuleId(RULE_2['security-rule'].rule_id)).should(
+ 'not.exist'
+ );
+
+ // Navigate back to rules table and assert rule is installed
+ cy.get(GO_BACK_TO_RULES_TABLE_BUTTON).click();
+ cy.get(RULES_MANAGEMENT_TABLE).contains(RULE_2['security-rule'].name);
+ });
+
+ it('should be able to upgrade prebuilt rules', () => {
+ // Install one prebuilt rule asset to assert that user can upgrade it
+ createAndInstallMockedPrebuiltRules([OUTDATED_RULE_1]);
+ // Create a new version of the rule to make it available for upgrade
+ installPrebuiltRuleAssets([UPDATED_RULE_1]);
+ loginPageAsWriteAuthorizedUser(RULES_MANAGEMENT_URL);
+
+ // Check that Rule Update tab is shown
+ cy.get(RULES_UPDATES_TAB).should('exist');
+
+ // Navigate to Rule Update tab and assert that rules can be selected
+ // and all upgrade buttons are enabled
+ cy.get(RULES_UPDATES_TAB).click();
+ cy.get(UPGRADE_ALL_RULES_BUTTON).should('not.be.disabled');
+ cy.get(RULE_CHECKBOX).should('exist');
+ cy.get(getUpgradeSingleRuleButtonByRuleId(OUTDATED_RULE_1['security-rule'].rule_id)).should(
+ 'exist'
+ );
+
+ // Upgrade the rule and assert that it's upgraded
+ cy.get(
+ getUpgradeSingleRuleButtonByRuleId(OUTDATED_RULE_1['security-rule'].rule_id)
+ ).click();
+ cy.get(RULES_MANAGEMENT_TAB).click();
+ cy.get(RULES_MANAGEMENT_TABLE).contains(UPDATED_RULE_1['security-rule'].name);
+ });
+ });
}
);
diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_error_handling.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_error_handling.cy.ts
index a0004572f8608..effb732489849 100644
--- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_error_handling.cy.ts
+++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_error_handling.cy.ts
@@ -6,20 +6,32 @@
*/
import { createRuleAssetSavedObject } from '../../../helpers/rules';
-import { createAndInstallMockedPrebuiltRules } from '../../../tasks/api_calls/prebuilt_rules';
-import { resetRulesTableState, deleteAlertsAndRules } from '../../../tasks/common';
+import {
+ getInstallSingleRuleButtonByRuleId,
+ getUpgradeSingleRuleButtonByRuleId,
+ INSTALL_ALL_RULES_BUTTON,
+ INSTALL_SELECTED_RULES_BUTTON,
+ SELECT_ALL_RULES_ON_PAGE_CHECKBOX,
+ UPGRADE_ALL_RULES_BUTTON,
+ UPGRADE_SELECTED_RULES_BUTTON,
+} from '../../../screens/alerts_detection_rules';
+import { selectRulesByName } from '../../../tasks/alerts_detection_rules';
+import {
+ installPrebuiltRuleAssets,
+ createAndInstallMockedPrebuiltRules,
+ preventPrebuiltRulesPackageInstallation,
+} from '../../../tasks/api_calls/prebuilt_rules';
+import { cleanKibana } from '../../../tasks/common';
import { login } from '../../../tasks/login';
import {
addElasticRulesButtonClick,
- assertRuleAvailableForInstallAndInstallOne,
- assertRuleAvailableForInstallAndInstallSelected,
- assertRuleAvailableForInstallAndInstallAllInPage,
- assertRuleAvailableForInstallAndInstallAll,
- assertRuleUpgradeAvailableAndUpgradeOne,
- assertRuleUpgradeAvailableAndUpgradeSelected,
- assertRuleUpgradeAvailableAndUpgradeAllInPage,
- assertRuleUpgradeAvailableAndUpgradeAll,
+ assertInstallationRequestIsComplete,
+ interceptInstallationRequestToFail,
+ interceptUpgradeRequestToFail,
+ assertUpgradeFailure,
ruleUpdatesTabClick,
+ assertInstallationFailure,
+ assertUpgradeRequestIsComplete,
} from '../../../tasks/prebuilt_rules';
import { visitRulesManagementTable } from '../../../tasks/rules_management';
@@ -28,10 +40,9 @@ describe(
{ tags: ['@ess', '@serverless'] },
() => {
beforeEach(() => {
+ preventPrebuiltRulesPackageInstallation();
+ cleanKibana();
login();
- resetRulesTableState();
- deleteAlertsAndRules();
- cy.task('esArchiverResetKibana');
visitRulesManagementTable();
});
@@ -45,37 +56,52 @@ describe(
name: 'Test rule 2',
rule_id: 'rule_2',
});
+
beforeEach(() => {
- createAndInstallMockedPrebuiltRules({ rules: [RULE_1, RULE_2], installToKibana: false });
+ // Make two mock rules available for installation
+ installPrebuiltRuleAssets([RULE_1, RULE_2]);
});
it('installing prebuilt rules one by one', () => {
+ // Navigate to install Elastic rules page
addElasticRulesButtonClick();
- assertRuleAvailableForInstallAndInstallOne({ rules: [RULE_1], didRequestFail: true });
+
+ // Intercept and force the installation request to fail
+ interceptInstallationRequestToFail([RULE_1]);
+
+ // Attempt to install rule
+ cy.get(getInstallSingleRuleButtonByRuleId(RULE_1['security-rule'].rule_id)).click();
+ // Wait for request to complete
+ assertInstallationRequestIsComplete([RULE_1]);
+
+ assertInstallationFailure([RULE_1]);
});
it('installing multiple selected prebuilt rules by selecting them individually', () => {
addElasticRulesButtonClick();
- assertRuleAvailableForInstallAndInstallSelected({
- rules: [RULE_1, RULE_2],
- didRequestFail: true,
- });
+
+ interceptInstallationRequestToFail([RULE_1, RULE_2]);
+ selectRulesByName([RULE_1['security-rule'].name, RULE_2['security-rule'].name]);
+ cy.get(INSTALL_SELECTED_RULES_BUTTON).click();
+ assertInstallationRequestIsComplete([RULE_1, RULE_2]);
+ assertInstallationFailure([RULE_1, RULE_2]);
});
it('installing multiple selected prebuilt rules by selecting all in page', () => {
addElasticRulesButtonClick();
- assertRuleAvailableForInstallAndInstallAllInPage({
- rules: [RULE_1, RULE_2],
- didRequestFail: true,
- });
+ interceptInstallationRequestToFail([RULE_1, RULE_2]);
+ cy.get(SELECT_ALL_RULES_ON_PAGE_CHECKBOX).click();
+ cy.get(INSTALL_SELECTED_RULES_BUTTON).click();
+ assertInstallationRequestIsComplete([RULE_1, RULE_2]);
+ assertInstallationFailure([RULE_1, RULE_2]);
});
it('installing all available rules at once', () => {
addElasticRulesButtonClick();
- assertRuleAvailableForInstallAndInstallAll({
- rules: [RULE_1, RULE_2],
- didRequestFail: true,
- });
+ interceptInstallationRequestToFail([RULE_1, RULE_2]);
+ cy.get(INSTALL_ALL_RULES_BUTTON).click();
+ assertInstallationRequestIsComplete([RULE_1, RULE_2]);
+ assertInstallationFailure([RULE_1, RULE_2]);
});
});
@@ -102,44 +128,66 @@ describe(
rule_id: RULE_2_ID,
version: 2,
});
+
beforeEach(() => {
/* Create a new rule and install it */
- createAndInstallMockedPrebuiltRules({ rules: [OUTDATED_RULE_1, OUTDATED_RULE_2] });
+ createAndInstallMockedPrebuiltRules([OUTDATED_RULE_1, OUTDATED_RULE_2]);
/* Create a second version of the rule, making it available for update */
- createAndInstallMockedPrebuiltRules({
- rules: [UPDATED_RULE_1, UPDATED_RULE_2],
- installToKibana: false,
- });
+ installPrebuiltRuleAssets([UPDATED_RULE_1, UPDATED_RULE_2]);
cy.reload();
});
it('upgrading prebuilt rules one by one', () => {
+ interceptUpgradeRequestToFail([OUTDATED_RULE_1]);
+
+ // Navigate to Rule Upgrade table
ruleUpdatesTabClick();
- assertRuleUpgradeAvailableAndUpgradeOne({ rules: [OUTDATED_RULE_1], didRequestFail: true });
+
+ // Attempt to upgrade rule
+ cy.get(
+ getUpgradeSingleRuleButtonByRuleId(OUTDATED_RULE_1['security-rule'].rule_id)
+ ).click();
+ // Wait for request to complete
+ assertUpgradeRequestIsComplete([OUTDATED_RULE_1]);
+
+ assertUpgradeFailure([OUTDATED_RULE_1]);
});
it('upgrading multiple selected prebuilt rules by selecting them individually', () => {
+ interceptUpgradeRequestToFail([OUTDATED_RULE_1, OUTDATED_RULE_2]);
+
+ // Navigate to Rule Upgrade table
ruleUpdatesTabClick();
- assertRuleUpgradeAvailableAndUpgradeSelected({
- rules: [OUTDATED_RULE_1, OUTDATED_RULE_2],
- didRequestFail: true,
- });
+
+ selectRulesByName([
+ OUTDATED_RULE_1['security-rule'].name,
+ OUTDATED_RULE_2['security-rule'].name,
+ ]);
+ cy.get(UPGRADE_SELECTED_RULES_BUTTON).click();
+ assertUpgradeRequestIsComplete([OUTDATED_RULE_1, OUTDATED_RULE_2]);
+ assertUpgradeFailure([OUTDATED_RULE_1, OUTDATED_RULE_2]);
});
it('upgrading multiple selected prebuilt rules by selecting all in page', () => {
+ interceptUpgradeRequestToFail([OUTDATED_RULE_1, OUTDATED_RULE_2]);
+
+ // Navigate to Rule Upgrade table
ruleUpdatesTabClick();
- assertRuleUpgradeAvailableAndUpgradeAllInPage({
- rules: [OUTDATED_RULE_1, OUTDATED_RULE_2],
- didRequestFail: true,
- });
+ cy.get(SELECT_ALL_RULES_ON_PAGE_CHECKBOX).click();
+ cy.get(UPGRADE_SELECTED_RULES_BUTTON).click();
+ assertUpgradeRequestIsComplete([OUTDATED_RULE_1, OUTDATED_RULE_2]);
+ assertUpgradeFailure([OUTDATED_RULE_1, OUTDATED_RULE_2]);
});
it('upgrading all rules with available upgrades at once', () => {
+ interceptUpgradeRequestToFail([OUTDATED_RULE_1, OUTDATED_RULE_2]);
+
+ // Navigate to Rule Upgrade table
ruleUpdatesTabClick();
- assertRuleUpgradeAvailableAndUpgradeAll({
- rules: [OUTDATED_RULE_1, OUTDATED_RULE_2],
- didRequestFail: true,
- });
+
+ cy.get(UPGRADE_ALL_RULES_BUTTON).click();
+ assertUpgradeRequestIsComplete([OUTDATED_RULE_1, OUTDATED_RULE_2]);
+ assertUpgradeFailure([OUTDATED_RULE_1, OUTDATED_RULE_2]);
});
});
}
diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_workflows.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_workflows.cy.ts
index 5c8ff2a4d4963..68830ff0611a8 100644
--- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_workflows.cy.ts
+++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_workflows.cy.ts
@@ -10,33 +10,35 @@ import type { Rule } from '@kbn/security-solution-plugin/public/detection_engine
import { createRuleAssetSavedObject } from '../../../helpers/rules';
import {
+ getInstallSingleRuleButtonByRuleId,
+ getUpgradeSingleRuleButtonByRuleId,
GO_BACK_TO_RULES_TABLE_BUTTON,
INSTALL_ALL_RULES_BUTTON,
INSTALL_SELECTED_RULES_BUTTON,
- NO_RULES_AVAILABLE_FOR_INSTALL_MESSSAGE,
- NO_RULES_AVAILABLE_FOR_UPGRADE_MESSSAGE,
+ NO_RULES_AVAILABLE_FOR_INSTALL_MESSAGE,
+ NO_RULES_AVAILABLE_FOR_UPGRADE_MESSAGE,
RULES_UPDATES_TAB,
RULE_CHECKBOX,
SELECT_ALL_RULES_ON_PAGE_CHECKBOX,
TOASTER,
+ UPGRADE_ALL_RULES_BUTTON,
+ UPGRADE_SELECTED_RULES_BUTTON,
} from '../../../screens/alerts_detection_rules';
+import { selectRulesByName } from '../../../tasks/alerts_detection_rules';
import {
getRuleAssets,
+ installPrebuiltRuleAssets,
createAndInstallMockedPrebuiltRules,
} from '../../../tasks/api_calls/prebuilt_rules';
import { resetRulesTableState, deleteAlertsAndRules } from '../../../tasks/common';
import { login } from '../../../tasks/login';
import {
addElasticRulesButtonClick,
- assertRuleAvailableForInstallAndInstallOne,
- assertRuleAvailableForInstallAndInstallSelected,
- assertRuleAvailableForInstallAndInstallAllInPage,
- assertRuleAvailableForInstallAndInstallAll,
- assertRuleUpgradeAvailableAndUpgradeOne,
- assertRuleUpgradeAvailableAndUpgradeSelected,
- assertRuleUpgradeAvailableAndUpgradeAllInPage,
- assertRuleUpgradeAvailableAndUpgradeAll,
ruleUpdatesTabClick,
+ assertInstallationSuccess,
+ assertInstallationRequestIsComplete,
+ assertUpgradeRequestIsComplete,
+ assertUpgradeSuccess,
} from '../../../tasks/prebuilt_rules';
import { visitRulesManagementTable } from '../../../tasks/rules_management';
@@ -99,11 +101,17 @@ describe(
});
it('should install rules from the Fleet package when user clicks on CTA', () => {
+ interface Response {
+ body: {
+ hits: {
+ hits: Array<{ _source: { ['security-rule']: Rule } }>;
+ };
+ };
+ }
const getRulesAndAssertNumberInstalled = () => {
getRuleAssets().then((response) => {
- const ruleIds = response.body.hits.hits.map(
- (hit: { _source: { ['security-rule']: Rule } }) =>
- hit._source['security-rule'].rule_id
+ const ruleIds = (response as Response).body.hits.hits.map(
+ (hit) => hit._source['security-rule'].rule_id
);
const numberOfRulesToInstall = new Set(ruleIds).size;
@@ -147,52 +155,49 @@ describe(
rule_id: 'rule_2',
});
beforeEach(() => {
- createAndInstallMockedPrebuiltRules({ rules: [RULE_1, RULE_2], installToKibana: false });
+ installPrebuiltRuleAssets([RULE_1, RULE_2]);
cy.intercept('POST', '/internal/detection_engine/prebuilt_rules/installation/_perform').as(
'installPrebuiltRules'
);
+ addElasticRulesButtonClick();
});
it('should install prebuilt rules one by one', () => {
- addElasticRulesButtonClick();
- assertRuleAvailableForInstallAndInstallOne({ rules: [RULE_1] });
+ // Attempt to install rules
+ cy.get(getInstallSingleRuleButtonByRuleId(RULE_1['security-rule'].rule_id)).click();
+ // Wait for request to complete
+ assertInstallationRequestIsComplete([RULE_1]);
+ // Assert installation succeeded
+ assertInstallationSuccess([RULE_1]);
});
it('should install multiple selected prebuilt rules by selecting them individually', () => {
- addElasticRulesButtonClick();
- assertRuleAvailableForInstallAndInstallSelected({ rules: [RULE_1, RULE_2] });
+ selectRulesByName([RULE_1['security-rule'].name, RULE_2['security-rule'].name]);
+ cy.get(INSTALL_SELECTED_RULES_BUTTON).click();
+ assertInstallationRequestIsComplete([RULE_1, RULE_2]);
+ assertInstallationSuccess([RULE_1, RULE_2]);
});
it('should install multiple selected prebuilt rules by selecting all in page', () => {
- addElasticRulesButtonClick();
- assertRuleAvailableForInstallAndInstallAllInPage({ rules: [RULE_1, RULE_2] });
+ cy.get(SELECT_ALL_RULES_ON_PAGE_CHECKBOX).click();
+ cy.get(INSTALL_SELECTED_RULES_BUTTON).click();
+ assertInstallationRequestIsComplete([RULE_1, RULE_2]);
+ assertInstallationSuccess([RULE_1, RULE_2]);
});
it('should install all available rules at once', () => {
- addElasticRulesButtonClick();
- assertRuleAvailableForInstallAndInstallAll({ rules: [RULE_1, RULE_2] });
+ cy.get(INSTALL_ALL_RULES_BUTTON).click();
+ assertInstallationRequestIsComplete([RULE_1, RULE_2]);
+ assertInstallationSuccess([RULE_1, RULE_2]);
});
it('should display an empty screen when all available prebuilt rules have been installed', () => {
- addElasticRulesButtonClick();
cy.get(INSTALL_ALL_RULES_BUTTON).click();
cy.get(TOASTER).should('be.visible').should('have.text', `2 rules installed successfully.`);
cy.get(RULE_CHECKBOX).should('not.exist');
- cy.get(NO_RULES_AVAILABLE_FOR_INSTALL_MESSSAGE).should('exist');
+ cy.get(NO_RULES_AVAILABLE_FOR_INSTALL_MESSAGE).should('exist');
cy.get(GO_BACK_TO_RULES_TABLE_BUTTON).should('exist');
});
-
- it('should fail gracefully with toast error message when request to install rules fails', () => {
- /* Stub request to force rules installation to fail */
- cy.intercept('POST', '/internal/detection_engine/prebuilt_rules/installation/_perform', {
- statusCode: 500,
- }).as('installPrebuiltRules');
- addElasticRulesButtonClick();
- cy.get(SELECT_ALL_RULES_ON_PAGE_CHECKBOX).click();
- cy.get(INSTALL_SELECTED_RULES_BUTTON).click();
- cy.wait('@installPrebuiltRules');
- cy.get(TOASTER).should('be.visible').should('have.text', 'Rule installation failed');
- });
});
describe('Upgrade of prebuilt rules', () => {
@@ -223,43 +228,52 @@ describe(
'updatePrebuiltRules'
);
/* Create a new rule and install it */
- createAndInstallMockedPrebuiltRules({ rules: [OUTDATED_RULE_1, OUTDATED_RULE_2] });
+ createAndInstallMockedPrebuiltRules([OUTDATED_RULE_1, OUTDATED_RULE_2]);
/* Create a second version of the rule, making it available for update */
- createAndInstallMockedPrebuiltRules({
- rules: [UPDATED_RULE_1, UPDATED_RULE_2],
- installToKibana: false,
- });
- cy.reload();
+ installPrebuiltRuleAssets([UPDATED_RULE_1, UPDATED_RULE_2]);
+
+ visitRulesManagementTable();
+ ruleUpdatesTabClick();
});
it('should upgrade prebuilt rules one by one', () => {
- ruleUpdatesTabClick();
- assertRuleUpgradeAvailableAndUpgradeOne({ rules: [OUTDATED_RULE_1] });
+ // Attempt to upgrade rule
+ cy.get(
+ getUpgradeSingleRuleButtonByRuleId(OUTDATED_RULE_1['security-rule'].rule_id)
+ ).click();
+ // Wait for request to complete
+ assertUpgradeRequestIsComplete([OUTDATED_RULE_1]);
+
+ assertUpgradeSuccess([OUTDATED_RULE_1]);
});
it('should upgrade multiple selected prebuilt rules by selecting them individually', () => {
- ruleUpdatesTabClick();
- assertRuleUpgradeAvailableAndUpgradeSelected({ rules: [OUTDATED_RULE_1, OUTDATED_RULE_2] });
+ selectRulesByName([
+ OUTDATED_RULE_1['security-rule'].name,
+ OUTDATED_RULE_2['security-rule'].name,
+ ]);
+ cy.get(UPGRADE_SELECTED_RULES_BUTTON).click();
+ assertUpgradeRequestIsComplete([OUTDATED_RULE_1, OUTDATED_RULE_2]);
+ assertUpgradeSuccess([OUTDATED_RULE_1, OUTDATED_RULE_2]);
});
it('should upgrade multiple selected prebuilt rules by selecting all in page', () => {
- ruleUpdatesTabClick();
- assertRuleUpgradeAvailableAndUpgradeAllInPage({
- rules: [OUTDATED_RULE_1, OUTDATED_RULE_2],
- });
+ cy.get(SELECT_ALL_RULES_ON_PAGE_CHECKBOX).click();
+ cy.get(UPGRADE_SELECTED_RULES_BUTTON).click();
+ assertUpgradeRequestIsComplete([OUTDATED_RULE_1, OUTDATED_RULE_2]);
+ assertUpgradeSuccess([OUTDATED_RULE_1, OUTDATED_RULE_2]);
});
it('should upgrade all rules with available upgrades at once', () => {
- ruleUpdatesTabClick();
- assertRuleUpgradeAvailableAndUpgradeAll({ rules: [OUTDATED_RULE_1, OUTDATED_RULE_2] });
- cy.get(RULES_UPDATES_TAB).should('not.exist');
+ cy.get(UPGRADE_ALL_RULES_BUTTON).click();
+ assertUpgradeRequestIsComplete([OUTDATED_RULE_1, OUTDATED_RULE_2]);
+ assertUpgradeSuccess([OUTDATED_RULE_1, OUTDATED_RULE_2]);
});
it('should display an empty screen when all rules with available updates have been upgraded', () => {
- ruleUpdatesTabClick();
- assertRuleUpgradeAvailableAndUpgradeAll({ rules: [OUTDATED_RULE_1, OUTDATED_RULE_2] });
+ cy.get(UPGRADE_ALL_RULES_BUTTON).click();
cy.get(RULES_UPDATES_TAB).should('not.exist');
- cy.get(NO_RULES_AVAILABLE_FOR_UPGRADE_MESSSAGE).should('exist');
+ cy.get(NO_RULES_AVAILABLE_FOR_UPGRADE_MESSAGE).should('exist');
});
});
}
diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_management.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_management.cy.ts
index a7ef216bf9571..7fef8e4abbea2 100644
--- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_management.cy.ts
+++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_management.cy.ts
@@ -62,7 +62,7 @@ describe('Prebuilt rules', { tags: ['@ess', '@serverless'] }, () => {
deletePrebuiltRulesAssets();
preventPrebuiltRulesPackageInstallation();
visit(RULES_MANAGEMENT_URL);
- createAndInstallMockedPrebuiltRules({ rules });
+ createAndInstallMockedPrebuiltRules(rules);
cy.reload();
waitForPrebuiltDetectionRulesToBeLoaded();
disableAutoRefresh();
diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_notifications.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_notifications.cy.ts
index e98d6a9487c24..eef35c79d3624 100644
--- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_notifications.cy.ts
+++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_notifications.cy.ts
@@ -14,6 +14,7 @@ import {
import { deleteFirstRule } from '../../../tasks/alerts_detection_rules';
import {
installAllPrebuiltRulesRequest,
+ installPrebuiltRuleAssets,
createAndInstallMockedPrebuiltRules,
} from '../../../tasks/api_calls/prebuilt_rules';
import {
@@ -54,8 +55,8 @@ describe(
});
it('should NOT display install or update notifications when latest rules are installed', () => {
- createAndInstallMockedPrebuiltRules({ rules: [RULE_1], installToKibana: true });
visitRulesManagementTable();
+ createAndInstallMockedPrebuiltRules([RULE_1]);
/* Assert that there are no installation or update notifications */
/* Add Elastic Rules button should not contain a number badge */
@@ -67,7 +68,7 @@ describe(
describe('Notifications', () => {
beforeEach(() => {
- createAndInstallMockedPrebuiltRules({ rules: [RULE_1], installToKibana: false });
+ installPrebuiltRuleAssets([RULE_1]);
});
describe('Rules installation notification when no rules have been installed', () => {
@@ -96,11 +97,8 @@ describe(
rule_id: 'rule_3',
});
- createAndInstallMockedPrebuiltRules({
- rules: [RULE_2, RULE_3],
- installToKibana: false,
- });
visitRulesManagementTable();
+ installPrebuiltRuleAssets([RULE_2, RULE_3]);
});
});
@@ -136,9 +134,8 @@ describe(
rule_id: 'rule_1',
version: 2,
});
- createAndInstallMockedPrebuiltRules({ rules: [UPDATED_RULE], installToKibana: false });
+ installPrebuiltRuleAssets([UPDATED_RULE]);
visitRulesManagementTable();
- cy.reload();
});
});
@@ -167,10 +164,7 @@ describe(
rule_id: 'rule_1',
version: 2,
});
- createAndInstallMockedPrebuiltRules({
- rules: [RULE_2, UPDATED_RULE],
- installToKibana: false,
- });
+ installPrebuiltRuleAssets([RULE_2, UPDATED_RULE]);
visitRulesManagementTable();
});
});
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 c877221cb02bc..8d551b655fca4 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
@@ -194,7 +194,7 @@ describe(
});
it('Only prebuilt rules selected', () => {
- createAndInstallMockedPrebuiltRules({ rules: PREBUILT_RULES });
+ createAndInstallMockedPrebuiltRules(PREBUILT_RULES);
// select Elastic(prebuilt) rules, check if we can't proceed further, as Elastic rules are not editable
filterByElasticRules();
@@ -213,7 +213,7 @@ describe(
it('Prebuilt and custom rules selected: user proceeds with custom rules editing', () => {
getRulesManagementTableRows().then((existedRulesRows) => {
- createAndInstallMockedPrebuiltRules({ rules: PREBUILT_RULES });
+ createAndInstallMockedPrebuiltRules(PREBUILT_RULES);
// modal window should show how many rules can be edit, how many not
selectAllRules();
@@ -238,7 +238,7 @@ describe(
});
it('Prebuilt and custom rules selected: user cancels action', () => {
- createAndInstallMockedPrebuiltRules({ rules: PREBUILT_RULES });
+ createAndInstallMockedPrebuiltRules(PREBUILT_RULES);
getRulesManagementTableRows().then((rows) => {
// modal window should show how many rules can be edit, how many not
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 fb54b04005139..1d59135012a9d 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
@@ -145,7 +145,7 @@ describe(
rule_id: 'rule_2',
});
- createAndInstallMockedPrebuiltRules({ rules: [RULE_1, RULE_2] });
+ createAndInstallMockedPrebuiltRules([RULE_1, RULE_2]);
});
context('Restricted action privileges', () => {
diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/export_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/export_rule.cy.ts
index 2e1f4ec1524cf..262c6904db4bd 100644
--- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/export_rule.cy.ts
+++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/export_rule.cy.ts
@@ -103,7 +103,7 @@ describe('Export rules', { tags: ['@ess', '@serverless', '@brokenInServerless']
});
it('shows a modal saying that no rules can be exported if all the selected rules are prebuilt', function () {
- createAndInstallMockedPrebuiltRules({ rules: prebuiltRules });
+ createAndInstallMockedPrebuiltRules(prebuiltRules);
filterByElasticRules();
selectAllRules();
@@ -117,7 +117,7 @@ describe('Export rules', { tags: ['@ess', '@serverless', '@brokenInServerless']
it('exports only custom rules', function () {
const expectedNumberCustomRulesToBeExported = 1;
- createAndInstallMockedPrebuiltRules({ rules: prebuiltRules });
+ createAndInstallMockedPrebuiltRules(prebuiltRules);
selectAllRules();
bulkExportRules();
@@ -170,7 +170,7 @@ describe('Export rules', { tags: ['@ess', '@serverless', '@brokenInServerless']
// one rule with exception, one without it
const expectedNumberCustomRulesToBeExported = 2;
- createAndInstallMockedPrebuiltRules({ rules: prebuiltRules });
+ createAndInstallMockedPrebuiltRules(prebuiltRules);
reload();
selectAllRules();
bulkExportRules();
diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_selection.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_selection.cy.ts
index 6ae36029a8c0a..d07186c8252f9 100644
--- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_selection.cy.ts
+++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_selection.cy.ts
@@ -42,7 +42,7 @@ describe('Rules table: selection', { tags: ['@ess', '@serverless'] }, () => {
beforeEach(() => {
login();
/* Create and install two mock rules */
- createAndInstallMockedPrebuiltRules({ rules: [RULE_1, RULE_2] });
+ createAndInstallMockedPrebuiltRules([RULE_1, RULE_2]);
visit(RULES_MANAGEMENT_URL);
waitForPrebuiltDetectionRulesToBeLoaded();
});
diff --git a/x-pack/test/security_solution_cypress/cypress/screens/alerts_detection_rules.ts b/x-pack/test/security_solution_cypress/cypress/screens/alerts_detection_rules.ts
index 1ae1ed9d95dbb..14c885fc076e2 100644
--- a/x-pack/test/security_solution_cypress/cypress/screens/alerts_detection_rules.ts
+++ b/x-pack/test/security_solution_cypress/cypress/screens/alerts_detection_rules.ts
@@ -61,6 +61,14 @@ export const UPGRADE_ALL_RULES_BUTTON = '[data-test-subj="upgradeAllRulesButton"
export const UPGRADE_SELECTED_RULES_BUTTON = '[data-test-subj="upgradeSelectedRulesButton"]';
+export const getInstallSingleRuleLoadingSpinnerByRuleId = (ruleId: string) => {
+ return `[data-test-subj="installSinglePrebuiltRuleButton-loadingSpinner-${ruleId}"]`;
+};
+
+export const getUpgradeSingleRuleLoadingSpinnerByRuleId = (ruleId: string) => {
+ return `[data-test-subj="upgradeSinglePrebuiltRuleButton-loadingSpinner-${ruleId}"]`;
+};
+
export const GO_BACK_TO_RULES_TABLE_BUTTON = '[data-test-subj="addRulesGoBackToRulesTableBtn"]';
export const RULES_TABLE_REFRESH_INDICATOR = '[data-test-subj="loading-spinner"]';
@@ -179,7 +187,7 @@ export const getUpgradeSingleRuleButtonByRuleId = (ruleId: string) => {
return `[data-test-subj="upgradeSinglePrebuiltRuleButton-${ruleId}"]`;
};
-export const NO_RULES_AVAILABLE_FOR_INSTALL_MESSSAGE =
+export const NO_RULES_AVAILABLE_FOR_INSTALL_MESSAGE =
'[data-test-subj="noPrebuiltRulesAvailableForInstall"]';
-export const NO_RULES_AVAILABLE_FOR_UPGRADE_MESSSAGE =
+export const NO_RULES_AVAILABLE_FOR_UPGRADE_MESSAGE =
'[data-test-subj="noPrebuiltRulesAvailableForUpgrade"]';
diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/prebuilt_rules.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/prebuilt_rules.ts
index 48b21115b9895..98b9a884e683a 100644
--- a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/prebuilt_rules.ts
+++ b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/prebuilt_rules.ts
@@ -13,9 +13,10 @@ import { ELASTIC_SECURITY_RULE_ID } from '@kbn/security-solution-plugin/common/d
import type { PrePackagedRulesStatusResponse } from '@kbn/security-solution-plugin/public/detection_engine/rule_management/logic/types';
import { getPrebuiltRuleWithExceptionsMock } from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules/mocks';
import { createRuleAssetSavedObject } from '../../helpers/rules';
+import { rootRequest } from '../common';
export const getPrebuiltRulesStatus = () => {
- return cy.request({
+ return rootRequest({
method: 'GET',
url: 'api/detection_engine/rules/prepackaged/_status',
headers: {
@@ -39,7 +40,7 @@ export const SAMPLE_PREBUILT_RULE = createRuleAssetSavedObject({
* instead of all rules available in the `security_detection_engine` package
*/
export const installAllPrebuiltRulesRequest = () =>
- cy.request({
+ rootRequest({
method: 'POST',
url: PERFORM_RULE_INSTALLATION_URL,
headers: {
@@ -52,6 +53,30 @@ export const installAllPrebuiltRulesRequest = () =>
},
});
+/* Install specific prebuilt rules. Should be available as security-rule saved objects
+/* as a prerequisite for this request to succeed.
+ * Use in combination with `preventPrebuiltRulesPackageInstallation` and
+ * `createNewRuleAsset` to create mocked prebuilt rules and install only those
+ * instead of all rules available in the `security_detection_engine` package
+ */
+export const installSpecificPrebuiltRulesRequest = (rules: Array) =>
+ rootRequest({
+ method: 'POST',
+ url: PERFORM_RULE_INSTALLATION_URL,
+ headers: {
+ 'kbn-xsrf': 'cypress-creds',
+ 'x-elastic-internal-origin': 'security-solution',
+ 'elastic-api-version': '1',
+ },
+ body: {
+ mode: 'SPECIFIC_RULES',
+ rules: rules.map((rule) => ({
+ rule_id: rule['security-rule'].rule_id,
+ version: rule['security-rule'].version,
+ })),
+ },
+ });
+
export const getAvailablePrebuiltRulesCount = () => {
cy.log('Get prebuilt rules count');
return getPrebuiltRulesStatus().then(({ body }) => {
@@ -123,48 +148,44 @@ export const bulkCreateRuleAssets = ({
index?: string;
rules?: Array;
}) => {
- const url = `${Cypress.env('ELASTICSEARCH_URL')}/${index}/_bulk`;
+ cy.log(
+ 'Bulk Install prebuilt rules',
+ rules?.map((rule) => rule['security-rule'].rule_id).join(', ')
+ );
+ const url = `${Cypress.env('ELASTICSEARCH_URL')}/${index}/_bulk?refresh`;
const bulkIndexRequestBody = rules.reduce((body, rule) => {
const indexOperation = {
index: {
_index: index,
- _id: rule['security-rule'].rule_id,
+ _id: `security-rule:${rule['security-rule'].rule_id}`,
},
};
const documentData = JSON.stringify(rule);
-
return body.concat(JSON.stringify(indexOperation), '\n', documentData, '\n');
}, '');
- cy.request({
+ rootRequest({
method: 'PUT',
- url: `${Cypress.env('ELASTICSEARCH_URL')}/${index}/_mapping?refresh`,
+ url: `${Cypress.env('ELASTICSEARCH_URL')}/${index}/_mapping`,
body: {
dynamic: true,
},
headers: {
'Content-Type': 'application/json',
- 'x-elastic-internal-origin': 'security-solution',
},
});
cy.waitUntil(
() => {
- return cy
- .request({
- method: 'POST',
- url,
- headers: {
- 'kbn-xsrf': 'cypress-creds',
- 'x-elastic-internal-origin': 'security-solution',
- 'Content-Type': 'application/json',
- },
- failOnStatusCode: false,
- body: bulkIndexRequestBody,
- })
- .then((response) => response.status === 200);
+ return rootRequest({
+ method: 'POST',
+ url,
+ headers: { 'kbn-xsrf': 'cypress-creds', 'Content-Type': 'application/json' },
+ failOnStatusCode: false,
+ body: bulkIndexRequestBody,
+ }).then((response) => response.status === 200);
},
{ interval: 500, timeout: 12000 }
);
@@ -172,7 +193,7 @@ export const bulkCreateRuleAssets = ({
export const getRuleAssets = (index: string | undefined = '.kibana_security_solution') => {
const url = `${Cypress.env('ELASTICSEARCH_URL')}/${index}/_search?size=10000`;
- return cy.request({
+ return rootRequest({
method: 'GET',
url,
headers: {
@@ -194,6 +215,7 @@ export const getRuleAssets = (index: string | undefined = '.kibana_security_solu
/* Used primarily to prevent the unwanted installation of "real" prebuilt rules
/* during e2e tests, and allow for manual installation of mock rules instead. */
export const preventPrebuiltRulesPackageInstallation = () => {
+ cy.log('Prevent prebuilt rules package installation');
cy.intercept('POST', '/api/fleet/epm/packages/_bulk*', {});
cy.intercept('POST', '/api/fleet/epm/packages/security_detection_engine/*', {});
};
@@ -202,42 +224,31 @@ export const preventPrebuiltRulesPackageInstallation = () => {
* Install prebuilt rule assets. After installing these assets become available to be installed
* as prebuilt rules. Prebuilt rule assets can be generated via `createRuleAssetSavedObject()` helper function.
*
- * It's also important to take into account that business logic tries to fetch prebuilt rules Fleet package
+ * It's also important to take into account that the business logic tries to fetch prebuilt rules Fleet package
* and you need to add `preventPrebuiltRulesPackageInstallation()` to `beforeEach` section (before visit commands)
- * to avoid actually pulling a real Fleet package and have only provided prebuilt rule assets for testing.
+ * to avoid actually pulling a real Fleet package and have only the mocked prebuilt rule assets for testing.
*/
export const installPrebuiltRuleAssets = (ruleAssets: Array): void => {
cy.log('Create mocked available to install prebuilt rules', ruleAssets.length);
preventPrebuiltRulesPackageInstallation();
- // TODO: use this bulk method once the issue with Cypress is fixed
- // bulkCreateRuleAssets({ rules });
- ruleAssets.forEach((rule) => {
- createNewRuleAsset({ rule });
- });
+
+ bulkCreateRuleAssets({ rules: ruleAssets });
};
/**
* Prevent the installation of the `security_detection_engine` package from Fleet.
* The create a `security-rule` asset for each rule provided in the `rules` array.
- * Optionally install the rules to Kibana, with a flag defaulting to true
- * Explicitly set the `installToKibana` flag to false in cases when needing to
- * make mock rules available for installation or update, but do those operations manually
*
* * @param {Array} rules - Rule assets to be created and optionally installed
*
- * * @param {string} installToKibana - Flag to decide whether to install the rules as 'alerts' SO. Defaults to true.
*/
-export const createAndInstallMockedPrebuiltRules = ({
- rules: ruleAssets,
- installToKibana = true,
-}: {
- rules: Array;
- installToKibana?: boolean;
-}) => {
+export const createAndInstallMockedPrebuiltRules = (
+ ruleAssets: Array
+) => {
+ preventPrebuiltRulesPackageInstallation();
+ // Install assets into ES as `security-rule` SOs
installPrebuiltRuleAssets(ruleAssets);
- if (installToKibana) {
- cy.log('Install prebuilt rules', ruleAssets.length);
- return installAllPrebuiltRulesRequest();
- }
+ // Install rules into Kibana as `alerts` SOs
+ return installSpecificPrebuiltRulesRequest(ruleAssets);
};
diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/common.ts b/x-pack/test/security_solution_cypress/cypress/tasks/common.ts
index 3c2467c25f6ad..67bcf971c3b15 100644
--- a/x-pack/test/security_solution_cypress/cypress/tasks/common.ts
+++ b/x-pack/test/security_solution_cypress/cypress/tasks/common.ts
@@ -93,6 +93,7 @@ export const resetRulesTableState = () => {
export const cleanKibana = () => {
resetRulesTableState();
+ deletePrebuiltRulesAssets();
deleteAlertsAndRules();
deleteAllCasesItems();
deleteTimelines();
diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/prebuilt_rules.ts b/x-pack/test/security_solution_cypress/cypress/tasks/prebuilt_rules.ts
index 7b58dda17015f..fc78399fff8e4 100644
--- a/x-pack/test/security_solution_cypress/cypress/tasks/prebuilt_rules.ts
+++ b/x-pack/test/security_solution_cypress/cypress/tasks/prebuilt_rules.ts
@@ -9,18 +9,12 @@ import { RULES_ADD_PATH, RULES_UPDATES } from '@kbn/security-solution-plugin/com
import {
ADD_ELASTIC_RULES_BTN,
ADD_ELASTIC_RULES_TABLE,
- getInstallSingleRuleButtonByRuleId,
- getUpgradeSingleRuleButtonByRuleId,
- INSTALL_ALL_RULES_BUTTON,
- INSTALL_SELECTED_RULES_BUTTON,
+ getInstallSingleRuleLoadingSpinnerByRuleId,
+ getUpgradeSingleRuleLoadingSpinnerByRuleId,
RULES_MANAGEMENT_TABLE,
RULES_UPDATES_TAB,
RULES_UPDATES_TABLE,
- RULE_CHECKBOX,
- SELECT_ALL_RULES_ON_PAGE_CHECKBOX,
TOASTER,
- UPGRADE_ALL_RULES_BUTTON,
- UPGRADE_SELECTED_RULES_BUTTON,
} from '../screens/alerts_detection_rules';
import { RULE_MANAGEMENT_PAGE_BREADCRUMB } from '../screens/breadcrumbs';
import type { SAMPLE_PREBUILT_RULE } from './api_calls/prebuilt_rules';
@@ -35,190 +29,116 @@ export const ruleUpdatesTabClick = () => {
cy.location('pathname').should('include', RULES_UPDATES);
};
-interface RuleInstallUpgradeAssertionPayload {
- rules: Array;
- didRequestFail?: boolean;
-}
-
-export const assertRuleAvailableForInstallAndInstallOne = ({
- rules,
- didRequestFail = false,
-}: RuleInstallUpgradeAssertionPayload) => {
- interceptInstallationRequestToFail(rules, didRequestFail);
- const rule = rules[0];
- cy.get(getInstallSingleRuleButtonByRuleId(rule['security-rule'].rule_id)).click();
- cy.wait('@installPrebuiltRules');
- assertInstallationSuccessOrFailure([rule], didRequestFail);
-};
-
-export const assertRuleAvailableForInstallAndInstallSelected = ({
- rules,
- didRequestFail = false,
-}: RuleInstallUpgradeAssertionPayload) => {
- interceptInstallationRequestToFail(rules, didRequestFail);
- let i = 0;
+export const assertInstallationRequestIsComplete = (rules: Array) => {
for (const rule of rules) {
- cy.get(RULE_CHECKBOX).eq(i).click();
- cy.get(ADD_ELASTIC_RULES_TABLE).contains(rule['security-rule'].name);
- i++;
+ cy.get(getInstallSingleRuleLoadingSpinnerByRuleId(rule['security-rule'].rule_id)).should(
+ 'exist'
+ );
}
- cy.get(INSTALL_SELECTED_RULES_BUTTON).click();
- cy.wait('@installPrebuiltRules');
- assertInstallationSuccessOrFailure(rules, didRequestFail);
-};
-
-export const assertRuleAvailableForInstallAndInstallAllInPage = ({
- rules,
- didRequestFail = false,
-}: RuleInstallUpgradeAssertionPayload) => {
- interceptInstallationRequestToFail(rules, didRequestFail);
for (const rule of rules) {
- cy.get(ADD_ELASTIC_RULES_TABLE).contains(rule['security-rule'].name);
+ cy.get(getInstallSingleRuleLoadingSpinnerByRuleId(rule['security-rule'].rule_id)).should(
+ 'not.exist'
+ );
}
- cy.get(SELECT_ALL_RULES_ON_PAGE_CHECKBOX).click();
- cy.get(INSTALL_SELECTED_RULES_BUTTON).click();
- cy.wait('@installPrebuiltRules');
- assertInstallationSuccessOrFailure(rules, didRequestFail);
};
-export const assertRuleAvailableForInstallAndInstallAll = ({
- rules,
- didRequestFail = false,
-}: RuleInstallUpgradeAssertionPayload) => {
- interceptInstallationRequestToFail(rules, didRequestFail);
+export const assertUpgradeRequestIsComplete = (rules: Array) => {
for (const rule of rules) {
- cy.get(ADD_ELASTIC_RULES_TABLE).contains(rule['security-rule'].name);
+ cy.get(getUpgradeSingleRuleLoadingSpinnerByRuleId(rule['security-rule'].rule_id)).should(
+ 'exist'
+ );
+ }
+ for (const rule of rules) {
+ cy.get(getUpgradeSingleRuleLoadingSpinnerByRuleId(rule['security-rule'].rule_id)).should(
+ 'not.exist'
+ );
}
- cy.get(INSTALL_ALL_RULES_BUTTON).click();
- cy.wait('@installPrebuiltRules');
- assertInstallationSuccessOrFailure(rules, didRequestFail);
};
-const assertInstallationSuccessOrFailure = (
- rules: Array,
- didRequestFail: boolean
-) => {
+/**
+ * Assert that when the rule installation succeeds, the toast is shown with the right message
+ * -confirming the succesful install- and subsequently check that the rules available for installation
+ * are not present in the Add Elastic Rules table anymore
+ */
+export const assertInstallationSuccess = (rules: Array) => {
const rulesString = rules.length > 1 ? 'rules' : 'rule';
- const toastMessage = didRequestFail
- ? `${rules.length} ${rulesString} failed to install.`
- : `${rules.length} ${rulesString} installed successfully.`;
+ const toastMessage = `${rules.length} ${rulesString} installed successfully.`;
cy.get(TOASTER).should('be.visible').should('have.text', toastMessage);
- if (didRequestFail) {
- for (const rule of rules) {
- cy.get(ADD_ELASTIC_RULES_TABLE).contains(rule['security-rule'].name);
- }
- } else {
- cy.get(RULE_MANAGEMENT_PAGE_BREADCRUMB).click();
- for (const rule of rules) {
- cy.get(RULES_MANAGEMENT_TABLE).contains(rule['security-rule'].name);
- }
- }
-};
-const interceptInstallationRequestToFail = (
- rules: Array,
- didRequestFail: boolean
-) => {
- if (didRequestFail) {
- cy.intercept('POST', '/internal/detection_engine/prebuilt_rules/installation/_perform', {
- body: {
- summary: {
- succeeded: [],
- skipped: [],
- failed: rules.length,
- },
- },
- }).as('installPrebuiltRules');
+ // Go back to rules table and assert that the rules are installed
+ cy.get(RULE_MANAGEMENT_PAGE_BREADCRUMB).click();
+ for (const rule of rules) {
+ cy.get(RULES_MANAGEMENT_TABLE).contains(rule['security-rule'].name);
}
};
-export const assertRuleUpgradeAvailableAndUpgradeOne = ({
- rules,
- didRequestFail = false,
-}: RuleInstallUpgradeAssertionPayload) => {
- interceptUpgradeRequestToFail(rules, didRequestFail);
- const rule = rules[0];
- cy.get(getUpgradeSingleRuleButtonByRuleId(rule['security-rule'].rule_id)).click();
- cy.wait('@updatePrebuiltRules');
- assertUpgradeSuccessOrFailure([rule], didRequestFail);
-};
+/**
+ * Assert that when the rule installation fails, the toast is shown with the right message
+ * -notifying that the installation failed- and subsequently check that the rules available for installation
+ * are still present in the Rule Update table
+ */
+export const assertInstallationFailure = (rules: Array) => {
+ const rulesString = rules.length > 1 ? 'rules' : 'rule';
+ const toastMessage = `${rules.length} ${rulesString} failed to install.`;
+ cy.get(TOASTER).should('be.visible').should('have.text', toastMessage);
-export const assertRuleUpgradeAvailableAndUpgradeSelected = ({
- rules,
- didRequestFail = false,
-}: RuleInstallUpgradeAssertionPayload) => {
- interceptUpgradeRequestToFail(rules, didRequestFail);
- let i = 0;
+ // Check rules are still available for install
for (const rule of rules) {
- cy.get(RULE_CHECKBOX).eq(i).click();
- cy.get(RULES_UPDATES_TABLE).contains(rule['security-rule'].name);
- i++;
+ cy.get(ADD_ELASTIC_RULES_TABLE).contains(rule['security-rule'].name);
}
- cy.get(UPGRADE_SELECTED_RULES_BUTTON).click();
- cy.wait('@updatePrebuiltRules');
- assertUpgradeSuccessOrFailure(rules, didRequestFail);
};
-export const assertRuleUpgradeAvailableAndUpgradeAllInPage = ({
- rules,
- didRequestFail = false,
-}: RuleInstallUpgradeAssertionPayload) => {
- interceptUpgradeRequestToFail(rules, didRequestFail);
- for (const rule of rules) {
- cy.get(RULES_UPDATES_TABLE).contains(rule['security-rule'].name);
- }
- cy.get(SELECT_ALL_RULES_ON_PAGE_CHECKBOX).click();
- cy.get(UPGRADE_SELECTED_RULES_BUTTON).click();
- cy.wait('@updatePrebuiltRules');
- assertUpgradeSuccessOrFailure(rules, didRequestFail);
+export const interceptInstallationRequestToFail = (rules: Array) => {
+ cy.intercept('POST', '/internal/detection_engine/prebuilt_rules/installation/_perform', {
+ body: {
+ summary: {
+ succeeded: [],
+ skipped: [],
+ failed: rules.length,
+ },
+ },
+ delay: 500, // Add delay to give Cypress time to find the loading spinner
+ }).as('installPrebuiltRules');
};
-export const assertRuleUpgradeAvailableAndUpgradeAll = ({
- rules,
- didRequestFail = false,
-}: RuleInstallUpgradeAssertionPayload) => {
- interceptUpgradeRequestToFail(rules, didRequestFail);
+/**
+ * Assert that when the rule version upgrade succeeds, the toast is shown with the right message
+ * -confirming the succesful upgrade- and subsequently check that the rules available for upgrade
+ * are not present in the Rule Update table anymore
+ */
+export const assertUpgradeSuccess = (rules: Array) => {
+ const rulesString = rules.length > 1 ? 'rules' : 'rule';
+ const toastMessage = `${rules.length} ${rulesString} updated successfully.`;
+ cy.get(TOASTER).should('be.visible').should('have.text', toastMessage);
for (const rule of rules) {
- cy.get(RULES_UPDATES_TABLE).contains(rule['security-rule'].name);
+ cy.get(rule['security-rule'].name).should('not.exist');
}
- cy.get(UPGRADE_ALL_RULES_BUTTON).click();
- cy.wait('@updatePrebuiltRules');
- assertUpgradeSuccessOrFailure(rules, didRequestFail);
};
-const assertUpgradeSuccessOrFailure = (
- rules: Array,
- didRequestFail: boolean
-) => {
+/**
+ * Assert that when the rule version upgrade fails, the toast is shown with the right message
+ * -notifying that the upgrade failed- and subsequently check that the rules available for upgrade
+ * are still present in the Rule Update table
+ */
+export const assertUpgradeFailure = (rules: Array) => {
const rulesString = rules.length > 1 ? 'rules' : 'rule';
- const toastMessage = didRequestFail
- ? `${rules.length} ${rulesString} failed to update.`
- : `${rules.length} ${rulesString} updated successfully.`;
+ const toastMessage = `${rules.length} ${rulesString} failed to update.`;
cy.get(TOASTER).should('be.visible').should('have.text', toastMessage);
- if (didRequestFail) {
- for (const rule of rules) {
- cy.get(RULES_UPDATES_TABLE).contains(rule['security-rule'].name);
- }
- } else {
- for (const rule of rules) {
- cy.get(rule['security-rule'].name).should('not.exist');
- }
+
+ for (const rule of rules) {
+ cy.get(RULES_UPDATES_TABLE).contains(rule['security-rule'].name);
}
};
-const interceptUpgradeRequestToFail = (
- rules: Array,
- didRequestFail: boolean
-) => {
- if (didRequestFail) {
- cy.intercept('POST', '/internal/detection_engine/prebuilt_rules/upgrade/_perform', {
- body: {
- summary: {
- succeeded: [],
- skipped: [],
- failed: rules.length,
- },
+export const interceptUpgradeRequestToFail = (rules: Array) => {
+ cy.intercept('POST', '/internal/detection_engine/prebuilt_rules/upgrade/_perform', {
+ body: {
+ summary: {
+ succeeded: [],
+ skipped: [],
+ failed: rules.length,
},
- }).as('updatePrebuiltRules');
- }
+ },
+ delay: 500, // Add delay to give Cypress time to find the loading spinner
+ }).as('updatePrebuiltRules');
};