Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.9] [Security Solution] Unskip rules table auto-refresh Cypress tests (#163451) #164062

Merged
merged 2 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,36 @@
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';

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}` }));
}
});
Expand All @@ -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');
Expand All @@ -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();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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"]';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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';
Expand Down Expand Up @@ -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 = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,28 +41,50 @@ 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();
}
setIsRefreshOn(refreshOn);
closePopover();
},
[reFetchRules, setIsRefreshOn]
[reFetchRules, setIsRefreshOn, closePopover]
);

const handleGetRefreshSettingsPopoverContent = useCallback(
(closePopover: () => void) => (
return (
<EuiPopover
isOpen={isPopoverOpen}
closePopover={closePopover}
button={
<EuiButtonEmpty
data-test-subj="autoRefreshButton"
color={'text'}
iconType={'timeRefresh'}
onClick={togglePopover}
disabled={isDisabled}
css={css`
margin-left: 10px;
`}
>
{isRefreshOn ? 'On' : 'Off'}
</EuiButtonEmpty>
}
>
<EuiContextMenuPanel
items={[
<EuiSwitch
key="allRulesAutoRefreshSwitch"
label={i18n.REFRESH_RULE_POPOVER_DESCRIPTION}
checked={isRefreshOn ?? false}
onChange={handleAutoRefreshSwitch(closePopover)}
onChange={handleAutoRefreshSwitch}
compressed
disabled={isDisabled}
data-test-subj="refreshSettingsSwitch"
Expand All @@ -82,30 +104,6 @@ const AutoRefreshButtonComponent = ({
: []),
]}
/>
),
[isRefreshOn, handleAutoRefreshSwitch, isDisabled]
);

return (
<EuiPopover
isOpen={isPopoverOpen}
closePopover={() => setIsPopoverOpen(false)}
button={
<EuiButtonEmpty
data-test-subj="autoRefreshButton"
color={'text'}
iconType={'timeRefresh'}
onClick={() => setIsPopoverOpen(!isPopoverOpen)}
disabled={isDisabled}
css={css`
margin-left: 10px;
`}
>
{isRefreshOn ? 'On' : 'Off'}
</EuiButtonEmpty>
}
>
{handleGetRefreshSettingsPopoverContent(() => setIsPopoverOpen(false))}
</EuiPopover>
);
};
Expand Down