diff --git a/x-pack/plugins/security_solution/cypress/e2e/detection_rules/rules_table_auto_refresh.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/rules_table_auto_refresh.cy.ts index ec553a15c2b2f..10f6387a9289f 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/detection_rules/rules_table_auto_refresh.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/rules_table_auto_refresh.cy.ts @@ -8,20 +8,19 @@ import { RULE_CHECKBOX, REFRESH_RULES_STATUS, - REFRESH_SETTINGS_SWITCH, - REFRESH_SETTINGS_SELECTION_NOTE, + RULES_TABLE_AUTOREFRESH_INDICATOR, + RULES_MANAGEMENT_TABLE, } from '../../screens/alerts_detection_rules'; import { - checkAutoRefresh, - waitForRulesTableToBeLoaded, selectAllRules, - openRefreshSettingsPopover, clearAllRuleSelection, selectNumberOfRules, mockGlobalClock, disableAutoRefresh, - checkAutoRefreshIsDisabled, - checkAutoRefreshIsEnabled, + expectAutoRefreshIsDisabled, + expectAutoRefreshIsEnabled, + expectAutoRefreshIsDeactivated, + expectNumberOfRules, } from '../../tasks/alerts_detection_rules'; import { login, visit, visitWithoutDateRange } from '../../tasks/login'; @@ -29,16 +28,16 @@ import { DETECTIONS_RULE_MANAGEMENT_URL } from '../../urls/navigation'; import { createRule } from '../../tasks/api_calls/rules'; import { cleanKibana } from '../../tasks/common'; import { getNewRule } from '../../objects/rule'; -import { setRowsPerPageTo } from '../../tasks/table_pagination'; const DEFAULT_RULE_REFRESH_INTERVAL_VALUE = 60000; +const NUM_OF_TEST_RULES = 6; -// TODO: See https://github.com/elastic/kibana/issues/154694 -describe.skip('Alerts detection rules table auto-refresh', () => { +describe('Rules table: auto-refresh', () => { before(() => { cleanKibana(); login(); - for (let i = 1; i < 7; i += 1) { + + for (let i = 1; i <= NUM_OF_TEST_RULES; ++i) { createRule(getNewRule({ name: `Test rule ${i}`, rule_id: `${i}` })); } }); @@ -48,31 +47,31 @@ describe.skip('Alerts detection rules table auto-refresh', () => { }); it('Auto refreshes rules', () => { + mockGlobalClock(); visitWithoutDateRange(DETECTIONS_RULE_MANAGEMENT_URL); - waitForRulesTableToBeLoaded(); - - // ensure rules have rendered. As there is no user interaction in this test, - // rules were not rendered before test completes - cy.get(RULE_CHECKBOX).should('have.length', 6); + expectNumberOfRules(RULES_MANAGEMENT_TABLE, NUM_OF_TEST_RULES); // // mock 1 minute passing to make sure refresh is conducted - mockGlobalClock(); - checkAutoRefresh(DEFAULT_RULE_REFRESH_INTERVAL_VALUE, 'be.visible'); + cy.get(RULES_TABLE_AUTOREFRESH_INDICATOR).should('not.exist'); + cy.tick(DEFAULT_RULE_REFRESH_INTERVAL_VALUE); + cy.get(RULES_TABLE_AUTOREFRESH_INDICATOR).should('be.visible'); cy.contains(REFRESH_RULES_STATUS, 'Updated now'); }); it('should prevent table from rules refetch if any rule selected', () => { + mockGlobalClock(); visitWithoutDateRange(DETECTIONS_RULE_MANAGEMENT_URL); - waitForRulesTableToBeLoaded(); + expectNumberOfRules(RULES_MANAGEMENT_TABLE, NUM_OF_TEST_RULES); selectNumberOfRules(1); // mock 1 minute passing to make sure refresh is not conducted - mockGlobalClock(); - checkAutoRefresh(DEFAULT_RULE_REFRESH_INTERVAL_VALUE, 'not.exist'); + cy.get(RULES_TABLE_AUTOREFRESH_INDICATOR).should('not.exist'); + cy.tick(DEFAULT_RULE_REFRESH_INTERVAL_VALUE); + cy.get(RULES_TABLE_AUTOREFRESH_INDICATOR).should('not.exist'); // ensure rule is still selected cy.get(RULE_CHECKBOX).first().should('be.checked'); @@ -82,50 +81,37 @@ describe.skip('Alerts detection rules table auto-refresh', () => { it('should disable auto refresh when any rule selected and enable it after rules unselected', () => { visit(DETECTIONS_RULE_MANAGEMENT_URL); - waitForRulesTableToBeLoaded(); - setRowsPerPageTo(5); + + expectNumberOfRules(RULES_MANAGEMENT_TABLE, NUM_OF_TEST_RULES); // check refresh settings if it's enabled before selecting - openRefreshSettingsPopover(); - checkAutoRefreshIsEnabled(); + expectAutoRefreshIsEnabled(); selectAllRules(); - // auto refresh should be disabled after rules selected - openRefreshSettingsPopover(); - checkAutoRefreshIsDisabled(); - - // if any rule selected, refresh switch should be disabled and help note to users should displayed - cy.get(REFRESH_SETTINGS_SWITCH).should('be.disabled'); - cy.contains( - REFRESH_SETTINGS_SELECTION_NOTE, - 'Note: Refresh is disabled while there is an active selection.' - ); + // auto refresh should be deactivated (which means disabled without an ability to enable it) after rules selected + expectAutoRefreshIsDeactivated(); clearAllRuleSelection(); - // after all rules unselected, auto refresh should renew - openRefreshSettingsPopover(); - checkAutoRefreshIsEnabled(); + // after all rules unselected, auto refresh should be reset to its previous state + expectAutoRefreshIsEnabled(); }); it('should not enable auto refresh after rules were unselected if auto refresh was disabled', () => { visit(DETECTIONS_RULE_MANAGEMENT_URL); - waitForRulesTableToBeLoaded(); - setRowsPerPageTo(5); - openRefreshSettingsPopover(); + expectNumberOfRules(RULES_MANAGEMENT_TABLE, NUM_OF_TEST_RULES); + disableAutoRefresh(); selectAllRules(); - openRefreshSettingsPopover(); - checkAutoRefreshIsDisabled(); + expectAutoRefreshIsDeactivated(); clearAllRuleSelection(); // after all rules unselected, auto refresh should still be disabled - openRefreshSettingsPopover(); - checkAutoRefreshIsDisabled(); + expectAutoRefreshIsDisabled(); }); }); diff --git a/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts b/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts index 5ba64892e741a..c9f15f44ae23b 100644 --- a/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts +++ b/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts @@ -169,7 +169,7 @@ export const RULES_SELECTED_TAG = '.euiSelectableListItem[aria-checked="true"]'; export const SELECTED_RULES_NUMBER_LABEL = '[data-test-subj="selectedRules"]'; -export const REFRESH_SETTINGS_POPOVER = '[data-test-subj="refreshSettings-popover"]'; +export const AUTO_REFRESH_POPOVER_TRIGGER_BUTTON = '[data-test-subj="autoRefreshButton"]'; export const REFRESH_RULES_TABLE_BUTTON = '[data-test-subj="refreshRulesAction-linkIcon"]'; diff --git a/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts b/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts index 97dbdad4506a9..0a349fa26e124 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts @@ -42,7 +42,6 @@ import { RULES_TAGS_POPOVER_WRAPPER, INTEGRATIONS_POPOVER, SELECTED_RULES_NUMBER_LABEL, - REFRESH_SETTINGS_POPOVER, REFRESH_SETTINGS_SWITCH, ELASTIC_RULES_BTN, BULK_EXPORT_ACTION_BTN, @@ -65,6 +64,7 @@ import { DUPLICATE_WITH_EXCEPTIONS_WITHOUT_EXPIRED_OPTION, TOASTER_CLOSE_ICON, ADD_ELASTIC_RULES_EMPTY_PROMPT_BTN, + AUTO_REFRESH_POPOVER_TRIGGER_BUTTON, } from '../screens/alerts_detection_rules'; import type { RULES_MONITORING_TABLE } from '../screens/alerts_detection_rules'; import { EUI_CHECKBOX } from '../screens/common/controls'; @@ -506,22 +506,45 @@ export const testMultipleSelectedRulesLabel = (rulesCount: number) => { cy.get(SELECTED_RULES_NUMBER_LABEL).should('have.text', `Selected ${rulesCount} rules`); }; -export const openRefreshSettingsPopover = () => { - cy.get(REFRESH_SETTINGS_POPOVER).click(); +const openRefreshSettingsPopover = () => { + cy.get(REFRESH_SETTINGS_SWITCH).should('not.exist'); + cy.get(AUTO_REFRESH_POPOVER_TRIGGER_BUTTON).click(); cy.get(REFRESH_SETTINGS_SWITCH).should('be.visible'); }; -export const checkAutoRefreshIsDisabled = () => { +const closeRefreshSettingsPopover = () => { + cy.get(REFRESH_SETTINGS_SWITCH).should('be.visible'); + cy.get(AUTO_REFRESH_POPOVER_TRIGGER_BUTTON).click(); + cy.get(REFRESH_SETTINGS_SWITCH).should('not.exist'); +}; + +export const expectAutoRefreshIsDisabled = () => { + cy.get(AUTO_REFRESH_POPOVER_TRIGGER_BUTTON).should('be.enabled'); + cy.get(AUTO_REFRESH_POPOVER_TRIGGER_BUTTON).should('have.text', 'Off'); + openRefreshSettingsPopover(); cy.get(REFRESH_SETTINGS_SWITCH).should('have.attr', 'aria-checked', 'false'); + closeRefreshSettingsPopover(); }; -export const checkAutoRefreshIsEnabled = () => { +export const expectAutoRefreshIsEnabled = () => { + cy.get(AUTO_REFRESH_POPOVER_TRIGGER_BUTTON).should('be.enabled'); + cy.get(AUTO_REFRESH_POPOVER_TRIGGER_BUTTON).should('have.text', 'On'); + openRefreshSettingsPopover(); cy.get(REFRESH_SETTINGS_SWITCH).should('have.attr', 'aria-checked', 'true'); + closeRefreshSettingsPopover(); +}; + +// Expects the auto refresh to be deactivated which means it's disabled without an ability to enable it +// so it's even impossible to open the popover +export const expectAutoRefreshIsDeactivated = () => { + cy.get(AUTO_REFRESH_POPOVER_TRIGGER_BUTTON).should('be.disabled'); + cy.get(AUTO_REFRESH_POPOVER_TRIGGER_BUTTON).should('have.text', 'Off'); }; export const disableAutoRefresh = () => { + openRefreshSettingsPopover(); cy.get(REFRESH_SETTINGS_SWITCH).click(); - checkAutoRefreshIsDisabled(); + expectAutoRefreshIsDisabled(); }; export const mockGlobalClock = () => { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/auto_refresh_button/auto_refresh_button.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/auto_refresh_button/auto_refresh_button.tsx index 83499efd323c8..560be75abee26 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/auto_refresh_button/auto_refresh_button.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/auto_refresh_button/auto_refresh_button.tsx @@ -41,9 +41,14 @@ const AutoRefreshButtonComponent = ({ setIsRefreshOn, }: AutoRefreshButtonProps) => { const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const closePopover = useCallback(() => setIsPopoverOpen(false), [setIsPopoverOpen]); + const togglePopover = useCallback( + () => setIsPopoverOpen((prevState) => !prevState), + [setIsPopoverOpen] + ); const handleAutoRefreshSwitch = useCallback( - (closePopover: () => void) => (e: EuiSwitchEvent) => { + (e: EuiSwitchEvent) => { const refreshOn = e.target.checked; if (refreshOn) { reFetchRules(); @@ -51,18 +56,35 @@ const AutoRefreshButtonComponent = ({ setIsRefreshOn(refreshOn); closePopover(); }, - [reFetchRules, setIsRefreshOn] + [reFetchRules, setIsRefreshOn, closePopover] ); - const handleGetRefreshSettingsPopoverContent = useCallback( - (closePopover: () => void) => ( + return ( + + {isRefreshOn ? 'On' : 'Off'} + + } + > - ), - [isRefreshOn, handleAutoRefreshSwitch, isDisabled] - ); - - return ( - setIsPopoverOpen(false)} - button={ - setIsPopoverOpen(!isPopoverOpen)} - disabled={isDisabled} - css={css` - margin-left: 10px; - `} - > - {isRefreshOn ? 'On' : 'Off'} - - } - > - {handleGetRefreshSettingsPopoverContent(() => setIsPopoverOpen(false))} ); };