From cbeb60d2bb737e6800ed4b60bd66a7d56ec78fde Mon Sep 17 00:00:00 2001 From: Yara Tercero Date: Mon, 14 Mar 2022 17:59:20 -0700 Subject: [PATCH] [8.1] [Security Solution][Cypress] - Update exception table cypress test to reduce flake (#126706) (#127650) * [Security Solution][Cypress] - Update exception table cypress test to reduce flake (#126706) Addresses exception table cypress flake. (cherry picked from commit c36efa6af80105bed7cf6480e66355ab2a098b03) # Conflicts: # x-pack/plugins/security_solution/cypress/integration/exceptions/exceptions_table.spec.ts * Lint fix --- .../exceptions/exceptions_table.spec.ts | 114 +++++++++++------- .../cypress/objects/exception.ts | 2 +- .../security_solution/cypress/objects/rule.ts | 1 + .../cypress/tasks/api_calls/rules.ts | 1 + 4 files changed, 72 insertions(+), 46 deletions(-) diff --git a/x-pack/plugins/security_solution/cypress/integration/exceptions/exceptions_table.spec.ts b/x-pack/plugins/security_solution/cypress/integration/exceptions/exceptions_table.spec.ts index d85bf6a6af81bd..d2578f91720335 100644 --- a/x-pack/plugins/security_solution/cypress/integration/exceptions/exceptions_table.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/exceptions/exceptions_table.spec.ts @@ -6,30 +6,17 @@ */ import { ROLES } from '../../../common/test'; -import { - getException, - getExceptionList, - expectedExportedExceptionList, -} from '../../objects/exception'; +import { getExceptionList, expectedExportedExceptionList } from '../../objects/exception'; import { getNewRule } from '../../objects/rule'; -import { RULE_STATUS } from '../../screens/create_new_rule'; - import { createCustomRule } from '../../tasks/api_calls/rules'; -import { goToRuleDetails } from '../../tasks/alerts_detection_rules'; -import { esArchiverLoad, esArchiverUnload } from '../../tasks/es_archiver'; import { loginAndWaitForPageWithoutDateRange, waitForPageWithoutDateRange, } from '../../tasks/login'; -import { - addsExceptionFromRuleSettings, - goBackToAllRulesTable, - goToExceptionsTab, -} from '../../tasks/rule_details'; import { DETECTIONS_RULE_MANAGEMENT_URL, EXCEPTIONS_URL } from '../../urls/navigation'; -import { cleanKibana, reload } from '../../tasks/common'; +import { cleanKibana } from '../../tasks/common'; import { deleteExceptionListWithRuleReference, deleteExceptionListWithoutRuleReference, @@ -45,30 +32,47 @@ import { } from '../../screens/exceptions'; import { createExceptionList } from '../../tasks/api_calls/exceptions'; +const getExceptionList1 = () => ({ + ...getExceptionList(), + name: 'Test a new list 1', + list_id: 'exception_list_1', +}); +const getExceptionList2 = () => ({ + ...getExceptionList(), + name: 'Test list 2', + list_id: 'exception_list_2', +}); + describe('Exceptions Table', () => { before(() => { cleanKibana(); loginAndWaitForPageWithoutDateRange(DETECTIONS_RULE_MANAGEMENT_URL); - createCustomRule(getNewRule()); - reload(); - goToRuleDetails(); - - cy.get(RULE_STATUS).should('have.text', '—'); - - esArchiverLoad('auditbeat_for_exceptions'); - // Add a detections exception list - goToExceptionsTab(); - addsExceptionFromRuleSettings(getException()); + // Create exception list associated with a rule + createExceptionList(getExceptionList2(), getExceptionList2().list_id).then((response) => + createCustomRule({ + ...getNewRule(), + exceptionLists: [ + { + id: response.body.id, + list_id: getExceptionList2().list_id, + type: getExceptionList2().type, + namespace_type: getExceptionList2().namespace_type, + }, + ], + }) + ); // Create exception list not used by any rules - createExceptionList(getExceptionList(), getExceptionList().list_id).as('exceptionListResponse'); + createExceptionList(getExceptionList1(), getExceptionList1().list_id).as( + 'exceptionListResponse' + ); - goBackToAllRulesTable(); - }); + waitForPageWithoutDateRange(EXCEPTIONS_URL); - after(() => { - esArchiverUnload('auditbeat_for_exceptions'); + // Using cy.contains because we do not care about the exact text, + // just checking number of lists shown + cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '3'); }); it('Exports exception list', function () { @@ -89,61 +93,81 @@ describe('Exceptions Table', () => { waitForPageWithoutDateRange(EXCEPTIONS_URL); waitForExceptionsTableToBeLoaded(); - cy.get(EXCEPTIONS_TABLE_SHOWING_LISTS).should('have.text', `Showing 3 lists`); + // Using cy.contains because we do not care about the exact text, + // just checking number of lists shown + cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '3'); // Single word search searchForExceptionList('Endpoint'); - cy.get(EXCEPTIONS_TABLE_SHOWING_LISTS).should('have.text', `Showing 1 list`); + // Using cy.contains because we do not care about the exact text, + // just checking number of lists shown + cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '1'); cy.get(EXCEPTIONS_TABLE_LIST_NAME).should('have.text', 'Endpoint Security Exception List'); // Multi word search clearSearchSelection(); - searchForExceptionList('New Rule Test'); + searchForExceptionList('test'); - cy.get(EXCEPTIONS_TABLE_SHOWING_LISTS).should('have.text', `Showing 2 lists`); - cy.get(EXCEPTIONS_TABLE_LIST_NAME).eq(0).should('have.text', 'Test exception list'); - cy.get(EXCEPTIONS_TABLE_LIST_NAME).eq(1).should('have.text', 'New Rule Test'); + // Using cy.contains because we do not care about the exact text, + // just checking number of lists shown + cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '2'); + cy.get(EXCEPTIONS_TABLE_LIST_NAME).eq(1).should('have.text', 'Test list 2'); + cy.get(EXCEPTIONS_TABLE_LIST_NAME).eq(0).should('have.text', 'Test a new list 1'); // Exact phrase search clearSearchSelection(); - searchForExceptionList('"New Rule Test"'); + searchForExceptionList(`"${getExceptionList1().name}"`); - cy.get(EXCEPTIONS_TABLE_SHOWING_LISTS).should('have.text', `Showing 1 list`); - cy.get(EXCEPTIONS_TABLE_LIST_NAME).should('have.text', 'New Rule Test'); + // Using cy.contains because we do not care about the exact text, + // just checking number of lists shown + cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '1'); + cy.get(EXCEPTIONS_TABLE_LIST_NAME).should('have.text', getExceptionList1().name); // Field search clearSearchSelection(); searchForExceptionList('list_id:endpoint_list'); - cy.get(EXCEPTIONS_TABLE_SHOWING_LISTS).should('have.text', `Showing 1 list`); + // Using cy.contains because we do not care about the exact text, + // just checking number of lists shown + cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '1'); cy.get(EXCEPTIONS_TABLE_LIST_NAME).should('have.text', 'Endpoint Security Exception List'); clearSearchSelection(); - cy.get(EXCEPTIONS_TABLE_SHOWING_LISTS).should('have.text', `Showing 3 lists`); + // Using cy.contains because we do not care about the exact text, + // just checking number of lists shown + cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '3'); }); it('Deletes exception list without rule reference', () => { waitForPageWithoutDateRange(EXCEPTIONS_URL); waitForExceptionsTableToBeLoaded(); - cy.get(EXCEPTIONS_TABLE_SHOWING_LISTS).should('have.text', `Showing 3 lists`); + // Using cy.contains because we do not care about the exact text, + // just checking number of lists shown + cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '3'); deleteExceptionListWithoutRuleReference(); - cy.get(EXCEPTIONS_TABLE_SHOWING_LISTS).should('have.text', `Showing 2 lists`); + // Using cy.contains because we do not care about the exact text, + // just checking number of lists shown + cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '2'); }); it('Deletes exception list with rule reference', () => { waitForPageWithoutDateRange(EXCEPTIONS_URL); waitForExceptionsTableToBeLoaded(); - cy.get(EXCEPTIONS_TABLE_SHOWING_LISTS).should('have.text', `Showing 2 lists`); + // Using cy.contains because we do not care about the exact text, + // just checking number of lists shown + cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '2'); deleteExceptionListWithRuleReference(); - cy.get(EXCEPTIONS_TABLE_SHOWING_LISTS).should('have.text', `Showing 1 list`); + // Using cy.contains because we do not care about the exact text, + // just checking number of lists shown + cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '1'); }); }); diff --git a/x-pack/plugins/security_solution/cypress/objects/exception.ts b/x-pack/plugins/security_solution/cypress/objects/exception.ts index 1a70bb10383203..fbb000f43fdd23 100644 --- a/x-pack/plugins/security_solution/cypress/objects/exception.ts +++ b/x-pack/plugins/security_solution/cypress/objects/exception.ts @@ -41,5 +41,5 @@ export const expectedExportedExceptionList = ( exceptionListResponse: Cypress.Response ): string => { const jsonrule = exceptionListResponse.body; - return `{"_version":"${jsonrule._version}","created_at":"${jsonrule.created_at}","created_by":"elastic","description":"${jsonrule.description}","id":"${jsonrule.id}","immutable":false,"list_id":"test_exception_list","name":"Test exception list","namespace_type":"single","os_types":[],"tags":[],"tie_breaker_id":"${jsonrule.tie_breaker_id}","type":"detection","updated_at":"${jsonrule.updated_at}","updated_by":"elastic","version":1}\n{"exported_exception_list_count":1,"exported_exception_list_item_count":0,"missing_exception_list_item_count":0,"missing_exception_list_items":[],"missing_exception_lists":[],"missing_exception_lists_count":0}\n`; + return `{"_version":"${jsonrule._version}","created_at":"${jsonrule.created_at}","created_by":"elastic","description":"${jsonrule.description}","id":"${jsonrule.id}","immutable":false,"list_id":"${jsonrule.list_id}","name":"${jsonrule.name}","namespace_type":"single","os_types":[],"tags":[],"tie_breaker_id":"${jsonrule.tie_breaker_id}","type":"${jsonrule.type}","updated_at":"${jsonrule.updated_at}","updated_by":"elastic","version":1}\n{"exported_exception_list_count":1,"exported_exception_list_item_count":0,"missing_exception_list_item_count":0,"missing_exception_list_items":[],"missing_exception_lists":[],"missing_exception_lists_count":0}\n`; }; diff --git a/x-pack/plugins/security_solution/cypress/objects/rule.ts b/x-pack/plugins/security_solution/cypress/objects/rule.ts index 6a1c13b51509fc..64852cef276767 100644 --- a/x-pack/plugins/security_solution/cypress/objects/rule.ts +++ b/x-pack/plugins/security_solution/cypress/objects/rule.ts @@ -59,6 +59,7 @@ export interface CustomRule { timeline: CompleteTimeline; maxSignals: number; buildingBlockType?: string; + exceptionLists?: Array<{ id: string; list_id: string; type: string; namespace_type: string }>; } export interface ThresholdRule extends CustomRule { diff --git a/x-pack/plugins/security_solution/cypress/tasks/api_calls/rules.ts b/x-pack/plugins/security_solution/cypress/tasks/api_calls/rules.ts index 0e6f4e6851a1b1..8f150c7340bbfe 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/api_calls/rules.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/api_calls/rules.ts @@ -24,6 +24,7 @@ export const createCustomRule = (rule: CustomRule, ruleId = 'rule_testing', inte query: rule.customQuery, language: 'kuery', enabled: false, + exceptions_list: rule.exceptionLists ?? [], }, headers: { 'kbn-xsrf': 'cypress-creds' }, failOnStatusCode: false,