mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Security Solution] Minimize the use of es_archiver on cypress tests (#85019)
* minimizes the uses of es_archiver * refactor * fixes merge issue * fixes typecheck issue * Update x-pack/plugins/security_solution/cypress/integration/timelines_export.spec.ts Co-authored-by: Patryk Kopyciński <contact@patrykkopycinski.com> * final refactor * final touches * unskips skipped tests * removes async * fixes typo * removes unused lines * fixes failing test * fixes timelines failing tests * fixes merge issue Co-authored-by: Patryk Kopyciński <contact@patrykkopycinski.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
36525954a1
commit
1b5d43b2e2
31 changed files with 474 additions and 9167 deletions
|
@ -25,7 +25,7 @@ import {
|
|||
markInProgressFirstAlert,
|
||||
goToInProgressAlerts,
|
||||
} from '../tasks/alerts';
|
||||
import { removeSignalsIndex } from '../tasks/api_calls';
|
||||
import { removeSignalsIndex } from '../tasks/api_calls/rules';
|
||||
import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver';
|
||||
import { loginAndWaitForPage } from '../tasks/login';
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
goToOpenedAlerts,
|
||||
waitForAlertsIndexToBeCreated,
|
||||
} from '../tasks/alerts';
|
||||
import { createCustomRule, deleteCustomRule, removeSignalsIndex } from '../tasks/api_calls';
|
||||
import { createCustomRule, deleteCustomRule, removeSignalsIndex } from '../tasks/api_calls/rules';
|
||||
import { goToRuleDetails } from '../tasks/alerts_detection_rules';
|
||||
import { waitForAlertsToPopulate } from '../tasks/create_new_rule';
|
||||
import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver';
|
||||
|
@ -34,9 +34,8 @@ import { refreshPage } from '../tasks/security_header';
|
|||
|
||||
import { DETECTIONS_URL } from '../urls/navigation';
|
||||
|
||||
const NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS = 1;
|
||||
|
||||
describe('Exceptions', () => {
|
||||
const NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS = '1';
|
||||
beforeEach(() => {
|
||||
loginAndWaitForPageWithoutDateRange(DETECTIONS_URL);
|
||||
waitForAlertsIndexToBeCreated();
|
||||
|
@ -53,14 +52,7 @@ describe('Exceptions', () => {
|
|||
refreshPage();
|
||||
|
||||
cy.get(ALERTS_COUNT).should('exist');
|
||||
cy.get(NUMBER_OF_ALERTS)
|
||||
.invoke('text')
|
||||
.then((numberOfInitialAlertsText) => {
|
||||
cy.wrap(parseInt(numberOfInitialAlertsText, 10)).should(
|
||||
'eql',
|
||||
NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS
|
||||
);
|
||||
});
|
||||
cy.get(NUMBER_OF_ALERTS).should('have.text', NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -79,35 +71,20 @@ describe('Exceptions', () => {
|
|||
refreshPage();
|
||||
|
||||
cy.get(ALERTS_COUNT).should('exist');
|
||||
cy.get(NUMBER_OF_ALERTS)
|
||||
.invoke('text')
|
||||
.then((numberOfAlertsAfterCreatingExceptionText) => {
|
||||
cy.wrap(parseInt(numberOfAlertsAfterCreatingExceptionText, 10)).should('eql', 0);
|
||||
});
|
||||
cy.get(NUMBER_OF_ALERTS).should('have.text', '0');
|
||||
|
||||
goToClosedAlerts();
|
||||
refreshPage();
|
||||
|
||||
cy.get(ALERTS_COUNT).should('exist');
|
||||
cy.get(NUMBER_OF_ALERTS)
|
||||
.invoke('text')
|
||||
.then((numberOfClosedAlertsAfterCreatingExceptionText) => {
|
||||
cy.wrap(parseInt(numberOfClosedAlertsAfterCreatingExceptionText, 10)).should(
|
||||
'eql',
|
||||
NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS
|
||||
);
|
||||
});
|
||||
cy.get(NUMBER_OF_ALERTS).should('have.text', NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS);
|
||||
|
||||
goToOpenedAlerts();
|
||||
waitForTheRuleToBeExecuted();
|
||||
refreshPage();
|
||||
|
||||
cy.get(ALERTS_COUNT).should('exist');
|
||||
cy.get(NUMBER_OF_ALERTS)
|
||||
.invoke('text')
|
||||
.then((numberOfOpenedAlertsAfterCreatingExceptionText) => {
|
||||
cy.wrap(parseInt(numberOfOpenedAlertsAfterCreatingExceptionText, 10)).should('eql', 0);
|
||||
});
|
||||
cy.get(NUMBER_OF_ALERTS).should('have.text', '0');
|
||||
|
||||
goToExceptionsTab();
|
||||
removeException();
|
||||
|
@ -118,14 +95,7 @@ describe('Exceptions', () => {
|
|||
refreshPage();
|
||||
|
||||
cy.get(ALERTS_COUNT).should('exist');
|
||||
cy.get(NUMBER_OF_ALERTS)
|
||||
.invoke('text')
|
||||
.then((numberOfAlertsAfterRemovingExceptionsText) => {
|
||||
cy.wrap(parseInt(numberOfAlertsAfterRemovingExceptionsText, 10)).should(
|
||||
'eql',
|
||||
NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS
|
||||
);
|
||||
});
|
||||
cy.get(NUMBER_OF_ALERTS).should('have.text', NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -136,35 +106,20 @@ describe('Exceptions', () => {
|
|||
esArchiverLoad('auditbeat_for_exceptions2');
|
||||
|
||||
cy.get(ALERTS_COUNT).should('exist');
|
||||
cy.get(NUMBER_OF_ALERTS)
|
||||
.invoke('text')
|
||||
.then((numberOfAlertsAfterCreatingExceptionText) => {
|
||||
cy.wrap(parseInt(numberOfAlertsAfterCreatingExceptionText, 10)).should('eql', 0);
|
||||
});
|
||||
cy.get(NUMBER_OF_ALERTS).should('have.text', '0');
|
||||
|
||||
goToClosedAlerts();
|
||||
refreshPage();
|
||||
|
||||
cy.get(ALERTS_COUNT).should('exist');
|
||||
cy.get(NUMBER_OF_ALERTS)
|
||||
.invoke('text')
|
||||
.then((numberOfClosedAlertsAfterCreatingExceptionText) => {
|
||||
cy.wrap(parseInt(numberOfClosedAlertsAfterCreatingExceptionText, 10)).should(
|
||||
'eql',
|
||||
NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS
|
||||
);
|
||||
});
|
||||
cy.get(NUMBER_OF_ALERTS).should('have.text', NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS);
|
||||
|
||||
goToOpenedAlerts();
|
||||
waitForTheRuleToBeExecuted();
|
||||
refreshPage();
|
||||
|
||||
cy.get(ALERTS_COUNT).should('exist');
|
||||
cy.get(NUMBER_OF_ALERTS)
|
||||
.invoke('text')
|
||||
.then((numberOfOpenedAlertsAfterCreatingExceptionText) => {
|
||||
cy.wrap(parseInt(numberOfOpenedAlertsAfterCreatingExceptionText, 10)).should('eql', 0);
|
||||
});
|
||||
cy.get(NUMBER_OF_ALERTS).should('have.text', '0');
|
||||
|
||||
goToExceptionsTab();
|
||||
removeException();
|
||||
|
@ -174,14 +129,7 @@ describe('Exceptions', () => {
|
|||
refreshPage();
|
||||
|
||||
cy.get(ALERTS_COUNT).should('exist');
|
||||
cy.get(NUMBER_OF_ALERTS)
|
||||
.invoke('text')
|
||||
.then((numberOfAlertsAfterRemovingExceptionsText) => {
|
||||
cy.wrap(parseInt(numberOfAlertsAfterRemovingExceptionsText, 10)).should(
|
||||
'eql',
|
||||
NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS
|
||||
);
|
||||
});
|
||||
cy.get(NUMBER_OF_ALERTS).should('have.text', NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -85,7 +85,8 @@ import {
|
|||
waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded,
|
||||
waitForRulesToBeLoaded,
|
||||
} from '../tasks/alerts_detection_rules';
|
||||
import { removeSignalsIndex } from '../tasks/api_calls';
|
||||
import { removeSignalsIndex } from '../tasks/api_calls/rules';
|
||||
import { createTimeline, deleteTimeline } from '../tasks/api_calls/timelines';
|
||||
import {
|
||||
createAndActivateRule,
|
||||
fillAboutRule,
|
||||
|
@ -104,23 +105,24 @@ import { loginAndWaitForPageWithoutDateRange } from '../tasks/login';
|
|||
|
||||
import { DETECTIONS_URL } from '../urls/navigation';
|
||||
|
||||
const expectedUrls = newRule.referenceUrls.join('');
|
||||
const expectedFalsePositives = newRule.falsePositivesExamples.join('');
|
||||
const expectedTags = newRule.tags.join('');
|
||||
const expectedMitre = formatMitreAttackDescription(newRule.mitre);
|
||||
const expectedNumberOfRules = 1;
|
||||
const expectedEditedtags = editedRule.tags.join('');
|
||||
const expectedEditedIndexPatterns =
|
||||
editedRule.index && editedRule.index.length ? editedRule.index : indexPatterns;
|
||||
|
||||
describe('Custom detection rules creation', () => {
|
||||
const expectedUrls = newRule.referenceUrls.join('');
|
||||
const expectedFalsePositives = newRule.falsePositivesExamples.join('');
|
||||
const expectedTags = newRule.tags.join('');
|
||||
const expectedMitre = formatMitreAttackDescription(newRule.mitre);
|
||||
const expectedNumberOfRules = 1;
|
||||
|
||||
const rule = { ...newRule };
|
||||
|
||||
before(() => {
|
||||
esArchiverLoad('timeline');
|
||||
createTimeline(newRule.timeline).then((response) => {
|
||||
rule.timeline.id = response.body.data.persistTimeline.timeline.savedObjectId;
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
deleteRule();
|
||||
esArchiverUnload('timeline');
|
||||
deleteTimeline(rule.timeline.id!);
|
||||
removeSignalsIndex();
|
||||
});
|
||||
|
||||
|
@ -131,19 +133,19 @@ describe('Custom detection rules creation', () => {
|
|||
goToManageAlertsDetectionRules();
|
||||
waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded();
|
||||
goToCreateNewRule();
|
||||
fillDefineCustomRuleWithImportedQueryAndContinue(newRule);
|
||||
fillAboutRuleAndContinue(newRule);
|
||||
fillScheduleRuleAndContinue(newRule);
|
||||
fillDefineCustomRuleWithImportedQueryAndContinue(rule);
|
||||
fillAboutRuleAndContinue(rule);
|
||||
fillScheduleRuleAndContinue(rule);
|
||||
|
||||
// expect define step to repopulate
|
||||
cy.get(DEFINE_EDIT_BUTTON).click();
|
||||
cy.get(CUSTOM_QUERY_INPUT).should('have.value', newRule.customQuery);
|
||||
cy.get(CUSTOM_QUERY_INPUT).should('have.value', rule.customQuery);
|
||||
cy.get(DEFINE_CONTINUE_BUTTON).should('exist').click({ force: true });
|
||||
cy.get(DEFINE_CONTINUE_BUTTON).should('not.exist');
|
||||
|
||||
// expect about step to populate
|
||||
cy.get(ABOUT_EDIT_BUTTON).click();
|
||||
cy.get(RULE_NAME_INPUT).invoke('val').should('eql', newRule.name);
|
||||
cy.get(RULE_NAME_INPUT).invoke('val').should('eql', rule.name);
|
||||
cy.get(ABOUT_CONTINUE_BTN).should('exist').click({ force: true });
|
||||
cy.get(ABOUT_CONTINUE_BTN).should('not.exist');
|
||||
|
||||
|
@ -163,18 +165,18 @@ describe('Custom detection rules creation', () => {
|
|||
cy.get(RULES_TABLE).then(($table) => {
|
||||
cy.wrap($table.find(RULES_ROW).length).should('eql', 1);
|
||||
});
|
||||
cy.get(RULE_NAME).should('have.text', newRule.name);
|
||||
cy.get(RISK_SCORE).should('have.text', newRule.riskScore);
|
||||
cy.get(SEVERITY).should('have.text', newRule.severity);
|
||||
cy.get(RULE_NAME).should('have.text', rule.name);
|
||||
cy.get(RISK_SCORE).should('have.text', rule.riskScore);
|
||||
cy.get(SEVERITY).should('have.text', rule.severity);
|
||||
cy.get(RULE_SWITCH).should('have.attr', 'aria-checked', 'true');
|
||||
|
||||
goToRuleDetails();
|
||||
|
||||
cy.get(RULE_NAME_HEADER).should('have.text', `${newRule.name}`);
|
||||
cy.get(ABOUT_RULE_DESCRIPTION).should('have.text', newRule.description);
|
||||
cy.get(RULE_NAME_HEADER).should('have.text', `${rule.name}`);
|
||||
cy.get(ABOUT_RULE_DESCRIPTION).should('have.text', rule.description);
|
||||
cy.get(ABOUT_DETAILS).within(() => {
|
||||
getDetails(SEVERITY_DETAILS).should('have.text', newRule.severity);
|
||||
getDetails(RISK_SCORE_DETAILS).should('have.text', newRule.riskScore);
|
||||
getDetails(SEVERITY_DETAILS).should('have.text', rule.severity);
|
||||
getDetails(RISK_SCORE_DETAILS).should('have.text', rule.riskScore);
|
||||
getDetails(REFERENCE_URLS_DETAILS).should((details) => {
|
||||
expect(removeExternalLinkText(details.text())).equal(expectedUrls);
|
||||
});
|
||||
|
@ -188,7 +190,7 @@ describe('Custom detection rules creation', () => {
|
|||
cy.get(ABOUT_INVESTIGATION_NOTES).should('have.text', INVESTIGATION_NOTES_MARKDOWN);
|
||||
cy.get(DEFINITION_DETAILS).within(() => {
|
||||
getDetails(INDEX_PATTERNS_DETAILS).should('have.text', indexPatterns.join(''));
|
||||
getDetails(CUSTOM_QUERY_DETAILS).should('have.text', newRule.customQuery);
|
||||
getDetails(CUSTOM_QUERY_DETAILS).should('have.text', rule.customQuery);
|
||||
getDetails(RULE_TYPE_DETAILS).should('have.text', 'Query');
|
||||
getDetails(TIMELINE_TEMPLATE_DETAILS).should('have.text', 'None');
|
||||
});
|
||||
|
@ -207,11 +209,11 @@ describe('Custom detection rules creation', () => {
|
|||
waitForAlertsToPopulate();
|
||||
|
||||
cy.get(NUMBER_OF_ALERTS).invoke('text').then(parseFloat).should('be.above', 0);
|
||||
cy.get(ALERT_RULE_NAME).first().should('have.text', newRule.name);
|
||||
cy.get(ALERT_RULE_NAME).first().should('have.text', rule.name);
|
||||
cy.get(ALERT_RULE_VERSION).first().should('have.text', '1');
|
||||
cy.get(ALERT_RULE_METHOD).first().should('have.text', 'query');
|
||||
cy.get(ALERT_RULE_SEVERITY).first().should('have.text', newRule.severity.toLowerCase());
|
||||
cy.get(ALERT_RULE_RISK_SCORE).first().should('have.text', newRule.riskScore);
|
||||
cy.get(ALERT_RULE_SEVERITY).first().should('have.text', rule.severity.toLowerCase());
|
||||
cy.get(ALERT_RULE_RISK_SCORE).first().should('have.text', rule.riskScore);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -291,6 +293,10 @@ describe('Custom detection rules deletion and edition', () => {
|
|||
});
|
||||
|
||||
context('Edition', () => {
|
||||
const expectedEditedtags = editedRule.tags.join('');
|
||||
const expectedEditedIndexPatterns =
|
||||
editedRule.index && editedRule.index.length ? editedRule.index : indexPatterns;
|
||||
|
||||
it('Allows a rule to be edited', () => {
|
||||
editFirstRule();
|
||||
waitForKibana();
|
||||
|
|
|
@ -63,6 +63,7 @@ import {
|
|||
waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded,
|
||||
waitForRulesToBeLoaded,
|
||||
} from '../tasks/alerts_detection_rules';
|
||||
import { createTimeline, deleteTimeline } from '../tasks/api_calls/timelines';
|
||||
import {
|
||||
createAndActivateRule,
|
||||
fillAboutRuleAndContinue,
|
||||
|
@ -72,27 +73,29 @@ import {
|
|||
waitForAlertsToPopulate,
|
||||
waitForTheRuleToBeExecuted,
|
||||
} from '../tasks/create_new_rule';
|
||||
import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver';
|
||||
import { loginAndWaitForPageWithoutDateRange } from '../tasks/login';
|
||||
|
||||
import { DETECTIONS_URL } from '../urls/navigation';
|
||||
|
||||
const expectedUrls = eqlRule.referenceUrls.join('');
|
||||
const expectedFalsePositives = eqlRule.falsePositivesExamples.join('');
|
||||
const expectedTags = eqlRule.tags.join('');
|
||||
const expectedMitre = formatMitreAttackDescription(eqlRule.mitre);
|
||||
const expectedNumberOfRules = 1;
|
||||
const expectedNumberOfAlerts = 7;
|
||||
const expectedNumberOfSequenceAlerts = 1;
|
||||
|
||||
describe('Detection rules, EQL', () => {
|
||||
beforeEach(() => {
|
||||
esArchiverLoad('timeline');
|
||||
const expectedUrls = eqlRule.referenceUrls.join('');
|
||||
const expectedFalsePositives = eqlRule.falsePositivesExamples.join('');
|
||||
const expectedTags = eqlRule.tags.join('');
|
||||
const expectedMitre = formatMitreAttackDescription(eqlRule.mitre);
|
||||
const expectedNumberOfRules = 1;
|
||||
const expectedNumberOfAlerts = 7;
|
||||
|
||||
const rule = { ...eqlRule };
|
||||
|
||||
before(() => {
|
||||
createTimeline(eqlRule.timeline).then((response) => {
|
||||
rule.timeline.id = response.body.data.persistTimeline.timeline.savedObjectId;
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
after(() => {
|
||||
deleteTimeline(rule.timeline.id!);
|
||||
deleteRule();
|
||||
esArchiverUnload('timeline');
|
||||
});
|
||||
|
||||
it('Creates and activates a new EQL rule', () => {
|
||||
|
@ -103,9 +106,9 @@ describe('Detection rules, EQL', () => {
|
|||
waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded();
|
||||
goToCreateNewRule();
|
||||
selectEqlRuleType();
|
||||
fillDefineEqlRuleAndContinue(eqlRule);
|
||||
fillAboutRuleAndContinue(eqlRule);
|
||||
fillScheduleRuleAndContinue(eqlRule);
|
||||
fillDefineEqlRuleAndContinue(rule);
|
||||
fillAboutRuleAndContinue(rule);
|
||||
fillScheduleRuleAndContinue(rule);
|
||||
createAndActivateRule();
|
||||
|
||||
cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)');
|
||||
|
@ -122,18 +125,18 @@ describe('Detection rules, EQL', () => {
|
|||
cy.get(RULES_TABLE).then(($table) => {
|
||||
cy.wrap($table.find(RULES_ROW).length).should('eql', 1);
|
||||
});
|
||||
cy.get(RULE_NAME).should('have.text', eqlRule.name);
|
||||
cy.get(RISK_SCORE).should('have.text', eqlRule.riskScore);
|
||||
cy.get(SEVERITY).should('have.text', eqlRule.severity);
|
||||
cy.get(RULE_NAME).should('have.text', rule.name);
|
||||
cy.get(RISK_SCORE).should('have.text', rule.riskScore);
|
||||
cy.get(SEVERITY).should('have.text', rule.severity);
|
||||
cy.get(RULE_SWITCH).should('have.attr', 'aria-checked', 'true');
|
||||
|
||||
goToRuleDetails();
|
||||
|
||||
cy.get(RULE_NAME_HEADER).should('have.text', `${eqlRule.name}`);
|
||||
cy.get(ABOUT_RULE_DESCRIPTION).should('have.text', eqlRule.description);
|
||||
cy.get(RULE_NAME_HEADER).should('have.text', `${rule.name}`);
|
||||
cy.get(ABOUT_RULE_DESCRIPTION).should('have.text', rule.description);
|
||||
cy.get(ABOUT_DETAILS).within(() => {
|
||||
getDetails(SEVERITY_DETAILS).should('have.text', eqlRule.severity);
|
||||
getDetails(RISK_SCORE_DETAILS).should('have.text', eqlRule.riskScore);
|
||||
getDetails(SEVERITY_DETAILS).should('have.text', rule.severity);
|
||||
getDetails(RISK_SCORE_DETAILS).should('have.text', rule.riskScore);
|
||||
getDetails(REFERENCE_URLS_DETAILS).should((details) => {
|
||||
expect(removeExternalLinkText(details.text())).equal(expectedUrls);
|
||||
});
|
||||
|
@ -147,18 +150,18 @@ describe('Detection rules, EQL', () => {
|
|||
cy.get(ABOUT_INVESTIGATION_NOTES).should('have.text', INVESTIGATION_NOTES_MARKDOWN);
|
||||
cy.get(DEFINITION_DETAILS).within(() => {
|
||||
getDetails(INDEX_PATTERNS_DETAILS).should('have.text', indexPatterns.join(''));
|
||||
getDetails(CUSTOM_QUERY_DETAILS).should('have.text', eqlRule.customQuery);
|
||||
getDetails(CUSTOM_QUERY_DETAILS).should('have.text', rule.customQuery);
|
||||
getDetails(RULE_TYPE_DETAILS).should('have.text', 'Event Correlation');
|
||||
getDetails(TIMELINE_TEMPLATE_DETAILS).should('have.text', 'None');
|
||||
});
|
||||
cy.get(SCHEDULE_DETAILS).within(() => {
|
||||
getDetails(RUNS_EVERY_DETAILS).should(
|
||||
'have.text',
|
||||
`${eqlRule.runsEvery.interval}${eqlRule.runsEvery.type}`
|
||||
`${rule.runsEvery.interval}${rule.runsEvery.type}`
|
||||
);
|
||||
getDetails(ADDITIONAL_LOOK_BACK_DETAILS).should(
|
||||
'have.text',
|
||||
`${eqlRule.lookBack.interval}${eqlRule.lookBack.type}`
|
||||
`${rule.lookBack.interval}${rule.lookBack.type}`
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -166,11 +169,28 @@ describe('Detection rules, EQL', () => {
|
|||
waitForAlertsToPopulate();
|
||||
|
||||
cy.get(NUMBER_OF_ALERTS).should('have.text', expectedNumberOfAlerts);
|
||||
cy.get(ALERT_RULE_NAME).first().should('have.text', eqlRule.name);
|
||||
cy.get(ALERT_RULE_NAME).first().should('have.text', rule.name);
|
||||
cy.get(ALERT_RULE_VERSION).first().should('have.text', '1');
|
||||
cy.get(ALERT_RULE_METHOD).first().should('have.text', 'eql');
|
||||
cy.get(ALERT_RULE_SEVERITY).first().should('have.text', eqlRule.severity.toLowerCase());
|
||||
cy.get(ALERT_RULE_RISK_SCORE).first().should('have.text', eqlRule.riskScore);
|
||||
cy.get(ALERT_RULE_SEVERITY).first().should('have.text', rule.severity.toLowerCase());
|
||||
cy.get(ALERT_RULE_RISK_SCORE).first().should('have.text', rule.riskScore);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Detection rules, sequence EQL', () => {
|
||||
const expectedNumberOfRules = 1;
|
||||
const expectedNumberOfSequenceAlerts = 1;
|
||||
const rule = { ...eqlSequenceRule };
|
||||
|
||||
before(() => {
|
||||
createTimeline(eqlSequenceRule.timeline).then((response) => {
|
||||
rule.timeline.id = response.body.data.persistTimeline.timeline.savedObjectId;
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
deleteTimeline(eqlSequenceRule.timeline.id!);
|
||||
deleteRule();
|
||||
});
|
||||
|
||||
it('Creates and activates a new EQL rule with a sequence', () => {
|
||||
|
@ -181,9 +201,9 @@ describe('Detection rules, EQL', () => {
|
|||
waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded();
|
||||
goToCreateNewRule();
|
||||
selectEqlRuleType();
|
||||
fillDefineEqlRuleAndContinue(eqlSequenceRule);
|
||||
fillAboutRuleAndContinue(eqlSequenceRule);
|
||||
fillScheduleRuleAndContinue(eqlSequenceRule);
|
||||
fillDefineEqlRuleAndContinue(rule);
|
||||
fillAboutRuleAndContinue(rule);
|
||||
fillScheduleRuleAndContinue(rule);
|
||||
createAndActivateRule();
|
||||
|
||||
cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)');
|
||||
|
@ -201,10 +221,10 @@ describe('Detection rules, EQL', () => {
|
|||
waitForAlertsToPopulate();
|
||||
|
||||
cy.get(NUMBER_OF_ALERTS).should('have.text', expectedNumberOfSequenceAlerts);
|
||||
cy.get(ALERT_RULE_NAME).first().should('have.text', eqlSequenceRule.name);
|
||||
cy.get(ALERT_RULE_NAME).first().should('have.text', rule.name);
|
||||
cy.get(ALERT_RULE_VERSION).first().should('have.text', '1');
|
||||
cy.get(ALERT_RULE_METHOD).first().should('have.text', 'eql');
|
||||
cy.get(ALERT_RULE_SEVERITY).first().should('have.text', eqlSequenceRule.severity.toLowerCase());
|
||||
cy.get(ALERT_RULE_RISK_SCORE).first().should('have.text', eqlSequenceRule.riskScore);
|
||||
cy.get(ALERT_RULE_SEVERITY).first().should('have.text', rule.severity.toLowerCase());
|
||||
cy.get(ALERT_RULE_RISK_SCORE).first().should('have.text', rule.riskScore);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,44 +4,42 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { expectedExportedRule, newRule } from '../objects/rule';
|
||||
import {
|
||||
goToManageAlertsDetectionRules,
|
||||
waitForAlertsIndexToBeCreated,
|
||||
waitForAlertsPanelToBeLoaded,
|
||||
} from '../tasks/alerts';
|
||||
import { exportFirstRule } from '../tasks/alerts_detection_rules';
|
||||
import { removeSignalsIndex } from '../tasks/api_calls';
|
||||
import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver';
|
||||
import { createCustomRule, deleteCustomRule } from '../tasks/api_calls/rules';
|
||||
import { loginAndWaitForPageWithoutDateRange } from '../tasks/login';
|
||||
|
||||
import { DETECTIONS_URL } from '../urls/navigation';
|
||||
|
||||
const EXPECTED_EXPORTED_RULE_FILE_PATH = 'cypress/test_files/expected_rules_export.ndjson';
|
||||
|
||||
describe('Export rules', () => {
|
||||
let ruleResponse: Cypress.Response;
|
||||
before(() => {
|
||||
esArchiverLoad('export_rule');
|
||||
cy.intercept(
|
||||
'POST',
|
||||
'/api/detection_engine/rules/_export?exclude_export_details=false&file_name=rules_export.ndjson'
|
||||
).as('export');
|
||||
});
|
||||
|
||||
after(() => {
|
||||
esArchiverUnload('export_rule');
|
||||
removeSignalsIndex();
|
||||
});
|
||||
|
||||
it('Exports a custom rule', () => {
|
||||
loginAndWaitForPageWithoutDateRange(DETECTIONS_URL);
|
||||
waitForAlertsPanelToBeLoaded();
|
||||
waitForAlertsIndexToBeCreated();
|
||||
createCustomRule(newRule).then((response) => {
|
||||
ruleResponse = response;
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
deleteCustomRule();
|
||||
});
|
||||
|
||||
it('Exports a custom rule', () => {
|
||||
goToManageAlertsDetectionRules();
|
||||
exportFirstRule();
|
||||
cy.wait('@export').then(({ response }) => {
|
||||
cy.readFile(EXPECTED_EXPORTED_RULE_FILE_PATH).then(($expectedExportedJson) => {
|
||||
cy.wrap(response!.body).should('eql', $expectedExportedJson);
|
||||
});
|
||||
cy.wrap(response!.body).should('eql', expectedExportedRule(ruleResponse));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -66,7 +66,7 @@ import {
|
|||
waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded,
|
||||
waitForRulesToBeLoaded,
|
||||
} from '../tasks/alerts_detection_rules';
|
||||
import { removeSignalsIndex } from '../tasks/api_calls';
|
||||
import { removeSignalsIndex } from '../tasks/api_calls/rules';
|
||||
import {
|
||||
createAndActivateRule,
|
||||
fillAboutRuleAndContinue,
|
||||
|
@ -81,14 +81,14 @@ import { loginAndWaitForPageWithoutDateRange } from '../tasks/login';
|
|||
|
||||
import { DETECTIONS_URL } from '../urls/navigation';
|
||||
|
||||
const expectedUrls = newThreatIndicatorRule.referenceUrls.join('');
|
||||
const expectedFalsePositives = newThreatIndicatorRule.falsePositivesExamples.join('');
|
||||
const expectedTags = newThreatIndicatorRule.tags.join('');
|
||||
const expectedMitre = formatMitreAttackDescription(newThreatIndicatorRule.mitre);
|
||||
const expectedNumberOfRules = 1;
|
||||
const expectedNumberOfAlerts = 1;
|
||||
|
||||
describe('Detection rules, Indicator Match', () => {
|
||||
const expectedUrls = newThreatIndicatorRule.referenceUrls.join('');
|
||||
const expectedFalsePositives = newThreatIndicatorRule.falsePositivesExamples.join('');
|
||||
const expectedTags = newThreatIndicatorRule.tags.join('');
|
||||
const expectedMitre = formatMitreAttackDescription(newThreatIndicatorRule.mitre);
|
||||
const expectedNumberOfRules = 1;
|
||||
const expectedNumberOfAlerts = 1;
|
||||
|
||||
beforeEach(() => {
|
||||
esArchiverLoad('threat_indicator');
|
||||
esArchiverLoad('threat_data');
|
||||
|
@ -153,7 +153,10 @@ describe('Detection rules, Indicator Match', () => {
|
|||
cy.get(ABOUT_INVESTIGATION_NOTES).should('have.text', INVESTIGATION_NOTES_MARKDOWN);
|
||||
|
||||
cy.get(DEFINITION_DETAILS).within(() => {
|
||||
getDetails(INDEX_PATTERNS_DETAILS).should('have.text', newThreatIndicatorRule.index.join(''));
|
||||
getDetails(INDEX_PATTERNS_DETAILS).should(
|
||||
'have.text',
|
||||
newThreatIndicatorRule.index!.join('')
|
||||
);
|
||||
getDetails(CUSTOM_QUERY_DETAILS).should('have.text', '*:*');
|
||||
getDetails(RULE_TYPE_DETAILS).should('have.text', 'Indicator Match');
|
||||
getDetails(TIMELINE_TEMPLATE_DETAILS).should('have.text', 'None');
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { formatMitreAttackDescription } from '../helpers/rules';
|
||||
import { machineLearningRule, totalNumberOfPrebuiltRulesInEsArchive } from '../objects/rule';
|
||||
import { machineLearningRule } from '../objects/rule';
|
||||
|
||||
import {
|
||||
CUSTOM_RULES_BTN,
|
||||
|
@ -53,7 +53,6 @@ import {
|
|||
waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded,
|
||||
waitForRulesToBeLoaded,
|
||||
} from '../tasks/alerts_detection_rules';
|
||||
import { removeSignalsIndex } from '../tasks/api_calls';
|
||||
import {
|
||||
createAndActivateRule,
|
||||
fillAboutRuleAndContinue,
|
||||
|
@ -61,26 +60,19 @@ import {
|
|||
fillScheduleRuleAndContinue,
|
||||
selectMachineLearningRuleType,
|
||||
} from '../tasks/create_new_rule';
|
||||
import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver';
|
||||
import { loginAndWaitForPageWithoutDateRange } from '../tasks/login';
|
||||
|
||||
import { DETECTIONS_URL } from '../urls/navigation';
|
||||
|
||||
const expectedUrls = machineLearningRule.referenceUrls.join('');
|
||||
const expectedFalsePositives = machineLearningRule.falsePositivesExamples.join('');
|
||||
const expectedTags = machineLearningRule.tags.join('');
|
||||
const expectedMitre = formatMitreAttackDescription(machineLearningRule.mitre);
|
||||
const expectedNumberOfRules = totalNumberOfPrebuiltRulesInEsArchive + 1;
|
||||
|
||||
describe('Detection rules, machine learning', () => {
|
||||
before(() => {
|
||||
esArchiverLoad('prebuilt_rules_loaded');
|
||||
});
|
||||
const expectedUrls = machineLearningRule.referenceUrls.join('');
|
||||
const expectedFalsePositives = machineLearningRule.falsePositivesExamples.join('');
|
||||
const expectedTags = machineLearningRule.tags.join('');
|
||||
const expectedMitre = formatMitreAttackDescription(machineLearningRule.mitre);
|
||||
const expectedNumberOfRules = 1;
|
||||
|
||||
after(() => {
|
||||
deleteRule();
|
||||
esArchiverUnload('prebuilt_rules_loaded');
|
||||
removeSignalsIndex();
|
||||
});
|
||||
|
||||
it('Creates and activates a new ml rule', () => {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import { formatMitreAttackDescription } from '../helpers/rules';
|
||||
import { indexPatterns, newOverrideRule, severitiesOverride } from '../objects/rule';
|
||||
|
||||
import {
|
||||
NUMBER_OF_ALERTS,
|
||||
ALERT_RULE_NAME,
|
||||
|
@ -62,12 +63,14 @@ import {
|
|||
} from '../tasks/alerts';
|
||||
import {
|
||||
changeToThreeHundredRowsPerPage,
|
||||
deleteRule,
|
||||
filterByCustomRules,
|
||||
goToCreateNewRule,
|
||||
goToRuleDetails,
|
||||
waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded,
|
||||
waitForRulesToBeLoaded,
|
||||
} from '../tasks/alerts_detection_rules';
|
||||
import { createTimeline, deleteTimeline } from '../tasks/api_calls/timelines';
|
||||
import {
|
||||
createAndActivateRule,
|
||||
fillAboutRuleWithOverrideAndContinue,
|
||||
|
@ -76,24 +79,27 @@ import {
|
|||
waitForAlertsToPopulate,
|
||||
waitForTheRuleToBeExecuted,
|
||||
} from '../tasks/create_new_rule';
|
||||
import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver';
|
||||
import { loginAndWaitForPageWithoutDateRange } from '../tasks/login';
|
||||
|
||||
import { DETECTIONS_URL } from '../urls/navigation';
|
||||
|
||||
const expectedUrls = newOverrideRule.referenceUrls.join('');
|
||||
const expectedFalsePositives = newOverrideRule.falsePositivesExamples.join('');
|
||||
const expectedTags = newOverrideRule.tags.join('');
|
||||
const expectedMitre = formatMitreAttackDescription(newOverrideRule.mitre);
|
||||
describe('Detection rules, override', () => {
|
||||
const expectedUrls = newOverrideRule.referenceUrls.join('');
|
||||
const expectedFalsePositives = newOverrideRule.falsePositivesExamples.join('');
|
||||
const expectedTags = newOverrideRule.tags.join('');
|
||||
const expectedMitre = formatMitreAttackDescription(newOverrideRule.mitre);
|
||||
|
||||
// FLAKY: https://github.com/elastic/kibana/issues/84020
|
||||
describe.skip('Detection rules, override', () => {
|
||||
before(() => {
|
||||
esArchiverLoad('timeline');
|
||||
const rule = { ...newOverrideRule };
|
||||
|
||||
beforeEach(() => {
|
||||
createTimeline(newOverrideRule.timeline).then((response) => {
|
||||
rule.timeline.id = response.body.data.persistTimeline.timeline.savedObjectId;
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
esArchiverUnload('timeline');
|
||||
afterEach(() => {
|
||||
deleteTimeline(rule.timeline.id!);
|
||||
deleteRule();
|
||||
});
|
||||
|
||||
it('Creates and activates a new custom rule with override option', () => {
|
||||
|
@ -103,9 +109,9 @@ describe.skip('Detection rules, override', () => {
|
|||
goToManageAlertsDetectionRules();
|
||||
waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded();
|
||||
goToCreateNewRule();
|
||||
fillDefineCustomRuleWithImportedQueryAndContinue(newOverrideRule);
|
||||
fillAboutRuleWithOverrideAndContinue(newOverrideRule);
|
||||
fillScheduleRuleAndContinue(newOverrideRule);
|
||||
fillDefineCustomRuleWithImportedQueryAndContinue(rule);
|
||||
fillAboutRuleWithOverrideAndContinue(rule);
|
||||
fillScheduleRuleAndContinue(rule);
|
||||
createAndActivateRule();
|
||||
|
||||
cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)');
|
||||
|
@ -123,23 +129,23 @@ describe.skip('Detection rules, override', () => {
|
|||
cy.get(RULES_TABLE).then(($table) => {
|
||||
cy.wrap($table.find(RULES_ROW).length).should('eql', 1);
|
||||
});
|
||||
cy.get(RULE_NAME).should('have.text', newOverrideRule.name);
|
||||
cy.get(RISK_SCORE).should('have.text', newOverrideRule.riskScore);
|
||||
cy.get(SEVERITY).should('have.text', newOverrideRule.severity);
|
||||
cy.get(RULE_NAME).should('have.text', rule.name);
|
||||
cy.get(RISK_SCORE).should('have.text', rule.riskScore);
|
||||
cy.get(SEVERITY).should('have.text', rule.severity);
|
||||
cy.get(RULE_SWITCH).should('have.attr', 'aria-checked', 'true');
|
||||
|
||||
goToRuleDetails();
|
||||
|
||||
cy.get(RULE_NAME_HEADER).should('have.text', `${newOverrideRule.name}`);
|
||||
cy.get(ABOUT_RULE_DESCRIPTION).should('have.text', newOverrideRule.description);
|
||||
cy.get(RULE_NAME_HEADER).should('have.text', `${rule.name}`);
|
||||
cy.get(ABOUT_RULE_DESCRIPTION).should('have.text', rule.description);
|
||||
cy.get(ABOUT_DETAILS).within(() => {
|
||||
getDetails(SEVERITY_DETAILS).should('have.text', newOverrideRule.severity);
|
||||
getDetails(RISK_SCORE_DETAILS).should('have.text', newOverrideRule.riskScore);
|
||||
getDetails(SEVERITY_DETAILS).should('have.text', rule.severity);
|
||||
getDetails(RISK_SCORE_DETAILS).should('have.text', rule.riskScore);
|
||||
getDetails(RISK_SCORE_OVERRIDE_DETAILS).should(
|
||||
'have.text',
|
||||
`${newOverrideRule.riskOverride}signal.rule.risk_score`
|
||||
`${rule.riskOverride}signal.rule.risk_score`
|
||||
);
|
||||
getDetails(RULE_NAME_OVERRIDE_DETAILS).should('have.text', newOverrideRule.nameOverride);
|
||||
getDetails(RULE_NAME_OVERRIDE_DETAILS).should('have.text', rule.nameOverride);
|
||||
getDetails(REFERENCE_URLS_DETAILS).should((details) => {
|
||||
expect(removeExternalLinkText(details.text())).equal(expectedUrls);
|
||||
});
|
||||
|
@ -148,11 +154,11 @@ describe.skip('Detection rules, override', () => {
|
|||
expect(removeExternalLinkText(mitre.text())).equal(expectedMitre);
|
||||
});
|
||||
getDetails(TAGS_DETAILS).should('have.text', expectedTags);
|
||||
getDetails(TIMESTAMP_OVERRIDE_DETAILS).should('have.text', newOverrideRule.timestampOverride);
|
||||
getDetails(TIMESTAMP_OVERRIDE_DETAILS).should('have.text', rule.timestampOverride);
|
||||
cy.contains(DETAILS_TITLE, 'Severity override')
|
||||
.invoke('index', DETAILS_TITLE) // get index relative to other titles, not all siblings
|
||||
.then((severityOverrideIndex) => {
|
||||
newOverrideRule.severityOverride.forEach((severity, i) => {
|
||||
rule.severityOverride.forEach((severity, i) => {
|
||||
cy.get(DETAILS_DESCRIPTION)
|
||||
.eq(severityOverrideIndex + i)
|
||||
.should(
|
||||
|
@ -166,18 +172,18 @@ describe.skip('Detection rules, override', () => {
|
|||
cy.get(ABOUT_INVESTIGATION_NOTES).should('have.text', INVESTIGATION_NOTES_MARKDOWN);
|
||||
cy.get(DEFINITION_DETAILS).within(() => {
|
||||
getDetails(INDEX_PATTERNS_DETAILS).should('have.text', indexPatterns.join(''));
|
||||
getDetails(CUSTOM_QUERY_DETAILS).should('have.text', newOverrideRule.customQuery);
|
||||
getDetails(CUSTOM_QUERY_DETAILS).should('have.text', rule.customQuery);
|
||||
getDetails(RULE_TYPE_DETAILS).should('have.text', 'Query');
|
||||
getDetails(TIMELINE_TEMPLATE_DETAILS).should('have.text', 'None');
|
||||
});
|
||||
cy.get(SCHEDULE_DETAILS).within(() => {
|
||||
getDetails(RUNS_EVERY_DETAILS).should(
|
||||
'have.text',
|
||||
`${newOverrideRule.runsEvery.interval}${newOverrideRule.runsEvery.type}`
|
||||
`${rule.runsEvery.interval}${rule.runsEvery.type}`
|
||||
);
|
||||
getDetails(ADDITIONAL_LOOK_BACK_DETAILS).should(
|
||||
'have.text',
|
||||
`${newOverrideRule.lookBack.interval}${newOverrideRule.lookBack.type}`
|
||||
`${rule.lookBack.interval}${rule.lookBack.type}`
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import { formatMitreAttackDescription } from '../helpers/rules';
|
||||
import { indexPatterns, newThresholdRule } from '../objects/rule';
|
||||
|
||||
import {
|
||||
ALERT_RULE_METHOD,
|
||||
ALERT_RULE_NAME,
|
||||
|
@ -64,6 +65,7 @@ import {
|
|||
waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded,
|
||||
waitForRulesToBeLoaded,
|
||||
} from '../tasks/alerts_detection_rules';
|
||||
import { createTimeline, deleteTimeline } from '../tasks/api_calls/timelines';
|
||||
import {
|
||||
createAndActivateRule,
|
||||
fillAboutRuleAndContinue,
|
||||
|
@ -73,24 +75,27 @@ import {
|
|||
waitForAlertsToPopulate,
|
||||
waitForTheRuleToBeExecuted,
|
||||
} from '../tasks/create_new_rule';
|
||||
import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver';
|
||||
import { loginAndWaitForPageWithoutDateRange } from '../tasks/login';
|
||||
|
||||
import { DETECTIONS_URL } from '../urls/navigation';
|
||||
|
||||
const expectedUrls = newThresholdRule.referenceUrls.join('');
|
||||
const expectedFalsePositives = newThresholdRule.falsePositivesExamples.join('');
|
||||
const expectedTags = newThresholdRule.tags.join('');
|
||||
const expectedMitre = formatMitreAttackDescription(newThresholdRule.mitre);
|
||||
|
||||
describe('Detection rules, threshold', () => {
|
||||
before(() => {
|
||||
esArchiverLoad('timeline');
|
||||
const expectedUrls = newThresholdRule.referenceUrls.join('');
|
||||
const expectedFalsePositives = newThresholdRule.falsePositivesExamples.join('');
|
||||
const expectedTags = newThresholdRule.tags.join('');
|
||||
const expectedMitre = formatMitreAttackDescription(newThresholdRule.mitre);
|
||||
|
||||
const rule = { ...newThresholdRule };
|
||||
|
||||
beforeEach(() => {
|
||||
createTimeline(newThresholdRule.timeline).then((response) => {
|
||||
rule.timeline.id = response.body.data.persistTimeline.timeline.savedObjectId;
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
afterEach(() => {
|
||||
deleteTimeline(rule.timeline.id!);
|
||||
deleteRule();
|
||||
esArchiverUnload('timeline');
|
||||
});
|
||||
|
||||
it('Creates and activates a new threshold rule', () => {
|
||||
|
@ -101,9 +106,9 @@ describe('Detection rules, threshold', () => {
|
|||
waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded();
|
||||
goToCreateNewRule();
|
||||
selectThresholdRuleType();
|
||||
fillDefineThresholdRuleAndContinue(newThresholdRule);
|
||||
fillAboutRuleAndContinue(newThresholdRule);
|
||||
fillScheduleRuleAndContinue(newThresholdRule);
|
||||
fillDefineThresholdRuleAndContinue(rule);
|
||||
fillAboutRuleAndContinue(rule);
|
||||
fillScheduleRuleAndContinue(rule);
|
||||
createAndActivateRule();
|
||||
|
||||
cy.get(CUSTOM_RULES_BTN).should('have.text', 'Custom rules (1)');
|
||||
|
@ -121,18 +126,18 @@ describe('Detection rules, threshold', () => {
|
|||
cy.get(RULES_TABLE).then(($table) => {
|
||||
cy.wrap($table.find(RULES_ROW).length).should('eql', 1);
|
||||
});
|
||||
cy.get(RULE_NAME).should('have.text', newThresholdRule.name);
|
||||
cy.get(RISK_SCORE).should('have.text', newThresholdRule.riskScore);
|
||||
cy.get(SEVERITY).should('have.text', newThresholdRule.severity);
|
||||
cy.get(RULE_NAME).should('have.text', rule.name);
|
||||
cy.get(RISK_SCORE).should('have.text', rule.riskScore);
|
||||
cy.get(SEVERITY).should('have.text', rule.severity);
|
||||
cy.get(RULE_SWITCH).should('have.attr', 'aria-checked', 'true');
|
||||
|
||||
goToRuleDetails();
|
||||
|
||||
cy.get(RULE_NAME_HEADER).should('have.text', `${newThresholdRule.name}`);
|
||||
cy.get(ABOUT_RULE_DESCRIPTION).should('have.text', newThresholdRule.description);
|
||||
cy.get(RULE_NAME_HEADER).should('have.text', `${rule.name}`);
|
||||
cy.get(ABOUT_RULE_DESCRIPTION).should('have.text', rule.description);
|
||||
cy.get(ABOUT_DETAILS).within(() => {
|
||||
getDetails(SEVERITY_DETAILS).should('have.text', newThresholdRule.severity);
|
||||
getDetails(RISK_SCORE_DETAILS).should('have.text', newThresholdRule.riskScore);
|
||||
getDetails(SEVERITY_DETAILS).should('have.text', rule.severity);
|
||||
getDetails(RISK_SCORE_DETAILS).should('have.text', rule.riskScore);
|
||||
getDetails(REFERENCE_URLS_DETAILS).should((details) => {
|
||||
expect(removeExternalLinkText(details.text())).equal(expectedUrls);
|
||||
});
|
||||
|
@ -146,22 +151,22 @@ describe('Detection rules, threshold', () => {
|
|||
cy.get(ABOUT_INVESTIGATION_NOTES).should('have.text', INVESTIGATION_NOTES_MARKDOWN);
|
||||
cy.get(DEFINITION_DETAILS).within(() => {
|
||||
getDetails(INDEX_PATTERNS_DETAILS).should('have.text', indexPatterns.join(''));
|
||||
getDetails(CUSTOM_QUERY_DETAILS).should('have.text', newThresholdRule.customQuery);
|
||||
getDetails(CUSTOM_QUERY_DETAILS).should('have.text', rule.customQuery);
|
||||
getDetails(RULE_TYPE_DETAILS).should('have.text', 'Threshold');
|
||||
getDetails(TIMELINE_TEMPLATE_DETAILS).should('have.text', 'None');
|
||||
getDetails(THRESHOLD_DETAILS).should(
|
||||
'have.text',
|
||||
`Results aggregated by ${newThresholdRule.thresholdField} >= ${newThresholdRule.threshold}`
|
||||
`Results aggregated by ${rule.thresholdField} >= ${rule.threshold}`
|
||||
);
|
||||
});
|
||||
cy.get(SCHEDULE_DETAILS).within(() => {
|
||||
getDetails(RUNS_EVERY_DETAILS).should(
|
||||
'have.text',
|
||||
`${newThresholdRule.runsEvery.interval}${newThresholdRule.runsEvery.type}`
|
||||
`${rule.runsEvery.interval}${rule.runsEvery.type}`
|
||||
);
|
||||
getDetails(ADDITIONAL_LOOK_BACK_DETAILS).should(
|
||||
'have.text',
|
||||
`${newThresholdRule.lookBack.interval}${newThresholdRule.lookBack.type}`
|
||||
`${rule.lookBack.interval}${rule.lookBack.type}`
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -169,12 +174,10 @@ describe('Detection rules, threshold', () => {
|
|||
waitForAlertsToPopulate();
|
||||
|
||||
cy.get(NUMBER_OF_ALERTS).invoke('text').then(parseFloat).should('be.below', 100);
|
||||
cy.get(ALERT_RULE_NAME).first().should('have.text', newThresholdRule.name);
|
||||
cy.get(ALERT_RULE_NAME).first().should('have.text', rule.name);
|
||||
cy.get(ALERT_RULE_VERSION).first().should('have.text', '1');
|
||||
cy.get(ALERT_RULE_METHOD).first().should('have.text', 'threshold');
|
||||
cy.get(ALERT_RULE_SEVERITY)
|
||||
.first()
|
||||
.should('have.text', newThresholdRule.severity.toLowerCase());
|
||||
cy.get(ALERT_RULE_RISK_SCORE).first().should('have.text', newThresholdRule.riskScore);
|
||||
cy.get(ALERT_RULE_SEVERITY).first().should('have.text', rule.severity.toLowerCase());
|
||||
cy.get(ALERT_RULE_RISK_SCORE).first().should('have.text', rule.riskScore);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -38,7 +38,8 @@ import {
|
|||
import { TIMELINE_DESCRIPTION, TIMELINE_QUERY, TIMELINE_TITLE } from '../screens/timeline';
|
||||
|
||||
import { goToCaseDetails, goToCreateNewCase } from '../tasks/all_cases';
|
||||
import { openCaseTimeline } from '../tasks/case_details';
|
||||
import { createTimeline, deleteTimeline } from '../tasks/api_calls/timelines';
|
||||
import { deleteCase, openCaseTimeline } from '../tasks/case_details';
|
||||
import {
|
||||
attachTimeline,
|
||||
backToCases,
|
||||
|
@ -46,24 +47,30 @@ import {
|
|||
fillCasesMandatoryfields,
|
||||
} from '../tasks/create_new_case';
|
||||
import { loginAndWaitForPageWithoutDateRange } from '../tasks/login';
|
||||
import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver';
|
||||
import { closeTimeline } from '../tasks/timeline';
|
||||
|
||||
import { CASES_URL } from '../urls/navigation';
|
||||
|
||||
describe('Cases', () => {
|
||||
const mycase = { ...case1 };
|
||||
|
||||
before(() => {
|
||||
esArchiverLoad('timeline');
|
||||
createTimeline(case1.timeline).then((response) => {
|
||||
mycase.timeline.id = response.body.data.persistTimeline.timeline.savedObjectId;
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
esArchiverUnload('timeline');
|
||||
closeTimeline();
|
||||
deleteTimeline(mycase.timeline.id!);
|
||||
deleteCase();
|
||||
});
|
||||
|
||||
it('Creates a new case with timeline and opens the timeline', () => {
|
||||
loginAndWaitForPageWithoutDateRange(CASES_URL);
|
||||
goToCreateNewCase();
|
||||
fillCasesMandatoryfields(case1);
|
||||
attachTimeline(case1);
|
||||
fillCasesMandatoryfields(mycase);
|
||||
attachTimeline(mycase);
|
||||
createCase();
|
||||
backToCases();
|
||||
|
||||
|
@ -74,9 +81,9 @@ describe('Cases', () => {
|
|||
cy.get(ALL_CASES_OPEN_CASES_COUNT).should('have.text', 'Open (1)');
|
||||
cy.get(ALL_CASES_REPORTERS_COUNT).should('have.text', 'Reporter1');
|
||||
cy.get(ALL_CASES_TAGS_COUNT).should('have.text', 'Tags2');
|
||||
cy.get(ALL_CASES_NAME).should('have.text', case1.name);
|
||||
cy.get(ALL_CASES_REPORTER).should('have.text', case1.reporter);
|
||||
case1.tags.forEach((tag, index) => {
|
||||
cy.get(ALL_CASES_NAME).should('have.text', mycase.name);
|
||||
cy.get(ALL_CASES_REPORTER).should('have.text', mycase.reporter);
|
||||
mycase.tags.forEach((tag, index) => {
|
||||
cy.get(ALL_CASES_TAGS(index)).should('have.text', tag);
|
||||
});
|
||||
cy.get(ALL_CASES_COMMENTS_COUNT).should('have.text', '0');
|
||||
|
@ -87,24 +94,24 @@ describe('Cases', () => {
|
|||
|
||||
goToCaseDetails();
|
||||
|
||||
const expectedTags = case1.tags.join('');
|
||||
cy.get(CASE_DETAILS_PAGE_TITLE).should('have.text', case1.name);
|
||||
const expectedTags = mycase.tags.join('');
|
||||
cy.get(CASE_DETAILS_PAGE_TITLE).should('have.text', mycase.name);
|
||||
cy.get(CASE_DETAILS_STATUS).should('have.text', 'Open');
|
||||
cy.get(CASE_DETAILS_USER_ACTION_DESCRIPTION_USERNAME).should('have.text', case1.reporter);
|
||||
cy.get(CASE_DETAILS_USER_ACTION_DESCRIPTION_USERNAME).should('have.text', mycase.reporter);
|
||||
cy.get(CASE_DETAILS_USER_ACTION_DESCRIPTION_EVENT).should('have.text', 'added description');
|
||||
cy.get(CASE_DETAILS_DESCRIPTION).should(
|
||||
'have.text',
|
||||
`${case1.description} ${case1.timeline.title}`
|
||||
`${mycase.description} ${mycase.timeline.title}`
|
||||
);
|
||||
cy.get(CASE_DETAILS_USERNAMES).eq(REPORTER).should('have.text', case1.reporter);
|
||||
cy.get(CASE_DETAILS_USERNAMES).eq(PARTICIPANTS).should('have.text', case1.reporter);
|
||||
cy.get(CASE_DETAILS_USERNAMES).eq(REPORTER).should('have.text', mycase.reporter);
|
||||
cy.get(CASE_DETAILS_USERNAMES).eq(PARTICIPANTS).should('have.text', mycase.reporter);
|
||||
cy.get(CASE_DETAILS_TAGS).should('have.text', expectedTags);
|
||||
cy.get(CASE_DETAILS_PUSH_TO_EXTERNAL_SERVICE_BTN).should('have.attr', 'disabled');
|
||||
|
||||
openCaseTimeline();
|
||||
|
||||
cy.get(TIMELINE_TITLE).contains(case1.timeline.title);
|
||||
cy.get(TIMELINE_DESCRIPTION).contains(case1.timeline.description);
|
||||
cy.get(TIMELINE_QUERY).invoke('text').should('eq', case1.timeline.query);
|
||||
cy.get(TIMELINE_TITLE).contains(mycase.timeline.title);
|
||||
cy.get(TIMELINE_DESCRIPTION).contains(mycase.timeline.description);
|
||||
cy.get(TIMELINE_QUERY).invoke('text').should('eq', mycase.timeline.query);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -13,40 +13,47 @@ import {
|
|||
} from '../tasks/timeline';
|
||||
import { DESCRIPTION_INPUT, ADD_COMMENT_INPUT } from '../screens/create_new_case';
|
||||
import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver';
|
||||
import { caseTimeline, TIMELINE_CASE_ID } from '../objects/case';
|
||||
import { TIMELINE_CASE_ID } from '../objects/case';
|
||||
import { caseTimeline, timeline } from '../objects/timeline';
|
||||
import { createTimeline, deleteTimeline } from '../tasks/api_calls/timelines';
|
||||
|
||||
describe('attach timeline to case', () => {
|
||||
beforeEach(() => {
|
||||
loginAndWaitForTimeline(caseTimeline.id);
|
||||
});
|
||||
const myTimeline = { ...timeline };
|
||||
|
||||
context('without cases created', () => {
|
||||
before(() => {
|
||||
esArchiverLoad('timeline');
|
||||
createTimeline(timeline).then((response) => {
|
||||
myTimeline.id = response.body.data.persistTimeline.timeline.savedObjectId;
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
esArchiverUnload('timeline');
|
||||
deleteTimeline(myTimeline.id!);
|
||||
});
|
||||
|
||||
it('attach timeline to a new case', () => {
|
||||
loginAndWaitForTimeline(myTimeline.id!);
|
||||
attachTimelineToNewCase();
|
||||
|
||||
cy.location('origin').then((origin) => {
|
||||
cy.get(DESCRIPTION_INPUT).should(
|
||||
'have.text',
|
||||
`[${caseTimeline.title}](${origin}/app/security/timelines?timeline=(id:%27${caseTimeline.id}%27,isOpen:!t))`
|
||||
`[${myTimeline.title}](${origin}/app/security/timelines?timeline=(id:%27${myTimeline.id}%27,isOpen:!t))`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('attach timeline to an existing case with no case', () => {
|
||||
loginAndWaitForTimeline(myTimeline.id!);
|
||||
attachTimelineToExistingCase();
|
||||
addNewCase();
|
||||
|
||||
cy.location('origin').then((origin) => {
|
||||
cy.get(DESCRIPTION_INPUT).should(
|
||||
'have.text',
|
||||
`[${caseTimeline.title}](${origin}/app/security/timelines?timeline=(id:%27${caseTimeline.id}%27,isOpen:!t))`
|
||||
`[${
|
||||
myTimeline.title
|
||||
}](${origin}/app/security/timelines?timeline=(id:%27${myTimeline.id!}%27,isOpen:!t))`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -62,13 +69,16 @@ describe('attach timeline to case', () => {
|
|||
});
|
||||
|
||||
it('attach timeline to an existing case', () => {
|
||||
loginAndWaitForTimeline(caseTimeline.id!);
|
||||
attachTimelineToExistingCase();
|
||||
selectCase(TIMELINE_CASE_ID);
|
||||
|
||||
cy.location('origin').then((origin) => {
|
||||
cy.get(ADD_COMMENT_INPUT).should(
|
||||
'have.text',
|
||||
`[${caseTimeline.title}](${origin}/app/security/timelines?timeline=(id:%27${caseTimeline.id}%27,isOpen:!t))`
|
||||
`[${
|
||||
caseTimeline.title
|
||||
}](${origin}/app/security/timelines?timeline=(id:%27${caseTimeline.id!}%27,isOpen:!t))`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -24,6 +24,7 @@ import {
|
|||
TIMELINES_NOTES_COUNT,
|
||||
TIMELINES_FAVORITE,
|
||||
} from '../screens/timelines';
|
||||
import { deleteTimeline } from '../tasks/api_calls/timelines';
|
||||
|
||||
import { loginAndWaitForPage } from '../tasks/login';
|
||||
import { openTimelineUsingToggle } from '../tasks/security_main';
|
||||
|
@ -44,8 +45,13 @@ import { openTimeline } from '../tasks/timelines';
|
|||
|
||||
import { OVERVIEW_URL } from '../urls/navigation';
|
||||
|
||||
// FLAKY: https://github.com/elastic/kibana/issues/79389
|
||||
describe.skip('Timelines', () => {
|
||||
describe('Timelines', () => {
|
||||
let timelineId: string;
|
||||
|
||||
after(() => {
|
||||
deleteTimeline(timelineId);
|
||||
});
|
||||
|
||||
it('Creates a timeline', () => {
|
||||
cy.intercept('PATCH', '/api/timeline').as('timeline');
|
||||
|
||||
|
@ -61,7 +67,7 @@ describe.skip('Timelines', () => {
|
|||
addNameToTimeline(timeline.title);
|
||||
|
||||
cy.wait('@timeline').then(({ response }) => {
|
||||
const timelineId = response!.body.data.persistTimeline.timeline.savedObjectId;
|
||||
timelineId = response!.body.data.persistTimeline.timeline.savedObjectId;
|
||||
|
||||
addDescriptionToTimeline(timeline.description);
|
||||
addNotesToTimeline(timeline.notes);
|
||||
|
@ -82,7 +88,7 @@ describe.skip('Timelines', () => {
|
|||
cy.get(FAVORITE_TIMELINE).should('exist');
|
||||
cy.get(TIMELINE_TITLE).should('have.text', timeline.title);
|
||||
cy.get(TIMELINE_DESCRIPTION).should('have.text', timeline.description);
|
||||
cy.get(TIMELINE_QUERY).should('have.text', timeline.query);
|
||||
cy.get(TIMELINE_QUERY).should('have.text', `${timeline.query} `);
|
||||
// Comments this assertion until we agreed what to do with the filters.
|
||||
// cy.get(TIMELINE_FILTER(timeline.filter)).should('exist');
|
||||
// cy.get(NOTES_COUNT).should('have.text', '1');
|
||||
|
|
|
@ -24,9 +24,7 @@ import { closeTimeline, createNewTimeline } from '../tasks/timeline';
|
|||
|
||||
import { HOSTS_URL } from '../urls/navigation';
|
||||
|
||||
// FLAKY: https://github.com/elastic/kibana/issues/85098
|
||||
// FLAKY: https://github.com/elastic/kibana/issues/62060
|
||||
describe.skip('timeline data providers', () => {
|
||||
describe('timeline data providers', () => {
|
||||
before(() => {
|
||||
loginAndWaitForPage(HOSTS_URL);
|
||||
waitForAllHostsToBeLoaded();
|
||||
|
|
|
@ -5,44 +5,40 @@
|
|||
*/
|
||||
|
||||
import { exportTimeline } from '../tasks/timelines';
|
||||
import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver';
|
||||
import { loginAndWaitForPageWithoutDateRange } from '../tasks/login';
|
||||
import { timeline as timelineTemplate } from '../objects/timeline';
|
||||
import {
|
||||
expectedExportedTimelineTemplate,
|
||||
timeline as timelineTemplate,
|
||||
} from '../objects/timeline';
|
||||
|
||||
import { TIMELINE_TEMPLATES_URL } from '../urls/navigation';
|
||||
import { addNameToTimeline, closeTimeline, createNewTimelineTemplate } from '../tasks/timeline';
|
||||
import {
|
||||
createTimelineTemplate,
|
||||
deleteTimeline as deleteTimelineTemplate,
|
||||
} from '../tasks/api_calls/timelines';
|
||||
|
||||
describe('Export timelines', () => {
|
||||
let templateResponse: Cypress.Response;
|
||||
let templateId: string;
|
||||
|
||||
before(() => {
|
||||
esArchiverLoad('timeline');
|
||||
cy.intercept('PATCH', '/api/timeline').as('timeline');
|
||||
cy.intercept('POST', '/api/timeline/_export?file_name=timelines_export.ndjson').as('export');
|
||||
cy.intercept('POST', 'api/timeline/_export?file_name=timelines_export.ndjson').as('export');
|
||||
createTimelineTemplate(timelineTemplate).then((response) => {
|
||||
templateResponse = response;
|
||||
templateId = response.body.data.persistTimeline.timeline.savedObjectId;
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
esArchiverUnload('timeline');
|
||||
deleteTimelineTemplate(templateId);
|
||||
});
|
||||
|
||||
it('Exports a custom timeline template', () => {
|
||||
loginAndWaitForPageWithoutDateRange(TIMELINE_TEMPLATES_URL);
|
||||
createNewTimelineTemplate();
|
||||
addNameToTimeline(timelineTemplate.title);
|
||||
closeTimeline();
|
||||
exportTimeline(templateId!);
|
||||
|
||||
cy.wait('@timeline').then(({ response }) => {
|
||||
const {
|
||||
savedObjectId: timelineId,
|
||||
templateTimelineId,
|
||||
} = response!.body.data.persistTimeline.timeline;
|
||||
|
||||
exportTimeline(timelineId);
|
||||
|
||||
cy.wait('@export').then(({ response: exportResponse }) => {
|
||||
cy.wrap(JSON.parse(exportResponse!.body as string).templateTimelineId).should(
|
||||
'eql',
|
||||
templateTimelineId
|
||||
);
|
||||
});
|
||||
cy.wait('@export').then(({ response }) => {
|
||||
cy.wrap(response!.body).should('eql', expectedExportedTimelineTemplate(templateResponse));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,14 +4,15 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { timeline } from '../objects/timeline';
|
||||
import {
|
||||
ID_HEADER_FIELD,
|
||||
ID_TOGGLE_FIELD,
|
||||
TIMESTAMP_HEADER_FIELD,
|
||||
TIMESTAMP_TOGGLE_FIELD,
|
||||
} from '../screens/timeline';
|
||||
import { createTimeline, deleteTimeline } from '../tasks/api_calls/timelines';
|
||||
|
||||
import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver';
|
||||
import { loginAndWaitForPage } from '../tasks/login';
|
||||
import { openTimelineUsingToggle } from '../tasks/security_main';
|
||||
import {
|
||||
|
@ -27,13 +28,17 @@ import {
|
|||
import { HOSTS_URL } from '../urls/navigation';
|
||||
|
||||
describe('toggle column in timeline', () => {
|
||||
let timelineId: string;
|
||||
before(() => {
|
||||
esArchiverLoad('timeline');
|
||||
loginAndWaitForPage(HOSTS_URL);
|
||||
cy.intercept('POST', '/api/timeline/_export?file_name=timelines_export.ndjson').as('export');
|
||||
createTimeline(timeline).then((response) => {
|
||||
timelineId = response.body.data.persistTimeline.timeline.savedObjectId;
|
||||
loginAndWaitForPage(HOSTS_URL);
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
esArchiverUnload('timeline');
|
||||
deleteTimeline(timelineId);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
|
@ -5,36 +5,35 @@
|
|||
*/
|
||||
|
||||
import { exportTimeline, waitForTimelinesPanelToBeLoaded } from '../tasks/timelines';
|
||||
import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver';
|
||||
import { loginAndWaitForPageWithoutDateRange } from '../tasks/login';
|
||||
|
||||
import { TIMELINES_URL } from '../urls/navigation';
|
||||
|
||||
const EXPECTED_EXPORTED_TIMELINE_PATH = 'cypress/test_files/expected_timelines_export.ndjson';
|
||||
import { createTimeline, deleteTimeline } from '../tasks/api_calls/timelines';
|
||||
import { expectedExportedTimeline, timeline } from '../objects/timeline';
|
||||
|
||||
describe('Export timelines', () => {
|
||||
let timelineResponse: Cypress.Response;
|
||||
let timelineId: string;
|
||||
before(() => {
|
||||
esArchiverLoad('timeline');
|
||||
cy.intercept('POST', '/api/timeline/_export?file_name=timelines_export.ndjson').as('export');
|
||||
createTimeline(timeline).then((response) => {
|
||||
timelineResponse = response;
|
||||
timelineId = response.body.data.persistTimeline.timeline.savedObjectId;
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
esArchiverUnload('timeline');
|
||||
deleteTimeline(timelineId);
|
||||
});
|
||||
|
||||
it('Exports a custom timeline', () => {
|
||||
loginAndWaitForPageWithoutDateRange(TIMELINES_URL);
|
||||
waitForTimelinesPanelToBeLoaded();
|
||||
exportTimeline(timelineId);
|
||||
|
||||
cy.readFile(EXPECTED_EXPORTED_TIMELINE_PATH).then(($expectedExportedJson) => {
|
||||
const parsedJson = JSON.parse($expectedExportedJson);
|
||||
const timelineId = parsedJson.savedObjectId;
|
||||
exportTimeline(timelineId);
|
||||
|
||||
cy.wait('@export').then(({ response }) => {
|
||||
cy.wrap(response!.statusCode).should('eql', 200);
|
||||
cy.wrap(response!.body).should('eql', $expectedExportedJson);
|
||||
});
|
||||
cy.wait('@export').then(({ response }) => {
|
||||
cy.wrap(response!.statusCode).should('eql', 200);
|
||||
cy.wrap(response!.body).should('eql', expectedExportedTimeline(timelineResponse));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -48,8 +48,7 @@ const ABSOLUTE_DATE = {
|
|||
startTimeTimeline: '2019-08-02T20:03:29.186Z',
|
||||
};
|
||||
|
||||
// SKIP: https://github.com/elastic/kibana/issues/85289
|
||||
describe.skip('url state', () => {
|
||||
describe('url state', () => {
|
||||
it('sets the global start and end dates from the url', () => {
|
||||
loginAndWaitForPageWithoutDateRange(ABSOLUTE_DATE_RANGE.url);
|
||||
cy.get(DATE_PICKER_START_DATE_POPOVER_BUTTON).should(
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { Timeline, TimelineWithId } from './timeline';
|
||||
import { CompleteTimeline, timeline } from './timeline';
|
||||
|
||||
export interface TestCase {
|
||||
name: string;
|
||||
tags: string[];
|
||||
description: string;
|
||||
timeline: Timeline;
|
||||
timeline: CompleteTimeline;
|
||||
reporter: string;
|
||||
}
|
||||
|
||||
|
@ -38,18 +38,11 @@ export interface IbmResilientConnectorOptions {
|
|||
incidentTypes: string[];
|
||||
}
|
||||
|
||||
export const caseTimeline: TimelineWithId = {
|
||||
title: 'SIEM test',
|
||||
description: 'description',
|
||||
query: 'host.name:*',
|
||||
id: '0162c130-78be-11ea-9718-118a926974a4',
|
||||
};
|
||||
|
||||
export const case1: TestCase = {
|
||||
name: 'This is the title of the case',
|
||||
tags: ['Tag1', 'Tag2'],
|
||||
description: 'This is the case description',
|
||||
timeline: caseTimeline,
|
||||
timeline,
|
||||
reporter: 'elastic',
|
||||
};
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
*/
|
||||
|
||||
/* eslint-disable @kbn/eslint/no-restricted-paths */
|
||||
import { mockThreatData } from '../../public/detections/mitre/mitre_tactics_techniques';
|
||||
import { rawRules } from '../../server/lib/detection_engine/rules/prepackaged_rules/index';
|
||||
/* eslint-enable @kbn/eslint/no-restricted-paths */
|
||||
import { mockThreatData } from '../../public/detections/mitre/mitre_tactics_techniques';
|
||||
import { CompleteTimeline, timeline } from './timeline';
|
||||
|
||||
export const totalNumberOfPrebuiltRules = rawRules.length;
|
||||
|
||||
|
@ -40,7 +40,7 @@ export interface CustomRule {
|
|||
customQuery?: string;
|
||||
name: string;
|
||||
description: string;
|
||||
index: string[];
|
||||
index?: string[];
|
||||
interval?: string;
|
||||
severity: string;
|
||||
riskScore: string;
|
||||
|
@ -50,9 +50,9 @@ export interface CustomRule {
|
|||
falsePositivesExamples: string[];
|
||||
mitre: Mitre[];
|
||||
note: string;
|
||||
timelineId?: string;
|
||||
runsEvery: Interval;
|
||||
lookBack: Interval;
|
||||
timeline: CompleteTimeline;
|
||||
}
|
||||
|
||||
export interface ThresholdRule extends CustomRule {
|
||||
|
@ -159,7 +159,7 @@ const lookBack: Interval = {
|
|||
};
|
||||
|
||||
export const newRule: CustomRule = {
|
||||
customQuery: 'host.name:*',
|
||||
customQuery: 'host.name: *',
|
||||
index: indexPatterns,
|
||||
name: 'New Rule Test',
|
||||
description: 'The new rule description.',
|
||||
|
@ -170,9 +170,9 @@ export const newRule: CustomRule = {
|
|||
falsePositivesExamples: ['False1', 'False2'],
|
||||
mitre: [mitre1, mitre2],
|
||||
note: '# test markdown',
|
||||
timelineId: '0162c130-78be-11ea-9718-118a926974a4',
|
||||
runsEvery,
|
||||
lookBack,
|
||||
timeline,
|
||||
};
|
||||
|
||||
export const existingRule: CustomRule = {
|
||||
|
@ -195,13 +195,13 @@ export const existingRule: CustomRule = {
|
|||
falsePositivesExamples: [],
|
||||
mitre: [],
|
||||
note: 'This is my note',
|
||||
timelineId: '',
|
||||
runsEvery,
|
||||
lookBack,
|
||||
timeline,
|
||||
};
|
||||
|
||||
export const newOverrideRule: OverrideRule = {
|
||||
customQuery: 'host.name:*',
|
||||
customQuery: 'host.name: *',
|
||||
index: indexPatterns,
|
||||
name: 'New Rule Test',
|
||||
description: 'The new rule description.',
|
||||
|
@ -212,17 +212,17 @@ export const newOverrideRule: OverrideRule = {
|
|||
falsePositivesExamples: ['False1', 'False2'],
|
||||
mitre: [mitre1, mitre2],
|
||||
note: '# test markdown',
|
||||
timelineId: '0162c130-78be-11ea-9718-118a926974a4',
|
||||
severityOverride: [severityOverride1, severityOverride2, severityOverride3, severityOverride4],
|
||||
riskOverride: 'destination.port',
|
||||
nameOverride: 'agent.type',
|
||||
timestampOverride: '@timestamp',
|
||||
runsEvery,
|
||||
lookBack,
|
||||
timeline,
|
||||
};
|
||||
|
||||
export const newThresholdRule: ThresholdRule = {
|
||||
customQuery: 'host.name:*',
|
||||
customQuery: 'host.name: *',
|
||||
index: indexPatterns,
|
||||
name: 'New Rule Test',
|
||||
description: 'The new rule description.',
|
||||
|
@ -233,11 +233,11 @@ export const newThresholdRule: ThresholdRule = {
|
|||
falsePositivesExamples: ['False1', 'False2'],
|
||||
mitre: [mitre1, mitre2],
|
||||
note: '# test markdown',
|
||||
timelineId: '0162c130-78be-11ea-9718-118a926974a4',
|
||||
thresholdField: 'host.name',
|
||||
threshold: '10',
|
||||
runsEvery,
|
||||
lookBack,
|
||||
timeline,
|
||||
};
|
||||
|
||||
export const machineLearningRule: MachineLearningRule = {
|
||||
|
@ -268,9 +268,9 @@ export const eqlRule: CustomRule = {
|
|||
falsePositivesExamples: ['False1', 'False2'],
|
||||
mitre: [mitre1, mitre2],
|
||||
note: '# test markdown',
|
||||
timelineId: '0162c130-78be-11ea-9718-118a926974a4',
|
||||
runsEvery,
|
||||
lookBack,
|
||||
timeline,
|
||||
};
|
||||
|
||||
export const eqlSequenceRule: CustomRule = {
|
||||
|
@ -288,9 +288,9 @@ export const eqlSequenceRule: CustomRule = {
|
|||
falsePositivesExamples: ['False1', 'False2'],
|
||||
mitre: [mitre1, mitre2],
|
||||
note: '# test markdown',
|
||||
timelineId: '0162c130-78be-11ea-9718-118a926974a4',
|
||||
runsEvery,
|
||||
lookBack,
|
||||
timeline,
|
||||
};
|
||||
|
||||
export const newThreatIndicatorRule: ThreatIndicatorRule = {
|
||||
|
@ -309,6 +309,7 @@ export const newThreatIndicatorRule: ThreatIndicatorRule = {
|
|||
indicatorIndexPattern: ['threat-indicator-*'],
|
||||
indicatorMapping: 'agent.id',
|
||||
indicatorIndexField: 'agent.threat',
|
||||
timeline,
|
||||
};
|
||||
|
||||
export const severitiesOverride = ['Low', 'Medium', 'High', 'Critical'];
|
||||
|
@ -319,3 +320,9 @@ export const editedRule = {
|
|||
description: 'Edited Rule description',
|
||||
tags: [...existingRule.tags, 'edited'],
|
||||
};
|
||||
|
||||
export const expectedExportedRule = (ruleResponse: Cypress.Response) => {
|
||||
const jsonrule = ruleResponse.body;
|
||||
|
||||
return `{"author":[],"actions":[],"created_at":"${jsonrule.created_at}","updated_at":"${jsonrule.updated_at}","created_by":"elastic","description":"${jsonrule.description}","enabled":false,"false_positives":[],"from":"now-17520h","id":"${jsonrule.id}","immutable":false,"index":["exceptions-*"],"interval":"10s","rule_id":"rule_testing","language":"kuery","output_index":".siem-signals-default","max_signals":100,"risk_score":${jsonrule.risk_score},"risk_score_mapping":[],"name":"${jsonrule.name}","query":"${jsonrule.query}","references":[],"severity":"${jsonrule.severity}","severity_mapping":[],"updated_by":"elastic","tags":[],"to":"now","type":"query","threat":[],"throttle":"no_actions","version":1,"exceptions_list":[]}\n{"exported_count":1,"missing_rules":[],"missing_rules_count":0}\n`;
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@ export interface Timeline {
|
|||
title: string;
|
||||
description: string;
|
||||
query: string;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export interface CompleteTimeline extends Timeline {
|
||||
|
@ -21,10 +22,6 @@ export interface TimelineFilter {
|
|||
value?: string;
|
||||
}
|
||||
|
||||
export interface TimelineWithId extends Timeline {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export const filter: TimelineFilter = {
|
||||
field: 'host.name',
|
||||
operator: 'exists',
|
||||
|
@ -33,7 +30,27 @@ export const filter: TimelineFilter = {
|
|||
export const timeline: CompleteTimeline = {
|
||||
title: 'Security Timeline',
|
||||
description: 'This is the best timeline',
|
||||
query: 'host.name: * ',
|
||||
query: 'host.name: *',
|
||||
notes: 'Yes, the best timeline',
|
||||
filter,
|
||||
};
|
||||
|
||||
export const caseTimeline: Timeline = {
|
||||
title: 'SIEM test',
|
||||
description: 'description',
|
||||
query: 'host.name: *',
|
||||
id: '0162c130-78be-11ea-9718-118a926974a4',
|
||||
};
|
||||
|
||||
export const expectedExportedTimelineTemplate = (templateResponse: Cypress.Response) => {
|
||||
const timelineTemplateBody = templateResponse.body.data.persistTimeline.timeline;
|
||||
|
||||
return `{"savedObjectId":"${timelineTemplateBody.savedObjectId}","version":"${timelineTemplateBody.version}","columns":[{"id":"@timestamp"},{"id":"user.name"},{"id":"event.category"},{"id":"event.action"},{"id":"host.name"}],"kqlMode":"filter","kqlQuery":{"filterQuery":{"kuery":{"expression":"${timelineTemplateBody.kqlQuery.filterQuery.kuery.expression}","kind":"kuery"}}},"dateRange":{"start":"${timelineTemplateBody.dateRange.start}","end":"${timelineTemplateBody.dateRange.end}"},"description":"${timelineTemplateBody.description}","title":"${timelineTemplateBody.title}","templateTimelineVersion":1,"timelineType":"template","created":${timelineTemplateBody.created},"createdBy":"elastic","updated":${timelineTemplateBody.updated},"updatedBy":"elastic","sort":[],"eventNotes":[],"globalNotes":[],"pinnedEventIds":[]}
|
||||
`;
|
||||
};
|
||||
|
||||
export const expectedExportedTimeline = (timelineResponse: Cypress.Response) => {
|
||||
const timelineBody = timelineResponse.body.data.persistTimeline.timeline;
|
||||
|
||||
return `{"savedObjectId":"${timelineBody.savedObjectId}","version":"${timelineBody.version}","columns":[{"id":"@timestamp"},{"id":"user.name"},{"id":"event.category"},{"id":"event.action"},{"id":"host.name"}],"kqlMode":"filter","kqlQuery":{"filterQuery":{"kuery":{"expression":"${timelineBody.kqlQuery.filterQuery.kuery.expression}","kind":"kuery"}}},"dateRange":{"start":"${timelineBody.dateRange.start}","end":"${timelineBody.dateRange.end}"},"description":"${timelineBody.description}","title":"${timelineBody.title}","created":${timelineBody.created},"createdBy":"elastic","updated":${timelineBody.updated},"updatedBy":"elastic","timelineType":"default","sort":[],"eventNotes":[],"globalNotes":[],"pinnedEventIds":[]}\n`;
|
||||
};
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands';
|
||||
import 'cypress-promise/register';
|
||||
|
||||
Cypress.Cookies.defaults({
|
||||
preserve: 'sid',
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { CustomRule } from '../objects/rule';
|
||||
import { CustomRule } from '../../objects/rule';
|
||||
|
||||
export const createCustomRule = (rule: CustomRule) => {
|
||||
export const createCustomRule = (rule: CustomRule) =>
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: 'api/detection_engine/rules',
|
||||
|
@ -26,7 +26,6 @@ export const createCustomRule = (rule: CustomRule) => {
|
|||
},
|
||||
headers: { 'kbn-xsrf': 'cypress-creds' },
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteCustomRule = () => {
|
||||
cy.request({
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { CompleteTimeline } from '../../objects/timeline';
|
||||
|
||||
export const createTimeline = (timeline: CompleteTimeline) =>
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: 'api/timeline',
|
||||
body: {
|
||||
timeline: {
|
||||
columns: [
|
||||
{
|
||||
id: '@timestamp',
|
||||
},
|
||||
{
|
||||
id: 'user.name',
|
||||
},
|
||||
{
|
||||
id: 'event.category',
|
||||
},
|
||||
{
|
||||
id: 'event.action',
|
||||
},
|
||||
{
|
||||
id: 'host.name',
|
||||
},
|
||||
],
|
||||
kqlMode: 'filter',
|
||||
kqlQuery: {
|
||||
filterQuery: {
|
||||
kuery: {
|
||||
expression: timeline.query,
|
||||
kind: 'kuery',
|
||||
},
|
||||
},
|
||||
},
|
||||
dateRange: {
|
||||
end: '1577881376000',
|
||||
start: '1514809376000',
|
||||
},
|
||||
description: timeline.description,
|
||||
title: timeline.title,
|
||||
},
|
||||
},
|
||||
headers: { 'kbn-xsrf': 'cypress-creds' },
|
||||
});
|
||||
|
||||
export const createTimelineTemplate = (timeline: CompleteTimeline) =>
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: 'api/timeline',
|
||||
body: {
|
||||
timeline: {
|
||||
columns: [
|
||||
{
|
||||
id: '@timestamp',
|
||||
},
|
||||
{
|
||||
id: 'user.name',
|
||||
},
|
||||
{
|
||||
id: 'event.category',
|
||||
},
|
||||
{
|
||||
id: 'event.action',
|
||||
},
|
||||
{
|
||||
id: 'host.name',
|
||||
},
|
||||
],
|
||||
kqlMode: 'filter',
|
||||
kqlQuery: {
|
||||
filterQuery: {
|
||||
kuery: {
|
||||
expression: timeline.query,
|
||||
kind: 'kuery',
|
||||
},
|
||||
},
|
||||
},
|
||||
dateRange: {
|
||||
end: '1577881376000',
|
||||
start: '1514809376000',
|
||||
},
|
||||
description: timeline.description,
|
||||
title: timeline.title,
|
||||
templateTimelineVersion: 1,
|
||||
timelineType: 'template',
|
||||
},
|
||||
},
|
||||
headers: { 'kbn-xsrf': 'cypress-creds' },
|
||||
});
|
||||
|
||||
export const deleteTimeline = (timelineId: string) => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: 'api/solutions/security/graphql',
|
||||
body: {
|
||||
operationName: 'DeleteTimelineMutation',
|
||||
variables: {
|
||||
id: [timelineId],
|
||||
},
|
||||
query: 'mutation DeleteTimelineMutation($id: [ID!]!) {\n deleteTimeline(id: $id)\n}\n',
|
||||
},
|
||||
headers: { 'kbn-xsrf': 'delete-signals' },
|
||||
});
|
||||
};
|
|
@ -72,9 +72,9 @@ import {
|
|||
MITRE_ATTACK_ADD_TECHNIQUE_BUTTON,
|
||||
} from '../screens/create_new_rule';
|
||||
import { NOTIFICATION_TOASTS, TOAST_ERROR_CLASS } from '../screens/shared';
|
||||
import { SERVER_SIDE_EVENT_COUNT } from '../screens/timeline';
|
||||
import { TIMELINE } from '../screens/timelines';
|
||||
import { refreshPage } from './security_header';
|
||||
import { NUMBER_OF_ALERTS } from '../screens/alerts';
|
||||
|
||||
export const createAndActivateRule = () => {
|
||||
cy.get(SCHEDULE_CONTINUE_BUTTON).click({ force: true });
|
||||
|
@ -229,7 +229,7 @@ export const fillDefineCustomRuleWithImportedQueryAndContinue = (
|
|||
rule: CustomRule | OverrideRule
|
||||
) => {
|
||||
cy.get(IMPORT_QUERY_FROM_SAVED_TIMELINE_LINK).click();
|
||||
cy.get(TIMELINE(rule.timelineId!)).click();
|
||||
cy.get(TIMELINE(rule.timeline.id!)).click();
|
||||
cy.get(CUSTOM_QUERY_INPUT).should('have.value', rule.customQuery);
|
||||
cy.get(DEFINE_CONTINUE_BUTTON).should('exist').click({ force: true });
|
||||
|
||||
|
@ -331,6 +331,22 @@ export const selectThresholdRuleType = () => {
|
|||
cy.get(THRESHOLD_TYPE).click({ force: true });
|
||||
};
|
||||
|
||||
export const waitForAlertsToPopulate = async () => {
|
||||
cy.waitUntil(
|
||||
() => {
|
||||
refreshPage();
|
||||
return cy
|
||||
.get(SERVER_SIDE_EVENT_COUNT)
|
||||
.invoke('text')
|
||||
.then((countText) => {
|
||||
const alertCount = parseInt(countText, 10) || 0;
|
||||
return alertCount > 0;
|
||||
});
|
||||
},
|
||||
{ interval: 500, timeout: 12000 }
|
||||
);
|
||||
};
|
||||
|
||||
export const waitForTheRuleToBeExecuted = () => {
|
||||
cy.waitUntil(() => {
|
||||
cy.get(REFRESH_BUTTON).click();
|
||||
|
@ -340,16 +356,3 @@ export const waitForTheRuleToBeExecuted = () => {
|
|||
.then((ruleStatus) => ruleStatus === 'succeeded');
|
||||
});
|
||||
};
|
||||
|
||||
export const waitForAlertsToPopulate = async () => {
|
||||
cy.waitUntil(() => {
|
||||
refreshPage();
|
||||
return cy
|
||||
.get(NUMBER_OF_ALERTS)
|
||||
.invoke('text')
|
||||
.then((countText) => {
|
||||
const alertCount = parseInt(countText, 10) || 0;
|
||||
return alertCount > 0;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
{"author":[],"actions":[],"created_at":"2020-07-15T10:45:15.954Z","updated_at":"2020-07-15T10:45:16.874Z","created_by":"elastic","description":"Export rule","enabled":true,"false_positives":[],"filters":[],"from":"now-360s","id":"a4772daa-a3ef-44a3-8035-6abd1bf2893a","immutable":false,"index":["apm-*-transaction*","auditbeat-*","endgame-*","filebeat-*","logs-*","packetbeat-*","winlogbeat-*"],"interval":"5m","rule_id":"1b08a0c2-8243-463e-92c2-b464a8c97cd4","language":"kuery","license":"","output_index":".siem-signals-default","max_signals":100,"risk_score":50,"risk_score_mapping":[],"name":"Export rule","query":"host.name: *","references":[],"meta":{"from":"1m","kibana_siem_app_url":"http://localhost:5620/app/security/detections"},"severity":"low","severity_mapping":[],"updated_by":"elastic","tags":[],"to":"now","type":"query","threat":[],"throttle":"no_actions","version":1,"exceptions_list":[]}
|
||||
{"exported_count":1,"missing_rules":[],"missing_rules_count":0}
|
|
@ -1 +0,0 @@
|
|||
{"savedObjectId":"0162c130-78be-11ea-9718-118a926974a4","version":"WzcsMV0=","columns":[{"columnHeaderType":"not-filtered","id":"@timestamp"},{"columnHeaderType":"not-filtered","id":"message"},{"columnHeaderType":"not-filtered","id":"event.category"},{"columnHeaderType":"not-filtered","id":"event.action"},{"columnHeaderType":"not-filtered","id":"host.name"},{"columnHeaderType":"not-filtered","id":"source.ip"},{"columnHeaderType":"not-filtered","id":"destination.ip"},{"columnHeaderType":"not-filtered","id":"user.name"}],"created":1586256805054,"createdBy":"elastic","dataProviders":[],"dateRange":{"end":1586256837669,"start":1546343624710},"description":"description","eventType":"all","filters":[],"kqlMode":"filter","kqlQuery":{"filterQuery":{"kuery":{"expression":"host.name:*","kind":"kuery"},"serializedQuery":"{\"bool\":{\"should\":[{\"exists\":{\"field\":\"host.name\"}}],\"minimum_should_match\":1}}"}},"savedQueryId":null,"sort":[{"columnId":"@timestamp","sortDirection":"desc"}],"title":"SIEM test","updated":1586256839298,"updatedBy":"elastic","timelineType":"default","eventNotes":[],"globalNotes":[],"pinnedEventIds":[]}
|
|
@ -3114,4 +3114,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue