From d1c23837d7da64422afbffafe57e35620a06a377 Mon Sep 17 00:00:00 2001 From: Amardeepsingh Siglani Date: Wed, 11 Oct 2023 12:25:51 -0700 Subject: [PATCH] Security analytics latest tests (#825) * updated tests Signed-off-by: Amardeepsingh Siglani * excluded a couple tests; fixed alerts tests Signed-off-by: Amardeepsingh Siglani * dummy change to trigger tests Signed-off-by: Amardeepsingh Siglani * Updated cypress commands to avoid duplication (#835) * updated commands to avoid duplication Signed-off-by: Amardeepsingh Siglani * updated command header for create rule; changed url for searching rules Signed-off-by: Amardeepsingh Siglani * fix linter issues Signed-off-by: Amardeepsingh Siglani --------- Signed-off-by: Amardeepsingh Siglani * updated mappings for test index (#841) Signed-off-by: Amardeepsingh Siglani * avoid clicking filter menu btn twice (#849) Signed-off-by: Amardeepsingh Siglani * removed check for url since it differs with and without security (#863) Signed-off-by: Amardeepsingh Siglani * namespaced all commands; updated tests for 2.11 Signed-off-by: Amardeepsingh Siglani * addressed PR comments Signed-off-by: Amardeepsingh Siglani --------- Signed-off-by: Amardeepsingh Siglani --- .../1_detectors.spec.js | 214 ++++++++---------- .../2_rules.spec.js | 123 +++++----- .../3_alerts.spec.js | 6 +- .../4_findings.spec.js | 32 +-- .../commands.js | 93 ++++---- .../constants.js | 10 +- .../index.d.ts | 140 ++++++------ 7 files changed, 301 insertions(+), 317 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 5f6b9306d..823d2f84e 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 @@ -22,33 +22,32 @@ const cypressLogTypeDns = 'dns'; const cypressDNSRule = dns_name_rule_data.title; const getNameField = () => - cy.getInputByPlaceholder('Enter a name for the detector.'); + cy.sa_getInputByPlaceholder('Enter a name for the detector.'); -const getNextButton = () => cy.getButtonByText('Next'); - -const getCreateDetectorButton = () => cy.getButtonByText('Create detector'); +const getNextButton = () => cy.sa_getButtonByText('Next'); +const getCreateDetectorButton = () => cy.sa_getButtonByText('Create detector'); const validateAlertPanel = (alertName) => cy - .getElementByText('.euiTitle', 'Alert triggers') + .sa_getElementByText('.euiTitle', 'Alert triggers') .parentsUntil('.euiPanel') .siblings() .eq(2) - .within(() => cy.getElementByText('button', alertName)); + .within(() => cy.sa_getElementByText('button', alertName)); const dataSourceLabel = 'Select or input source indexes or index patterns'; -const getDataSourceField = () => cy.getFieldByLabel(dataSourceLabel); +const getDataSourceField = () => cy.sa_getFieldByLabel(dataSourceLabel); const logTypeLabel = 'Select a log type you would like to detect'; -const getLogTypeField = () => cy.getFieldByLabel(logTypeLabel); +const getLogTypeField = () => cy.sa_getFieldByLabel(logTypeLabel); const openDetectorDetails = (detectorName) => { - cy.getInputByPlaceholder('Search threat detectors') + cy.sa_getInputByPlaceholder('Search threat detectors') .type(`${detectorName}`) - .pressEnterKey(); - cy.getElementByText('.euiTableCellContent button', detectorName).click(); + .sa_pressEnterKey(); + cy.sa_getElementByText('.euiTableCellContent button', detectorName).click(); }; const getMappingFields = (properties, items = [], prefix = '') => { @@ -93,10 +92,10 @@ const validateFieldMappingsTable = (message = '') => { }; const editDetectorDetails = (detectorName, panelTitle) => { - cy.urlShouldContain('detector-details').then(() => { - cy.getElementByText('.euiTitle', detectorName); - cy.getElementByText('.euiPanel .euiTitle', panelTitle); - cy.getElementByText('.euiPanel .euiTitle', panelTitle) + cy.sa_urlShouldContain('detector-details').then(() => { + cy.sa_getElementByText('.euiTitle', detectorName); + cy.sa_getElementByText('.euiPanel .euiTitle', panelTitle); + cy.sa_getElementByText('.euiPanel .euiTitle', panelTitle) .parent() .siblings() .within(() => cy.get('button').contains('Edit').click()); @@ -113,9 +112,9 @@ const validateAutomaticFieldMappingsPanel = (mappings) => cy.get($btn[0]) .click() .then(() => { - cy.getElementByTestSubject('auto-mapped-fields-table') + cy.sa_getElementByTestSubject('auto-mapped-fields-table') .find('.euiBasicTable') - .validateTable(mappings); + .sa_validateTable(mappings); }); } }); @@ -124,22 +123,22 @@ const validateAutomaticFieldMappingsPanel = (mappings) => const validatePendingFieldMappingsPanel = (mappings) => { cy.get('.editFieldMappings').within(() => { // Pending field mappings - cy.getElementByText('.euiTitle', 'Pending field mappings') + cy.sa_getElementByText('.euiTitle', 'Pending field mappings') .parents('.euiPanel') .within(() => { - cy.getElementByTestSubject('pending-mapped-fields-table') + cy.sa_getElementByTestSubject('pending-mapped-fields-table') .find('.euiBasicTable') - .validateTable(mappings); + .sa_validateTable(mappings); }); }); }; const fillDetailsForm = (detectorName, dataSource) => { getNameField().type(detectorName); - getDataSourceField().selectComboboxItem(dataSource); - getDataSourceField().blur(); - getLogTypeField().selectComboboxItem(cypressLogTypeDns); - getLogTypeField().blur(); + getDataSourceField().sa_selectComboboxItem(dataSource); + getDataSourceField().focus().blur(); + getLogTypeField().sa_selectComboboxItem(cypressLogTypeDns); + getLogTypeField().focus().blur(); }; const createDetector = (detectorName, dataSource, expectFailure) => { @@ -147,17 +146,14 @@ const createDetector = (detectorName, dataSource, expectFailure) => { fillDetailsForm(detectorName, dataSource); - cy.getElementByText( + cy.sa_getElementByText( '.euiAccordion .euiTitle', 'Detection rules (14 selected)' ) .click({ force: true, timeout: 5000 }) .then(() => cy.contains('.euiTable .euiTableRow', 'Dns')); - cy.getElementByText( - '.euiAccordion .euiTitle', - 'Configure field mapping - optional' - ); + cy.sa_getElementByText('.euiAccordion .euiTitle', 'Field mapping - optional'); cy.get('[aria-controls="mappedTitleFieldsAccordion"]').then(($btn) => { // first check if the accordion is expanded, if not than expand the accordion if ($btn && $btn[0] && $btn[0].getAttribute('aria-expanded') === 'false') { @@ -169,47 +165,27 @@ const createDetector = (detectorName, dataSource, expectFailure) => { getNextButton().click({ force: true }); // TEST ALERTS PAGE - cy.getElementByText('.euiTitle.euiTitle--medium', 'Set up alert triggers'); - cy.getInputByPlaceholder('Enter a name to describe the alert condition').type( - 'test_trigger' - ); - cy.getElementByTestSubject('alert-tags-combo-box') + // 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.getFieldByLabel('Specify alert severity').selectComboboxItem( + cy.sa_getFieldByLabel('Specify alert severity').sa_selectComboboxItem( '1 (Highest)' ); - // go to review page - getNextButton().click({ force: true }); - - // TEST REVIEW AND CREATE PAGE - cy.getElementByText('.euiTitle', 'Review and create'); - cy.getElementByText('.euiTitle', 'Detector details'); - cy.getElementByText('.euiTitle', 'Field mapping'); - cy.getElementByText('.euiTitle', 'Alert triggers'); - - cy.validateDetailsItem('Detector name', detectorName); - cy.validateDetailsItem('Description', '-'); - cy.validateDetailsItem('Detector schedule', 'Every 1 minute'); - cy.validateDetailsItem('Detection rules', '14'); - cy.validateDetailsItem('Created at', '-'); - cy.validateDetailsItem('Last updated time', '-'); - cy.validateDetailsItem( - 'Detector dashboard', - 'Not available for this log type' - ); - - validateAlertPanel('test_trigger'); - cy.intercept('POST', NODE_API.MAPPINGS_BASE).as('createMappingsRequest'); cy.intercept('POST', NODE_API.DETECTORS_BASE).as('createDetectorRequest'); // create the detector - cy.getElementByText('button', 'Create').click({ force: true }); + cy.sa_getElementByText('button', 'Create').click({ force: true }); // TEST DETECTOR DETAILS PAGE cy.wait('@createMappingsRequest'); @@ -221,28 +197,28 @@ const createDetector = (detectorName, dataSource, expectFailure) => { cy.url() .should('contain', detectorId) .then(() => { - cy.getElementByText( + cy.sa_getElementByText( '.euiCallOut', `Detector created successfully: ${detectorName}` ); // Confirm detector state - cy.getElementByText('.euiTitle', detectorName); - cy.getElementByText('.euiHealth', 'Active').then(() => { - cy.validateDetailsItem('Detector name', detectorName); - cy.validateDetailsItem('Description', '-'); - cy.validateDetailsItem('Detector schedule', 'Every 1 minute'); - cy.validateDetailsItem('Detection rules', '14'); - cy.validateDetailsItem( + cy.sa_getElementByText('.euiTitle', detectorName); + cy.sa_getElementByText('.euiHealth', 'Active').then(() => { + cy.sa_validateDetailsItem('Detector name', detectorName); + cy.sa_validateDetailsItem('Description', '-'); + cy.sa_validateDetailsItem('Detector schedule', 'Every 1 minute'); + cy.sa_validateDetailsItem('Detection rules', '14'); + cy.sa_validateDetailsItem( 'Detector dashboard', 'Not available for this log type' ); cy.wait(5000); // waiting for the page to be reloaded after pushing detector id into route - cy.getElementByText('button.euiTab', 'Alert triggers') + cy.sa_getElementByText('button.euiTab', 'Alert triggers') .should('be.visible') .click(); - validateAlertPanel('test_trigger'); + validateAlertPanel('Trigger 1'); }); }); }); @@ -252,12 +228,12 @@ const createDetector = (detectorName, dataSource, expectFailure) => { const openCreateForm = () => getCreateDetectorButton().click({ force: true }); const getDescriptionField = () => - cy.getTextareaByLabel('Description - optional'); -const getTriggerNameField = () => cy.getFieldByLabel('Trigger name'); + cy.sa_getTextareaByLabel('Description - optional'); +const getTriggerNameField = () => cy.sa_getFieldByLabel('Trigger name'); describe('Detectors', () => { before(() => { - cy.cleanUpTests(); + cy.sa_cleanUpTests(); cy.sa_createIndex(cypressIndexWindows, sample_windows_index_settings); @@ -283,8 +259,8 @@ describe('Detectors', () => { .should('have.property', 'status', 200) ); - cy.createRule(dns_name_rule_data); - cy.createRule(dns_type_rule_data); + cy.sa_createRule(dns_name_rule_data); + cy.sa_createRule(dns_type_rule_data); }); describe('...should validate form fields', () => { @@ -381,7 +357,7 @@ describe('Detectors', () => { .siblings() .contains('Select an input source.'); - getDataSourceField().selectComboboxItem(cypressIndexDns); + getDataSourceField().sa_selectComboboxItem(cypressIndexDns); getDataSourceField() .focus() .blur() @@ -400,38 +376,32 @@ describe('Detectors', () => { it('...should validate alerts page', () => { fillDetailsForm(detectorName, cypressIndexDns); getNextButton().click({ force: true }); - getTriggerNameField().should('be.empty'); - - getTriggerNameField().focus().blur(); - getTriggerNameField() - .parents('.euiFormRow__fieldWrapper') - .find('.euiFormErrorText') - .contains('Enter a name.'); - - getTriggerNameField().type('Trigger name').focus().blur(); + // Open the trigger details accordion + cy.get('[data-test-subj="trigger-details-btn"]').click({ force: true }); + getTriggerNameField().should('have.value', 'Trigger 1'); getTriggerNameField() .parents('.euiFormRow__fieldWrapper') .find('.euiFormErrorText') .should('not.exist'); - getNextButton().should('be.enabled'); + getCreateDetectorButton().should('be.enabled'); getTriggerNameField() .type('{selectall}') .type('{backspace}') .focus() .blur(); - getNextButton().should('be.disabled'); + getCreateDetectorButton().should('be.disabled'); - cy.getButtonByText('Remove').click({ force: true }); - getNextButton().should('be.enabled'); + cy.sa_getButtonByText('Remove').click({ force: true }); + getCreateDetectorButton().should('be.enabled'); }); it('...should show mappings warning', () => { fillDetailsForm(detectorName, cypressIndexDns); - getDataSourceField().selectComboboxItem(cypressIndexWindows); + getDataSourceField().sa_selectComboboxItem(cypressIndexWindows); getDataSourceField().focus().blur(); cy.get('[data-test-subj="define-detector-diff-log-types-warning"]') @@ -455,12 +425,12 @@ describe('Detectors', () => { it('...can fail creation', () => { createDetector(`${detectorName}_fail`, '.kibana_1', true); - cy.getElementByText('.euiCallOut', 'Create detector failed.'); + cy.sa_getElementByText('.euiCallOut', 'Create detector failed.'); }); it('...can be created', () => { createDetector(detectorName, cypressIndexDns, false); - cy.getElementByText('.euiCallOut', 'Detector created successfully'); + cy.sa_getElementByText('.euiCallOut', 'Detector created successfully'); }); it('...basic details can be edited', () => { @@ -469,31 +439,33 @@ describe('Detectors', () => { editDetectorDetails(detectorName, 'Detector details'); - cy.urlShouldContain('edit-detector-details').then(() => { - cy.getElementByText('.euiTitle', 'Edit detector details'); + cy.sa_urlShouldContain('edit-detector-details').then(() => { + cy.sa_getElementByText('.euiTitle', 'Edit detector details'); }); cy.wait('@getIndices'); getNameField() .type('{selectall}{backspace}') .type('test detector edited'); - cy.getTextareaByLabel('Description - optional').type( + cy.sa_getTextareaByLabel('Description - optional').type( 'Edited description' ); - getDataSourceField().clearCombobox(); - getDataSourceField().selectComboboxItem(cypressIndexWindows); + getDataSourceField().sa_clearCombobox(); + getDataSourceField().sa_selectComboboxItem(cypressIndexWindows); - cy.getFieldByLabel('Run every').type('{selectall}{backspace}').type('10'); - cy.getFieldByLabel('Run every', 'select').select('Hours'); + cy.sa_getFieldByLabel('Run every') + .type('{selectall}{backspace}') + .type('10'); + cy.sa_getFieldByLabel('Run every', 'select').select('Hours'); - cy.getElementByText('button', 'Save changes').click({ force: true }); + cy.sa_getElementByText('button', 'Save changes').click({ force: true }); - cy.urlShouldContain('detector-details').then(() => { - cy.validateDetailsItem('Detector name', 'test detector edited'); - cy.validateDetailsItem('Description', 'Edited description'); - cy.validateDetailsItem('Detector schedule', 'Every 10 hours'); - cy.validateDetailsItem('Data source', cypressIndexWindows); + cy.sa_urlShouldContain('detector-details').then(() => { + cy.sa_validateDetailsItem('Detector name', 'test detector edited'); + cy.sa_validateDetailsItem('Description', 'Edited description'); + cy.sa_validateDetailsItem('Detector schedule', 'Every 10 hours'); + cy.sa_validateDetailsItem('Data source', cypressIndexWindows); }); }); @@ -501,23 +473,23 @@ describe('Detectors', () => { openDetectorDetails(detectorName); editDetectorDetails(detectorName, 'Active rules'); - cy.getElementByText('.euiTitle', 'Detection rules (14)'); + cy.sa_getElementByText('.euiTitle', 'Detection rules (14)'); - cy.getInputByPlaceholder('Search...') + cy.sa_getInputByPlaceholder('Search...') .type(`${cypressDNSRule}`) - .pressEnterKey(); + .sa_pressEnterKey(); - cy.getElementByText('.euiTableCellContent button', cypressDNSRule) + cy.sa_getElementByText('.euiTableCellContent button', cypressDNSRule) .parents('td') .prev() .find('.euiTableCellContent button') .click(); - cy.getElementByText('.euiTitle', 'Detection rules (13)'); - cy.getElementByText('button', 'Save changes').click({ force: true }); - cy.urlShouldContain('detector-details').then(() => { - cy.getElementByText('.euiTitle', detectorName); - cy.getElementByText('.euiPanel .euiTitle', 'Active rules (13)'); + cy.sa_getElementByText('.euiTitle', 'Detection rules (13)'); + cy.sa_getElementByText('button', 'Save changes').click({ force: true }); + cy.sa_urlShouldContain('detector-details').then(() => { + cy.sa_getElementByText('.euiTitle', detectorName); + cy.sa_getElementByText('.euiPanel .euiTitle', 'Active rules (13)'); }); }); @@ -530,20 +502,20 @@ describe('Detectors', () => { editDetectorDetails(detectorName, 'Detector details'); - cy.urlShouldContain('edit-detector-details').then(() => { - cy.getElementByText('.euiTitle', 'Edit detector details'); + cy.sa_urlShouldContain('edit-detector-details').then(() => { + cy.sa_getElementByText('.euiTitle', 'Edit detector details'); }); cy.wait('@getIndices'); cy.get('.reviewFieldMappings').should('not.exist'); - getDataSourceField().clearCombobox(); + getDataSourceField().sa_clearCombobox(); getDataSourceField().should('not.have.value'); getDataSourceField().type(`${cypressIndexDns}{enter}`); validateFieldMappingsTable('data source is changed'); - cy.getElementByText('button', 'Save changes').click({ force: true }); + cy.sa_getElementByText('button', 'Save changes').click({ force: true }); }); xit('...should show field mappings if rule selection is changed', () => { @@ -555,8 +527,8 @@ describe('Detectors', () => { editDetectorDetails(detectorName, 'Active rules'); - cy.urlShouldContain('edit-detector-rules').then(() => { - cy.getElementByText('.euiTitle', 'Edit detector rules'); + cy.sa_urlShouldContain('edit-detector-rules').then(() => { + cy.sa_getElementByText('.euiTitle', 'Edit detector rules'); }); cy.get('.reviewFieldMappings').should('not.exist'); @@ -584,11 +556,11 @@ describe('Detectors', () => { cy.wait('@getCustomRules'); cy.wait('@getSigmaRules'); - cy.getButtonByText('Actions') + cy.sa_getButtonByText('Actions') .click({ force: true }) .then(() => { cy.intercept(`${NODE_API.DETECTORS_BASE}/_search`).as('detectors'); - cy.getElementByText('.euiContextMenuItem', 'Delete').click({ + cy.sa_getElementByText('.euiContextMenuItem', 'Delete').click({ force: true, }); cy.wait('@detectors').then(() => { @@ -598,5 +570,5 @@ describe('Detectors', () => { }); }); - after(() => cy.cleanUpTests()); + after(() => cy.sa_cleanUpTests()); }); 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 ac9998122..4b6fa5774 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 @@ -19,7 +19,7 @@ const SAMPLE_RULE = { 'FieldKey|contains:', '- FieldValue', ], - severity: 'critical', + severity: 'Critical', tags: [ 'attack.persistence', 'attack.privilege_escalation', @@ -43,7 +43,7 @@ const YAML_RULE_LINES = [ `- ${SAMPLE_RULE.tags[2]}`, `falsepositives:`, `- ${SAMPLE_RULE.falsePositive}`, - `level: ${SAMPLE_RULE.severity}`, + `level: ${SAMPLE_RULE.severity.toLowerCase()}`, `status: ${SAMPLE_RULE.status}`, `references:`, `- '${SAMPLE_RULE.references}'`, @@ -54,7 +54,7 @@ const YAML_RULE_LINES = [ const checkRulesFlyout = () => { // Search for the rule - cy.get(`input[placeholder="Search rules"]`).ospSearch(SAMPLE_RULE.name); + cy.get(`input[placeholder="Search rules"]`).sa_ospSearch(SAMPLE_RULE.name); // Click the rule link to open the details flyout cy.get(`[data-test-subj="rule_link_${SAMPLE_RULE.name}"]`).click({ @@ -90,7 +90,7 @@ const checkRulesFlyout = () => { // Validate severity cy.get('[data-test-subj="rule_flyout_rule_severity"]').contains( - SAMPLE_RULE.severity + SAMPLE_RULE.severity.toLowerCase() ); // Validate tags @@ -151,12 +151,13 @@ const checkRulesFlyout = () => { }; const getCreateButton = () => cy.get('[data-test-subj="create_rule_button"]'); -const getNameField = () => cy.getFieldByLabel('Rule name'); -const getRuleStatusField = () => cy.getFieldByLabel('Rule Status'); -const getDescriptionField = () => cy.getFieldByLabel('Description - optional'); -const getAuthorField = () => cy.getFieldByLabel('Author'); -const getLogTypeField = () => cy.getFieldByLabel('Log type'); -const getRuleLevelField = () => cy.getFieldByLabel('Rule level (severity)'); +const getNameField = () => cy.sa_getFieldByLabel('Rule name'); +const getRuleStatusField = () => cy.sa_getFieldByLabel('Rule Status'); +const getDescriptionField = () => + cy.sa_getFieldByLabel('Description - optional'); +const getAuthorField = () => cy.sa_getFieldByLabel('Author'); +const getLogTypeField = () => cy.sa_getFieldByLabel('Log type'); +const getRuleLevelField = () => cy.sa_getFieldByLabel('Rule level (severity)'); const getSelectionPanelByIndex = (index) => cy.get(`[data-test-subj="detection-visual-editor-${index}"]`); const getSelectionNameField = () => cy.get('[data-test-subj="selection_name"]'); @@ -195,8 +196,8 @@ const fillCreateForm = () => { getAuthorField().type(`${SAMPLE_RULE.author}`); // rule details - getLogTypeField().type(SAMPLE_RULE.logType); - getRuleLevelField().selectComboboxItem(SAMPLE_RULE.severity); + getLogTypeField().sa_selectComboboxItem(SAMPLE_RULE.logType); + getRuleLevelField().sa_selectComboboxItem(SAMPLE_RULE.severity); // rule detection getSelectionPanelByIndex(0).within(() => { @@ -213,7 +214,7 @@ const fillCreateForm = () => { SAMPLE_RULE.tags.forEach((tag, idx) => { getTagField(idx).type(tag); idx < SAMPLE_RULE.tags.length - 1 && - cy.getButtonByText('Add tag').click({ force: true }); + cy.sa_getButtonByText('Add tag').click({ force: true }); }); getReferenceFieldByIndex(0).type(SAMPLE_RULE.references); @@ -221,7 +222,7 @@ const fillCreateForm = () => { }; describe('Rules', () => { - before(() => cy.cleanUpTests()); + before(() => cy.sa_cleanUpTests()); describe('...should validate form fields', () => { beforeEach(() => { @@ -233,7 +234,7 @@ describe('Rules', () => { cy.wait('@rulesSearch').should('have.property', 'state', 'Complete'); // Check that correct page is showing - cy.waitForPageLoad('rules', { + cy.sa_waitForPageLoad('rules', { contains: 'Detection rules', }); @@ -241,15 +242,15 @@ describe('Rules', () => { }); it('...should validate rule name', () => { - getNameField().containsHelperText( + getNameField().sa_containsHelperText( 'Rule name must contain 5-50 characters. Valid characters are a-z, A-Z, 0-9, hyphens, spaces, and underscores' ); getNameField().should('be.empty'); getNameField().focus().blur(); - getNameField().containsError('Rule name is required'); + getNameField().sa_containsError('Rule name is required'); getNameField().type('text').focus().blur(); - getNameField().containsError('Invalid rule name.'); + getNameField().sa_containsError('Invalid rule name.'); getNameField() .type('{selectall}') @@ -257,7 +258,7 @@ describe('Rules', () => { .type('tex&') .focus() .blur(); - getNameField().containsError('Invalid rule name.'); + getNameField().sa_containsError('Invalid rule name.'); getNameField() .type('{selectall}') @@ -265,7 +266,7 @@ describe('Rules', () => { .type('Rule name') .focus() .blur() - .shouldNotHaveError(); + .sa_shouldNotHaveError(); }); it('...should validate rule description field', () => { @@ -301,15 +302,15 @@ describe('Rules', () => { }); it('...should validate author', () => { - getAuthorField().containsHelperText( + getAuthorField().sa_containsHelperText( 'Combine multiple authors separated with a comma' ); getAuthorField().should('be.empty'); getAuthorField().focus().blur(); - getAuthorField().containsError('Author name is required'); + getAuthorField().sa_containsError('Author name is required'); getAuthorField().type('text').focus().blur(); - getAuthorField().containsError('Invalid author.'); + getAuthorField().sa_containsError('Invalid author.'); getAuthorField() .type('{selectall}') @@ -317,7 +318,7 @@ describe('Rules', () => { .type('tex&') .focus() .blur(); - getAuthorField().containsError('Invalid author.'); + getAuthorField().sa_containsError('Invalid author.'); getAuthorField() .type('{selectall}') @@ -325,40 +326,40 @@ describe('Rules', () => { .type('Rule name') .focus() .blur() - .shouldNotHaveError(); + .sa_shouldNotHaveError(); }); it('...should validate log type field', () => { getLogTypeField().should('be.empty'); getLogTypeField().focus().blur(); - getLogTypeField().containsError('Log type is required'); + getLogTypeField().sa_containsError('Log type is required'); - getLogTypeField().selectComboboxItem(SAMPLE_RULE.logType); - getLogTypeField().focus().blur().shouldNotHaveError(); + getLogTypeField().sa_selectComboboxItem(SAMPLE_RULE.logType); + getLogTypeField().focus().blur().sa_shouldNotHaveError(); }); it('...should validate rule level field', () => { getRuleLevelField().should('be.empty'); getRuleLevelField().focus().blur(); - getRuleLevelField().containsError('Rule level is required'); + getRuleLevelField().sa_containsError('Rule level is required'); - getRuleLevelField().selectComboboxItem(SAMPLE_RULE.severity); - getRuleLevelField().focus().blur().shouldNotHaveError(); + getRuleLevelField().sa_selectComboboxItem(SAMPLE_RULE.severity); + getRuleLevelField().focus().blur().sa_shouldNotHaveError(); }); it('...should validate rule status field', () => { - getRuleStatusField().containsValue(SAMPLE_RULE.status); - getRuleStatusField().focus().blur().shouldNotHaveError(); + getRuleStatusField().sa_containsValue(SAMPLE_RULE.status); + getRuleStatusField().focus().blur().sa_shouldNotHaveError(); - getRuleStatusField().clearCombobox(); + getRuleStatusField().sa_clearCombobox(); getRuleStatusField().focus().blur(); - getRuleStatusField().containsError('Rule status is required'); + getRuleStatusField().sa_containsError('Rule status is required'); }); it('...should validate selection', () => { getSelectionPanelByIndex(0).within(() => { getSelectionNameField().should('have.value', 'Selection_1'); - getSelectionNameField().clearValue(); + getSelectionNameField().sa_clearValue(); getSelectionNameField().focus().blur(); getSelectionNameField() .parentsUntil('.euiFormRow__fieldWrapper') @@ -456,7 +457,7 @@ describe('Rules', () => { .parents('.euiFormRow__fieldWrapper') .contains("Tags must start with 'attack.'"); - getTagField(0).clearValue().type('attack.tag'); + getTagField(0).sa_clearValue().type('attack.tag'); getTagField(0) .parents('.euiFormRow__fieldWrapper') .find('.euiFormErrorText') @@ -468,29 +469,29 @@ describe('Rules', () => { fillCreateForm(); // rule name field - getNameField().clearValue(); + getNameField().sa_clearValue(); toastShouldExist(); getNameField().type('Rule name'); // author field - getAuthorField().clearValue(); + getAuthorField().sa_clearValue(); toastShouldExist(); getAuthorField().type('John Doe'); // log field - getLogTypeField().clearCombobox(); + getLogTypeField().sa_clearCombobox(); toastShouldExist(); - getLogTypeField().selectComboboxItem(SAMPLE_RULE.logType); + getLogTypeField().sa_selectComboboxItem(SAMPLE_RULE.logType); // severity field - getRuleLevelField().clearCombobox(); + getRuleLevelField().sa_clearCombobox(); toastShouldExist(); - getRuleLevelField().selectComboboxItem(SAMPLE_RULE.severity); + getRuleLevelField().sa_selectComboboxItem(SAMPLE_RULE.severity); // status field - getRuleStatusField().clearCombobox(); + getRuleStatusField().sa_clearCombobox(); toastShouldExist(); - getRuleStatusField().selectComboboxItem(SAMPLE_RULE.status); + getRuleStatusField().sa_selectComboboxItem(SAMPLE_RULE.status); // selection name field getSelectionPanelByIndex(0).within(() => @@ -522,7 +523,7 @@ describe('Rules', () => { // selection map list field getSelectionPanelByIndex(0).within(() => { getListRadioField().click({ force: true }); - getMapListField().clearValue(); + getMapListField().sa_clearValue(); }); toastShouldExist(); getSelectionPanelByIndex(0).within(() => { @@ -536,9 +537,9 @@ describe('Rules', () => { getConditionAddButton().click({ force: true }); // tags field - getTagField(0).clearValue().type('wrong.tag'); + getTagField(0).sa_clearValue().type('wrong.tag'); toastShouldExist(); - getTagField(0).clearValue().type('attack.tag'); + getTagField(0).sa_clearValue().type('attack.tag'); }); }); @@ -552,7 +553,7 @@ describe('Rules', () => { cy.wait('@rulesSearch').should('have.property', 'state', 'Complete'); // Check that correct page is showing - cy.waitForPageLoad('rules', { + cy.sa_waitForPageLoad('rules', { contains: 'Detection rules', }); }); @@ -579,7 +580,7 @@ describe('Rules', () => { cy.wait('@getRules'); - cy.waitForPageLoad('rules', { + cy.sa_waitForPageLoad('rules', { contains: 'Detection rules', }); @@ -587,11 +588,13 @@ describe('Rules', () => { }); it('...can be edited', () => { - cy.waitForPageLoad('rules', { + cy.sa_waitForPageLoad('rules', { contains: 'Detection rules', }); - cy.get(`input[placeholder="Search rules"]`).ospSearch(SAMPLE_RULE.name); + cy.get(`input[placeholder="Search rules"]`).sa_ospSearch( + SAMPLE_RULE.name + ); cy.get(`[data-test-subj="rule_link_${SAMPLE_RULE.name}"]`).click({ force: true, }); @@ -611,13 +614,13 @@ describe('Rules', () => { getNameField().type(SAMPLE_RULE.name); getNameField().should('have.value', SAMPLE_RULE.name); - getLogTypeField().clearCombobox(); + getLogTypeField().sa_clearCombobox(); SAMPLE_RULE.logType = 'dns'; YAML_RULE_LINES[2] = `product: ${SAMPLE_RULE.logType}`; YAML_RULE_LINES[3] = `title: ${SAMPLE_RULE.name}`; - getLogTypeField().type(SAMPLE_RULE.logType).type('{enter}'); + getLogTypeField().sa_selectComboboxItem(SAMPLE_RULE.logType); getLogTypeField() - .containsValue(SAMPLE_RULE.logType) + .sa_containsValue(SAMPLE_RULE.logType) .contains(SAMPLE_RULE.logType); SAMPLE_RULE.description += ' edited'; @@ -632,7 +635,7 @@ describe('Rules', () => { submitRule(); - cy.waitForPageLoad('rules', { + cy.sa_waitForPageLoad('rules', { contains: 'Detection rules', }); @@ -650,7 +653,9 @@ describe('Rules', () => { delay: 5000, }).as('getCustomRules'); - cy.get(`input[placeholder="Search rules"]`).ospSearch(SAMPLE_RULE.name); + cy.get(`input[placeholder="Search rules"]`).sa_ospSearch( + SAMPLE_RULE.name + ); // Click the rule link to open the details flyout cy.get(`[data-test-subj="rule_link_${SAMPLE_RULE.name}"]`).click({ @@ -677,7 +682,7 @@ describe('Rules', () => { // Search for sample_detector, presumably deleted cy.wait(3000); - cy.get(`input[placeholder="Search rules"]`).ospSearch( + cy.get(`input[placeholder="Search rules"]`).sa_ospSearch( SAMPLE_RULE.name ); // Click the rule link to open the details flyout @@ -686,5 +691,5 @@ describe('Rules', () => { }); }); - after(() => cy.cleanUpTests()); + after(() => cy.sa_cleanUpTests()); }); 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 f84b86cab..8812d5c28 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 @@ -55,7 +55,7 @@ describe('Alerts', () => { cy.wait('@detectorsSearch').should('have.property', 'state', 'Complete'); // Wait for page to load - cy.waitForPageLoad('alerts', { + cy.sa_waitForPageLoad('alerts', { contains: 'Security alerts', }); @@ -145,7 +145,7 @@ describe('Alerts', () => { expect($tr, `timestamp`).to.contain(date); expect($tr, `rule name`).to.contain('Cypress USB Rule'); expect($tr, `detector name`).to.contain(testDetectorCfg.name); - expect($tr, `log type`).to.contain('windows'); + expect($tr, `log type`).to.contain('System Activity: Windows'); }); // Close the flyout @@ -466,5 +466,5 @@ describe('Alerts', () => { ); }); - after(() => cy.cleanUpTests()); + after(() => cy.sa_cleanUpTests()); }); 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 462c83fa2..f692a6b52 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 @@ -40,7 +40,7 @@ describe('Findings', () => { cy.visit(`${OPENSEARCH_DASHBOARDS_URL}/findings`); // Wait for page to load - cy.waitForPageLoad('findings', { + cy.sa_waitForPageLoad('findings', { contains: 'Findings', }); @@ -55,18 +55,20 @@ describe('Findings', () => { cy.contains('No items found').should('not.exist'); // Check for expected findings - cy.contains('windows'); + cy.contains('System Activity: Windows'); cy.contains('High'); }); it('displays finding details flyout when user clicks on View details icon', () => { // filter table to show only sample_detector findings - cy.get(`input[placeholder="Search findings"]`).ospSearch(indexName); + cy.get(`input[placeholder="Search findings"]`).sa_ospSearch(indexName); // Click View details icon - cy.getTableFirstRow('[data-test-subj="view-details-icon"]').then(($el) => { - cy.get($el).click({ force: true }); - }); + cy.sa_getTableFirstRow('[data-test-subj="view-details-icon"]').then( + ($el) => { + cy.get($el).click({ force: true }); + } + ); // Confirm flyout contents cy.contains('Finding details'); @@ -80,10 +82,10 @@ describe('Findings', () => { it('displays finding details flyout when user clicks on Finding ID', () => { // filter table to show only sample_detector findings - cy.get(`input[placeholder="Search findings"]`).ospSearch(indexName); + cy.get(`input[placeholder="Search findings"]`).sa_ospSearch(indexName); // Click findingId to trigger Finding details flyout - cy.getTableFirstRow( + cy.sa_getTableFirstRow( '[data-test-subj="finding-details-flyout-button"]' ).then(($el) => { cy.get($el).click({ force: true }); @@ -101,7 +103,7 @@ describe('Findings', () => { it('allows user to view details about rules that were triggered', () => { // filter table to show only sample_detector findings - cy.get(`input[placeholder="Search findings"]`).ospSearch(indexName); + cy.get(`input[placeholder="Search findings"]`).sa_ospSearch(indexName); // open Finding details flyout via finding id link. cy.wait essential, timeout insufficient. cy.get(`[data-test-subj="view-details-icon"]`).eq(0).click({ force: true }); @@ -128,12 +130,14 @@ describe('Findings', () => { it('opens rule details flyout when rule name inside accordion drop down is clicked', () => { // filter table to show only sample_detector findings - cy.get(`input[placeholder="Search findings"]`).ospSearch(indexName); + cy.get(`input[placeholder="Search findings"]`).sa_ospSearch(indexName); // open Finding details flyout via finding id link. cy.wait essential, timeout insufficient. - cy.getTableFirstRow('[data-test-subj="view-details-icon"]').then(($el) => { - cy.get($el).click({ force: true }); - }); + cy.sa_getTableFirstRow('[data-test-subj="view-details-icon"]').then( + ($el) => { + cy.get($el).click({ force: true }); + } + ); // Click rule link cy.get( @@ -148,5 +152,5 @@ describe('Findings', () => { }); }); - after(() => cy.cleanUpTests()); + after(() => cy.sa_cleanUpTests()); }); diff --git a/cypress/utils/plugins/security-analytics-dashboards-plugin/commands.js b/cypress/utils/plugins/security-analytics-dashboards-plugin/commands.js index 989590f8b..708b1e8bc 100644 --- a/cypress/utils/plugins/security-analytics-dashboards-plugin/commands.js +++ b/cypress/utils/plugins/security-analytics-dashboards-plugin/commands.js @@ -36,19 +36,19 @@ const { BACKEND_BASE_PATH } = require('../../base_constants'); // -- This will overwrite an existing command -- // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) -Cypress.Commands.add('cleanUpTests', () => { - cy.deleteAllCustomRules(); - cy.deleteAllDetectors(); +Cypress.Commands.add('sa_cleanUpTests', () => { + cy.sa_deleteAllCustomRules(); + cy.sa_deleteAllDetectors(); cy.sa_deleteAllIndices(); }); -Cypress.Commands.add('getTableFirstRow', (selector) => { +Cypress.Commands.add('sa_getTableFirstRow', (selector) => { if (!selector) return cy.get('tbody > tr').first(); return cy.get('tbody > tr:first').find(selector); }); Cypress.Commands.add( - 'waitForPageLoad', + 'sa_waitForPageLoad', (pathname, { timeout = 60000, contains = null }) => { const fullUrl = `${OPENSEARCH_DASHBOARDS_URL}/${pathname}`; Cypress.log({ @@ -60,7 +60,7 @@ Cypress.Commands.add( } ); -Cypress.Commands.add('createDetector', (detectorJSON) => { +Cypress.Commands.add('sa_createDetector', (detectorJSON) => { cy.request( 'POST', `${BACKEND_BASE_PATH}${NODE_API.DETECTORS_BASE}`, @@ -69,7 +69,7 @@ Cypress.Commands.add('createDetector', (detectorJSON) => { }); Cypress.Commands.add( - 'createAliasMappings', + 'sa_createAliasMappings', (indexName, ruleTopic, aliasMappingsBody, partial = true) => { const body = { index_name: indexName, @@ -85,7 +85,7 @@ Cypress.Commands.add( } ); -Cypress.Commands.add('updateDetector', (detectorId, detectorJSON) => { +Cypress.Commands.add('sa_updateDetector', (detectorId, detectorJSON) => { cy.request( 'PUT', `${BACKEND_BASE_PATH}${NODE_API.DETECTORS_BASE}/${detectorId}`, @@ -93,7 +93,7 @@ Cypress.Commands.add('updateDetector', (detectorId, detectorJSON) => { ); }); -Cypress.Commands.add('deleteDetector', (detectorName) => { +Cypress.Commands.add('sa_deleteDetector', (detectorName) => { const body = { from: 0, size: 5000, @@ -125,7 +125,7 @@ Cypress.Commands.add('deleteDetector', (detectorName) => { }); }); -Cypress.Commands.add('deleteAllDetectors', () => { +Cypress.Commands.add('sa_deleteAllDetectors', () => { cy.request({ method: 'DELETE', url: `${BACKEND_BASE_PATH}/.opensearch-sap-detectors-config`, @@ -136,58 +136,58 @@ Cypress.Commands.add('deleteAllDetectors', () => { }); }); -Cypress.Commands.add('getElementByText', (locator, text) => { +Cypress.Commands.add('sa_getElementByText', (locator, text) => { Cypress.log({ message: `Get element by text: ${text}` }); return locator ? cy.get(locator).filter(`:contains("${text}")`).should('be.visible') : cy.contains(text).should('be.visible'); }); -Cypress.Commands.add('getButtonByText', (text) => { +Cypress.Commands.add('sa_getButtonByText', (text) => { Cypress.log({ message: `Get button by text: ${text}` }); - return cy.getElementByText('.euiButton', text); + return cy.sa_getElementByText('.euiButton', text); }); -Cypress.Commands.add('getInputByPlaceholder', (placeholder) => { +Cypress.Commands.add('sa_getInputByPlaceholder', (placeholder) => { Cypress.log({ message: `Get input element by placeholder: ${placeholder}` }); return cy.get(`input[placeholder="${placeholder}"]`); }); -Cypress.Commands.add('getComboboxByPlaceholder', (placeholder) => { +Cypress.Commands.add('sa_getComboboxByPlaceholder', (placeholder) => { Cypress.log({ message: `Get combobox element by placeholder: ${placeholder}`, }); return cy - .getElementByText('.euiComboBoxPlaceholder', placeholder) + .sa_getElementByText('.euiComboBoxPlaceholder', placeholder) .siblings('.euiComboBox__input') .find('input'); }); -Cypress.Commands.add('getFieldByLabel', (label, type = 'input') => { +Cypress.Commands.add('sa_getFieldByLabel', (label, type = 'input') => { Cypress.log({ message: `Get field by label: ${label}` }); return cy - .getElementByText('.euiFormRow__labelWrapper', label) + .sa_getElementByText('.euiFormRow__labelWrapper', label) .siblings() .find(type); }); -Cypress.Commands.add('getTextareaByLabel', (label) => { +Cypress.Commands.add('sa_getTextareaByLabel', (label) => { Cypress.log({ message: `Get textarea by label: ${label}` }); - return cy.getFieldByLabel(label, 'textarea'); + return cy.sa_getFieldByLabel(label, 'textarea'); }); -Cypress.Commands.add('getElementByTestSubject', (subject) => { +Cypress.Commands.add('sa_getElementByTestSubject', (subject) => { Cypress.log({ message: `Get element by test subject: ${subject}` }); return cy.get(`[data-test-subj="${subject}"]`); }); -Cypress.Commands.add('getRadioButtonById', (id) => { +Cypress.Commands.add('sa_getRadioButtonById', (id) => { Cypress.log({ message: `Get radio button by id: ${id}` }); return cy.get(`input[id="${id}"]`); }); Cypress.Commands.add( - 'selectComboboxItem', + 'sa_selectComboboxItem', { prevSubject: true, }, @@ -196,12 +196,15 @@ Cypress.Commands.add( items = [items]; } Cypress.log({ message: `Select combobox items: ${items.join(' | ')}` }); - items.map((item) => cy.wrap(subject).type(item).type('{enter}')); + items.map((item) => { + cy.wrap(subject).type(item); + cy.get(`[title="${item}"]`).click({ force: true }); + }); } ); Cypress.Commands.add( - 'clearCombobox', + 'sa_clearCombobox', { prevSubject: true, }, @@ -215,7 +218,7 @@ Cypress.Commands.add( ); Cypress.Commands.add( - 'containsValue', + 'sa_containsValue', { prevSubject: true, }, @@ -226,7 +229,7 @@ Cypress.Commands.add( ); Cypress.Commands.add( - 'clearValue', + 'sa_clearValue', { prevSubject: true, }, @@ -234,7 +237,7 @@ Cypress.Commands.add( ); Cypress.Commands.add( - 'containsError', + 'sa_containsError', { prevSubject: true, }, @@ -247,7 +250,7 @@ Cypress.Commands.add( ); Cypress.Commands.add( - 'containsHelperText', + 'sa_containsHelperText', { prevSubject: true, }, @@ -260,7 +263,7 @@ Cypress.Commands.add( ); Cypress.Commands.add( - 'shouldNotHaveError', + 'sa_shouldNotHaveError', { prevSubject: true, }, @@ -272,24 +275,24 @@ Cypress.Commands.add( .should('not.exist') ); -Cypress.Commands.add('validateDetailsItem', (label, value) => { +Cypress.Commands.add('sa_validateDetailsItem', (label, value) => { Cypress.log({ message: `Validate details item by label: ${label} and value: ${value}`, }); return cy - .getElementByText('.euiFlexItem label', label) + .sa_getElementByText('.euiFlexItem label', label) .parent() .siblings() .contains(value); }); -Cypress.Commands.add('urlShouldContain', (path) => { +Cypress.Commands.add('sa_urlShouldContain', (path) => { Cypress.log({ message: `Url should contain path: ${path}` }); return cy.url().should('contain', `#/${path}`); }); Cypress.Commands.add( - 'pressEnterKey', + 'sa_pressEnterKey', { prevSubject: true, }, @@ -311,7 +314,7 @@ Cypress.Commands.add( ); Cypress.Commands.add( - 'validateTable', + 'sa_validateTable', { prevSubject: true, }, @@ -352,12 +355,12 @@ Cypress.Commands.add('sa_createIndex', (index, settings = {}) => { ); }); -Cypress.Commands.add('ingestDocument', (indexId, documentJSON) => { +Cypress.Commands.add('sa_ingestDocument', (indexId, documentJSON) => { cy.request('POST', `${BACKEND_BASE_PATH}/${indexId}/_doc`, documentJSON); }); Cypress.Commands.add( - 'insertDocumentToIndex', + 'sa_insertDocumentToIndex', (indexName, documentId, documentBody) => { cy.request({ method: 'POST', @@ -379,7 +382,7 @@ Cypress.Commands.add('sa_deleteAllIndices', () => { }); }); -Cypress.Commands.add('createRule', (ruleJSON) => { +Cypress.Commands.add('sa_createRule', (ruleJSON) => { return cy.request({ method: 'POST', url: `${OPENSEARCH_DASHBOARDS}${NODE_API.RULES_BASE}?category=${ruleJSON.category}`, @@ -390,7 +393,7 @@ Cypress.Commands.add('createRule', (ruleJSON) => { }); }); -Cypress.Commands.add('updateRule', (ruleId, ruleJSON) => { +Cypress.Commands.add('sa_updateRule', (ruleId, ruleJSON) => { cy.request( 'PUT', `${BACKEND_BASE_PATH}${NODE_API.RULES_BASE}/${ruleId}`, @@ -398,7 +401,7 @@ Cypress.Commands.add('updateRule', (ruleId, ruleJSON) => { ); }); -Cypress.Commands.add('deleteRule', (ruleName) => { +Cypress.Commands.add('sa_deleteRule', (ruleName) => { const body = { from: 0, size: 5000, @@ -431,7 +434,7 @@ Cypress.Commands.add('deleteRule', (ruleName) => { }); }); -Cypress.Commands.add('deleteAllCustomRules', () => { +Cypress.Commands.add('sa_deleteAllCustomRules', () => { const url = `${BACKEND_BASE_PATH}/.opensearch-sap-custom-rules-config`; cy.request({ method: 'DELETE', @@ -445,17 +448,17 @@ Cypress.Commands.add('deleteAllCustomRules', () => { }); Cypress.Commands.add( - 'ospSearch', + 'sa_ospSearch', { prevSubject: true, }, (subject, text) => { - return cy.get(subject).clear().ospType(text).realPress('Enter'); + return cy.get(subject).clear().sa_ospType(text).realPress('Enter'); } ); Cypress.Commands.add( - 'ospClear', + 'sa_ospClear', { prevSubject: true, }, @@ -470,7 +473,7 @@ Cypress.Commands.add( ); Cypress.Commands.add( - 'ospType', + 'sa_ospType', { prevSubject: true, }, diff --git a/cypress/utils/plugins/security-analytics-dashboards-plugin/constants.js b/cypress/utils/plugins/security-analytics-dashboards-plugin/constants.js index d7b7595c9..79c637364 100644 --- a/cypress/utils/plugins/security-analytics-dashboards-plugin/constants.js +++ b/cypress/utils/plugins/security-analytics-dashboards-plugin/constants.js @@ -80,13 +80,13 @@ export const createDetector = ( ], }; - cy.cleanUpTests() + cy.sa_cleanUpTests() // Create test index .then(() => cy.sa_createIndex(indexName, indexSettings)) // Create field mappings .then(() => - cy.createAliasMappings( + cy.sa_createAliasMappings( indexName, detectorConfig.detector_type, indexMappings, @@ -95,14 +95,14 @@ export const createDetector = ( ) // Create rule .then(() => { - cy.createRule(ruleSettings) + cy.sa_createRule(ruleSettings) .then((response) => { detectorConfig.inputs[0].detector_input.custom_rules[0].id = response.body.response._id; detectorConfig.triggers[0].ids.push(response.body.response._id); }) // create the detector - .then(() => cy.createDetector(detectorConfig)); + .then(() => cy.sa_createDetector(detectorConfig)); }) .then(() => { // Go to the detectors table page @@ -121,7 +121,7 @@ export const createDetector = ( cy.wait(65000); // Ingest documents to the test index for (let i = 0; i < indexDocsCount; i++) { - cy.insertDocumentToIndex(indexName, '', indexDoc); + cy.sa_insertDocumentToIndex(indexName, '', indexDoc); } return detectorConfig; diff --git a/cypress/utils/plugins/security-analytics-dashboards-plugin/index.d.ts b/cypress/utils/plugins/security-analytics-dashboards-plugin/index.d.ts index c4805c8cc..5e0eb0119 100644 --- a/cypress/utils/plugins/security-analytics-dashboards-plugin/index.d.ts +++ b/cypress/utils/plugins/security-analytics-dashboards-plugin/index.d.ts @@ -11,198 +11,198 @@ declare namespace Cypress { /** * Returns element by its text * @example - * cy.getElementByText('.euiTitle', 'Some title') + * cy.sa_getElementByText('.euiTitle', 'Some title') */ - getElementByText(locator: string, text: string): Chainable; + sa_getElementByText(locator: string, text: string): Chainable; /** * Returns button by its text * @example - * cy.getButtonByText('Button text') + * cy.sa_getButtonByText('Button text') */ - getButtonByText(text: string): Chainable; + sa_getButtonByText(text: string): Chainable; /** * Returns input by its placeholder * @example - * cy.getInputByPlaceholder('Search rules...') + * cy.sa_getInputByPlaceholder('Search rules...') */ - getInputByPlaceholder(placeholder: string): Chainable; + sa_getInputByPlaceholder(placeholder: string): Chainable; /** * Returns combobox input by its placeholder * @example - * cy.getComboboxByPlaceholder('Select data input...') + * cy.sa_getComboboxByPlaceholder('Select data input...') */ - getComboboxByPlaceholder(placeholder: string): Chainable; + sa_getComboboxByPlaceholder(placeholder: string): Chainable; /** * Returns field input by label * @example - * cy.getFieldByLabel('Detector name') + * cy.sa_getFieldByLabel('Detector name') */ - getFieldByLabel(label: string, type?: string): Chainable; + sa_getFieldByLabel(label: string, type?: string): Chainable; /** * Returns textarea by label * @example - * cy.getTextareaByLabel('Detector description') + * cy.sa_getTextareaByLabel('Detector description') */ - getTextareaByLabel(label: string): Chainable; + sa_getTextareaByLabel(label: string): Chainable; /** * Returns element by data-test-subj attribute value * @example - * cy.getElementByTestSubject('alerts-input-element') + * cy.sa_getElementByTestSubject('alerts-input-element') */ - getElementByTestSubject(subject: string): Chainable; + sa_getElementByTestSubject(subject: string): Chainable; /** * Returns radio by id * @example - * cy.getRadioButtonById('radioId') + * cy.sa_getRadioButtonById('radioId') */ - getRadioButtonById(id: string): Chainable; + sa_getRadioButtonById(id: string): Chainable; /** * Selects combobox item(s) * @example - * cy.get('combo).selectComboboxItem('some item value') + * cy.get('combo).sa_selectComboboxItem('some item value') */ - selectComboboxItem(items: string | string[]): Chainable; + sa_selectComboboxItem(items: string | string[]): Chainable; /** * Clears combobox value(s) * @example - * cy.get('combo).clearCombobox() + * cy.get('combo).sa_clearCombobox() */ - clearCombobox(): Chainable; + sa_clearCombobox(): Chainable; /** * Triggers enter key event on the focused element * @example - * cy.pressEnterKey() + * cy.sa_pressEnterKey() */ - pressEnterKey(): Chainable; + sa_pressEnterKey(): Chainable; /** * Triggers backspace key event on the focused element * @example - * cy.pressBackspaceKey() + * cy.sa_pressBackspaceKey() */ - pressBackspaceKey(numberOfPresses?: number): Chainable; + sa_pressBackspaceKey(numberOfPresses?: number): Chainable; /** * Validates details panel item * @example - * cy.validateDetailsItem('Data source', '.index-name') + * cy.sa_validateDetailsItem('Data source', '.index-name') */ - validateDetailsItem(label: string, value: string): Chainable; + sa_validateDetailsItem(label: string, value: string): Chainable; /** * Should clear a field value (use with text and textarea fields) * @example - * cy.getFieldByLabel('Rule name').clearValue() + * cy.sa_getFieldByLabel('Rule name').sa_clearValue() */ - clearValue(): Chainable; + sa_clearValue(): Chainable; /** * Validates that field contains value * Should be used with combobox or other fields that don't print its value in inputs * @example - * cy.getFieldByLabel('Rule name').containsValue('Name') + * cy.sa_getFieldByLabel('Rule name').sa_containsValue('Name') */ - containsValue(value: string): Chainable; + sa_containsValue(value: string): Chainable; /** * Validates that field has error text * @example - * cy.getFieldByLabel('Rule name').containsError('This fields is invalid') + * cy.sa_getFieldByLabel('Rule name').sa_containsError('This fields is invalid') */ - containsError(errorText: string): Chainable; + sa_containsError(errorText: string): Chainable; /** * Validates that field has helper text * @example - * cy.getFieldByLabel('Rule name').containsHelperText('Use this field for...') + * cy.sa_getFieldByLabel('Rule name').sa_containsHelperText('Use this field for...') */ - containsHelperText(helperText: string): Chainable; + sa_containsHelperText(helperText: string): Chainable; /** * Should not have error text * @example - * cy.getFieldByLabel('Rule name').shouldNotHaveError() + * cy.sa_getFieldByLabel('Rule name').sa_shouldNotHaveError() */ - shouldNotHaveError(): Chainable; + sa_shouldNotHaveError(): Chainable; /** * Validates url path * @example - * cy.urlShouldContain('/detector-details') + * cy.sa_urlShouldContain('/detector-details') */ - urlShouldContain(path: string): Chainable; + sa_urlShouldContain(path: string): Chainable; /** * Validates table items * @example - * cy.validateTable('/detector-details') + * cy.sa_validateTable('/detector-details') */ - validateTable(data: { [key: string]: string }[]): Chainable; + sa_validateTable(data: { [key: string]: string }[]): Chainable; /** * Removes custom indices, detectors and rules * @example - * cy.cleanUpTests() + * cy.sa_cleanUpTests() */ - cleanUpTests(): Chainable; + sa_cleanUpTests(): Chainable; /** * Returns table first row * Finds elements deeper in a row with selector * @param {string} selector * @example - * cy.getTableFirstRow() - * cy.getTableFirstRow('td') + * cy.sa_getTableFirstRow() + * cy.sa_getTableFirstRow('td') */ - getTableFirstRow(selector: string): Chainable; + sa_getTableFirstRow(selector: string): Chainable; /** * Waits for page to be loaded * @param {string} pathname * @param {any} opts * @example - * cy.waitForPageLoad('detectors') - * cy.waitForPageLoad('detectors', { + * cy.sa_waitForPageLoad('detectors') + * cy.sa_waitForPageLoad('detectors', { * timeout: 20000, * contains: 'text to verify' * }) */ - waitForPageLoad(pathname: string, opts?: any): Chainable; + sa_waitForPageLoad(pathname: string, opts?: any): Chainable; /** * Returns table first row * Can find elements deeper in a row with selector * @param {string} text * @example - * cy.get('selector').ospSearch('Txt to write into input') + * cy.get('selector').sa_ospSearch('Txt to write into input') */ - ospSearch(text: string): Chainable; + sa_ospSearch(text: string): Chainable; /** * Clears input text * @example - * cy.get('selector').ospClear() + * cy.get('selector').sa_ospClear() */ - ospClear(): Chainable; + sa_ospClear(): Chainable; /** * Returns table first row * Can find elements deeper in a row with selector * @param {string} text * @example - * cy.get('selector').ospType('Txt to write into input') + * cy.get('selector').sa_ospType('Txt to write into input') */ - ospType(text: string): Chainable; + sa_ospType(text: string): Chainable; /** * Creates index with optional settings @@ -214,9 +214,9 @@ declare namespace Cypress { /** * Creates an index template. * @example - * cy.createIndexTemplate("some_index_template", { "index_patterns": "abc", "properties": { ... } }) + * cy.sa_createIndexTemplate("some_index_template", { "index_patterns": "abc", "properties": { ... } }) */ - createIndexTemplate(name: string, template: object): Chainable; + sa_createIndexTemplate(name: string, template: object): Chainable; /** /** @@ -229,30 +229,30 @@ declare namespace Cypress { /** * Deletes all custom rules in cluster * @example - * cy.deleteAllCustomRules() + * cy.sa_deleteAllCustomRules() */ - deleteAllCustomRules(): Chainable; + sa_deleteAllCustomRules(): Chainable; /** * Deletes all detectors in cluster * @example - * cy.deleteAllDetectors() + * cy.sa_deleteAllDetectors() */ - deleteAllDetectors(): Chainable; + sa_deleteAllDetectors(): Chainable; /** * Creates a detector * @example - * cy.createPolicy({ "detector_type": ... }) + * cy.sa_createPolicy({ "detector_type": ... }) */ - createDetector(detectorJSON: object): Chainable; + sa_createDetector(detectorJSON: object): Chainable; /** * Creates a fields mapping aliases for detector * @example - * cy.createAliasMappings('indexName', 'windows', {...}, true) + * cy.sa_createAliasMappings('indexName', 'windows', {...}, true) */ - createAliasMappings( + sa_createAliasMappings( indexName: string, ruleTopic: string, aliasMappingsBody: object, @@ -262,22 +262,22 @@ declare namespace Cypress { /** * Creates a custom rule * @example - * cy.createRule({}) + * cy.sa_createRule({}) */ - createRule(ruleJSON: object): Chainable; + sa_createRule(ruleJSON: object): Chainable; /** * Updates settings for index * @example - * cy.updateIndexSettings("some_index", settings) + * cy.sa_updateIndexSettings("some_index", settings) */ - updateDetector(detectorId: string, detectorJSON: object): Chainable; + sa_updateDetector(detectorId: string, detectorJSON: object): Chainable; /** * Deletes detector by its name * @example - * cy.deleteDetector("Cypress detector name") + * cy.sa_deleteDetector("Cypress detector name") */ - deleteDetector(name: string): Chainable; + sa_deleteDetector(name: string): Chainable; } }