From 28c90f20aa04a90558b80e3581d15089eb320f99 Mon Sep 17 00:00:00 2001 From: Amardeepsingh Siglani Date: Tue, 31 Oct 2023 17:26:06 -0700 Subject: [PATCH 1/8] updated tests Signed-off-by: Amardeepsingh Siglani --- .../1_detectors.spec.js | 10 +++------- .../3_alerts.spec.js | 6 +++--- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js index 823d2f84e..275be3931 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js @@ -18,6 +18,7 @@ const cypressIndexDns = 'cypress-index-dns'; const cypressIndexWindows = 'cypress-index-windows'; const detectorName = 'test detector'; const cypressLogTypeDns = 'dns'; +const creationFailedMessage = 'Create detector failed.'; const cypressDNSRule = dns_name_rule_data.title; @@ -197,11 +198,6 @@ const createDetector = (detectorName, dataSource, expectFailure) => { cy.url() .should('contain', detectorId) .then(() => { - cy.sa_getElementByText( - '.euiCallOut', - `Detector created successfully: ${detectorName}` - ); - // Confirm detector state cy.sa_getElementByText('.euiTitle', detectorName); cy.sa_getElementByText('.euiHealth', 'Active').then(() => { @@ -425,12 +421,12 @@ describe('Detectors', () => { it('...can fail creation', () => { createDetector(`${detectorName}_fail`, '.kibana_1', true); - cy.sa_getElementByText('.euiCallOut', 'Create detector failed.'); + cy.sa_getElementByText('.euiCallOut', creationFailedMessage); }); it('...can be created', () => { createDetector(detectorName, cypressIndexDns, false); - cy.sa_getElementByText('.euiCallOut', 'Detector created successfully'); + cy.contains(creationFailedMessage).should('not.exist'); }); it('...basic details can be edited', () => { diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js index 8812d5c28..e74eb7fdb 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js @@ -138,12 +138,12 @@ describe('Alerts', () => { // Wait for the findings table to finish loading cy.contains('Findings (1)'); - cy.contains('Cypress USB Rule'); + cy.contains('Detection rules'); // Confirm alert findings contain expected values cy.get('tbody > tr').should(($tr) => { expect($tr, `timestamp`).to.contain(date); - expect($tr, `rule name`).to.contain('Cypress USB Rule'); + expect($tr, `detection type`).to.contain('Detection rules'); expect($tr, `detector name`).to.contain(testDetectorCfg.name); expect($tr, `log type`).to.contain('System Activity: Windows'); }); @@ -169,7 +169,7 @@ describe('Alerts', () => { cy.get('[data-test-subj="alert-details-flyout"]').within(() => { // Wait for findings table to finish loading - cy.contains('Cypress USB Rule'); + cy.contains('Detection rules'); // Click the details button for the first finding cy.get('tbody > tr') From b84942aab7037247756d76a74acff505055d0877 Mon Sep 17 00:00:00 2001 From: Amardeepsingh Siglani Date: Tue, 31 Oct 2023 18:53:24 -0700 Subject: [PATCH 2/8] updated tests Signed-off-by: Amardeepsingh Siglani --- .../1_detectors.spec.js | 18 +++----- .../2_rules.spec.js | 13 +++--- .../3_alerts.spec.js | 45 ++----------------- .../constants.js | 18 ++++++++ .../helpers.js | 10 +++++ 5 files changed, 45 insertions(+), 59 deletions(-) create mode 100644 cypress/utils/plugins/security-analytics-dashboards-plugin/helpers.js diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js index 275be3931..930dc9e61 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js @@ -7,6 +7,7 @@ import { NODE_API, OPENSEARCH_DASHBOARDS_URL, } from '../../../utils/plugins/security-analytics-dashboards-plugin/constants'; +import { getLogTypeLabel } from '../../../utils/plugins/security-analytics-dashboards-plugin/helpers'; import sample_windows_index_settings from '../../../fixtures/plugins/security-analytics-dashboards-plugin/sample_windows_index_settings.json'; import sample_dns_index_settings from '../../../fixtures/plugins/security-analytics-dashboards-plugin/sample_dns_index_settings.json'; import dns_name_rule_data from '../../../fixtures/plugins/security-analytics-dashboards-plugin/integration_tests/rule/create_dns_rule_with_name_selection.json'; @@ -40,7 +41,7 @@ const dataSourceLabel = 'Select or input source indexes or index patterns'; const getDataSourceField = () => cy.sa_getFieldByLabel(dataSourceLabel); -const logTypeLabel = 'Select a log type you would like to detect'; +const logTypeLabel = 'Log type'; const getLogTypeField = () => cy.sa_getFieldByLabel(logTypeLabel); @@ -138,7 +139,7 @@ const fillDetailsForm = (detectorName, dataSource) => { getNameField().type(detectorName); getDataSourceField().sa_selectComboboxItem(dataSource); getDataSourceField().focus().blur(); - getLogTypeField().sa_selectComboboxItem(cypressLogTypeDns); + getLogTypeField().sa_selectComboboxItem(getLogTypeLabel(cypressLogTypeDns)); getLogTypeField().focus().blur(); }; @@ -149,10 +150,10 @@ const createDetector = (detectorName, dataSource, expectFailure) => { cy.sa_getElementByText( '.euiAccordion .euiTitle', - 'Detection rules (14 selected)' + 'Selected detection rules (14)' ) .click({ force: true, timeout: 5000 }) - .then(() => cy.contains('.euiTable .euiTableRow', 'Dns')); + .then(() => cy.contains('.euiTable .euiTableRow', getLogTypeLabel(cypressLogTypeDns))); cy.sa_getElementByText('.euiAccordion .euiTitle', 'Field mapping - optional'); cy.get('[aria-controls="mappedTitleFieldsAccordion"]').then(($btn) => { @@ -169,19 +170,12 @@ const createDetector = (detectorName, dataSource, expectFailure) => { // Open the trigger details accordion cy.get('[data-test-subj="trigger-details-btn"]').click({ force: true }); cy.sa_getElementByText('.euiTitle.euiTitle--medium', 'Set up alert triggers'); - cy.sa_getInputByPlaceholder( - 'Enter a name to describe the alert condition' - ).type('test_trigger'); cy.sa_getElementByTestSubject('alert-tags-combo-box') .type(`attack.defense_evasion{enter}`) .find('input') .focus() .blur(); - cy.sa_getFieldByLabel('Specify alert severity').sa_selectComboboxItem( - '1 (Highest)' - ); - cy.intercept('POST', NODE_API.MAPPINGS_BASE).as('createMappingsRequest'); cy.intercept('POST', NODE_API.DETECTORS_BASE).as('createDetectorRequest'); @@ -213,7 +207,7 @@ const createDetector = (detectorName, dataSource, expectFailure) => { cy.wait(5000); // waiting for the page to be reloaded after pushing detector id into route cy.sa_getElementByText('button.euiTab', 'Alert triggers') .should('be.visible') - .click(); + .click({ force: true }); validateAlertPanel('Trigger 1'); }); }); diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js index 4b6fa5774..6e9e15ccf 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js @@ -7,6 +7,7 @@ import { NODE_API, OPENSEARCH_DASHBOARDS_URL, } from '../../../utils/plugins/security-analytics-dashboards-plugin/constants'; +import { getLogTypeLabel } from '../../../utils/plugins/security-analytics-dashboards-plugin/helpers'; const uniqueId = Cypress._.random(0, 1e6); const SAMPLE_RULE = { @@ -72,7 +73,7 @@ const checkRulesFlyout = () => { // Validate log type cy.get('[data-test-subj="rule_flyout_rule_log_type"]').contains( - SAMPLE_RULE.logType + getLogTypeLabel(SAMPLE_RULE.logType) ); // Validate description @@ -196,7 +197,7 @@ const fillCreateForm = () => { getAuthorField().type(`${SAMPLE_RULE.author}`); // rule details - getLogTypeField().sa_selectComboboxItem(SAMPLE_RULE.logType); + getLogTypeField().sa_selectComboboxItem(getLogTypeLabel(SAMPLE_RULE.logType)); getRuleLevelField().sa_selectComboboxItem(SAMPLE_RULE.severity); // rule detection @@ -334,7 +335,7 @@ describe('Rules', () => { getLogTypeField().focus().blur(); getLogTypeField().sa_containsError('Log type is required'); - getLogTypeField().sa_selectComboboxItem(SAMPLE_RULE.logType); + getLogTypeField().sa_selectComboboxItem(getLogTypeLabel(SAMPLE_RULE.logType)); getLogTypeField().focus().blur().sa_shouldNotHaveError(); }); @@ -481,7 +482,7 @@ describe('Rules', () => { // log field getLogTypeField().sa_clearCombobox(); toastShouldExist(); - getLogTypeField().sa_selectComboboxItem(SAMPLE_RULE.logType); + getLogTypeField().sa_selectComboboxItem(getLogTypeLabel(SAMPLE_RULE.logType)); // severity field getRuleLevelField().sa_clearCombobox(); @@ -618,10 +619,10 @@ describe('Rules', () => { SAMPLE_RULE.logType = 'dns'; YAML_RULE_LINES[2] = `product: ${SAMPLE_RULE.logType}`; YAML_RULE_LINES[3] = `title: ${SAMPLE_RULE.name}`; - getLogTypeField().sa_selectComboboxItem(SAMPLE_RULE.logType); + getLogTypeField().sa_selectComboboxItem(getLogTypeLabel(SAMPLE_RULE.logType)); getLogTypeField() .sa_containsValue(SAMPLE_RULE.logType) - .contains(SAMPLE_RULE.logType); + .contains(getLogTypeLabel(SAMPLE_RULE.logType)); SAMPLE_RULE.description += ' edited'; YAML_RULE_LINES[4] = `description: ${SAMPLE_RULE.description}`; diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js index e74eb7fdb..8070b18e2 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js @@ -193,10 +193,10 @@ describe('Alerts', () => { date ); - // Confirm finding detector name - cy.get( - '[data-test-subj="finding-details-flyout-detector-link"]' - ).contains(testDetectorCfg.name); + // Confirm finding detection type + cy.get('[data-test-subj="finding-details-flyout-detection-type"]').contains( + 'Detection rules' + ); // Confirm there's only 1 rule details accordion cy.get( @@ -429,42 +429,5 @@ describe('Alerts', () => { }); }); - it('detector name hyperlink on finding details flyout redirects to the detector details page', () => { - // Open first alert details flyout - cy.get('tbody > tr') - .first() - .within(() => { - // Click the "View details" button for the first alert - cy.get('[aria-label="View details"]').click({ force: true }); - }); - - cy.get('[data-test-subj="alert-details-flyout"]').within(() => { - // Wait for findings table to finish loading - cy.contains('Cypress USB Rule'); - - // Click the details button for the first finding - cy.get('tbody > tr') - .first() - .within(() => { - cy.get('[data-test-subj="finding-details-flyout-button"]').click({ - force: true, - }); - }); - }); - - cy.get('[data-test-subj="finding-details-flyout"]').within(() => { - // Click the detector name hyperlink - cy.get('[data-test-subj="finding-details-flyout-detector-link"]') - // Removing the "target" attribute so the link won't open a new tab. Cypress wouldn't test the new tab. - .invoke('removeAttr', 'target') - .click({ force: true }); - }); - - // Confirm the detector details page is for the expected detector - cy.get('[data-test-subj="detector-details-detector-name"]').contains( - testDetectorCfg.name - ); - }); - after(() => cy.sa_cleanUpTests()); }); diff --git a/cypress/utils/plugins/security-analytics-dashboards-plugin/constants.js b/cypress/utils/plugins/security-analytics-dashboards-plugin/constants.js index 79c637364..b9c853fbf 100644 --- a/cypress/utils/plugins/security-analytics-dashboards-plugin/constants.js +++ b/cypress/utils/plugins/security-analytics-dashboards-plugin/constants.js @@ -126,3 +126,21 @@ export const createDetector = ( return detectorConfig; }; + +export const logTypeLabels = { + cloudtrail: 'AWS Cloudtrail', + dns: 'DNS', + vpcflow: 'VPC Flow', + ad_ldap: 'AD/LDAP', + apache_access: 'Apache Access', + m365: 'Microsoft 365', + okta: 'Okta', + waf: 'WAF', + s3: 'AWS S3', + github: 'Github', + gworkspace: 'Google Workspace', + windows: 'Microsoft Windows', + network: 'Network', + linux: 'Linux System Logs', + azure: 'Microsoft Azure', +}; diff --git a/cypress/utils/plugins/security-analytics-dashboards-plugin/helpers.js b/cypress/utils/plugins/security-analytics-dashboards-plugin/helpers.js new file mode 100644 index 000000000..000e67e2b --- /dev/null +++ b/cypress/utils/plugins/security-analytics-dashboards-plugin/helpers.js @@ -0,0 +1,10 @@ +/* +* Copyright OpenSearch Contributors +* SPDX-License-Identifier: Apache-2.0 +*/ + +import { logTypeLabels } from './constants'; + +export function getLogTypeLabel(name) { + return !name ? DEFAULT_EMPTY_DATA : logTypeLabels[name.toLowerCase()] || startCase(name); +}; \ No newline at end of file From 58d368389f301364763c1e0de62cb1b7e336093f Mon Sep 17 00:00:00 2001 From: Amardeepsingh Siglani Date: Tue, 31 Oct 2023 19:19:23 -0700 Subject: [PATCH 3/8] updated tests Signed-off-by: Amardeepsingh Siglani --- .../security-analytics-dashboards-plugin/3_alerts.spec.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js index 8070b18e2..7192b6025 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js @@ -103,6 +103,7 @@ describe('Alerts', () => { // Click the "View details" button for the first alert cy.get('[aria-label="View details"]').click({ force: true }); }); + cy.wait(3000); // Get the details flyout, and validate its content cy.get('[data-test-subj="alert-details-flyout"]').within(() => { @@ -145,7 +146,7 @@ describe('Alerts', () => { expect($tr, `timestamp`).to.contain(date); expect($tr, `detection type`).to.contain('Detection rules'); expect($tr, `detector name`).to.contain(testDetectorCfg.name); - expect($tr, `log type`).to.contain('System Activity: Windows'); + expect($tr, `log type`).to.contain('System Activity: Microsoft Windows'); }); // Close the flyout @@ -166,6 +167,8 @@ describe('Alerts', () => { // Click the "View details" button for the first alert cy.get('[aria-label="View details"]').click({ force: true }); }); + + cy.wait(3000); cy.get('[data-test-subj="alert-details-flyout"]').within(() => { // Wait for findings table to finish loading From 437544e0a1dc34804942ebcef9302da3f0aace80 Mon Sep 17 00:00:00 2001 From: Amardeepsingh Siglani Date: Mon, 6 Nov 2023 17:45:23 -0800 Subject: [PATCH 4/8] updated intercepts Signed-off-by: Amardeepsingh Siglani --- .../1_detectors.spec.js | 34 ++++++------------- .../2_rules.spec.js | 31 +++++------------ .../3_alerts.spec.js | 3 +- .../4_findings.spec.js | 2 +- .../helpers.js | 7 +++- 5 files changed, 29 insertions(+), 48 deletions(-) diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js index 930dc9e61..6fef6e708 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js @@ -7,7 +7,7 @@ import { NODE_API, OPENSEARCH_DASHBOARDS_URL, } from '../../../utils/plugins/security-analytics-dashboards-plugin/constants'; -import { getLogTypeLabel } from '../../../utils/plugins/security-analytics-dashboards-plugin/helpers'; +import { getLogTypeLabel, setupIntercept } from '../../../utils/plugins/security-analytics-dashboards-plugin/helpers'; import sample_windows_index_settings from '../../../fixtures/plugins/security-analytics-dashboards-plugin/sample_windows_index_settings.json'; import sample_dns_index_settings from '../../../fixtures/plugins/security-analytics-dashboards-plugin/sample_dns_index_settings.json'; import dns_name_rule_data from '../../../fixtures/plugins/security-analytics-dashboards-plugin/integration_tests/rule/create_dns_rule_with_name_selection.json'; @@ -176,8 +176,8 @@ const createDetector = (detectorName, dataSource, expectFailure) => { .focus() .blur(); - cy.intercept('POST', NODE_API.MAPPINGS_BASE).as('createMappingsRequest'); - cy.intercept('POST', NODE_API.DETECTORS_BASE).as('createDetectorRequest'); + setupIntercept(cy, NODE_API.MAPPINGS_BASE, 'createMappingsRequest'); + setupIntercept(cy, NODE_API.DETECTORS_BASE, 'createDetectorRequest'); // create the detector cy.sa_getElementByText('button', 'Create').click({ force: true }); @@ -255,7 +255,7 @@ describe('Detectors', () => { describe('...should validate form fields', () => { beforeEach(() => { - cy.intercept(NODE_API.SEARCH_DETECTORS).as('detectorsSearch'); + setupIntercept(cy, NODE_API.SEARCH_DETECTORS, 'detectorsSearch'); // Visit Detectors page before any test cy.visit(`${OPENSEARCH_DASHBOARDS_URL}/detectors`); @@ -404,9 +404,7 @@ describe('Detectors', () => { describe('...validate create detector flow', () => { beforeEach(() => { - cy.intercept(NODE_API.SEARCH_DETECTORS) - .as('detectorsSearch') - .as('detectorsSearch'); + setupIntercept(cy, NODE_API.SEARCH_DETECTORS, 'detectorsSearch'); // Visit Detectors page before any test cy.visit(`${OPENSEARCH_DASHBOARDS_URL}/detectors`); @@ -424,7 +422,7 @@ describe('Detectors', () => { }); it('...basic details can be edited', () => { - cy.intercept('GET', NODE_API.INDICES_BASE).as('getIndices'); + setupIntercept(cy, NODE_API.INDICES_BASE, 'getIndices', 'GET'); openDetectorDetails(detectorName); editDetectorDetails(detectorName, 'Detector details'); @@ -484,10 +482,8 @@ describe('Detectors', () => { }); xit('...should update field mappings if data source is changed', () => { - cy.intercept( - `${NODE_API.MAPPINGS_VIEW}?indexName=cypress-index-dns&ruleTopic=dns` - ).as('getMappingsView'); - cy.intercept('GET', NODE_API.INDICES_BASE).as('getIndices'); + setupIntercept(cy, `${NODE_API.MAPPINGS_VIEW}?indexName=cypress-index-dns&ruleTopic=dns`, 'getMappingsView', 'GET'); + setupIntercept(cy, NODE_API.INDICES_BASE, 'getIndices', 'GET'); openDetectorDetails(detectorName); editDetectorDetails(detectorName, 'Detector details'); @@ -509,9 +505,7 @@ describe('Detectors', () => { }); xit('...should show field mappings if rule selection is changed', () => { - cy.intercept( - `${NODE_API.MAPPINGS_VIEW}?indexName=cypress-index-windows&ruleTopic=dns` - ).as('getMappingsView'); + setupIntercept(cy, `${NODE_API.MAPPINGS_VIEW}`, 'getMappingsView', 'GET'); openDetectorDetails(detectorName); @@ -534,22 +528,16 @@ describe('Detectors', () => { }); it('...can be deleted', () => { - cy.intercept(`${NODE_API.RULES_BASE}/_search?prePackaged=true`).as( - 'getSigmaRules' - ); - cy.intercept(`${NODE_API.RULES_BASE}/_search?prePackaged=false`).as( - 'getCustomRules' - ); + setupIntercept(cy, `${NODE_API.RULES_BASE}/_search`, 'getSigmaRules'); openDetectorDetails(detectorName); cy.wait('@detectorsSearch'); - cy.wait('@getCustomRules'); cy.wait('@getSigmaRules'); cy.sa_getButtonByText('Actions') .click({ force: true }) .then(() => { - cy.intercept(`${NODE_API.DETECTORS_BASE}/_search`).as('detectors'); + setupIntercept(cy, `${NODE_API.DETECTORS_BASE}/_search`, 'detectors'); cy.sa_getElementByText('.euiContextMenuItem', 'Delete').click({ force: true, }); diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js index 6e9e15ccf..b4aa65bee 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js @@ -7,7 +7,7 @@ import { NODE_API, OPENSEARCH_DASHBOARDS_URL, } from '../../../utils/plugins/security-analytics-dashboards-plugin/constants'; -import { getLogTypeLabel } from '../../../utils/plugins/security-analytics-dashboards-plugin/helpers'; +import { getLogTypeLabel, setupIntercept } from '../../../utils/plugins/security-analytics-dashboards-plugin/helpers'; const uniqueId = Cypress._.random(0, 1e6); const SAMPLE_RULE = { @@ -227,9 +227,7 @@ describe('Rules', () => { describe('...should validate form fields', () => { beforeEach(() => { - cy.intercept(`${NODE_API.RULES_BASE}/_search?prePackaged=true`).as( - 'rulesSearch' - ); + setupIntercept(cy, `${NODE_API.RULES_BASE}/_search`, 'rulesSearch'); // Visit Rules page cy.visit(`${OPENSEARCH_DASHBOARDS_URL}/rules`); cy.wait('@rulesSearch').should('have.property', 'state', 'Complete'); @@ -546,9 +544,7 @@ describe('Rules', () => { describe('...should validate create rule flow', () => { beforeEach(() => { - cy.intercept(`${NODE_API.RULES_BASE}/_search?prePackaged=false`).as( - 'rulesSearch' - ); + setupIntercept(cy, `${NODE_API.RULES_BASE}/_search`, 'rulesSearch'); // Visit Rules page cy.visit(`${OPENSEARCH_DASHBOARDS_URL}/rules`); cy.wait('@rulesSearch').should('have.property', 'state', 'Complete'); @@ -573,9 +569,7 @@ describe('Rules', () => { cy.get('[data-test-subj="rule_yaml_editor"]').contains(line) ); - cy.intercept({ - url: `${NODE_API.RULES_BASE}/_search?prePackaged=false`, - }).as('getRules'); + setupIntercept(cy, `${NODE_API.RULES_BASE}/_search`, 'getRules'); submitRule(); @@ -630,9 +624,7 @@ describe('Rules', () => { getDescriptionField().type(SAMPLE_RULE.description); getDescriptionField().should('have.value', SAMPLE_RULE.description); - cy.intercept({ - url: `${NODE_API.RULES_BASE}/_search?prePackaged=false`, - }).as('getRules'); + setupIntercept(cy, `${NODE_API.RULES_BASE}/_search`, 'getRules'); submitRule(); @@ -646,13 +638,9 @@ describe('Rules', () => { }); it('...can be deleted', () => { - cy.intercept('POST', `${NODE_API.RULES_BASE}/_search?prePackaged=true`, { - delay: 5000, - }).as('getPrePackagedRules'); - - cy.intercept('POST', `${NODE_API.RULES_BASE}/_search?prePackaged=false`, { - delay: 5000, - }).as('getCustomRules'); + setupIntercept(cy, `${NODE_API.RULES_BASE}/_search`, 'getRules', 'POST', { + delay: 5000 + }); cy.get(`input[placeholder="Search rules"]`).sa_ospSearch( SAMPLE_RULE.name @@ -678,8 +666,7 @@ describe('Rules', () => { ); cy.wait(5000); - cy.wait('@getCustomRules'); - cy.wait('@getPrePackagedRules'); + cy.wait('@getRules'); // Search for sample_detector, presumably deleted cy.wait(3000); diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js index 7192b6025..c000e7231 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js @@ -13,6 +13,7 @@ import indexSettings from '../../../fixtures/plugins/security-analytics-dashboar import aliasMappings from '../../../fixtures/plugins/security-analytics-dashboards-plugin/sample_alias_mappings.json'; import indexDoc from '../../../fixtures/plugins/security-analytics-dashboards-plugin/sample_document.json'; import ruleSettings from '../../../fixtures/plugins/security-analytics-dashboards-plugin/integration_tests/rule/create_windows_usb_rule.json'; +import { setupIntercept } from '../../../utils/plugins/security-analytics-dashboards-plugin/helpers'; const indexName = 'test-index'; const detectorName = 'test-detector'; @@ -49,7 +50,7 @@ describe('Alerts', () => { beforeEach(() => { // Visit Alerts table page - cy.intercept(`${NODE_API.DETECTORS_BASE}/_search`).as('detectorsSearch'); + setupIntercept(cy, `${NODE_API.DETECTORS_BASE}/_search`, 'detectorsSearch'); // Visit Detectors page cy.visit(`${OPENSEARCH_DASHBOARDS_URL}/alerts`); cy.wait('@detectorsSearch').should('have.property', 'state', 'Complete'); diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/4_findings.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/4_findings.spec.js index f692a6b52..c8d458992 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/4_findings.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/4_findings.spec.js @@ -55,7 +55,7 @@ describe('Findings', () => { cy.contains('No items found').should('not.exist'); // Check for expected findings - cy.contains('System Activity: Windows'); + cy.contains('System Activity: Microsoft Windows'); cy.contains('High'); }); diff --git a/cypress/utils/plugins/security-analytics-dashboards-plugin/helpers.js b/cypress/utils/plugins/security-analytics-dashboards-plugin/helpers.js index 000e67e2b..7157e040d 100644 --- a/cypress/utils/plugins/security-analytics-dashboards-plugin/helpers.js +++ b/cypress/utils/plugins/security-analytics-dashboards-plugin/helpers.js @@ -7,4 +7,9 @@ import { logTypeLabels } from './constants'; export function getLogTypeLabel(name) { return !name ? DEFAULT_EMPTY_DATA : logTypeLabels[name.toLowerCase()] || startCase(name); -}; \ No newline at end of file +}; + +export function setupIntercept(cy, url, interceptName, method = 'POST', options = {}) { + const urlRegex = new RegExp(`.*${url}.*`); + cy.intercept(method, urlRegex, options).as(interceptName); +} \ No newline at end of file From 3b7ddd1df1ee7648d95c3d6e0f96135cbd9a45e6 Mon Sep 17 00:00:00 2001 From: Amardeepsingh Siglani Date: Mon, 6 Nov 2023 17:50:17 -0800 Subject: [PATCH 5/8] fixed lint errors Signed-off-by: Amardeepsingh Siglani --- .../1_detectors.spec.js | 16 +++++++++++--- .../2_rules.spec.js | 19 ++++++++++++----- .../3_alerts.spec.js | 12 ++++++----- .../helpers.js | 21 ++++++++++++------- 4 files changed, 48 insertions(+), 20 deletions(-) diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js index 6fef6e708..1be512700 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js @@ -7,7 +7,10 @@ import { NODE_API, OPENSEARCH_DASHBOARDS_URL, } from '../../../utils/plugins/security-analytics-dashboards-plugin/constants'; -import { getLogTypeLabel, setupIntercept } from '../../../utils/plugins/security-analytics-dashboards-plugin/helpers'; +import { + getLogTypeLabel, + setupIntercept, +} from '../../../utils/plugins/security-analytics-dashboards-plugin/helpers'; import sample_windows_index_settings from '../../../fixtures/plugins/security-analytics-dashboards-plugin/sample_windows_index_settings.json'; import sample_dns_index_settings from '../../../fixtures/plugins/security-analytics-dashboards-plugin/sample_dns_index_settings.json'; import dns_name_rule_data from '../../../fixtures/plugins/security-analytics-dashboards-plugin/integration_tests/rule/create_dns_rule_with_name_selection.json'; @@ -153,7 +156,9 @@ const createDetector = (detectorName, dataSource, expectFailure) => { 'Selected detection rules (14)' ) .click({ force: true, timeout: 5000 }) - .then(() => cy.contains('.euiTable .euiTableRow', getLogTypeLabel(cypressLogTypeDns))); + .then(() => + cy.contains('.euiTable .euiTableRow', getLogTypeLabel(cypressLogTypeDns)) + ); cy.sa_getElementByText('.euiAccordion .euiTitle', 'Field mapping - optional'); cy.get('[aria-controls="mappedTitleFieldsAccordion"]').then(($btn) => { @@ -482,7 +487,12 @@ describe('Detectors', () => { }); xit('...should update field mappings if data source is changed', () => { - setupIntercept(cy, `${NODE_API.MAPPINGS_VIEW}?indexName=cypress-index-dns&ruleTopic=dns`, 'getMappingsView', 'GET'); + setupIntercept( + cy, + `${NODE_API.MAPPINGS_VIEW}?indexName=cypress-index-dns&ruleTopic=dns`, + 'getMappingsView', + 'GET' + ); setupIntercept(cy, NODE_API.INDICES_BASE, 'getIndices', 'GET'); openDetectorDetails(detectorName); diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js index b4aa65bee..698c2245b 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js @@ -7,7 +7,10 @@ import { NODE_API, OPENSEARCH_DASHBOARDS_URL, } from '../../../utils/plugins/security-analytics-dashboards-plugin/constants'; -import { getLogTypeLabel, setupIntercept } from '../../../utils/plugins/security-analytics-dashboards-plugin/helpers'; +import { + getLogTypeLabel, + setupIntercept, +} from '../../../utils/plugins/security-analytics-dashboards-plugin/helpers'; const uniqueId = Cypress._.random(0, 1e6); const SAMPLE_RULE = { @@ -333,7 +336,9 @@ describe('Rules', () => { getLogTypeField().focus().blur(); getLogTypeField().sa_containsError('Log type is required'); - getLogTypeField().sa_selectComboboxItem(getLogTypeLabel(SAMPLE_RULE.logType)); + getLogTypeField().sa_selectComboboxItem( + getLogTypeLabel(SAMPLE_RULE.logType) + ); getLogTypeField().focus().blur().sa_shouldNotHaveError(); }); @@ -480,7 +485,9 @@ describe('Rules', () => { // log field getLogTypeField().sa_clearCombobox(); toastShouldExist(); - getLogTypeField().sa_selectComboboxItem(getLogTypeLabel(SAMPLE_RULE.logType)); + getLogTypeField().sa_selectComboboxItem( + getLogTypeLabel(SAMPLE_RULE.logType) + ); // severity field getRuleLevelField().sa_clearCombobox(); @@ -613,7 +620,9 @@ describe('Rules', () => { SAMPLE_RULE.logType = 'dns'; YAML_RULE_LINES[2] = `product: ${SAMPLE_RULE.logType}`; YAML_RULE_LINES[3] = `title: ${SAMPLE_RULE.name}`; - getLogTypeField().sa_selectComboboxItem(getLogTypeLabel(SAMPLE_RULE.logType)); + getLogTypeField().sa_selectComboboxItem( + getLogTypeLabel(SAMPLE_RULE.logType) + ); getLogTypeField() .sa_containsValue(SAMPLE_RULE.logType) .contains(getLogTypeLabel(SAMPLE_RULE.logType)); @@ -639,7 +648,7 @@ describe('Rules', () => { it('...can be deleted', () => { setupIntercept(cy, `${NODE_API.RULES_BASE}/_search`, 'getRules', 'POST', { - delay: 5000 + delay: 5000, }); cy.get(`input[placeholder="Search rules"]`).sa_ospSearch( diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js index c000e7231..0f7de238e 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/3_alerts.spec.js @@ -147,7 +147,9 @@ describe('Alerts', () => { expect($tr, `timestamp`).to.contain(date); expect($tr, `detection type`).to.contain('Detection rules'); expect($tr, `detector name`).to.contain(testDetectorCfg.name); - expect($tr, `log type`).to.contain('System Activity: Microsoft Windows'); + expect($tr, `log type`).to.contain( + 'System Activity: Microsoft Windows' + ); }); // Close the flyout @@ -168,7 +170,7 @@ describe('Alerts', () => { // Click the "View details" button for the first alert cy.get('[aria-label="View details"]').click({ force: true }); }); - + cy.wait(3000); cy.get('[data-test-subj="alert-details-flyout"]').within(() => { @@ -198,9 +200,9 @@ describe('Alerts', () => { ); // Confirm finding detection type - cy.get('[data-test-subj="finding-details-flyout-detection-type"]').contains( - 'Detection rules' - ); + cy.get( + '[data-test-subj="finding-details-flyout-detection-type"]' + ).contains('Detection rules'); // Confirm there's only 1 rule details accordion cy.get( diff --git a/cypress/utils/plugins/security-analytics-dashboards-plugin/helpers.js b/cypress/utils/plugins/security-analytics-dashboards-plugin/helpers.js index 7157e040d..b4dd0f16c 100644 --- a/cypress/utils/plugins/security-analytics-dashboards-plugin/helpers.js +++ b/cypress/utils/plugins/security-analytics-dashboards-plugin/helpers.js @@ -1,15 +1,22 @@ /* -* Copyright OpenSearch Contributors -* SPDX-License-Identifier: Apache-2.0 -*/ + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ import { logTypeLabels } from './constants'; +import { startCase } from 'lodash'; export function getLogTypeLabel(name) { - return !name ? DEFAULT_EMPTY_DATA : logTypeLabels[name.toLowerCase()] || startCase(name); -}; + return !name ? '-' : logTypeLabels[name.toLowerCase()] || startCase(name); +} -export function setupIntercept(cy, url, interceptName, method = 'POST', options = {}) { +export function setupIntercept( + cy, + url, + interceptName, + method = 'POST', + options = {} +) { const urlRegex = new RegExp(`.*${url}.*`); cy.intercept(method, urlRegex, options).as(interceptName); -} \ No newline at end of file +} From bbc89c45f8bf808275974c6889f498c5f80040de Mon Sep 17 00:00:00 2001 From: Amardeepsingh Siglani Date: Wed, 7 Feb 2024 18:12:26 +0530 Subject: [PATCH 6/8] updated tests Signed-off-by: Amardeepsingh Siglani --- .../1_detectors.spec.js | 18 ++++++++++--- .../2_rules.spec.js | 25 +++---------------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js index 1be512700..bb2244e46 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/1_detectors.spec.js @@ -138,9 +138,21 @@ const validatePendingFieldMappingsPanel = (mappings) => { }); }; -const fillDetailsForm = (detectorName, dataSource) => { +const fillDetailsForm = ( + detectorName, + dataSource, + isCustomDataSource = false +) => { getNameField().type(detectorName); - getDataSourceField().sa_selectComboboxItem(dataSource); + + if (isCustomDataSource) { + getDataSourceField() + .focus() + .type(dataSource + '{enter}'); + } else { + getDataSourceField().sa_selectComboboxItem(dataSource); + } + getDataSourceField().focus().blur(); getLogTypeField().sa_selectComboboxItem(getLogTypeLabel(cypressLogTypeDns)); getLogTypeField().focus().blur(); @@ -149,7 +161,7 @@ const fillDetailsForm = (detectorName, dataSource) => { const createDetector = (detectorName, dataSource, expectFailure) => { getCreateDetectorButton().click({ force: true }); - fillDetailsForm(detectorName, dataSource); + fillDetailsForm(detectorName, dataSource, expectFailure); cy.sa_getElementByText( '.euiAccordion .euiTitle', diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js index 698c2245b..716e44529 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js @@ -174,10 +174,6 @@ const getListRadioField = () => cy.get('[for="selection-map-list-0-0"]'); const getTextRadioField = () => cy.get('[for="selection-map-value-0-0"]'); const getConditionField = () => cy.get('[data-test-subj="rule_detection_field"]'); -const getConditionAddButton = () => - cy.get('[data-test-subj="condition-add-selection-btn"]'); -const getConditionRemoveButton = (index) => - cy.get(`[data-test-subj="selection-exp-field-item-remove-${index}"]`); const getRuleSubmitButton = () => cy.get('[data-test-subj="submit_rule_form_button"]'); const getTagField = (index) => @@ -212,8 +208,6 @@ const fillCreateForm = () => { getMapValueField().type('FieldValue'); }); - getConditionAddButton().click({ force: true }); - // rule additional details SAMPLE_RULE.tags.forEach((tag, idx) => { getTagField(idx).type(tag); @@ -387,7 +381,7 @@ describe('Rules', () => { getMapKeyField() .parentsUntil('.euiFormRow__fieldWrapper') .siblings() - .contains('Key name is required'); + .contains('Invalid key name'); getMapKeyField().type('FieldKey'); getMapKeyField() @@ -443,15 +437,8 @@ describe('Rules', () => { getRuleSubmitButton().click({ force: true }); getConditionField() .parents('.euiFormRow__fieldWrapper') - .contains('Condition is required'); - - getConditionAddButton().click({ force: true }); - getConditionField().find('.euiFormErrorText').should('not.exist'); - - getConditionRemoveButton(0).click({ force: true }); - getConditionField() - .parents('.euiFormRow__fieldWrapper') - .contains('Condition is required'); + .contains('Condition is required') + .should('not.exist'); }); it('...should validate tag field', () => { @@ -512,7 +499,6 @@ describe('Rules', () => { getSelectionPanelByIndex(0).within(() => getMapKeyField().type('{selectall}').type('{backspace}') ); - toastShouldExist(); getSelectionPanelByIndex(0).within(() => getMapKeyField().type('FieldKey') ); @@ -537,11 +523,6 @@ describe('Rules', () => { getMapListField().type('FieldValue'); }); - // condition field - getConditionRemoveButton(0).click({ force: true }); - toastShouldExist(); - getConditionAddButton().click({ force: true }); - // tags field getTagField(0).sa_clearValue().type('wrong.tag'); toastShouldExist(); From 8283e230115c4df2b4dbb85047b9adc6727cb38a Mon Sep 17 00:00:00 2001 From: Amardeepsingh Siglani Date: Thu, 8 Feb 2024 15:22:07 +0530 Subject: [PATCH 7/8] fixed incorrect intercept setup Signed-off-by: Amardeepsingh Siglani --- .../2_rules.spec.js | 4 +--- .../security-analytics-dashboards-plugin/helpers.js | 10 ++-------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js index 716e44529..ab5df8f7f 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js @@ -628,9 +628,7 @@ describe('Rules', () => { }); it('...can be deleted', () => { - setupIntercept(cy, `${NODE_API.RULES_BASE}/_search`, 'getRules', 'POST', { - delay: 5000, - }); + setupIntercept(cy, `${NODE_API.RULES_BASE}/_search`, 'getRules', 'POST'); cy.get(`input[placeholder="Search rules"]`).sa_ospSearch( SAMPLE_RULE.name diff --git a/cypress/utils/plugins/security-analytics-dashboards-plugin/helpers.js b/cypress/utils/plugins/security-analytics-dashboards-plugin/helpers.js index b4dd0f16c..edc7cd4af 100644 --- a/cypress/utils/plugins/security-analytics-dashboards-plugin/helpers.js +++ b/cypress/utils/plugins/security-analytics-dashboards-plugin/helpers.js @@ -10,13 +10,7 @@ export function getLogTypeLabel(name) { return !name ? '-' : logTypeLabels[name.toLowerCase()] || startCase(name); } -export function setupIntercept( - cy, - url, - interceptName, - method = 'POST', - options = {} -) { +export function setupIntercept(cy, url, interceptName, method = 'POST') { const urlRegex = new RegExp(`.*${url}.*`); - cy.intercept(method, urlRegex, options).as(interceptName); + cy.intercept(method, urlRegex).as(interceptName); } From 8aa1469da432e10c2d1a17cc1caafb4a4509c604 Mon Sep 17 00:00:00 2001 From: Amardeepsingh Siglani Date: Wed, 14 Feb 2024 13:51:01 -0800 Subject: [PATCH 8/8] updated rules test Signed-off-by: Amardeepsingh Siglani --- .../2_rules.spec.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js b/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js index ab5df8f7f..0288cb077 100644 --- a/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js +++ b/cypress/integration/plugins/security-analytics-dashboards-plugin/2_rules.spec.js @@ -377,13 +377,20 @@ describe('Rules', () => { it('...should validate selection map key field', () => { getSelectionPanelByIndex(0).within(() => { getMapKeyField().should('be.empty'); - getMapKeyField().focus().blur(); + getMapKeyField() + .focus() + .blur() + .parents('.euiFormRow__fieldWrapper') + .find('.euiFormErrorText') + .should('not.exist'); + + getMapKeyField().type('hello@'); getMapKeyField() .parentsUntil('.euiFormRow__fieldWrapper') .siblings() .contains('Invalid key name'); - getMapKeyField().type('FieldKey'); + getMapKeyField().focus().type('{selectall}').type('FieldKey'); getMapKeyField() .focus() .blur()