[Security Solution] Unskip rules bulk actions Serverless Cypress tests (#168307)

**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) 🟢
This commit is contained in:
Maxim Palenov 2023-10-19 00:26:55 +02:00 committed by GitHub
parent 8fd827f868
commit 4f9108273c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 704 additions and 719 deletions

View file

@ -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);
});
}
);
});
});

View file

@ -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');
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,
},
frequency: {
summary: true,
throttle: null,
notifyWhen: 'onActiveAlert',
},
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',
},
},
];
createRule(
getNewRule({
rule_id: '1',
name: ruleNameToAssert,
max_signals: 500,
actions,
enabled: false,
})
);
});
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]);
});
context('Restricted action privileges', () => {
it("User with no privileges can't add rule actions", () => {
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",
{ 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();
it('Add a rule action to rules (existing connector)', () => {
const expectedActionFrequency: RuleActionCustomFrequency = {
throttle: 1,
throttleUnit: 'd',
};
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',
]);
});
excessivelyInstallAllPrebuiltRules();
it('Add a rule action to rules (existing connector)', () => {
const expectedActionFrequency: RuleActionCustomFrequency = {
throttle: 1,
throttleUnit: 'd',
};
excessivelyInstallAllPrebuiltRules();
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');
addSlackRuleAction(expectedSlackMessage);
pickSummaryOfAlertsOption();
pickCustomFrequencyOption(expectedActionFrequency);
submitBulkEditForm();
waitForBulkEditActionToFinish({ updatedCount: rows.length });
// 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');
});
});
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('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);
// ensure rule actions info callout displayed on the form
cy.get(RULES_BULK_EDIT_ACTIONS_INFO).should('be.visible');
addSlackRuleAction(expectedSlackMessage);
pickSummaryOfAlertsOption();
pickCustomFrequencyOption(expectedActionFrequency);
submitBulkEditForm();
waitForBulkEditActionToFinish({ updatedCount: rulesToSelect.length });
waitForBulkEditActionToFinish({ updatedCount: rows.length });
// check if rule has been updated
goToEditRuleActionsSettingsOf(ruleNameToAssert);
assertSelectedSummaryOfAlertsOption();
assertSelectedCustomFrequencyOption(expectedActionFrequency, 1);
assertEmailRuleAction(expectedEmail, expectedSubject);
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('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);
});
});
});

View file

@ -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',