From 9f02c06e7ec07b821e4d9985e900c026c909928b Mon Sep 17 00:00:00 2001 From: MadameSheema Date: Tue, 5 May 2020 13:13:46 +0200 Subject: [PATCH] [SIEM] Adds Cypress 'Exports custom rule' test (#64099) (#65233) * changes default browser download folder * adds 'exportRuleAction' data-test-subj attribute * implements 'Exports a custom rule' test * changes headless browser to chrome * updates path * updates 'EXPECTED_RULE_FILE_PATH' * gives time to the file to be downloaded * adds downloads folder * updates download directory * updates paths * captures API call to check the content of the file * removes browser launch hook since is not needed anymore Co-authored-by: Elastic Machine Co-authored-by: Elastic Machine --- .../signal_detection_rules_export.spec.ts | 46 +++++++++++++++++++ x-pack/plugins/siem/cypress/plugins/index.js | 1 + .../cypress/screens/signal_detection_rules.ts | 2 + x-pack/plugins/siem/cypress/support/index.js | 5 ++ .../cypress/tasks/signal_detection_rules.ts | 9 ++++ .../test_files/expected_rules_export.ndjson | 2 + x-pack/plugins/siem/package.json | 2 +- .../detection_engine/rules/all/columns.tsx | 1 + 8 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugins/siem/cypress/integration/signal_detection_rules_export.spec.ts create mode 100644 x-pack/plugins/siem/cypress/test_files/expected_rules_export.ndjson diff --git a/x-pack/plugins/siem/cypress/integration/signal_detection_rules_export.spec.ts b/x-pack/plugins/siem/cypress/integration/signal_detection_rules_export.spec.ts new file mode 100644 index 0000000000000..f0e8b4556f704 --- /dev/null +++ b/x-pack/plugins/siem/cypress/integration/signal_detection_rules_export.spec.ts @@ -0,0 +1,46 @@ +/* + * 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 { + goToManageSignalDetectionRules, + waitForSignalsIndexToBeCreated, + waitForSignalsPanelToBeLoaded, +} from '../tasks/detections'; +import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver'; +import { loginAndWaitForPageWithoutDateRange } from '../tasks/login'; +import { exportFirstRule } from '../tasks/signal_detection_rules'; + +import { DETECTIONS } from '../urls/navigation'; + +const EXPECTED_EXPORTED_RULE_FILE_PATH = 'cypress/test_files/expected_rules_export.ndjson'; + +describe('Export rules', () => { + before(() => { + esArchiverLoad('custom_rules'); + cy.server(); + cy.route( + 'POST', + '**api/detection_engine/rules/_export?exclude_export_details=false&file_name=rules_export.ndjson*' + ).as('export'); + }); + + after(() => { + esArchiverUnload('custom_rules'); + }); + + it('Exports a custom rule', () => { + loginAndWaitForPageWithoutDateRange(DETECTIONS); + waitForSignalsPanelToBeLoaded(); + waitForSignalsIndexToBeCreated(); + goToManageSignalDetectionRules(); + exportFirstRule(); + cy.wait('@export').then(xhr => { + cy.readFile(EXPECTED_EXPORTED_RULE_FILE_PATH).then($expectedExportedJson => { + cy.wrap(xhr.responseBody).should('eql', $expectedExportedJson); + }); + }); + }); +}); diff --git a/x-pack/plugins/siem/cypress/plugins/index.js b/x-pack/plugins/siem/cypress/plugins/index.js index 1132e66cc16dd..01d31b85de463 100644 --- a/x-pack/plugins/siem/cypress/plugins/index.js +++ b/x-pack/plugins/siem/cypress/plugins/index.js @@ -19,6 +19,7 @@ // eslint-disable-next-line import/no-extraneous-dependencies const wp = require('@cypress/webpack-preprocessor'); + module.exports = on => { const options = { webpackOptions: { diff --git a/x-pack/plugins/siem/cypress/screens/signal_detection_rules.ts b/x-pack/plugins/siem/cypress/screens/signal_detection_rules.ts index f74f5c26ddc2e..a41b8296f83e4 100644 --- a/x-pack/plugins/siem/cypress/screens/signal_detection_rules.ts +++ b/x-pack/plugins/siem/cypress/screens/signal_detection_rules.ts @@ -18,6 +18,8 @@ export const DELETE_RULE_BULK_BTN = '[data-test-subj="deleteRuleBulk"]'; export const ELASTIC_RULES_BTN = '[data-test-subj="show-elastic-rules-filter-button"]'; +export const EXPORT_ACTION_BTN = '[data-test-subj="exportRuleAction"]'; + export const FIFTH_RULE = 4; export const FIRST_RULE = 0; diff --git a/x-pack/plugins/siem/cypress/support/index.js b/x-pack/plugins/siem/cypress/support/index.js index 37fa920a8bc31..672acfd41a264 100644 --- a/x-pack/plugins/siem/cypress/support/index.js +++ b/x-pack/plugins/siem/cypress/support/index.js @@ -32,5 +32,10 @@ Cypress.on('uncaught:exception', err => { } }); +Cypress.on('window:before:load', win => { + win.fetch = null; + win.Blob = null; +}); + // Alternatively you can use CommonJS syntax: // require('./commands') diff --git a/x-pack/plugins/siem/cypress/tasks/signal_detection_rules.ts b/x-pack/plugins/siem/cypress/tasks/signal_detection_rules.ts index a404f1142cba7..5a4d71de9e851 100644 --- a/x-pack/plugins/siem/cypress/tasks/signal_detection_rules.ts +++ b/x-pack/plugins/siem/cypress/tasks/signal_detection_rules.ts @@ -23,6 +23,7 @@ import { RULES_TABLE, SORT_RULES_BTN, THREE_HUNDRED_ROWS, + EXPORT_ACTION_BTN, } from '../screens/signal_detection_rules'; export const activateRule = (rulePosition: number) => { @@ -48,6 +49,14 @@ export const deleteSelectedRules = () => { cy.get(DELETE_RULE_BULK_BTN).click(); }; +export const exportFirstRule = () => { + cy.get(COLLAPSED_ACTION_BTN) + .first() + .click({ force: true }); + cy.get(EXPORT_ACTION_BTN).click(); + cy.get(EXPORT_ACTION_BTN).should('not.exist'); +}; + export const filterByCustomRules = () => { cy.get(CUSTOM_RULES_BTN).click({ force: true }); cy.get(LOADING_SPINNER).should('exist'); diff --git a/x-pack/plugins/siem/cypress/test_files/expected_rules_export.ndjson b/x-pack/plugins/siem/cypress/test_files/expected_rules_export.ndjson new file mode 100644 index 0000000000000..c2e779feeca77 --- /dev/null +++ b/x-pack/plugins/siem/cypress/test_files/expected_rules_export.ndjson @@ -0,0 +1,2 @@ +{"actions":[],"created_at":"2020-03-26T10:09:07.569Z","updated_at":"2020-03-26T10:09:08.021Z","created_by":"elastic","description":"Rule 1","enabled":true,"false_positives":[],"filters":[],"from":"now-360s","id":"49db5bd1-bdd5-4821-be26-bb70a815dedb","immutable":false,"index":["apm-*-transaction*","auditbeat-*","endgame-*","filebeat-*","packetbeat-*","winlogbeat-*"],"interval":"5m","rule_id":"0cea4194-03f2-4072-b281-d31b72221d9d","language":"kuery","output_index":".siem-signals-default","max_signals":100,"risk_score":50,"name":"Rule 1","query":"host.name:*","references":[],"meta":{"from":"1m","throttle":"no_actions"},"severity":"low","updated_by":"elastic","tags":["rule1"],"to":"now","type":"query","threat":[],"throttle":"no_actions","version":1} +{"exported_count":1,"missing_rules":[],"missing_rules_count":0} diff --git a/x-pack/plugins/siem/package.json b/x-pack/plugins/siem/package.json index 829332918d3c4..a055d011a5cbb 100644 --- a/x-pack/plugins/siem/package.json +++ b/x-pack/plugins/siem/package.json @@ -8,7 +8,7 @@ "extract-mitre-attacks": "node scripts/extract_tactics_techniques_mitre.js && node ../../../scripts/eslint ./public/pages/detection_engine/mitre/mitre_tactics_techniques.ts --fix", "build-graphql-types": "node scripts/generate_types_from_graphql.js", "cypress:open": "cypress open --config-file ./cypress/cypress.json", - "cypress:run": "cypress run --spec ./cypress/integration/**/*.spec.ts --config-file ./cypress/cypress.json --reporter ../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json; status=$?; ../../node_modules/.bin/mochawesome-merge --reportDir ../../../target/kibana-siem/cypress/results > ../../../target/kibana-siem/cypress/results/output.json; ../../../node_modules/.bin/marge ../../../target/kibana-siem/cypress/results/output.json --reportDir ../../../target/kibana-siem/cypress/results; mkdir -p ../../../target/junit && cp ../../../target/kibana-siem/cypress/results/*.xml ../../../target/junit/ && exit $status;", + "cypress:run": "cypress run --browser chrome --headless --spec ./cypress/integration/**/*.spec.ts --config-file ./cypress/cypress.json --reporter ../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json; status=$?; ../../node_modules/.bin/mochawesome-merge --reportDir ../../../target/kibana-siem/cypress/results > ../../../target/kibana-siem/cypress/results/output.json; ../../../node_modules/.bin/marge ../../../target/kibana-siem/cypress/results/output.json --reportDir ../../../target/kibana-siem/cypress/results; mkdir -p ../../../target/junit && cp ../../../target/kibana-siem/cypress/results/*.xml ../../../target/junit/ && exit $status;", "cypress:run-as-ci": "node ../../../scripts/functional_tests --config ../../test/siem_cypress/config.ts" }, "devDependencies": { diff --git a/x-pack/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx b/x-pack/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx index e3495ba325788..16cdf8ff91a46 100644 --- a/x-pack/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx +++ b/x-pack/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx @@ -64,6 +64,7 @@ export const getActions = ( }, }, { + 'data-test-subj': 'exportRuleAction', description: i18n.EXPORT_RULE, type: 'icon', icon: 'exportAction',