diff --git a/cypress/integration/1_detectors.spec.js b/cypress/integration/1_detectors.spec.js index 47e8e35f0..5d4439ecf 100644 --- a/cypress/integration/1_detectors.spec.js +++ b/cypress/integration/1_detectors.spec.js @@ -129,7 +129,7 @@ const createDetector = (detectorName, dataSource, expectFailure) => { .click({ force: true, timeout: 5000 }) .then(() => cy.contains('.euiTable .euiTableRow', 'Dns')); - cy.getElementByText('.euiAccordion .euiTitle', 'Configure field mapping - optional'); + cy.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') { @@ -141,8 +141,9 @@ const createDetector = (detectorName, dataSource, expectFailure) => { getNextButton().click({ force: true }); // TEST ALERTS PAGE + // Open the trigger details accordion + cy.get('[data-test-subj="trigger-details-btn"]').click({ force: true }); 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') .type(`attack.defense_evasion{enter}`) .find('input') @@ -151,27 +152,8 @@ const createDetector = (detectorName, dataSource, expectFailure) => { cy.getFieldByLabel('Specify alert severity').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', '/mappings').as('createMappingsRequest'); - cy.intercept('POST', '/detectors').as('createDetectorRequest'); + cy.intercept('POST', '/_plugins/_security_analytics/mappings').as('createMappingsRequest'); + cy.intercept('POST', '/_plugins/_security_analytics/detectors').as('createDetectorRequest'); // create the detector cy.getElementByText('button', 'Create').click({ force: true }); @@ -199,7 +181,7 @@ const createDetector = (detectorName, dataSource, expectFailure) => { cy.wait(5000); // waiting for the page to be reloaded after pushing detector id into route cy.getElementByText('button.euiTab', 'Alert triggers').should('be.visible').click(); - validateAlertPanel('test_trigger'); + validateAlertPanel('Trigger 1'); }); }); }); @@ -239,7 +221,7 @@ describe('Detectors', () => { describe('...should validate form fields', () => { beforeEach(() => { - cy.intercept('/detectors/_search').as('detectorsSearch'); + cy.intercept('/_plugins/_security_analytics/detectors/_search').as('detectorsSearch'); // Visit Detectors page before any test cy.visit(`${OPENSEARCH_DASHBOARDS_URL}/detectors`); @@ -342,28 +324,21 @@ 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'); + getCreateDetectorButton().should('be.enabled'); }); it('...should show mappings warning', () => { @@ -382,7 +357,7 @@ describe('Detectors', () => { describe('...validate create detector flow', () => { beforeEach(() => { - cy.intercept('/detectors/_search').as('detectorsSearch'); + cy.intercept('/_plugins/_security_analytics/detectors/_search').as('detectorsSearch'); // Visit Detectors page before any test cy.visit(`${OPENSEARCH_DASHBOARDS_URL}/detectors`); @@ -400,7 +375,7 @@ describe('Detectors', () => { }); it('...basic details can be edited', () => { - cy.intercept('GET', '/indices').as('getIndices'); + cy.intercept('GET', '/_plugins/_security_analytics/indices').as('getIndices'); openDetectorDetails(detectorName); editDetectorDetails(detectorName, 'Detector details'); diff --git a/public/pages/CreateDetector/components/ConfigureAlerts/components/AlertCondition/AlertConditionPanel.tsx b/public/pages/CreateDetector/components/ConfigureAlerts/components/AlertCondition/AlertConditionPanel.tsx index 79939763b..9025bd3e9 100644 --- a/public/pages/CreateDetector/components/ConfigureAlerts/components/AlertCondition/AlertConditionPanel.tsx +++ b/public/pages/CreateDetector/components/ConfigureAlerts/components/AlertCondition/AlertConditionPanel.tsx @@ -18,7 +18,6 @@ import { EuiText, EuiTextArea, } from '@elastic/eui'; -import { Detector } from '../../../../../../../models/interfaces'; import { AlertCondition } from '../../../../../../../models/interfaces'; import { createSelectedOptions, @@ -31,6 +30,7 @@ import { NotificationChannelOption, NotificationChannelTypeOptions } from '../.. import { NOTIFICATIONS_HREF } from '../../../../../../utils/constants'; import { getNameErrorMessage, validateName } from '../../../../../../utils/validation'; import { NotificationsCallOut } from '../../../../../../components/NotificationsCallOut'; +import { Detector } from '../../../../../../../types'; interface AlertConditionPanelProps extends RouteComponentProps { alertCondition: AlertCondition; @@ -299,172 +299,213 @@ export default class AlertConditionPanel extends Component< }); } + const triggerDetailsSubheading = ` + ${ + selectedNames.length === 1 + ? '1 rule' + : `${!selectedNames.length ? 'All' : selectedNames.length} rules` + }, + ${ + ruleSeverityLevels.length === 1 + ? '1 severity' + : `${!ruleSeverityLevels.length ? 'All' : ruleSeverityLevels.length} severities` + }, + ${tags.length === 1 ? '1 tag' : `${!tags.length ? 'All' : tags.length} tags`} + `; + return (
- -

Trigger name

- + + Trigger details and condition + + {triggerDetailsSubheading} + +
} - isInvalid={nameFieldTouched && nameIsInvalid} - error={getNameErrorMessage(name, nameIsInvalid, nameFieldTouched)} > - - - - - -

If a detection rule matches

-
- + +

Trigger name

+ + } + isInvalid={nameFieldTouched && nameIsInvalid} + error={getNameErrorMessage(name, nameIsInvalid, nameFieldTouched)} + > + +
+ + + +

If a detection rule matches

+
+ - -

Rule names

- - } - > - -
- + +

Rule names

+ + } + > + +
+ - -

Rule Severities

- - } - > - -
- + +

Rule Severities

+ + } + > + +
+ - -

Tags

- - } - > - -
- - + +

Tags

+ + } + > + +
+ + + -

Alert and notify

+

Notification

- -

Specify alert severity

- + + Notification + + {`Configure notification to receive alerts when the trigger condition is met.`} + + } > - +

Specify alert severity

+ } - onChange={this.onAlertSeverityChange} - singleSelection={{ asPlainText: true }} - isClearable={false} - data-test-subj={'security-levels-combo-box'} - /> -
+ > + + - + - - - -

Select channel to notify

- - } - > - []} - selectedOptions={ - selectedNotificationChannelOption as EuiComboBoxOptionOption[] + + + +

Select channel to notify

+ } - onChange={this.onNotificationChannelsChange} - singleSelection={{ asPlainText: true }} - onBlur={refreshNotificationChannels} + > + []} + selectedOptions={ + selectedNotificationChannelOption as EuiComboBoxOptionOption[] + } + onChange={this.onNotificationChannelsChange} + singleSelection={{ asPlainText: true }} + onBlur={refreshNotificationChannels} + isDisabled={!hasNotificationPlugin} + /> +
+
+ + -
-
- - - Manage channels - - -
- - {!hasNotificationPlugin && ( - <> - - - - )} - - + > + Manage channels + + + + + {!hasNotificationPlugin && ( + <> + + + + )} + + + -

Show notify message

+

Notification message

} - paddingSize={'none'} + paddingSize={'l'} initialIsOpen={false} > -
-
- -
-
-
-
- -
-
-
-
-
-
-

- If a detection rule matches -

-
-
-
- -
-
- -
-
-
-
-
- + +
- -
-
-
- -
-
-