From a48eb829fe85ed9eded71bb9ce8dffc92628ae1e Mon Sep 17 00:00:00 2001 From: Luke G <11671118+lgestc@users.noreply.github.com> Date: Mon, 8 Jan 2024 21:25:00 +0100 Subject: [PATCH] [Security Solution] Unskip alerts cell actions tests (#174096) ## Summary This PR unskips alerts cell actions tests, skipped here: https://github.com/elastic/kibana/issues/172233 https://github.com/elastic/kibana/issues/172231 https://github.com/elastic/kibana/issues/173442 https://github.com/elastic/kibana/issues/172230 https://github.com/elastic/kibana/issues/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 --- .../alerts/alerts_cell_actions.cy.ts | 192 +++++++----------- .../cypress/screens/alerts.ts | 2 + .../cypress/tasks/alerts.ts | 36 +++- .../cypress/tasks/search_bar.ts | 3 - .../cypress/tasks/timeline.ts | 2 +- 5 files changed, 114 insertions(+), 121 deletions(-) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/alerts_cell_actions.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/alerts_cell_actions.cy.ts index f05b5cc9ab020..49dd7dc2259fc 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/alerts_cell_actions.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/alerts_cell_actions.cy.ts @@ -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'; @@ -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`); }); }); diff --git a/x-pack/test/security_solution_cypress/cypress/screens/alerts.ts b/x-pack/test/security_solution_cypress/cypress/screens/alerts.ts index 83de06466f251..417e53e86b952 100644 --- a/x-pack/test/security_solution_cypress/cypress/screens/alerts.ts +++ b/x-pack/test/security_solution_cypress/cypress/screens/alerts.ts @@ -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"]'; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/alerts.ts b/x-pack/test/security_solution_cypress/cypress/tasks/alerts.ts index a976336100d2f..d75d94ed519d6 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/alerts.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/alerts.ts @@ -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'; @@ -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(); @@ -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); @@ -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 = () => { diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/search_bar.ts b/x-pack/test/security_solution_cypress/cypress/tasks/search_bar.ts index 3a4355cad2e7e..bd6ca6775c12f 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/search_bar.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/search_bar.ts @@ -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(); }; @@ -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}`); diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/timeline.ts b/x-pack/test/security_solution_cypress/cypress/tasks/timeline.ts index 8c5c0fe14c146..d9db1f7debcfa 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/timeline.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/timeline.ts @@ -405,7 +405,7 @@ export const openTimelineById = (timelineId: string): Cypress.Chainable { - cy.get(ACTIVE_TIMELINE_BOTTOM_BAR).click({ force: true }); + cy.get(ACTIVE_TIMELINE_BOTTOM_BAR).click(); }; export const pinFirstEvent = (): Cypress.Chainable> => {