Skip to content

Commit

Permalink
[Security Solution] Unskip alerts cell actions tests (#174096)
Browse files Browse the repository at this point in the history
## Summary

This PR unskips alerts cell actions tests, skipped here:

#172233
#172231
#173442
#172230
#172232

It also:
- combines a few cases and beforeEach steps.
- removes some of the force clicks from the click action task.

FTR build:
https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4783
  • Loading branch information
lgestc authored Jan 8, 2024
1 parent befc63e commit a48eb82
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 121 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
clickExpandActions,
filterOutAlertProperty,
} from '../../../tasks/alerts';
import { deleteAlertsAndRules } from '../../../tasks/api_calls/common';
import { createRule } from '../../../tasks/api_calls/rules';
import { waitForAlertsToPopulate } from '../../../tasks/create_new_rule';
import { login } from '../../../tasks/login';
Expand All @@ -31,145 +32,110 @@ import {
fillAddFilterForm,
fillKqlQueryBar,
openAddFilterPopover,
removeKqlFilter,
} from '../../../tasks/search_bar';
import { openActiveTimeline } from '../../../tasks/timeline';

import { ALERTS_URL } from '../../../urls/navigation';

describe.skip('Alerts cell actions', { tags: ['@ess', '@serverless'] }, () => {
before(() => {
describe('Alerts cell actions', { tags: ['@ess', '@serverless'] }, () => {
beforeEach(() => {
deleteAlertsAndRules();
createRule(getNewRule());
login();
visit(ALERTS_URL);
waitForAlertsToPopulate();
});

describe('Filter', () => {
beforeEach(() => {
login();
visit(ALERTS_URL);
waitForAlertsToPopulate();
});
it('should filter for and out', () => {
cy.log('should work for a non-empty property');
cy.get(ALERT_TABLE_SEVERITY_VALUES)
.first()
.invoke('text')
.then((severityVal) => {
scrollAlertTableColumnIntoView(ALERT_TABLE_SEVERITY_HEADER);
filterForAlertProperty(ALERT_TABLE_SEVERITY_VALUES, 0);
cy.get(FILTER_BADGE).first().should('have.text', `kibana.alert.severity: ${severityVal}`);
});

it('should filter for a non-empty property', () => {
cy.get(ALERT_TABLE_SEVERITY_VALUES)
.first()
.invoke('text')
.then((severityVal) => {
scrollAlertTableColumnIntoView(ALERT_TABLE_SEVERITY_HEADER);
filterForAlertProperty(ALERT_TABLE_SEVERITY_VALUES, 0);
cy.get(FILTER_BADGE).first().should('have.text', `kibana.alert.severity: ${severityVal}`);
});
});
removeKqlFilter();

it('should filter for an empty property', () => {
// add query condition to make sure the field is empty
fillKqlQueryBar('not file.name: *{enter}');
cy.log('should work for empty properties');
// add query condition to make sure the field is empty
fillKqlQueryBar('not file.name: *{enter}');

scrollAlertTableColumnIntoView(ALERT_TABLE_FILE_NAME_HEADER);
filterForAlertProperty(ALERT_TABLE_FILE_NAME_VALUES, 0);
scrollAlertTableColumnIntoView(ALERT_TABLE_FILE_NAME_HEADER);

cy.get(FILTER_BADGE).first().should('have.text', 'NOT file.name: exists');
});
cy.log('filter for alert property');

it('should filter out a non-empty property', () => {
cy.get(ALERT_TABLE_SEVERITY_VALUES)
.first()
.invoke('text')
.then((severityVal) => {
scrollAlertTableColumnIntoView(ALERT_TABLE_SEVERITY_HEADER);
filterOutAlertProperty(ALERT_TABLE_SEVERITY_VALUES, 0);
cy.get(FILTER_BADGE)
.first()
.should('have.text', `NOT kibana.alert.severity: ${severityVal}`);
});
});
filterForAlertProperty(ALERT_TABLE_FILE_NAME_VALUES, 0);

it('should filter out an empty property', () => {
// add query condition to make sure the field is empty
fillKqlQueryBar('not file.name: *{enter}');
cy.get(FILTER_BADGE).first().should('have.text', 'NOT file.name: exists');

scrollAlertTableColumnIntoView(ALERT_TABLE_FILE_NAME_HEADER);
filterOutAlertProperty(ALERT_TABLE_FILE_NAME_VALUES, 0);
cy.log('filter out alert property');

cy.get(FILTER_BADGE).first().should('have.text', 'file.name: exists');
});
});
filterOutAlertProperty(ALERT_TABLE_FILE_NAME_VALUES, 0);

// FLAKY: https://github.com/elastic/kibana/issues/172231
describe.skip('Add to timeline', () => {
beforeEach(() => {
login();
visit(ALERTS_URL);
waitForAlertsToPopulate();
});
cy.get(FILTER_BADGE).first().should('have.text', 'file.name: exists');

it('should add a non-empty property to default timeline', () => {
cy.get(ALERT_TABLE_SEVERITY_VALUES)
.first()
.invoke('text')
.then((severityVal) => {
scrollAlertTableColumnIntoView(ALERT_TABLE_SEVERITY_HEADER);
addAlertPropertyToTimeline(ALERT_TABLE_SEVERITY_VALUES, 0);
openActiveTimeline();
cy.get(PROVIDER_BADGE)
.first()
.should('have.text', `kibana.alert.severity: "${severityVal}"`);
});
});
removeKqlFilter();
scrollAlertTableColumnIntoView(ALERT_TABLE_SEVERITY_HEADER);

it('should add an empty property to default timeline', () => {
// add condition to make sure the field is empty
openAddFilterPopover();
cy.log('should allow copy paste');

fillAddFilterForm({ key: 'file.name', operator: 'does not exist' });
scrollAlertTableColumnIntoView(ALERT_TABLE_FILE_NAME_HEADER);
addAlertPropertyToTimeline(ALERT_TABLE_FILE_NAME_VALUES, 0);
openActiveTimeline();
cy.get(PROVIDER_BADGE).first().should('have.text', 'NOT file.name exists');
cy.window().then((win) => {
cy.stub(win, 'prompt').returns('DISABLED WINDOW PROMPT');
});
clickExpandActions(ALERT_TABLE_SEVERITY_VALUES, 0);
// We are not able to test the "copy to clipboard" action execution
// due to browsers security limitation accessing the clipboard services.
// We assume external `copy` library works
cy.get(CELL_COPY_BUTTON).should('exist');

cy.log('should filter out a non-empty property');

cy.get(ALERT_TABLE_SEVERITY_VALUES)
.first()
.invoke('text')
.then((severityVal) => {
scrollAlertTableColumnIntoView(ALERT_TABLE_SEVERITY_HEADER);
filterOutAlertProperty(ALERT_TABLE_SEVERITY_VALUES, 0);
cy.get(FILTER_BADGE)
.first()
.should('have.text', `NOT kibana.alert.severity: ${severityVal}`);
});
});

// FLAKY: https://github.com/elastic/kibana/issues/172232
describe.skip('Show Top N', () => {
beforeEach(() => {
login();
visit(ALERTS_URL);
waitForAlertsToPopulate();
});
it('should add a non-empty property to default timeline', () => {
cy.get(ALERT_TABLE_SEVERITY_VALUES)
.first()
.invoke('text')
.then((severityVal) => {
scrollAlertTableColumnIntoView(ALERT_TABLE_SEVERITY_HEADER);
addAlertPropertyToTimeline(ALERT_TABLE_SEVERITY_VALUES, 0);
openActiveTimeline();
cy.get(PROVIDER_BADGE)
.first()
.should('have.text', `kibana.alert.severity: "${severityVal}"`);
});
});

it('should show top for a property', () => {
cy.get(ALERT_TABLE_SEVERITY_VALUES)
.first()
.invoke('text')
.then(() => {
scrollAlertTableColumnIntoView(ALERT_TABLE_SEVERITY_HEADER);
showTopNAlertProperty(ALERT_TABLE_SEVERITY_VALUES, 0);
cy.get(SHOW_TOP_N_HEADER).first().should('have.text', `Top kibana.alert.severity`);
});
});
it('should add an empty property to default timeline', () => {
// add condition to make sure the field is empty
openAddFilterPopover();

fillAddFilterForm({ key: 'file.name', operator: 'does not exist' });
scrollAlertTableColumnIntoView(ALERT_TABLE_FILE_NAME_HEADER);
addAlertPropertyToTimeline(ALERT_TABLE_FILE_NAME_VALUES, 0);
openActiveTimeline();
cy.get(PROVIDER_BADGE).first().should('have.text', 'NOT file.name exists');
});

// FLAKY: https://github.com/elastic/kibana/issues/172233
describe.skip('Copy to clipboard', () => {
beforeEach(() => {
login();
visit(ALERTS_URL);
waitForAlertsToPopulate();
});
it('should show top for a property', () => {
cy.get(ALERT_TABLE_SEVERITY_VALUES);

it('should copy to clipboard', () => {
cy.get(ALERT_TABLE_SEVERITY_VALUES)
.first()
.invoke('text')
.then(() => {
scrollAlertTableColumnIntoView(ALERT_TABLE_SEVERITY_HEADER);
cy.window().then((win) => {
cy.stub(win, 'prompt').returns('DISABLED WINDOW PROMPT');
});
clickExpandActions(ALERT_TABLE_SEVERITY_VALUES, 0);
cy.get(CELL_COPY_BUTTON).should('exist');
// We are not able to test the "copy to clipboard" action execution
// due to browsers security limitation accessing the clipboard services.
// We assume external `copy` library works
});
});
scrollAlertTableColumnIntoView(ALERT_TABLE_SEVERITY_HEADER);
showTopNAlertProperty(ALERT_TABLE_SEVERITY_VALUES, 0);
cy.get(SHOW_TOP_N_HEADER).first().should('have.text', `Top kibana.alert.severity`);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,5 @@ export const ALERT_DETAILS_ASSIGN_BUTTON =
'[data-test-subj="securitySolutionFlyoutHeaderAssigneesAddButton"]';

export const ALERT_DETAILS_TAKE_ACTION_BUTTON = '[data-test-subj="take-action-dropdown-btn"]';

export const TOOLTIP = '[data-test-subj="message-tool-tip"]';
36 changes: 32 additions & 4 deletions x-pack/test/security_solution_cypress/cypress/tasks/alerts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import {
ALERT_TABLE_EVENT_RENDERED_VIEW_OPTION,
HOVER_ACTIONS_CONTAINER,
ALERT_TABLE_GRID_VIEW_OPTION,
TOOLTIP,
} from '../screens/alerts';
import { LOADING_INDICATOR, REFRESH_BUTTON } from '../screens/security_header';
import { TIMELINE_COLUMN_SPINNER } from '../screens/timeline';
Expand Down Expand Up @@ -146,6 +147,14 @@ export const expandFirstAlert = () => {
cy.get(EXPAND_ALERT_BTN).first().click();
};

export const hideMessageTooltip = () => {
cy.get('body').then(($body) => {
if ($body.find(TOOLTIP).length > 0) {
cy.get(TOOLTIP).first().invoke('hide');
}
});
};

export const closeAlertFlyout = () => cy.get(CLOSE_FLYOUT).click();

export const viewThreatIntelTab = () => cy.get(THREAT_INTEL_TAB).click();
Expand Down Expand Up @@ -341,8 +350,17 @@ export const clickAlertsHistogramLegendFilterFor = (ruleName: string) => {
};

const clickAction = (propertySelector: string, rowIndex: number, actionSelector: string) => {
cy.get(propertySelector).eq(rowIndex).trigger('mouseover');
cy.get(actionSelector).first().click({ force: true });
recurse(
() => {
// To clear focus
cy.get('body').type('{esc}');
cy.get(propertySelector).eq(rowIndex).realHover();
return cy.get(actionSelector).first();
},
($el) => $el.is(':visible')
);

cy.get(actionSelector).first().click();
};
export const clickExpandActions = (propertySelector: string, rowIndex: number) => {
clickAction(propertySelector, rowIndex, ACTIONS_EXPAND_BUTTON);
Expand All @@ -356,9 +374,19 @@ export const filterForAlertProperty = (propertySelector: string, rowIndex: numbe
export const filterOutAlertProperty = (propertySelector: string, rowIndex: number) => {
clickAction(propertySelector, rowIndex, CELL_FILTER_OUT_BUTTON);
};

export const showTopNAlertProperty = (propertySelector: string, rowIndex: number) => {
clickExpandActions(propertySelector, rowIndex);
cy.get(CELL_SHOW_TOP_FIELD_BUTTON).first().click({ force: true });
recurse(
() => {
clickExpandActions(propertySelector, rowIndex);
return cy.get(CELL_SHOW_TOP_FIELD_BUTTON).first();
},
($el) => $el.is(':visible')
);

hideMessageTooltip();

cy.get(CELL_SHOW_TOP_FIELD_BUTTON).first().should('be.visible').click();
};

export const waitForAlerts = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {

export const openAddFilterPopover = () => {
cy.get(GLOBAL_SEARCH_BAR_SUBMIT_BUTTON).should('be.enabled');
cy.get(GLOBAL_SEARCH_BAR_ADD_FILTER).should('be.visible');
cy.get(GLOBAL_SEARCH_BAR_ADD_FILTER).click();
};

Expand Down Expand Up @@ -53,8 +52,6 @@ export const removeKqlFilter = () => {
};

export const fillAddFilterForm = ({ key, operator, value }: SearchBarFilter) => {
cy.get(ADD_FILTER_FORM_FIELD_INPUT).should('exist');
cy.get(ADD_FILTER_FORM_FIELD_INPUT).should('be.visible');
cy.get(ADD_FILTER_FORM_FIELD_INPUT).type(`${key}{downarrow}{enter}`);

cy.get(ADD_FILTER_FORM_OPERATOR_FIELD).type(`${operator}{downarrow}{enter}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ export const openTimelineById = (timelineId: string): Cypress.Chainable<JQuery<H
};

export const openActiveTimeline = () => {
cy.get(ACTIVE_TIMELINE_BOTTOM_BAR).click({ force: true });
cy.get(ACTIVE_TIMELINE_BOTTOM_BAR).click();
};

export const pinFirstEvent = (): Cypress.Chainable<JQuery<HTMLElement>> => {
Expand Down

0 comments on commit a48eb82

Please sign in to comment.