diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b88935d43b3c..df64d99949b9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1316,6 +1316,7 @@ x-pack/test/security_solution_cypress/config.ts @elastic/security-engineering-pr x-pack/test/security_solution_cypress/runner.ts @elastic/security-engineering-productivity x-pack/test/security_solution_cypress/serverless_config.ts @elastic/security-engineering-productivity x-pack/test/security_solution_cypress/cypress/tags.ts @elastic/security-engineering-productivity +x-pack/plugins/security_solution/scripts/run_cypress @MadameSheema @patrykkopycinski @oatkiller @maximpn @banderror ## Security Solution sub teams - adaptive-workload-protection x-pack/plugins/security_solution/public/common/components/sessions_viewer @elastic/kibana-cloud-security-posture diff --git a/x-pack/plugins/security_solution/scripts/run_cypress/parallel.ts b/x-pack/plugins/security_solution/scripts/run_cypress/parallel.ts index 45b48a5d428e..a9f1d2186064 100644 --- a/x-pack/plugins/security_solution/scripts/run_cypress/parallel.ts +++ b/x-pack/plugins/security_solution/scripts/run_cypress/parallel.ts @@ -63,8 +63,14 @@ const retrieveIntegrations = (integrationsPaths: string[]) => { export const cli = () => { run( async () => { + const log = new ToolingLog({ + level: 'info', + writeTo: process.stdout, + }); + const { argv } = yargs(process.argv.slice(2)) - .coerce('spec', (arg) => (_.isArray(arg) ? [_.last(arg)] : [arg])) + .coerce('configFile', (arg) => (_.isArray(arg) ? _.last(arg) : arg)) + .coerce('spec', (arg) => (_.isArray(arg) ? _.last(arg) : arg)) .coerce('env', (arg: string) => arg.split(',').reduce((acc, curr) => { const [key, value] = curr.split('='); @@ -77,22 +83,72 @@ export const cli = () => { }, {} as Record) ); + log.info(` +---------------------------------------------- +Script arguments: +---------------------------------------------- + +${JSON.stringify(argv, null, 2)} + +---------------------------------------------- +`); + const isOpen = argv._[0] === 'open'; - const cypressConfigFilePath = require.resolve( - `../../${_.isArray(argv.configFile) ? _.last(argv.configFile) : argv.configFile}` - ) as string; + + const cypressConfigFilePath = require.resolve(`../../${argv.configFile}`) as string; const cypressConfigFile = await import(cypressConfigFilePath); + + log.info(` +---------------------------------------------- +Cypress config for file: ${cypressConfigFilePath}: +---------------------------------------------- + +${JSON.stringify(cypressConfigFile, null, 2)} + +---------------------------------------------- +`); + + const specConfig = cypressConfigFile.e2e.specPattern; + const specArg = argv.spec; + const specPattern = specArg ?? specConfig; + + log.info('Config spec pattern:', specConfig); + log.info('Arguments spec pattern:', specArg); + log.info('Resulting spec pattern:', specPattern); + + // The grep function will filter Cypress specs by tags: it will include and exclude + // spec files according to the tags configuration. const grepSpecPattern = grep({ ...cypressConfigFile, - specPattern: argv.spec ?? cypressConfigFile.e2e.specPattern, + specPattern, excludeSpecPattern: [], }).specPattern; - let files = retrieveIntegrations( - _.isArray(grepSpecPattern) - ? grepSpecPattern - : globby.sync(argv.spec ?? cypressConfigFile.e2e.specPattern) - ); + log.info('Resolved spec files or pattern after grep:', grepSpecPattern); + + const isGrepReturnedFilePaths = _.isArray(grepSpecPattern); + const isGrepReturnedSpecPattern = !isGrepReturnedFilePaths && grepSpecPattern === specPattern; + + // IMPORTANT! + // When grep returns the same spec pattern as it gets in its arguments, we treat it as + // it couldn't find any concrete specs to execute (maybe because all of them are skipped). + // In this case, we do an early return - it's important to do that. + // If we don't return early, these specs will start executing, and Cypress will be skipping + // tests at runtime: those that should be excluded according to the tags passed in the config. + // This can take so much time that the job can fail by timeout in CI. + if (isGrepReturnedSpecPattern) { + log.info('No tests found - all tests could have been skipped via Cypress tags'); + // eslint-disable-next-line no-process-exit + return process.exit(0); + } + + const concreteFilePaths = isGrepReturnedFilePaths + ? grepSpecPattern // use the returned concrete file paths + : globby.sync(specPattern); // convert the glob pattern to concrete file paths + + let files = retrieveIntegrations(concreteFilePaths); + + log.info('Resolved spec files after retrieveIntegrations:', files); if (argv.changedSpecsOnly) { files = (findChangedFiles('main', false) as string[]).reduce((acc, itemPath) => { @@ -108,11 +164,6 @@ export const cli = () => { files = files.slice(0, 3); } - const log = new ToolingLog({ - level: 'info', - writeTo: process.stdout, - }); - if (!files?.length) { log.info('No tests found'); // eslint-disable-next-line no-process-exit diff --git a/x-pack/test/security_solution_cypress/cypress/README.md b/x-pack/test/security_solution_cypress/cypress/README.md index 21a6a8a9db49..aa749344201f 100644 --- a/x-pack/test/security_solution_cypress/cypress/README.md +++ b/x-pack/test/security_solution_cypress/cypress/README.md @@ -40,7 +40,12 @@ of data for your test, [**Running the tests**](#running-the-tests) to know how t Please, before opening a PR with the new test, please make sure that the test fails. If you never see your test fail you don’t know if your test is actually testing the right thing, or testing anything at all. -Note that we use tags in order to select which tests we want to execute: @serverless, @ess and @brokenInServerless +Note that we use tags in order to select which tests we want to execute: + +- `@serverless` includes a test in the Serverless test suite. You need to explicitly add this tag to any test you want to run against a Serverless environment. +- `@ess` includes a test in the normal, non-Serverless test suite. You need to explicitly add this tag to any test you want to run against a non-Serverless environment. +- `@brokenInServerless` excludes a test from the Serverless test suite (even if it's tagged as `@serverless`). Indicates that a test should run in Serverless, but currently is broken. +- `@skipInServerless` excludes a test from the Serverless test suite (even if it's tagged as `@serverless`). Could indicate many things, e.g. "the test is flaky in Serverless", "the test is Flaky in any type of environemnt", "the test has been temporarily excluded, see the comment above why". Please, before opening a PR with a new test, make sure that the test fails. If you never see your test fail you don’t know if your test is actually testing the right thing, or testing anything at all. diff --git a/x-pack/test/security_solution_cypress/cypress/cypress_ci_serverless.config.ts b/x-pack/test/security_solution_cypress/cypress/cypress_ci_serverless.config.ts index 5ce5af4e639f..eafcd67682a6 100644 --- a/x-pack/test/security_solution_cypress/cypress/cypress_ci_serverless.config.ts +++ b/x-pack/test/security_solution_cypress/cypress/cypress_ci_serverless.config.ts @@ -18,7 +18,7 @@ export default defineCypressConfig({ env: { grepFilterSpecs: true, grepOmitFiltered: true, - grepTags: '@serverless --@brokenInServerless', + grepTags: '@serverless --@brokenInServerless --@skipInServerless', }, execTimeout: 150000, pageLoadTimeout: 150000, diff --git a/x-pack/test/security_solution_cypress/cypress/cypress_serverless.config.ts b/x-pack/test/security_solution_cypress/cypress/cypress_serverless.config.ts index d0a89bb34a68..d172248fb406 100644 --- a/x-pack/test/security_solution_cypress/cypress/cypress_serverless.config.ts +++ b/x-pack/test/security_solution_cypress/cypress/cypress_serverless.config.ts @@ -23,7 +23,7 @@ export default defineCypressConfig({ numTestsKeptInMemory: 10, env: { grepFilterSpecs: true, - grepTags: '@serverless --@brokenInServerless', + grepTags: '@serverless --@brokenInServerless --@skipInServerless', }, e2e: { experimentalRunAllSpecs: true, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/data_sources/create_runtime_field.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/data_sources/create_runtime_field.cy.ts index b9a514b8c221..f78670bc14b4 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/data_sources/create_runtime_field.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/data_sources/create_runtime_field.cy.ts @@ -25,6 +25,7 @@ import { GET_TIMELINE_HEADER } from '../../screens/timeline'; const alertRunTimeField = 'field.name.alert.page'; const timelineRuntimeField = 'field.name.timeline'; +// TODO: https://github.com/elastic/kibana/issues/161539 describe( 'Create DataView runtime field', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/data_sources/sourcerer.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/data_sources/sourcerer.cy.ts index 7ea130b0230d..77206d714c96 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/data_sources/sourcerer.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/data_sources/sourcerer.cy.ts @@ -35,12 +35,14 @@ const rolesToCreate = [secReadCasesAll]; const siemDataViewTitle = 'Security Default Data View'; const dataViews = ['auditbeat-*,fakebeat-*', 'auditbeat-*,*beat*,siem-read*,.kibana*,fakebeat-*']; -describe('Sourcerer', () => { +// TODO: https://github.com/elastic/kibana/issues/161539 +describe('Sourcerer', { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { before(() => { cy.task('esArchiverResetKibana'); dataViews.forEach((dataView: string) => postDataView(dataView)); }); + // TODO: https://github.com/elastic/kibana/issues/161539 describe('permissions', { tags: ['@ess', '@brokenInServerless'] }, () => { before(() => { createUsersAndRoles(usersToCreate, rolesToCreate); @@ -52,6 +54,7 @@ describe('Sourcerer', () => { }); }); + // TODO: https://github.com/elastic/kibana/issues/161539 // FLAKY: https://github.com/elastic/kibana/issues/165766 describe('Default scope', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { beforeEach(() => { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/data_sources/sourcerer_timeline.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/data_sources/sourcerer_timeline.cy.ts index 1476e82421cd..69244ddce38f 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/data_sources/sourcerer_timeline.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/data_sources/sourcerer_timeline.cy.ts @@ -38,7 +38,8 @@ import { closeTimeline, openTimelineById } from '../../tasks/timeline'; const siemDataViewTitle = 'Security Default Data View'; const dataViews = ['auditbeat-*,fakebeat-*', 'auditbeat-*,*beat*,siem-read*,.kibana*,fakebeat-*']; -describe('Timeline scope', { tags: '@brokenInServerless' }, () => { +// TODO: https://github.com/elastic/kibana/issues/161539 +describe.skip('Timeline scope', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { beforeEach(() => { cy.clearLocalStorage(); login(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/data_sources/sourcerer_timeline.ts b/x-pack/test/security_solution_cypress/cypress/e2e/data_sources/sourcerer_timeline.ts index 1476e82421cd..979cf8c657b1 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/data_sources/sourcerer_timeline.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/data_sources/sourcerer_timeline.ts @@ -38,7 +38,8 @@ import { closeTimeline, openTimelineById } from '../../tasks/timeline'; const siemDataViewTitle = 'Security Default Data View'; const dataViews = ['auditbeat-*,fakebeat-*', 'auditbeat-*,*beat*,siem-read*,.kibana*,fakebeat-*']; -describe('Timeline scope', { tags: '@brokenInServerless' }, () => { +// TODO: https://github.com/elastic/kibana/issues/161539 +describe('Timeline scope', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { beforeEach(() => { cy.clearLocalStorage(); login(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/alert_tags.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/alert_tags.cy.ts index 1013a4d7d53d..48c7f49c1486 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/alert_tags.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/alert_tags.cy.ts @@ -24,6 +24,7 @@ import { UNSELECTED_ALERT_TAG, } from '../../screens/alerts'; +// TODO: https://github.com/elastic/kibana/issues/161539 describe('Alert tagging', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { before(() => { cleanKibana(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/alerts_charts.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/alerts_charts.cy.ts index 313d2a625ad9..2c00882fb15d 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/alerts_charts.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/alerts_charts.cy.ts @@ -24,6 +24,7 @@ import { } from '../../screens/search_bar'; import { TOASTER } from '../../screens/alerts_detection_rules'; +// TODO: https://github.com/elastic/kibana/issues/161539 describe( 'Histogram legend hover actions', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/alerts_detection_callouts_index_outdated.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/alerts_detection_callouts_index_outdated.cy.ts index 69227eb6a7c6..d751f2a68812 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/alerts_detection_callouts_index_outdated.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/alerts_detection_callouts_index_outdated.cy.ts @@ -29,9 +29,10 @@ const waitForPageTitleToBeShown = () => { cy.get(PAGE_TITLE).should('be.visible'); }; +// TODO: https://github.com/elastic/kibana/issues/161539 Does it need to run in Serverless? describe( 'Detections > Need Admin Callouts indicating an admin is needed to migrate the alert data set', - { tags: '@ess' }, + { tags: ['@ess', '@skipInServerless'] }, () => { before(() => { // First, we have to open the app on behalf of a privileged user in order to initialize it. diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/cti_enrichments.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/cti_enrichments.cy.ts index 9ab88f2802be..90226eca02e5 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/cti_enrichments.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/cti_enrichments.cy.ts @@ -27,6 +27,7 @@ import { openJsonView, openThreatIndicatorDetails } from '../../tasks/alerts_det import { ruleDetailsUrl } from '../../urls/navigation'; import { addsFieldsToTimeline } from '../../tasks/rule_details'; +// TODO: https://github.com/elastic/kibana/issues/161539 describe('CTI Enrichment', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { before(() => { cleanKibana(); @@ -50,6 +51,7 @@ describe('CTI Enrichment', { tags: ['@ess', '@serverless', '@brokenInServerless' ); }); + // TODO: https://github.com/elastic/kibana/issues/161539 // Skipped: https://github.com/elastic/kibana/issues/162818 it.skip('Displays enrichment matched.* fields on the timeline', () => { const expectedFields = { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/enrichments.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/enrichments.cy.ts index 102405eb95a6..393123650c38 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/enrichments.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/enrichments.cy.ts @@ -30,6 +30,7 @@ import { login, visit } from '../../tasks/login'; import { ALERTS_URL } from '../../urls/navigation'; +// TODO: https://github.com/elastic/kibana/issues/161539 describe('Enrichment', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { before(() => { cleanKibana(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/missing_privileges_callout.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/missing_privileges_callout.cy.ts index 30e0383ff3fa..a4e74d40dc92 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/missing_privileges_callout.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/missing_privileges_callout.cy.ts @@ -41,7 +41,8 @@ const waitForPageTitleToBeShown = () => { cy.get(PAGE_TITLE).should('be.visible'); }; -describe('Detections > Callouts', { tags: '@ess' }, () => { +// TODO: https://github.com/elastic/kibana/issues/161539 +describe('Detections > Callouts', { tags: ['@ess', '@skipInServerless'] }, () => { before(() => { // First, we have to open the app on behalf of a privileged user in order to initialize it. // Otherwise the app will be disabled and show a "welcome"-like page. diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/ransomware_detection.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/ransomware_detection.cy.ts index a38ac3b2fb84..7c7cd582baa3 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/ransomware_detection.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/ransomware_detection.cy.ts @@ -14,6 +14,7 @@ import { TIMELINE_QUERY, TIMELINE_VIEW_IN_ANALYZER } from '../../screens/timelin import { selectAlertsHistogram } from '../../tasks/alerts'; import { createTimeline } from '../../tasks/timelines'; +// TODO: https://github.com/elastic/kibana/issues/161539 describe( 'Ransomware Detection Alerts', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/ransomware_prevention.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/ransomware_prevention.cy.ts index c71c3634246a..8c62fb192931 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/ransomware_prevention.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_alerts/ransomware_prevention.cy.ts @@ -15,6 +15,7 @@ import { selectAlertsHistogram } from '../../tasks/alerts'; import { createTimeline } from '../../tasks/timelines'; import { cleanKibana } from '../../tasks/common'; +// TODO: https://github.com/elastic/kibana/issues/161539 describe( 'Ransomware Prevention Alerts', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_authorization.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_authorization.cy.ts index 30059c9ad585..19684d539c28 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_authorization.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_authorization.cy.ts @@ -55,9 +55,11 @@ const loadPageAsReadOnlyUser = (url: string) => { waitForPageWithoutDateRange(url, ROLES.reader); }; +// TODO: https://github.com/elastic/kibana/issues/164451 We should find a way to make this spec work in Serverless +// TODO: https://github.com/elastic/kibana/issues/161540 describe( 'Detection rules, Prebuilt Rules Installation and Update - Authorization/RBAC', - { tags: '@ess' }, + { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { beforeEach(() => { login(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_error_handling.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_error_handling.cy.ts index c9fe54f66f0b..b1bdae3ae49f 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_error_handling.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_error_handling.cy.ts @@ -22,9 +22,10 @@ import { ruleUpdatesTabClick, } from '../../../tasks/prebuilt_rules'; +// TODO: https://github.com/elastic/kibana/issues/161540 describe( 'Detection rules, Prebuilt Rules Installation and Update - Error handling', - { tags: '@ess' }, + { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { beforeEach(() => { login(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_workflows.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_workflows.cy.ts index b6852c698e63..a4fb84d557d3 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_workflows.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_install_update_workflows.cy.ts @@ -39,9 +39,10 @@ import { ruleUpdatesTabClick, } from '../../../tasks/prebuilt_rules'; +// TODO: https://github.com/elastic/kibana/issues/161540 describe( 'Detection rules, Prebuilt Rules Installation and Update workflow', - { tags: ['@ess', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { beforeEach(() => { login(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_management.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_management.cy.ts index b172b84b7695..00e38335792c 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_management.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_management.cy.ts @@ -50,7 +50,8 @@ const rules = Array.from(Array(5)).map((_, i) => { }); }); -describe('Prebuilt rules', { tags: ['@ess', '@serverless'] }, () => { +// TODO: https://github.com/elastic/kibana/issues/161540 +describe('Prebuilt rules', { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { before(() => { cleanKibana(); }); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_notifications.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_notifications.cy.ts index 9202b77044e9..3ee378f12f3d 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_notifications.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_notifications.cy.ts @@ -29,9 +29,10 @@ const RULE_1 = createRuleAssetSavedObject({ rule_id: 'rule_1', }); +// TODO: https://github.com/elastic/kibana/issues/161540 describe( 'Detection rules, Prebuilt Rules Installation and Update Notifications', - { tags: ['@ess', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { beforeEach(() => { login(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions.cy.ts index fef7df04844e..f835f6801ded 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions.cy.ts @@ -27,9 +27,10 @@ import { login, visit } from '../../../tasks/login'; import { RULE_CREATION } from '../../../urls/navigation'; +// TODO: https://github.com/elastic/kibana/issues/161539 describe( 'Rule actions during detection rule creation', - { tags: ['@ess', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { const indexConnector = getIndexConnector(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule.cy.ts index 18455fb11673..31c05a101180 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule.cy.ts @@ -115,7 +115,8 @@ import { import { enablesRule, getDetails, waitForTheRuleToBeExecuted } from '../../../tasks/rule_details'; import { ruleDetailsUrl, ruleEditUrl, RULE_CREATION } from '../../../urls/navigation'; -describe('Custom query rules', { tags: ['@ess', '@brokenInServerless'] }, () => { +// TODO: https://github.com/elastic/kibana/issues/161539 +describe('Custom query rules', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { beforeEach(() => { deleteAlertsAndRules(); }); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule_data_view.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule_data_view.cy.ts index da838f54457c..6d9785ec7ac0 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule_data_view.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule_data_view.cy.ts @@ -67,7 +67,8 @@ import { getDetails, waitForTheRuleToBeExecuted } from '../../../tasks/rule_deta import { RULE_CREATION } from '../../../urls/navigation'; -describe('Custom query rules', { tags: ['@ess', '@brokenInServerless'] }, () => { +// TODO: https://github.com/elastic/kibana/issues/161539 +describe('Custom query rules', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { describe('Custom detection rules creation with data views', () => { const rule = getDataViewRule(); const expectedUrls = rule.references?.join(''); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_saved_query_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_saved_query_rule.cy.ts index 747725c88aaa..5e0dc286a36a 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_saved_query_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_saved_query_rule.cy.ts @@ -50,7 +50,8 @@ const savedQueryName = 'custom saved query'; const savedQueryQuery = 'process.name: test'; const savedQueryFilterKey = 'testAgent.value'; -describe('Custom saved_query rules', { tags: ['@ess', '@brokenInServerless'] }, () => { +// TODO: https://github.com/elastic/kibana/issues/161539 +describe('Saved query rules', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { before(() => { cleanKibana(); }); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/event_correlation_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/event_correlation_rule.cy.ts index 35957cc31938..545af73b8a06 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/event_correlation_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/event_correlation_rule.cy.ts @@ -56,7 +56,8 @@ import { login, visit } from '../../../tasks/login'; import { RULE_CREATION } from '../../../urls/navigation'; -describe('EQL rules', { tags: ['@ess', '@brokenInServerless'] }, () => { +// TODO: https://github.com/elastic/kibana/issues/161539 +describe('EQL rules', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { before(() => { cleanKibana(); }); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/indicator_match_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/indicator_match_rule.cy.ts index 42dbf0ac0182..d093e9c37f33 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/indicator_match_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/indicator_match_rule.cy.ts @@ -116,7 +116,8 @@ import { const DEFAULT_THREAT_MATCH_QUERY = '@timestamp >= "now-30d/d"'; -describe('indicator match', { tags: ['@ess', '@brokenInServerless'] }, () => { +// TODO: https://github.com/elastic/kibana/issues/161539 +describe('indicator match', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { describe('Detection rules, Indicator Match', () => { const expectedUrls = getNewThreatIndicatorRule().references?.join(''); const expectedFalsePositives = getNewThreatIndicatorRule().false_positives?.join(''); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/machine_learning_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/machine_learning_rule.cy.ts index f258ff6c804b..cb820c60c120 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/machine_learning_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/machine_learning_rule.cy.ts @@ -53,7 +53,8 @@ import { login, visitWithoutDateRange } from '../../../tasks/login'; import { RULE_CREATION } from '../../../urls/navigation'; -describe('Detection rules, machine learning', { tags: ['@ess', '@brokenInServerless'] }, () => { +// TODO: https://github.com/elastic/kibana/issues/161539 +describe('Machine Learning rules', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { const expectedUrls = (getMachineLearningRule().references ?? []).join(''); const expectedFalsePositives = (getMachineLearningRule().false_positives ?? []).join(''); const expectedTags = (getMachineLearningRule().tags ?? []).join(''); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/new_terms_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/new_terms_rule.cy.ts index ffcda7468bb6..132b6d71295e 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/new_terms_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/new_terms_rule.cy.ts @@ -58,7 +58,8 @@ import { login, visit } from '../../../tasks/login'; import { RULE_CREATION } from '../../../urls/navigation'; -describe('New Terms rules', { tags: ['@ess', '@brokenInServerless'] }, () => { +// TODO: https://github.com/elastic/kibana/issues/161539 +describe('New Terms rules', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { before(() => { cleanKibana(); login(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/override.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/override.cy.ts index 837d0621cbe6..46d01f6b8363 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/override.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/override.cy.ts @@ -61,7 +61,8 @@ import { getDetails, waitForTheRuleToBeExecuted } from '../../../tasks/rule_deta import { RULE_CREATION } from '../../../urls/navigation'; -describe('Detection rules, override', { tags: ['@ess', '@brokenInServerless'] }, () => { +// TODO: https://github.com/elastic/kibana/issues/161539 +describe('Rules override', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { const rule = getNewOverrideRule(); const expectedUrls = rule.references?.join(''); const expectedFalsePositives = rule.false_positives?.join(''); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/threshold_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/threshold_rule.cy.ts index 1f93d745884e..182845599220 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/threshold_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/threshold_rule.cy.ts @@ -58,7 +58,8 @@ import { login, visitWithoutDateRange } from '../../../tasks/login'; import { RULE_CREATION } from '../../../urls/navigation'; -describe('Detection rules, threshold', { tags: ['@ess', '@brokenInServerless'] }, () => { +// TODO: https://github.com/elastic/kibana/issues/161539 +describe('Threshold rules', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { const rule = getNewThresholdRule(); const expectedUrls = rule.references?.join(''); const expectedFalsePositives = rule.false_positives?.join(''); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/authorization/all_rules_read_only.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/authorization/all_rules_read_only.cy.ts index dfb598bfa369..28fce3db9d55 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/authorization/all_rules_read_only.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/authorization/all_rules_read_only.cy.ts @@ -24,7 +24,9 @@ import { } from '../../../../tasks/common/callouts'; import { login, visitSecurityDetectionRulesPage } from '../../../../tasks/login'; -describe('All rules - read only', { tags: '@ess' }, () => { +// TODO: https://github.com/elastic/kibana/issues/164451 We should find a way to make this spec work in Serverless +// TODO: https://github.com/elastic/kibana/issues/161540 +describe('All rules - read only', { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { before(() => { cleanKibana(); createRule(getNewRule({ rule_id: '1', enabled: false })); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/maintenance_windows/maintenance_window_callout.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/maintenance_windows/maintenance_window_callout.cy.ts index 605ce523eb35..1ba764c09000 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/maintenance_windows/maintenance_window_callout.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/maintenance_windows/maintenance_window_callout.cy.ts @@ -12,47 +12,52 @@ import { cleanKibana } from '../../../../tasks/common'; import { login, visit } from '../../../../tasks/login'; import { DETECTIONS_RULE_MANAGEMENT_URL } from '../../../../urls/navigation'; -describe('Maintenance window callout on Rule Management page', { tags: ['@ess'] }, () => { - let maintenanceWindowId = ''; - - before(() => { - cleanKibana(); - login(); - - const body: AsApiContract = { - title: 'My maintenance window', - duration: 60000, // 1 minute - r_rule: { - dtstart: new Date().toISOString(), - tzid: 'Europe/Amsterdam', - freq: 0, - count: 1, - }, - }; - - // Create a test maintenance window - cy.request({ - method: 'POST', - url: INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH, - headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' }, - body, - }).then((response) => { - maintenanceWindowId = response.body.id; +// TODO: https://github.com/elastic/kibana/issues/161540 +describe( + 'Maintenance window callout on Rule Management page', + { tags: ['@ess', '@serverless', '@skipInServerless'] }, + () => { + let maintenanceWindowId = ''; + + before(() => { + cleanKibana(); + login(); + + const body: AsApiContract = { + title: 'My maintenance window', + duration: 60000, // 1 minute + r_rule: { + dtstart: new Date().toISOString(), + tzid: 'Europe/Amsterdam', + freq: 0, + count: 1, + }, + }; + + // Create a test maintenance window + cy.request({ + method: 'POST', + url: INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH, + headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' }, + body, + }).then((response) => { + maintenanceWindowId = response.body.id; + }); }); - }); - - after(() => { - // Delete a test maintenance window - cy.request({ - method: 'DELETE', - url: `${INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH}/${maintenanceWindowId}`, - headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' }, + + after(() => { + // Delete a test maintenance window + cy.request({ + method: 'DELETE', + url: `${INTERNAL_ALERTING_API_MAINTENANCE_WINDOW_PATH}/${maintenanceWindowId}`, + headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' }, + }); }); - }); - it('Displays the callout when there are running maintenance windows', () => { - visit(DETECTIONS_RULE_MANAGEMENT_URL); + it('Displays the callout when there are running maintenance windows', () => { + visit(DETECTIONS_RULE_MANAGEMENT_URL); - cy.contains('Maintenance window is running'); - }); -}); + cy.contains('Maintenance window is running'); + }); + } +); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/related_integrations/related_integrations.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/related_integrations/related_integrations.cy.ts index f5aaef1b4e84..b115d93dfd7e 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/related_integrations/related_integrations.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/related_integrations/related_integrations.cy.ts @@ -47,7 +47,8 @@ import { import { ruleDetailsUrl } from '../../../../urls/navigation'; import { enablesRule, waitForPageToBeLoaded } from '../../../../tasks/rule_details'; -describe('Related integrations', { tags: ['@ess', '@brokenInServerless'] }, () => { +// TODO: https://github.com/elastic/kibana/issues/161540 +describe('Related integrations', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { const DATA_STREAM_NAME = 'logs-related-integrations-test'; const PREBUILT_RULE_NAME = 'Prebuilt rule with related integrations'; const RULE_RELATED_INTEGRATIONS: IntegrationDefinition[] = [ @@ -189,6 +190,7 @@ describe('Related integrations', { tags: ['@ess', '@brokenInServerless'] }, () = }); }); + // TODO: https://github.com/elastic/kibana/issues/161540 // Flaky in serverless tests // @brokenInServerless tag is not working so a skip was needed describe.skip('rule details', { tags: ['@brokenInServerless'] }, () => { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_duplicate_rules.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_duplicate_rules.cy.ts index 96dd999b6e95..0771f384e132 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_duplicate_rules.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_duplicate_rules.cy.ts @@ -52,10 +52,11 @@ const EXPIRED_EXCEPTION_ITEM_NAME = 'Sample exception item'; const NON_EXPIRED_EXCEPTION_ITEM_NAME = 'Sample exception item with future expiration'; +// TODO: https://github.com/elastic/kibana/issues/161540 // Flaky on serverless describe( 'Detection rules, bulk duplicate', - { tags: ['@ess', '@serverless', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { before(() => { cleanKibana(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules.cy.ts index 6b2d3a530cca..e51bd3a73bde 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules.cy.ts @@ -114,550 +114,560 @@ const defaultRuleData = { timeline_id: '495ad7a7-316e-4544-8a0f-9c098daee76e', }; -describe('Detection rules, bulk edit', { tags: ['@ess', '@brokenInServerless'] }, () => { - before(() => { - cleanKibana(); - }); - beforeEach(() => { - login(); - // Make sure persisted rules table state is cleared - resetRulesTableState(); - deleteAlertsAndRules(); - preventPrebuiltRulesPackageInstallation(); // Make sure prebuilt rules aren't pulled from Fleet API - cy.task('esArchiverResetKibana'); - createRule(getNewRule({ name: RULE_NAME, ...defaultRuleData, rule_id: '1', enabled: false })); - createRule( - getEqlRule({ ...defaultRuleData, rule_id: '2', name: 'New EQL Rule', enabled: false }) - ); - createRule( - getMachineLearningRule({ - name: 'New ML Rule Test', - tags: ['test-default-tag-1', 'test-default-tag-2'], - enabled: false, - }) - ); - createRule( - getNewThreatIndicatorRule({ - ...defaultRuleData, - rule_id: '4', - name: 'Threat Indicator Rule Test', - enabled: false, - }) - ); - createRule( - getNewThresholdRule({ - ...defaultRuleData, - rule_id: '5', - name: 'Threshold Rule', - enabled: false, - }) - ); - createRule( - getNewTermsRule({ ...defaultRuleData, rule_id: '6', name: 'New Terms Rule', enabled: false }) - ); - - visitSecurityDetectionRulesPage(); - disableAutoRefresh(); - }); - - describe('Prerequisites', () => { - const PREBUILT_RULES = [ - createRuleAssetSavedObject({ - name: 'Prebuilt rule 1', - rule_id: 'rule_1', - }), - createRuleAssetSavedObject({ - name: 'Prebuilt rule 2', - rule_id: 'rule_2', - }), - ]; - - it('No rules selected', () => { - openBulkActionsMenu(); - - // when no rule selected all bulk edit options should be disabled - cy.get(TAGS_RULE_BULK_MENU_ITEM).should('be.disabled'); - cy.get(INDEX_PATTERNS_RULE_BULK_MENU_ITEM).should('be.disabled'); - cy.get(APPLY_TIMELINE_RULE_BULK_MENU_ITEM).should('be.disabled'); +// TODO: https://github.com/elastic/kibana/issues/161540 +describe( + 'Detection rules, bulk edit', + { tags: ['@ess', '@serverless', '@brokenInServerless'] }, + () => { + before(() => { + cleanKibana(); }); + beforeEach(() => { + login(); + // Make sure persisted rules table state is cleared + resetRulesTableState(); + deleteAlertsAndRules(); + preventPrebuiltRulesPackageInstallation(); // Make sure prebuilt rules aren't pulled from Fleet API + cy.task('esArchiverResetKibana'); + createRule(getNewRule({ name: RULE_NAME, ...defaultRuleData, rule_id: '1', enabled: false })); + createRule( + getEqlRule({ ...defaultRuleData, rule_id: '2', name: 'New EQL Rule', enabled: false }) + ); + createRule( + getMachineLearningRule({ + name: 'New ML Rule Test', + tags: ['test-default-tag-1', 'test-default-tag-2'], + enabled: false, + }) + ); + createRule( + getNewThreatIndicatorRule({ + ...defaultRuleData, + rule_id: '4', + name: 'Threat Indicator Rule Test', + enabled: false, + }) + ); + createRule( + getNewThresholdRule({ + ...defaultRuleData, + rule_id: '5', + name: 'Threshold Rule', + enabled: false, + }) + ); + createRule( + getNewTermsRule({ + ...defaultRuleData, + rule_id: '6', + name: 'New Terms Rule', + enabled: false, + }) + ); - it('Only prebuilt rules selected', () => { - createAndInstallMockedPrebuiltRules({ rules: PREBUILT_RULES }); - - // select Elastic(prebuilt) rules, check if we can't proceed further, as Elastic rules are not editable - filterByElasticRules(); - selectAllRulesOnPage(); - clickApplyTimelineTemplatesMenuItem(); - - getRulesManagementTableRows().then((rows) => { - // check modal window for Elastic rule that can't be edited - checkPrebuiltRulesCannotBeModified(rows.length); + visitSecurityDetectionRulesPage(); + disableAutoRefresh(); + }); - // the confirm button closes modal - cy.get(MODAL_CONFIRMATION_BTN).should('have.text', 'Close').click(); - cy.get(MODAL_CONFIRMATION_BODY).should('not.exist'); + describe('Prerequisites', () => { + const PREBUILT_RULES = [ + createRuleAssetSavedObject({ + name: 'Prebuilt rule 1', + rule_id: 'rule_1', + }), + createRuleAssetSavedObject({ + name: 'Prebuilt rule 2', + rule_id: 'rule_2', + }), + ]; + + it('No rules selected', () => { + openBulkActionsMenu(); + + // when no rule selected all bulk edit options should be disabled + cy.get(TAGS_RULE_BULK_MENU_ITEM).should('be.disabled'); + cy.get(INDEX_PATTERNS_RULE_BULK_MENU_ITEM).should('be.disabled'); + cy.get(APPLY_TIMELINE_RULE_BULK_MENU_ITEM).should('be.disabled'); }); - }); - it('Prebuilt and custom rules selected: user proceeds with custom rules editing', () => { - getRulesManagementTableRows().then((existedRulesRows) => { + it('Only prebuilt rules selected', () => { createAndInstallMockedPrebuiltRules({ rules: PREBUILT_RULES }); - // modal window should show how many rules can be edit, how many not - selectAllRules(); - clickAddTagsMenuItem(); + // select Elastic(prebuilt) rules, check if we can't proceed further, as Elastic rules are not editable + filterByElasticRules(); + selectAllRulesOnPage(); + clickApplyTimelineTemplatesMenuItem(); - waitForMixedRulesBulkEditModal(existedRulesRows.length); + getRulesManagementTableRows().then((rows) => { + // check modal window for Elastic rule that can't be edited + checkPrebuiltRulesCannotBeModified(rows.length); - getAvailablePrebuiltRulesCount().then((availablePrebuiltRulesCount) => { - checkPrebuiltRulesCannotBeModified(availablePrebuiltRulesCount); + // the confirm button closes modal + cy.get(MODAL_CONFIRMATION_BTN).should('have.text', 'Close').click(); + cy.get(MODAL_CONFIRMATION_BODY).should('not.exist'); }); + }); - // user can proceed with custom rule editing - cy.get(MODAL_CONFIRMATION_BTN) - .should('have.text', `Edit ${existedRulesRows.length} custom rules`) - .click(); + it('Prebuilt and custom rules selected: user proceeds with custom rules editing', () => { + getRulesManagementTableRows().then((existedRulesRows) => { + createAndInstallMockedPrebuiltRules({ rules: PREBUILT_RULES }); - // action should finish - typeTags(['test-tag']); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: existedRulesRows.length }); - }); - }); + // modal window should show how many rules can be edit, how many not + selectAllRules(); + clickAddTagsMenuItem(); - it('Prebuilt and custom rules selected: user cancels action', () => { - createAndInstallMockedPrebuiltRules({ rules: PREBUILT_RULES }); + waitForMixedRulesBulkEditModal(existedRulesRows.length); - getRulesManagementTableRows().then((rows) => { - // modal window should show how many rules can be edit, how many not - selectAllRules(); - clickAddTagsMenuItem(); - waitForMixedRulesBulkEditModal(rows.length); + getAvailablePrebuiltRulesCount().then((availablePrebuiltRulesCount) => { + checkPrebuiltRulesCannotBeModified(availablePrebuiltRulesCount); + }); - checkPrebuiltRulesCannotBeModified(PREBUILT_RULES.length); + // user can proceed with custom rule editing + cy.get(MODAL_CONFIRMATION_BTN) + .should('have.text', `Edit ${existedRulesRows.length} custom rules`) + .click(); - // user cancels action and modal disappears - cancelConfirmationModal(); + // action should finish + typeTags(['test-tag']); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: existedRulesRows.length }); + }); }); - }); - it('should not lose rules selection after edit action', () => { - const rulesToUpdate = [RULE_NAME, 'New EQL Rule', 'New Terms Rule'] as const; - // Switch to 5 rules per page, to have few pages in pagination(ideal way to test auto refresh and selection of few items) - setRowsPerPageTo(5); - // and make the rules order isn't changing (set sorting by rule name) over time if rules are run - sortByTableColumn('Rule'); - selectRulesByName(rulesToUpdate); - - // open add tags form and add 2 new tags - openBulkEditAddTagsForm(); - typeTags(['new-tag-1']); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rulesToUpdate.length }); - - testMultipleSelectedRulesLabel(rulesToUpdate.length); - // check if first four(rulesCount) rules still selected and tags are updated - for (const ruleName of rulesToUpdate) { - getRuleRow(ruleName).find(EUI_CHECKBOX).should('be.checked'); - getRuleRow(ruleName) - .find(RULES_TAGS_POPOVER_BTN) - .each(($el) => { - testTagsBadge($el, prePopulatedTags.concat(['new-tag-1'])); - }); - } - }); - }); + it('Prebuilt and custom rules selected: user cancels action', () => { + createAndInstallMockedPrebuiltRules({ rules: PREBUILT_RULES }); - describe('Tags actions', () => { - it('Display list of tags in tags select', () => { - selectAllRules(); + getRulesManagementTableRows().then((rows) => { + // modal window should show how many rules can be edit, how many not + selectAllRules(); + clickAddTagsMenuItem(); + waitForMixedRulesBulkEditModal(rows.length); - openBulkEditAddTagsForm(); - openTagsSelect(); + checkPrebuiltRulesCannotBeModified(PREBUILT_RULES.length); - cy.get(EUI_FILTER_SELECT_ITEM) - .should('have.length', prePopulatedTags.length) - .each(($el, index) => { - cy.wrap($el).should('have.text', prePopulatedTags[index]); + // user cancels action and modal disappears + cancelConfirmationModal(); }); - }); + }); - it('Add tags to custom rules', () => { - getRulesManagementTableRows().then((rows) => { - const tagsToBeAdded = ['tag-to-add-1', 'tag-to-add-2']; - const resultingTags = [...prePopulatedTags, ...tagsToBeAdded]; + it('should not lose rules selection after edit action', () => { + const rulesToUpdate = [RULE_NAME, 'New EQL Rule', 'New Terms Rule'] as const; + // Switch to 5 rules per page, to have few pages in pagination(ideal way to test auto refresh and selection of few items) + setRowsPerPageTo(5); + // and make the rules order isn't changing (set sorting by rule name) over time if rules are run + sortByTableColumn('Rule'); + selectRulesByName(rulesToUpdate); - // check if only pre-populated tags exist in the tags filter - checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); + // open add tags form and add 2 new tags + openBulkEditAddTagsForm(); + typeTags(['new-tag-1']); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rulesToUpdate.length }); + + testMultipleSelectedRulesLabel(rulesToUpdate.length); + // check if first four(rulesCount) rules still selected and tags are updated + for (const ruleName of rulesToUpdate) { + getRuleRow(ruleName).find(EUI_CHECKBOX).should('be.checked'); + getRuleRow(ruleName) + .find(RULES_TAGS_POPOVER_BTN) + .each(($el) => { + testTagsBadge($el, prePopulatedTags.concat(['new-tag-1'])); + }); + } + }); + }); + describe('Tags actions', () => { + it('Display list of tags in tags select', () => { selectAllRules(); - // open add tags form and add 2 new tags openBulkEditAddTagsForm(); - typeTags(tagsToBeAdded); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); + openTagsSelect(); + + cy.get(EUI_FILTER_SELECT_ITEM) + .should('have.length', prePopulatedTags.length) + .each(($el, index) => { + cy.wrap($el).should('have.text', prePopulatedTags[index]); + }); + }); - // check if all rules have been updated with new tags - testAllTagsBadges(resultingTags); + it('Add tags to custom rules', () => { + getRulesManagementTableRows().then((rows) => { + const tagsToBeAdded = ['tag-to-add-1', 'tag-to-add-2']; + const resultingTags = [...prePopulatedTags, ...tagsToBeAdded]; - // check that new tags were added to tags filter - // tags in tags filter sorted alphabetically - const resultingTagsInFilter = [...resultingTags].sort(); - checkTagsInTagsFilter(resultingTagsInFilter, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); + // check if only pre-populated tags exist in the tags filter + checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); + + selectAllRules(); + + // open add tags form and add 2 new tags + openBulkEditAddTagsForm(); + typeTags(tagsToBeAdded); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); + + // check if all rules have been updated with new tags + testAllTagsBadges(resultingTags); + + // check that new tags were added to tags filter + // tags in tags filter sorted alphabetically + const resultingTagsInFilter = [...resultingTags].sort(); + checkTagsInTagsFilter(resultingTagsInFilter, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); + }); }); - }); - it('Display success toast after adding tags', () => { - getRulesManagementTableRows().then((rows) => { - const tagsToBeAdded = ['tag-to-add-1', 'tag-to-add-2']; + it('Display success toast after adding tags', () => { + getRulesManagementTableRows().then((rows) => { + const tagsToBeAdded = ['tag-to-add-1', 'tag-to-add-2']; - // check if only pre-populated tags exist in the tags filter - checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); + // check if only pre-populated tags exist in the tags filter + checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); - selectAllRules(); + selectAllRules(); - // open add tags form and add 2 new tags - openBulkEditAddTagsForm(); - typeTags(tagsToBeAdded); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); + // open add tags form and add 2 new tags + openBulkEditAddTagsForm(); + typeTags(tagsToBeAdded); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); + }); }); - }); - it('Overwrite tags in custom rules', () => { - getRulesManagementTableRows().then((rows) => { - const tagsToOverwrite = ['overwrite-tag-1']; + it('Overwrite tags in custom rules', () => { + getRulesManagementTableRows().then((rows) => { + const tagsToOverwrite = ['overwrite-tag-1']; - // check if only pre-populated tags exist in the tags filter - checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); + // check if only pre-populated tags exist in the tags filter + checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); - selectAllRules(); + selectAllRules(); - // open add tags form, check overwrite tags and warning message, type tags - openBulkEditAddTagsForm(); - checkOverwriteTagsCheckbox(); + // open add tags form, check overwrite tags and warning message, type tags + openBulkEditAddTagsForm(); + checkOverwriteTagsCheckbox(); - cy.get(RULES_BULK_EDIT_TAGS_WARNING).should( - 'have.text', - `You’re about to overwrite tags for ${rows.length} selected rules, press Save to apply changes.` - ); + cy.get(RULES_BULK_EDIT_TAGS_WARNING).should( + 'have.text', + `You’re about to overwrite tags for ${rows.length} selected rules, press Save to apply changes.` + ); - typeTags(tagsToOverwrite); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); + typeTags(tagsToOverwrite); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); - // check if all rules have been updated with new tags - testAllTagsBadges(tagsToOverwrite); + // check if all rules have been updated with new tags + testAllTagsBadges(tagsToOverwrite); - // check that only new tags are in the tag filter - checkTagsInTagsFilter(tagsToOverwrite, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); + // check that only new tags are in the tag filter + checkTagsInTagsFilter(tagsToOverwrite, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); + }); }); - }); - it('Delete tags from custom rules', () => { - getRulesManagementTableRows().then((rows) => { - const tagsToDelete = prePopulatedTags.slice(0, 1); - const resultingTags = prePopulatedTags.slice(1); + it('Delete tags from custom rules', () => { + getRulesManagementTableRows().then((rows) => { + const tagsToDelete = prePopulatedTags.slice(0, 1); + const resultingTags = prePopulatedTags.slice(1); - // check if only pre-populated tags exist in the tags filter - checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); + // check if only pre-populated tags exist in the tags filter + checkTagsInTagsFilter(prePopulatedTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); - selectAllRules(); + selectAllRules(); - // open add tags form, check overwrite tags, type tags - openBulkEditDeleteTagsForm(); - typeTags(tagsToDelete); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); + // open add tags form, check overwrite tags, type tags + openBulkEditDeleteTagsForm(); + typeTags(tagsToDelete); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); - // check tags has been removed from all rules - testAllTagsBadges(resultingTags); + // check tags has been removed from all rules + testAllTagsBadges(resultingTags); - // check that tags were removed from the tag filter - checkTagsInTagsFilter(resultingTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); + // check that tags were removed from the tag filter + checkTagsInTagsFilter(resultingTags, EUI_SELECTABLE_LIST_ITEM_SR_TEXT); + }); }); }); - }); - describe('Index patterns', () => { - it('Index pattern action applied to custom rules, including machine learning: user proceeds with edit of custom non machine learning rule', () => { - getRulesManagementTableRows().then((rows) => { - const indexPattersToBeAdded = ['index-to-add-1-*', 'index-to-add-2-*']; - const resultingIndexPatterns = [...prePopulatedIndexPatterns, ...indexPattersToBeAdded]; + describe('Index patterns', () => { + it('Index pattern action applied to custom rules, including machine learning: user proceeds with edit of custom non machine learning rule', () => { + getRulesManagementTableRows().then((rows) => { + const indexPattersToBeAdded = ['index-to-add-1-*', 'index-to-add-2-*']; + const resultingIndexPatterns = [...prePopulatedIndexPatterns, ...indexPattersToBeAdded]; + + selectAllRules(); + clickAddIndexPatternsMenuItem(); + + // confirm editing custom rules, that are not Machine Learning + checkMachineLearningRulesCannotBeModified(expectedNumberOfMachineLearningRulesToBeEdited); + cy.get(MODAL_CONFIRMATION_BTN).click(); + + typeIndexPatterns(indexPattersToBeAdded); + submitBulkEditForm(); + + waitForBulkEditActionToFinish({ + updatedCount: rows.length - expectedNumberOfMachineLearningRulesToBeEdited, + }); + + // check if rule has been updated + goToRuleDetailsOf(RULE_NAME); + hasIndexPatterns(resultingIndexPatterns.join('')); + }); + }); + it('Index pattern action applied to custom rules, including machine learning: user cancels action', () => { selectAllRules(); clickAddIndexPatternsMenuItem(); // confirm editing custom rules, that are not Machine Learning checkMachineLearningRulesCannotBeModified(expectedNumberOfMachineLearningRulesToBeEdited); - cy.get(MODAL_CONFIRMATION_BTN).click(); - typeIndexPatterns(indexPattersToBeAdded); - submitBulkEditForm(); - - waitForBulkEditActionToFinish({ - updatedCount: rows.length - expectedNumberOfMachineLearningRulesToBeEdited, - }); - - // check if rule has been updated - goToRuleDetailsOf(RULE_NAME); - hasIndexPatterns(resultingIndexPatterns.join('')); + // user cancels action and modal disappears + cancelConfirmationModal(); }); - }); - it('Index pattern action applied to custom rules, including machine learning: user cancels action', () => { - selectAllRules(); - clickAddIndexPatternsMenuItem(); - - // confirm editing custom rules, that are not Machine Learning - checkMachineLearningRulesCannotBeModified(expectedNumberOfMachineLearningRulesToBeEdited); + it('Add index patterns to custom rules', () => { + getRulesManagementTableRows().then((rows) => { + const indexPattersToBeAdded = ['index-to-add-1-*', 'index-to-add-2-*']; + const resultingIndexPatterns = [...prePopulatedIndexPatterns, ...indexPattersToBeAdded]; + + // select only rules that are not ML + selectRulesByName([ + RULE_NAME, + 'New EQL Rule', + 'Threat Indicator Rule Test', + 'Threshold Rule', + 'New Terms Rule', + ]); + + openBulkEditAddIndexPatternsForm(); + typeIndexPatterns(indexPattersToBeAdded); + submitBulkEditForm(); + + waitForBulkEditActionToFinish({ + updatedCount: rows.length - expectedNumberOfMachineLearningRulesToBeEdited, + }); - // user cancels action and modal disappears - cancelConfirmationModal(); - }); + // check if rule has been updated + goToRuleDetailsOf(RULE_NAME); + hasIndexPatterns(resultingIndexPatterns.join('')); + }); + }); - it('Add index patterns to custom rules', () => { - getRulesManagementTableRows().then((rows) => { - const indexPattersToBeAdded = ['index-to-add-1-*', 'index-to-add-2-*']; - const resultingIndexPatterns = [...prePopulatedIndexPatterns, ...indexPattersToBeAdded]; + it('Display success toast after editing the index pattern', () => { + getRulesManagementTableRows().then((rows) => { + const indexPattersToBeAdded = ['index-to-add-1-*', 'index-to-add-2-*']; + + // select only rules that are not ML + selectRulesByName([ + RULE_NAME, + 'New EQL Rule', + 'Threat Indicator Rule Test', + 'Threshold Rule', + 'New Terms Rule', + ]); + + openBulkEditAddIndexPatternsForm(); + typeIndexPatterns(indexPattersToBeAdded); + submitBulkEditForm(); + + waitForBulkEditActionToFinish({ + updatedCount: rows.length - expectedNumberOfMachineLearningRulesToBeEdited, + }); + }); + }); - // select only rules that are not ML - selectRulesByName([ + it('Overwrite index patterns in custom rules', () => { + const rulesToSelect = [ RULE_NAME, 'New EQL Rule', 'Threat Indicator Rule Test', 'Threshold Rule', 'New Terms Rule', - ]); + ] as const; + const indexPattersToWrite = ['index-to-write-1-*', 'index-to-write-2-*']; + + // select only rules that are not ML + selectRulesByName(rulesToSelect); openBulkEditAddIndexPatternsForm(); - typeIndexPatterns(indexPattersToBeAdded); + + // check overwrite index patterns checkbox, ensure warning message is displayed and type index patterns + checkOverwriteIndexPatternsCheckbox(); + cy.get(RULES_BULK_EDIT_INDEX_PATTERNS_WARNING).should( + 'have.text', + `You’re about to overwrite index patterns for ${rulesToSelect.length} selected rules, press Save to apply changes.` + ); + + typeIndexPatterns(indexPattersToWrite); submitBulkEditForm(); - waitForBulkEditActionToFinish({ - updatedCount: rows.length - expectedNumberOfMachineLearningRulesToBeEdited, - }); + waitForBulkEditActionToFinish({ updatedCount: rulesToSelect.length }); // check if rule has been updated goToRuleDetailsOf(RULE_NAME); - hasIndexPatterns(resultingIndexPatterns.join('')); + hasIndexPatterns(indexPattersToWrite.join('')); }); - }); - - it('Display success toast after editing the index pattern', () => { - getRulesManagementTableRows().then((rows) => { - const indexPattersToBeAdded = ['index-to-add-1-*', 'index-to-add-2-*']; - // select only rules that are not ML - selectRulesByName([ + it('Delete index patterns from custom rules', () => { + const rulesToSelect = [ RULE_NAME, 'New EQL Rule', 'Threat Indicator Rule Test', 'Threshold Rule', 'New Terms Rule', - ]); - - openBulkEditAddIndexPatternsForm(); - typeIndexPatterns(indexPattersToBeAdded); - submitBulkEditForm(); - - waitForBulkEditActionToFinish({ - updatedCount: rows.length - expectedNumberOfMachineLearningRulesToBeEdited, - }); - }); - }); + ] as const; + const indexPatternsToDelete = prePopulatedIndexPatterns.slice(0, 1); + const resultingIndexPatterns = prePopulatedIndexPatterns.slice(1); - it('Overwrite index patterns in custom rules', () => { - const rulesToSelect = [ - RULE_NAME, - 'New EQL Rule', - 'Threat Indicator Rule Test', - 'Threshold Rule', - 'New Terms Rule', - ] as const; - const indexPattersToWrite = ['index-to-write-1-*', 'index-to-write-2-*']; - - // select only rules that are not ML - selectRulesByName(rulesToSelect); - - openBulkEditAddIndexPatternsForm(); - - // check overwrite index patterns checkbox, ensure warning message is displayed and type index patterns - checkOverwriteIndexPatternsCheckbox(); - cy.get(RULES_BULK_EDIT_INDEX_PATTERNS_WARNING).should( - 'have.text', - `You’re about to overwrite index patterns for ${rulesToSelect.length} selected rules, press Save to apply changes.` - ); + // select only not ML rules + selectRulesByName(rulesToSelect); - typeIndexPatterns(indexPattersToWrite); - submitBulkEditForm(); + openBulkEditDeleteIndexPatternsForm(); + typeIndexPatterns(indexPatternsToDelete); + submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rulesToSelect.length }); + waitForBulkEditActionToFinish({ updatedCount: rulesToSelect.length }); - // check if rule has been updated - goToRuleDetailsOf(RULE_NAME); - hasIndexPatterns(indexPattersToWrite.join('')); - }); - - it('Delete index patterns from custom rules', () => { - const rulesToSelect = [ - RULE_NAME, - 'New EQL Rule', - 'Threat Indicator Rule Test', - 'Threshold Rule', - 'New Terms Rule', - ] as const; - const indexPatternsToDelete = prePopulatedIndexPatterns.slice(0, 1); - const resultingIndexPatterns = prePopulatedIndexPatterns.slice(1); - - // select only not ML rules - selectRulesByName(rulesToSelect); - - openBulkEditDeleteIndexPatternsForm(); - typeIndexPatterns(indexPatternsToDelete); - submitBulkEditForm(); - - waitForBulkEditActionToFinish({ updatedCount: rulesToSelect.length }); - - // check if rule has been updated - goToRuleDetailsOf(RULE_NAME); - hasIndexPatterns(resultingIndexPatterns.join('')); - }); + // check if rule has been updated + goToRuleDetailsOf(RULE_NAME); + hasIndexPatterns(resultingIndexPatterns.join('')); + }); - it('Delete all index patterns from custom rules', () => { - const rulesToSelect = [ - RULE_NAME, - 'New EQL Rule', - 'Threat Indicator Rule Test', - 'Threshold Rule', - 'New Terms Rule', - ] as const; + it('Delete all index patterns from custom rules', () => { + const rulesToSelect = [ + RULE_NAME, + 'New EQL Rule', + 'Threat Indicator Rule Test', + 'Threshold Rule', + 'New Terms Rule', + ] as const; - // select only rules that are not ML - selectRulesByName(rulesToSelect); + // select only rules that are not ML + selectRulesByName(rulesToSelect); - openBulkEditDeleteIndexPatternsForm(); - typeIndexPatterns(prePopulatedIndexPatterns); - submitBulkEditForm(); + openBulkEditDeleteIndexPatternsForm(); + typeIndexPatterns(prePopulatedIndexPatterns); + submitBulkEditForm(); - // error toast should be displayed that that rules edit failed - waitForBulkEditActionToFinish({ failedCount: rulesToSelect.length }); + // error toast should be displayed that that rules edit failed + waitForBulkEditActionToFinish({ failedCount: rulesToSelect.length }); - // on error toast button click display error that index patterns can't be empty - clickErrorToastBtn(); - cy.contains(MODAL_ERROR_BODY, "Index patterns can't be empty"); + // on error toast button click display error that index patterns can't be empty + clickErrorToastBtn(); + cy.contains(MODAL_ERROR_BODY, "Index patterns can't be empty"); + }); }); - }); - describe('Timeline templates', () => { - beforeEach(() => { - loadPrepackagedTimelineTemplates(); - }); + describe('Timeline templates', () => { + beforeEach(() => { + loadPrepackagedTimelineTemplates(); + }); - it('Apply timeline template to custom rules', () => { - getRulesManagementTableRows().then((rows) => { - const timelineTemplateName = 'Generic Endpoint Timeline'; + it('Apply timeline template to custom rules', () => { + getRulesManagementTableRows().then((rows) => { + const timelineTemplateName = 'Generic Endpoint Timeline'; - selectAllRules(); + selectAllRules(); - // open Timeline template form, check warning, select timeline template - clickApplyTimelineTemplatesMenuItem(); - cy.get(RULES_BULK_EDIT_TIMELINE_TEMPLATES_WARNING).contains( - `You're about to apply changes to ${rows.length} selected rules. If you previously applied Timeline templates to these rules, they will be overwritten or (if you select 'None') reset to none.` - ); - selectTimelineTemplate(timelineTemplateName); + // open Timeline template form, check warning, select timeline template + clickApplyTimelineTemplatesMenuItem(); + cy.get(RULES_BULK_EDIT_TIMELINE_TEMPLATES_WARNING).contains( + `You're about to apply changes to ${rows.length} selected rules. If you previously applied Timeline templates to these rules, they will be overwritten or (if you select 'None') reset to none.` + ); + selectTimelineTemplate(timelineTemplateName); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); - // check if timeline template has been updated to selected one - goToRuleDetailsOf(RULE_NAME); - getDetails(TIMELINE_TEMPLATE_DETAILS).should('have.text', timelineTemplateName); + // check if timeline template has been updated to selected one + goToRuleDetailsOf(RULE_NAME); + getDetails(TIMELINE_TEMPLATE_DETAILS).should('have.text', timelineTemplateName); + }); }); - }); - it('Reset timeline template to None for custom rules', () => { - getRulesManagementTableRows().then((rows) => { - const noneTimelineTemplate = 'None'; + it('Reset timeline template to None for custom rules', () => { + getRulesManagementTableRows().then((rows) => { + const noneTimelineTemplate = 'None'; - selectAllRules(); + selectAllRules(); - // open Timeline template form, submit form without picking timeline template as None is selected by default - clickApplyTimelineTemplatesMenuItem(); + // open Timeline template form, submit form without picking timeline template as None is selected by default + clickApplyTimelineTemplatesMenuItem(); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); - // check if timeline template has been updated to selected one, by opening rule that have had timeline prior to editing - goToRuleDetailsOf(RULE_NAME); - getDetails(TIMELINE_TEMPLATE_DETAILS).should('have.text', noneTimelineTemplate); + // check if timeline template has been updated to selected one, by opening rule that have had timeline prior to editing + goToRuleDetailsOf(RULE_NAME); + getDetails(TIMELINE_TEMPLATE_DETAILS).should('have.text', noneTimelineTemplate); + }); }); }); - }); - describe('Schedule', () => { - it('Default values are applied to bulk edit schedule fields', () => { - getRulesManagementTableRows().then((rows) => { - selectAllRules(); - clickUpdateScheduleMenuItem(); + describe('Schedule', () => { + it('Default values are applied to bulk edit schedule fields', () => { + getRulesManagementTableRows().then((rows) => { + selectAllRules(); + clickUpdateScheduleMenuItem(); - assertUpdateScheduleWarningExists(rows.length); + assertUpdateScheduleWarningExists(rows.length); - assertDefaultValuesAreAppliedToScheduleFields({ - interval: 5, - lookback: 1, + assertDefaultValuesAreAppliedToScheduleFields({ + interval: 5, + lookback: 1, + }); }); }); - }); - it('Updates schedule for custom rules', () => { - getRulesManagementTableRows().then((rows) => { - selectAllRules(); - clickUpdateScheduleMenuItem(); + it('Updates schedule for custom rules', () => { + getRulesManagementTableRows().then((rows) => { + selectAllRules(); + clickUpdateScheduleMenuItem(); - assertUpdateScheduleWarningExists(rows.length); + assertUpdateScheduleWarningExists(rows.length); - typeScheduleInterval('20'); - setScheduleIntervalTimeUnit('Hours'); + typeScheduleInterval('20'); + setScheduleIntervalTimeUnit('Hours'); - typeScheduleLookback('10'); - setScheduleLookbackTimeUnit('Minutes'); + typeScheduleLookback('10'); + setScheduleLookbackTimeUnit('Minutes'); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); - goToRuleDetailsOf(RULE_NAME); + goToRuleDetailsOf(RULE_NAME); - assertRuleScheduleValues({ - interval: '20h', - lookback: '10m', + assertRuleScheduleValues({ + interval: '20h', + lookback: '10m', + }); }); }); - }); - it('Validates invalid inputs when scheduling for custom rules', () => { - getRulesManagementTableRows().then((rows) => { - selectAllRules(); - clickUpdateScheduleMenuItem(); + it('Validates invalid inputs when scheduling for custom rules', () => { + getRulesManagementTableRows().then((rows) => { + selectAllRules(); + clickUpdateScheduleMenuItem(); - // Validate invalid values are corrected to minimumValue - for 0 and negative values - typeScheduleInterval('0'); - setScheduleIntervalTimeUnit('Hours'); + // Validate invalid values are corrected to minimumValue - for 0 and negative values + typeScheduleInterval('0'); + setScheduleIntervalTimeUnit('Hours'); - typeScheduleLookback('-5'); - setScheduleLookbackTimeUnit('Seconds'); + typeScheduleLookback('-5'); + setScheduleLookbackTimeUnit('Seconds'); - submitBulkEditForm(); - waitForBulkEditActionToFinish({ updatedCount: rows.length }); + submitBulkEditForm(); + waitForBulkEditActionToFinish({ updatedCount: rows.length }); - goToRuleDetailsOf(RULE_NAME); + goToRuleDetailsOf(RULE_NAME); - assertRuleScheduleValues({ - interval: '1h', - lookback: '1s', + assertRuleScheduleValues({ + interval: '1h', + lookback: '1s', + }); }); }); }); - }); -}); + } +); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts index 997ded389422..a2575f825dd7 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts @@ -73,9 +73,10 @@ const ruleNameToAssert = 'Custom rule name with actions'; const expectedExistingSlackMessage = 'Existing slack action'; const expectedSlackMessage = 'Slack action test message'; +// TODO: https://github.com/elastic/kibana/issues/161540 describe( 'Detection rules, bulk edit of rule actions', - { tags: ['@ess', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { beforeEach(() => { cleanKibana(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_data_view.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_data_view.cy.ts index b8b26df371ed..23e708a47462 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_data_view.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_data_view.cy.ts @@ -52,9 +52,10 @@ const DATA_VIEW_ID = 'auditbeat'; const expectedIndexPatterns = ['index-1-*', 'index-2-*']; +// TODO: https://github.com/elastic/kibana/issues/161540 describe( 'Bulk editing index patterns of rules with a data view only', - { tags: ['@ess', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { const TESTED_CUSTOM_QUERY_RULE_DATA = getNewRule({ index: undefined, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/export_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/export_rule.cy.ts index a9c6d6d69312..050c944c42d2 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/export_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/export_rule.cy.ts @@ -55,7 +55,8 @@ const prebuiltRules = Array.from(Array(7)).map((_, i) => { }); }); -describe('Export rules', { tags: ['@ess', '@brokenInServerless'] }, () => { +// TODO: https://github.com/elastic/kibana/issues/161540 +describe('Export rules', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { const downloadsFolder = Cypress.config('downloadsFolder'); before(() => { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/import_rules.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/import_rules.cy.ts index f42dabbbc030..147148b724d7 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/import_rules.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/import_rules.cy.ts @@ -17,7 +17,8 @@ import { login, visitWithoutDateRange } from '../../../../../tasks/login'; import { DETECTIONS_RULE_MANAGEMENT_URL } from '../../../../../urls/navigation'; const RULES_TO_IMPORT_FILENAME = 'cypress/fixtures/7_16_rules.ndjson'; -describe('Import rules', { tags: ['@ess', '@brokenInServerless'] }, () => { +// TODO: https://github.com/elastic/kibana/issues/161540 +describe('Import rules', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { before(() => { cleanKibana(); }); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/snoozing/rule_snoozing.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/snoozing/rule_snoozing.cy.ts index 6f5dc717c860..b5121bda97b0 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/snoozing/rule_snoozing.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/snoozing/rule_snoozing.cy.ts @@ -47,8 +47,9 @@ import { TOOLTIP } from '../../../../../screens/common'; const RULES_TO_IMPORT_FILENAME = 'cypress/fixtures/7_16_rules.ndjson'; +// TODO: https://github.com/elastic/kibana/issues/161540 // Flaky in serverless tests -describe('rule snoozing', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { +describe('rule snoozing', { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { before(() => { cleanKibana(); }); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_auto_refresh.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_auto_refresh.cy.ts index 4d38fbda5525..ffcfb468e082 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_auto_refresh.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_auto_refresh.cy.ts @@ -33,86 +33,91 @@ import { getNewRule } from '../../../../objects/rule'; const DEFAULT_RULE_REFRESH_INTERVAL_VALUE = 60000; const NUM_OF_TEST_RULES = 6; -describe('Rules table: auto-refresh', { tags: ['@ess', '@brokenInServerless'] }, () => { - before(() => { - cleanKibana(); - login(); +// TODO: https://github.com/elastic/kibana/issues/161540 +describe( + 'Rules table: auto-refresh', + { tags: ['@ess', '@serverless', '@brokenInServerless'] }, + () => { + before(() => { + cleanKibana(); + login(); - for (let i = 1; i <= NUM_OF_TEST_RULES; ++i) { - createRule(getNewRule({ name: `Test rule ${i}`, rule_id: `${i}`, enabled: false })); - } - }); + for (let i = 1; i <= NUM_OF_TEST_RULES; ++i) { + createRule(getNewRule({ name: `Test rule ${i}`, rule_id: `${i}`, enabled: false })); + } + }); - beforeEach(() => { - login(); - }); + beforeEach(() => { + login(); + }); - it('Auto refreshes rules', () => { - mockGlobalClock(); - visitWithoutDateRange(DETECTIONS_RULE_MANAGEMENT_URL); + it('Auto refreshes rules', () => { + mockGlobalClock(); + visitWithoutDateRange(DETECTIONS_RULE_MANAGEMENT_URL); - expectNumberOfRules(RULES_MANAGEMENT_TABLE, NUM_OF_TEST_RULES); + expectNumberOfRules(RULES_MANAGEMENT_TABLE, NUM_OF_TEST_RULES); - // // mock 1 minute passing to make sure refresh is conducted - 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'); + // // mock 1 minute passing to make sure refresh is conducted + 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'); - }); + cy.contains(REFRESH_RULES_STATUS, 'Updated now'); + }); - it('should prevent table from rules refetch if any rule selected', () => { - mockGlobalClock(); - visitWithoutDateRange(DETECTIONS_RULE_MANAGEMENT_URL); + it('should prevent table from rules refetch if any rule selected', () => { + mockGlobalClock(); + visitWithoutDateRange(DETECTIONS_RULE_MANAGEMENT_URL); - expectNumberOfRules(RULES_MANAGEMENT_TABLE, NUM_OF_TEST_RULES); + expectNumberOfRules(RULES_MANAGEMENT_TABLE, NUM_OF_TEST_RULES); - selectRulesByName(['Test rule 1']); + selectRulesByName(['Test rule 1']); - // mock 1 minute passing to make sure refresh is not conducted - 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'); + // mock 1 minute passing to make sure refresh is not conducted + 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 - getRuleRow('Test rule 1').find(EUI_CHECKBOX).should('be.checked'); + // ensure rule is still selected + getRuleRow('Test rule 1').find(EUI_CHECKBOX).should('be.checked'); - cy.get(REFRESH_RULES_STATUS).should('have.not.text', 'Updated now'); - }); + cy.get(REFRESH_RULES_STATUS).should('have.not.text', 'Updated now'); + }); - it('should disable auto refresh when any rule selected and enable it after rules unselected', () => { - visit(DETECTIONS_RULE_MANAGEMENT_URL); + it('should disable auto refresh when any rule selected and enable it after rules unselected', () => { + visit(DETECTIONS_RULE_MANAGEMENT_URL); - expectNumberOfRules(RULES_MANAGEMENT_TABLE, NUM_OF_TEST_RULES); + expectNumberOfRules(RULES_MANAGEMENT_TABLE, NUM_OF_TEST_RULES); - // check refresh settings if it's enabled before selecting - expectAutoRefreshIsEnabled(); + // check refresh settings if it's enabled before selecting + expectAutoRefreshIsEnabled(); - selectAllRules(); + selectAllRules(); - // auto refresh should be deactivated (which means disabled without an ability to enable it) after rules selected - expectAutoRefreshIsDeactivated(); + // auto refresh should be deactivated (which means disabled without an ability to enable it) after rules selected + expectAutoRefreshIsDeactivated(); - clearAllRuleSelection(); + clearAllRuleSelection(); - // after all rules unselected, auto refresh should be reset to its previous state - expectAutoRefreshIsEnabled(); - }); + // 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); + it('should not enable auto refresh after rules were unselected if auto refresh was disabled', () => { + visit(DETECTIONS_RULE_MANAGEMENT_URL); - expectNumberOfRules(RULES_MANAGEMENT_TABLE, NUM_OF_TEST_RULES); + expectNumberOfRules(RULES_MANAGEMENT_TABLE, NUM_OF_TEST_RULES); - disableAutoRefresh(); + disableAutoRefresh(); - selectAllRules(); + selectAllRules(); - expectAutoRefreshIsDeactivated(); + expectAutoRefreshIsDeactivated(); - clearAllRuleSelection(); + clearAllRuleSelection(); - // after all rules unselected, auto refresh should still be disabled - expectAutoRefreshIsDisabled(); - }); -}); + // after all rules unselected, auto refresh should still be disabled + expectAutoRefreshIsDisabled(); + }); + } +); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_filtering.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_filtering.cy.ts index 97ccd8494e3d..d6cf2c415297 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_filtering.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_filtering.cy.ts @@ -28,8 +28,9 @@ import { import { disableAutoRefresh } from '../../../../tasks/alerts_detection_rules'; import { getNewRule } from '../../../../objects/rule'; +// TODO: https://github.com/elastic/kibana/issues/161540 // Flaky in serverless tests -describe('Rules table: filtering', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { +describe('Rules table: filtering', { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { before(() => { cleanKibana(); }); @@ -42,6 +43,7 @@ describe('Rules table: filtering', { tags: ['@ess', '@serverless', '@brokenInSer cy.task('esArchiverResetKibana'); }); + // TODO: https://github.com/elastic/kibana/issues/161540 describe.skip('Last response filter', () => { // Flaky in serverless tests // @brokenInServerless tag is not working so a skip was needed diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_links.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_links.cy.ts index d2fbd5433f87..a568bbefe7fa 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_links.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_links.cy.ts @@ -12,8 +12,9 @@ import { cleanKibana, deleteAlertsAndRules } from '../../../../tasks/common'; import { login, visitWithoutDateRange } from '../../../../tasks/login'; import { DETECTIONS_RULE_MANAGEMENT_URL } from '../../../../urls/navigation'; +// TODO: https://github.com/elastic/kibana/issues/161540 // Flaky in serverless tests -describe('Rules table: links', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { +describe('Rules table: links', { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { before(() => { cleanKibana(); }); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_persistent_state.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_persistent_state.cy.ts index d2b2f93200e2..c2b2d6e746a0 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_persistent_state.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_persistent_state.cy.ts @@ -99,310 +99,315 @@ function expectDefaultRulesTableState(): void { expectTablePage(1); } -describe('Rules table: persistent state', { tags: ['@ess', '@serverless'] }, () => { - before(() => { - cleanKibana(); - createTestRules(); - }); - - beforeEach(() => { - login(); - resetRulesTableState(); - }); - - // Flaky on serverless - // FLAKY: https://github.com/elastic/kibana/issues/165740 - describe( - 'while on a happy path', - { tags: ['@ess', '@serverless', '@brokenInServerless'] }, - () => { - it('activates management tab by default', () => { - visit(SECURITY_DETECTIONS_RULES_URL); - - expectRulesManagementTab(); - }); +// TODO: https://github.com/elastic/kibana/issues/161540 +describe( + 'Rules table: persistent state', + { tags: ['@ess', '@serverless', '@skipInServerless'] }, + () => { + before(() => { + cleanKibana(); + createTestRules(); + }); - it('leads to displaying a rule according to the specified filters', () => { - visitRulesTableWithState({ - searchTerm: 'rule', - tags: ['tag-b'], - source: 'custom', - enabled: false, - field: 'name', - order: 'asc', - perPage: 5, - page: 2, - }); + beforeEach(() => { + login(); + resetRulesTableState(); + }); - expectManagementTableRules(['rule 6']); - }); + // Flaky on serverless + // FLAKY: https://github.com/elastic/kibana/issues/165740 + describe( + 'while on a happy path', + { tags: ['@ess', '@serverless', '@brokenInServerless'] }, + () => { + it('activates management tab by default', () => { + visit(SECURITY_DETECTIONS_RULES_URL); - it('loads from the url', () => { - visitRulesTableWithState({ - searchTerm: 'rule', - tags: ['tag-b'], - source: 'custom', - enabled: false, - field: 'name', - order: 'asc', - perPage: 5, - page: 2, + expectRulesManagementTab(); }); - expectRulesManagementTab(); - expectFilterSearchTerm('rule'); - expectFilterByTags(['tag-b']); - expectFilterByCustomRules(); - expectFilterByDisabledRules(); - expectTableSorting('Rule', 'asc'); - expectRowsPerPage(5); - expectTablePage(2); - }); - - it('loads from the session storage', () => { - setStorageState({ - searchTerm: 'test', - tags: ['tag-a'], - source: 'prebuilt', - enabled: true, - field: 'severity', - order: 'desc', - perPage: 10, + it('leads to displaying a rule according to the specified filters', () => { + visitRulesTableWithState({ + searchTerm: 'rule', + tags: ['tag-b'], + source: 'custom', + enabled: false, + field: 'name', + order: 'asc', + perPage: 5, + page: 2, + }); + + expectManagementTableRules(['rule 6']); }); - visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL); + it('loads from the url', () => { + visitRulesTableWithState({ + searchTerm: 'rule', + tags: ['tag-b'], + source: 'custom', + enabled: false, + field: 'name', + order: 'asc', + perPage: 5, + page: 2, + }); - expectRulesManagementTab(); - expectFilterSearchTerm('test'); - expectFilterByTags(['tag-a']); - expectFilterByPrebuiltRules(); - expectFilterByEnabledRules(); - expectTableSorting('Severity', 'desc'); - }); - - it('prefers url state over storage state', () => { - setStorageState({ - searchTerm: 'test', - tags: ['tag-c'], - source: 'prebuilt', - enabled: true, - field: 'severity', - order: 'desc', - perPage: 10, - }); - - visitRulesTableWithState({ - searchTerm: 'rule', - tags: ['tag-b'], - source: 'custom', - enabled: false, - field: 'name', - order: 'asc', - perPage: 5, - page: 2, + expectRulesManagementTab(); + expectFilterSearchTerm('rule'); + expectFilterByTags(['tag-b']); + expectFilterByCustomRules(); + expectFilterByDisabledRules(); + expectTableSorting('Rule', 'asc'); + expectRowsPerPage(5); + expectTablePage(2); }); - expectRulesManagementTab(); - expectRulesTableState(); - expectTablePage(2); - }); + it('loads from the session storage', () => { + setStorageState({ + searchTerm: 'test', + tags: ['tag-a'], + source: 'prebuilt', + enabled: true, + field: 'severity', + order: 'desc', + perPage: 10, + }); - describe('and on the rules management tab', () => { - beforeEach(() => { - login(); visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL); - }); - - it('persists after reloading the page', () => { - changeRulesTableState(); - goToTablePage(2); - - cy.reload(); expectRulesManagementTab(); - expectRulesTableState(); - expectTablePage(2); + expectFilterSearchTerm('test'); + expectFilterByTags(['tag-a']); + expectFilterByPrebuiltRules(); + expectFilterByEnabledRules(); + expectTableSorting('Severity', 'desc'); }); - it('persists after navigating back from a rule details page', () => { - changeRulesTableState(); - goToTablePage(2); - - goToRuleDetailsOf('rule 6'); - cy.go('back'); + it('prefers url state over storage state', () => { + setStorageState({ + searchTerm: 'test', + tags: ['tag-c'], + source: 'prebuilt', + enabled: true, + field: 'severity', + order: 'desc', + perPage: 10, + }); + + visitRulesTableWithState({ + searchTerm: 'rule', + tags: ['tag-b'], + source: 'custom', + enabled: false, + field: 'name', + order: 'asc', + perPage: 5, + page: 2, + }); expectRulesManagementTab(); expectRulesTableState(); expectTablePage(2); }); - it('persists after navigating to another page inside Security Solution', () => { - changeRulesTableState(); - goToTablePage(2); + describe('and on the rules management tab', () => { + beforeEach(() => { + login(); + visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL); + }); - visit(DASHBOARDS_URL); - visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL); + it('persists after reloading the page', () => { + changeRulesTableState(); + goToTablePage(2); - expectRulesManagementTab(); - expectRulesTableState(); - expectTablePage(1); - }); + cy.reload(); - it('persists after navigating to another page outside Security Solution', () => { - changeRulesTableState(); - goToTablePage(2); + expectRulesManagementTab(); + expectRulesTableState(); + expectTablePage(2); + }); - visit(KIBANA_HOME); - visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL); + it('persists after navigating back from a rule details page', () => { + changeRulesTableState(); + goToTablePage(2); - expectRulesManagementTab(); - expectRulesTableState(); - expectTablePage(1); - }); - }); + goToRuleDetailsOf('rule 6'); + cy.go('back'); - describe('and on the rules monitoring tab', () => { - beforeEach(() => { - login(); - visit(SECURITY_DETECTIONS_RULES_MONITORING_URL); - }); + expectRulesManagementTab(); + expectRulesTableState(); + expectTablePage(2); + }); - it('persists the selected tab', () => { - changeRulesTableState(); + it('persists after navigating to another page inside Security Solution', () => { + changeRulesTableState(); + goToTablePage(2); - cy.reload(); + visit(DASHBOARDS_URL); + visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL); - expectRulesMonitoringTab(); - }); - }); - } - ); + expectRulesManagementTab(); + expectRulesTableState(); + expectTablePage(1); + }); - describe('upon state format upgrade', async () => { - beforeEach(() => { - login(); - }); + it('persists after navigating to another page outside Security Solution', () => { + changeRulesTableState(); + goToTablePage(2); + + visit(KIBANA_HOME); + visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL); - describe('and having state in the url', () => { - it('ignores unsupported state key', () => { - visitRulesTableWithState({ - someKey: 10, - searchTerm: 'rule', - tags: ['tag-b'], - source: 'custom', - enabled: false, - field: 'name', - order: 'asc', - perPage: 5, - page: 2, + expectRulesManagementTab(); + expectRulesTableState(); + expectTablePage(1); + }); }); - expectRulesTableState(); - expectTablePage(2); - }); - }); + describe('and on the rules monitoring tab', () => { + beforeEach(() => { + login(); + visit(SECURITY_DETECTIONS_RULES_MONITORING_URL); + }); - describe('and having state in the session storage', () => { - it('ignores unsupported state key', () => { - setStorageState({ - someKey: 10, - searchTerm: 'rule', - tags: ['tag-b'], - source: 'custom', - enabled: false, - field: 'name', - order: 'asc', - perPage: 5, - }); + it('persists the selected tab', () => { + changeRulesTableState(); - visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL); + cy.reload(); - expectRulesTableState(); - expectTablePage(1); - }); - }); - }); + expectRulesMonitoringTab(); + }); + }); + } + ); - describe('when persisted state is partially unavailable', () => { - describe('and on the rules management tab', () => { + describe('upon state format upgrade', async () => { beforeEach(() => { login(); - visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL); }); - it('persists after clearing the session storage', () => { - changeRulesTableState(); - goToTablePage(2); + describe('and having state in the url', () => { + it('ignores unsupported state key', () => { + visitRulesTableWithState({ + someKey: 10, + searchTerm: 'rule', + tags: ['tag-b'], + source: 'custom', + enabled: false, + field: 'name', + order: 'asc', + perPage: 5, + page: 2, + }); - cy.window().then((win) => { - win.sessionStorage.clear(); + expectRulesTableState(); + expectTablePage(2); }); - cy.reload(); - - expectRulesManagementTab(); - expectRulesTableState(); - expectTablePage(2); }); - it('persists after clearing the url state', () => { - changeRulesTableState(); - goToTablePage(2); + describe('and having state in the session storage', () => { + it('ignores unsupported state key', () => { + setStorageState({ + someKey: 10, + searchTerm: 'rule', + tags: ['tag-b'], + source: 'custom', + enabled: false, + field: 'name', + order: 'asc', + perPage: 5, + }); - visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL); + visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL); - expectRulesManagementTab(); - expectRulesTableState(); - expectTablePage(1); + expectRulesTableState(); + expectTablePage(1); + }); }); }); - }); - describe('when corrupted', () => { - describe('and on the rules management tab', () => { - beforeEach(() => { - login(); - visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL); - }); + describe('when persisted state is partially unavailable', () => { + describe('and on the rules management tab', () => { + beforeEach(() => { + login(); + visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL); + }); - it('persists after corrupting the session storage data', () => { - changeRulesTableState(); - goToTablePage(2); + it('persists after clearing the session storage', () => { + changeRulesTableState(); + goToTablePage(2); - cy.window().then((win) => { - win.sessionStorage.setItem('securitySolution.rulesTable', '!invalid'); + cy.window().then((win) => { + win.sessionStorage.clear(); + }); cy.reload(); expectRulesManagementTab(); expectRulesTableState(); expectTablePage(2); }); - }); - it('persists after corrupting the url param data', () => { - changeRulesTableState(); - goToTablePage(2); + it('persists after clearing the url state', () => { + changeRulesTableState(); + goToTablePage(2); - visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL, { qs: { rulesTable: '(!invalid)' } }); + visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL); - expectRulesManagementTab(); - expectRulesTableState(); - expectTablePage(1); + expectRulesManagementTab(); + expectRulesTableState(); + expectTablePage(1); + }); }); + }); - it('DOES NOT persist after corrupting the session storage and url param data', () => { - changeRulesTableState(); - goToTablePage(2); + describe('when corrupted', () => { + describe('and on the rules management tab', () => { + beforeEach(() => { + login(); + visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL); + }); - visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL, { - qs: { rulesTable: '(!invalid)' }, - onBeforeLoad: (win) => { + it('persists after corrupting the session storage data', () => { + changeRulesTableState(); + goToTablePage(2); + + cy.window().then((win) => { win.sessionStorage.setItem('securitySolution.rulesTable', '!invalid'); - }, + cy.reload(); + + expectRulesManagementTab(); + expectRulesTableState(); + expectTablePage(2); + }); + }); + + it('persists after corrupting the url param data', () => { + changeRulesTableState(); + goToTablePage(2); + + visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL, { qs: { rulesTable: '(!invalid)' } }); + + expectRulesManagementTab(); + expectRulesTableState(); + expectTablePage(1); }); - expectRulesManagementTab(); - expectDefaultRulesTableState(); + it('DOES NOT persist after corrupting the session storage and url param data', () => { + changeRulesTableState(); + goToTablePage(2); + + visit(SECURITY_DETECTIONS_RULES_MANAGEMENT_URL, { + qs: { rulesTable: '(!invalid)' }, + onBeforeLoad: (win) => { + win.sessionStorage.setItem('securitySolution.rulesTable', '!invalid'); + }, + }); + + expectRulesManagementTab(); + expectDefaultRulesTableState(); + }); }); }); - }); -}); + } +); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_selection.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_selection.cy.ts index 782e70dec837..383718c646f9 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_selection.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_selection.cy.ts @@ -33,69 +33,74 @@ const RULE_2 = createRuleAssetSavedObject({ rule_id: 'rule_2', }); +// TODO: https://github.com/elastic/kibana/issues/161540 // FLAKY: https://github.com/elastic/kibana/issues/165643 -describe.skip('Rules table: selection', { tags: ['@ess', '@serverless'] }, () => { - before(() => { - cleanKibana(); - }); +describe.skip( + 'Rules table: selection', + { tags: ['@ess', '@serverless', '@skipInServerless'] }, + () => { + before(() => { + cleanKibana(); + }); - beforeEach(() => { - login(); - /* Create and install two mock rules */ - createAndInstallMockedPrebuiltRules({ rules: [RULE_1, RULE_2] }); - visitWithoutDateRange(DETECTIONS_RULE_MANAGEMENT_URL); - waitForPrebuiltDetectionRulesToBeLoaded(); - }); + beforeEach(() => { + login(); + /* Create and install two mock rules */ + createAndInstallMockedPrebuiltRules({ rules: [RULE_1, RULE_2] }); + visitWithoutDateRange(DETECTIONS_RULE_MANAGEMENT_URL); + waitForPrebuiltDetectionRulesToBeLoaded(); + }); - it('should correctly update the selection label when rules are individually selected and unselected', () => { - waitForPrebuiltDetectionRulesToBeLoaded(); + it('should correctly update the selection label when rules are individually selected and unselected', () => { + waitForPrebuiltDetectionRulesToBeLoaded(); - selectRulesByName(['Test rule 1', 'Test rule 2']); + selectRulesByName(['Test rule 1', 'Test rule 2']); - cy.get(SELECTED_RULES_NUMBER_LABEL).should('contain.text', '2'); + cy.get(SELECTED_RULES_NUMBER_LABEL).should('contain.text', '2'); - unselectRulesByName(['Test rule 1', 'Test rule 2']); + unselectRulesByName(['Test rule 1', 'Test rule 2']); - cy.get(SELECTED_RULES_NUMBER_LABEL).should('contain.text', '0'); - }); + cy.get(SELECTED_RULES_NUMBER_LABEL).should('contain.text', '0'); + }); - it('should correctly update the selection label when rules are bulk selected and then bulk un-selected', () => { - waitForPrebuiltDetectionRulesToBeLoaded(); + it('should correctly update the selection label when rules are bulk selected and then bulk un-selected', () => { + waitForPrebuiltDetectionRulesToBeLoaded(); - cy.get(SELECT_ALL_RULES_BTN).click(); + cy.get(SELECT_ALL_RULES_BTN).click(); - getAvailablePrebuiltRulesCount().then((availablePrebuiltRulesCount) => { - cy.get(SELECTED_RULES_NUMBER_LABEL).should('contain.text', availablePrebuiltRulesCount); - }); + getAvailablePrebuiltRulesCount().then((availablePrebuiltRulesCount) => { + cy.get(SELECTED_RULES_NUMBER_LABEL).should('contain.text', availablePrebuiltRulesCount); + }); - // Un-select all rules via the Bulk Selection button from the Utility bar - cy.get(SELECT_ALL_RULES_BTN).click(); + // Un-select all rules via the Bulk Selection button from the Utility bar + cy.get(SELECT_ALL_RULES_BTN).click(); - // Current selection should be 0 rules - cy.get(SELECTED_RULES_NUMBER_LABEL).should('contain.text', '0'); - // Bulk selection button should be back to displaying all rules - getAvailablePrebuiltRulesCount().then((availablePrebuiltRulesCount) => { - cy.get(SELECT_ALL_RULES_BTN).should('contain.text', availablePrebuiltRulesCount); + // Current selection should be 0 rules + cy.get(SELECTED_RULES_NUMBER_LABEL).should('contain.text', '0'); + // Bulk selection button should be back to displaying all rules + getAvailablePrebuiltRulesCount().then((availablePrebuiltRulesCount) => { + cy.get(SELECT_ALL_RULES_BTN).should('contain.text', availablePrebuiltRulesCount); + }); }); - }); - it('should correctly update the selection label when rules are bulk selected and then unselected via the table select all checkbox', () => { - waitForPrebuiltDetectionRulesToBeLoaded(); + it('should correctly update the selection label when rules are bulk selected and then unselected via the table select all checkbox', () => { + waitForPrebuiltDetectionRulesToBeLoaded(); - cy.get(SELECT_ALL_RULES_BTN).click(); + cy.get(SELECT_ALL_RULES_BTN).click(); - getAvailablePrebuiltRulesCount().then((availablePrebuiltRulesCount) => { - cy.get(SELECTED_RULES_NUMBER_LABEL).should('contain.text', availablePrebuiltRulesCount); - }); + getAvailablePrebuiltRulesCount().then((availablePrebuiltRulesCount) => { + cy.get(SELECTED_RULES_NUMBER_LABEL).should('contain.text', availablePrebuiltRulesCount); + }); - // Un-select all rules via the Un-select All checkbox from the table - cy.get(SELECT_ALL_RULES_ON_PAGE_CHECKBOX).click(); + // Un-select all rules via the Un-select All checkbox from the table + cy.get(SELECT_ALL_RULES_ON_PAGE_CHECKBOX).click(); - // Current selection should be 0 rules - cy.get(SELECTED_RULES_NUMBER_LABEL).should('contain.text', '0'); - // Bulk selection button should be back to displaying all rules - getAvailablePrebuiltRulesCount().then((availablePrebuiltRulesCount) => { - cy.get(SELECT_ALL_RULES_BTN).should('contain.text', availablePrebuiltRulesCount); + // Current selection should be 0 rules + cy.get(SELECTED_RULES_NUMBER_LABEL).should('contain.text', '0'); + // Bulk selection button should be back to displaying all rules + getAvailablePrebuiltRulesCount().then((availablePrebuiltRulesCount) => { + cy.get(SELECT_ALL_RULES_BTN).should('contain.text', availablePrebuiltRulesCount); + }); }); - }); -}); + } +); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_sorting.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_sorting.cy.ts index d61d6fca9895..f132f89b248a 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_sorting.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_sorting.cy.ts @@ -36,6 +36,7 @@ import { } from '../../../../tasks/table_pagination'; import { TABLE_FIRST_PAGE, TABLE_SECOND_PAGE } from '../../../../screens/table_pagination'; +// TODO: https://github.com/elastic/kibana/issues/161540 describe('Rules table: sorting', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { before(() => { cleanKibana(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/value_lists/value_lists.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/value_lists/value_lists.cy.ts index 552f1c4f109e..7a2c6aeb35a2 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/value_lists/value_lists.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/value_lists/value_lists.cy.ts @@ -35,8 +35,10 @@ const TEXT_LIST_FILE_NAME = 'value_list.txt'; const IPS_LIST_FILE_NAME = 'ip_list.txt'; const CIDRS_LIST_FILE_NAME = 'cidr_list.txt'; +// TODO: https://github.com/elastic/kibana/issues/161539 // FLAKY: https://github.com/elastic/kibana/issues/165699 -describe('value lists', () => { +describe('value lists', { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { + // TODO: https://github.com/elastic/kibana/issues/161539 describe('management modal', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { beforeEach(() => { login(); @@ -56,6 +58,7 @@ describe('value lists', () => { closeValueListsModal(); }); + // TODO: https://github.com/elastic/kibana/issues/161539 // Flaky in serverless tests describe('create list types', { tags: ['@brokenInServerless'] }, () => { beforeEach(() => { @@ -115,6 +118,7 @@ describe('value lists', () => { }); }); + // TODO: https://github.com/elastic/kibana/issues/161539 // Flaky in serverless tests describe('delete list types', { tags: ['@brokenInServerless'] }, () => { it('deletes a "keyword" list from an uploaded file', () => { @@ -162,6 +166,7 @@ describe('value lists', () => { }); }); + // TODO: https://github.com/elastic/kibana/issues/161539 // Flaky in serverless tests describe('export list types', { tags: ['@brokenInServerless'] }, () => { it('exports a "keyword" list from an uploaded file', () => { @@ -259,11 +264,17 @@ describe('value lists', () => { }); }); - describe('user with restricted access role', { tags: '@ess' }, () => { - it('Does not allow a t1 analyst user to upload a value list', () => { - login(ROLES.t1_analyst); - visitWithoutDateRange(DETECTIONS_RULE_MANAGEMENT_URL, ROLES.t1_analyst); - cy.get(VALUE_LISTS_MODAL_ACTIVATOR).should('have.attr', 'disabled'); - }); - }); + // TODO: https://github.com/elastic/kibana/issues/164451 We should find a way to make this spec work in Serverless + // TODO: https://github.com/elastic/kibana/issues/161539 + describe( + 'user with restricted access role', + { tags: ['@ess', '@serverless', '@skipInServerless'] }, + () => { + it('Does not allow a t1 analyst user to upload a value list', () => { + login(ROLES.t1_analyst); + visitWithoutDateRange(DETECTIONS_RULE_MANAGEMENT_URL, ROLES.t1_analyst); + cy.get(VALUE_LISTS_MODAL_ACTIVATOR).should('have.attr', 'disabled'); + }); + } + ); }); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts index 36bc18210863..fca7699af784 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts @@ -39,13 +39,14 @@ import { previewErrorButtonClick, } from '../../tasks/entity_analytics'; +// TODO: https://github.com/elastic/kibana/issues/161539 describe( 'Entity analytics management page', { env: { ftrConfig: { enableExperimental: ['riskScoringRoutesEnabled', 'riskScoringPersistence'] }, }, - tags: ['@ess', '@brokenInServerless'], + tags: ['@ess', '@serverless', '@brokenInServerless'], }, () => { before(() => { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/endpoint_exceptions.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/endpoint_exceptions.cy.ts index 3ca8b633e656..184152c8c5bf 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/endpoint_exceptions.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/endpoint_exceptions.cy.ts @@ -36,10 +36,11 @@ import { } from '../../../screens/exceptions'; import { goToEndpointExceptionsTab, waitForTheRuleToBeExecuted } from '../../../tasks/rule_details'; +// TODO: https://github.com/elastic/kibana/issues/161539 // See https://github.com/elastic/kibana/issues/163967 describe.skip( 'Endpoint Exceptions workflows from Alert', - { tags: ['@ess', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { const ITEM_NAME = 'Sample Exception List Item'; const ITEM_NAME_EDIT = 'Sample Exception List Item'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions/auto_populate_with_alert_data.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions/auto_populate_with_alert_data.cy.ts index afd1f6c36e29..41a4dd607ffe 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions/auto_populate_with_alert_data.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions/auto_populate_with_alert_data.cy.ts @@ -37,10 +37,11 @@ import { } from '../../../../screens/exceptions'; import { waitForAlertsToPopulate } from '../../../../tasks/create_new_rule'; +// TODO: https://github.com/elastic/kibana/issues/161539 // See https://github.com/elastic/kibana/issues/163967 describe.skip( 'Auto populate exception with Alert data', - { tags: ['@ess', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { const ITEM_NAME = 'Sample Exception Item'; const ITEM_NAME_EDIT = 'Sample Exception Item Edit'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions/closing_all_matching_alerts.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions/closing_all_matching_alerts.cy.ts index f85e57216079..6efdc2e8c515 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions/closing_all_matching_alerts.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions/closing_all_matching_alerts.cy.ts @@ -26,8 +26,9 @@ import { submitNewExceptionItem, } from '../../../../tasks/exceptions'; +// TODO: https://github.com/elastic/kibana/issues/161539 // See https://github.com/elastic/kibana/issues/163967 -describe('Close matching Alerts ', () => { +describe('Close matching Alerts ', { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { const ITEM_NAME = 'Sample Exception Item'; beforeEach(() => { @@ -53,7 +54,8 @@ describe('Close matching Alerts ', () => { cy.task('esArchiverUnload', 'exceptions'); }); - it('Should create a Rule exception item from alert actions overflow menu and close all matching alerts', () => { + // TODO: https://github.com/elastic/kibana/issues/161539 + it.skip('Should create a Rule exception item from alert actions overflow menu and close all matching alerts', () => { cy.get(LOADING_INDICATOR).should('not.exist'); addExceptionFromFirstAlert(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/flyout_validation.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/flyout_validation.cy.ts index 04ef2368a7e1..97df23c52118 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/flyout_validation.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/flyout_validation.cy.ts @@ -56,6 +56,7 @@ import { } from '../../../tasks/api_calls/exceptions'; import { getExceptionList } from '../../../objects/exception'; +// TODO: https://github.com/elastic/kibana/issues/161539 // Test Skipped until we fix the Flyout rerendering issue // https://github.com/elastic/kibana/issues/154994 @@ -64,7 +65,7 @@ import { getExceptionList } from '../../../objects/exception'; // to test in enzyme and very small changes can inadvertently add // bugs. As the complexity within the builder grows, these should // ensure the most basic logic holds. -describe.skip('Exceptions flyout', { tags: ['@ess', '@serverless'] }, () => { +describe.skip('Exceptions flyout', { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { before(() => { cy.task('esArchiverResetKibana'); // this is a made-up index that has just the necessary diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/multiple_conditions.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/multiple_conditions.cy.ts index 2cf577d41e16..8da64aebc92d 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/multiple_conditions.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/multiple_conditions.cy.ts @@ -25,12 +25,13 @@ import { import { ruleDetailsUrl } from '../../../urls/navigation'; import { deleteAlertsAndRules } from '../../../tasks/common'; +// TODO: https://github.com/elastic/kibana/issues/161539 // FLAKY: https://github.com/elastic/kibana/issues/165651 // FLAKY: https://github.com/elastic/kibana/issues/165734 // FLAKY: https://github.com/elastic/kibana/issues/165652 describe( 'Add multiple conditions and validate the generated exceptions', - { tags: ['@ess', '@serverless', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { beforeEach(() => { cy.task('esArchiverResetKibana'); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/use_value_list.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/use_value_list.cy.ts index 0969b53d8cee..ff571faa0146 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/use_value_list.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/use_value_list.cy.ts @@ -43,10 +43,11 @@ const goToRulesAndOpenValueListModal = () => { openValueListsModal(); }; +// TODO: https://github.com/elastic/kibana/issues/161539 // Flaky on serverless describe( 'Use Value list in exception entry', - { tags: ['@ess', '@serverless', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { beforeEach(() => { cleanKibana(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_endpoint_exception.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_endpoint_exception.cy.ts index 170530f8c804..c5a1a8e25b33 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_endpoint_exception.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_endpoint_exception.cy.ts @@ -46,10 +46,11 @@ import { createEndpointExceptionListItem, } from '../../../tasks/api_calls/exceptions'; +// TODO: https://github.com/elastic/kibana/issues/161539 // FLAKY: https://github.com/elastic/kibana/issues/165736 describe( 'Add endpoint exception from rule details', - { tags: ['@ess', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { const ITEM_NAME = 'Sample Exception List Item'; const NEW_ITEM_NAME = 'Exception item-EDITED'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_exception.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_exception.cy.ts index 11f5a5867940..2f3d10a0b3ce 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_exception.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_exception.cy.ts @@ -58,273 +58,281 @@ import { } from '../../../tasks/api_calls/exceptions'; import { waitForAlertsToPopulate } from '../../../tasks/create_new_rule'; -describe('Add/edit exception from rule details', { tags: ['@ess', '@brokenInServerless'] }, () => { - const NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS = '1 alert'; - const FIELD_DIFFERENT_FROM_EXISTING_ITEM_FIELD = 'agent.name'; - const ITEM_FIELD = 'unique_value.test'; - - before(() => { - cy.task('esArchiverResetKibana'); - cy.task('esArchiverLoad', { archiveName: 'exceptions' }); - }); - - after(() => { - cy.task('esArchiverUnload', 'exceptions'); - }); - - beforeEach(() => { - login(); - deleteAlertsAndRules(); - - const exceptionList = getExceptionList(); - deleteExceptionList(exceptionList.list_id, exceptionList.namespace_type); - }); - - describe('existing list and items', () => { - const exceptionList = getExceptionList(); +// TODO: https://github.com/elastic/kibana/issues/161539 +describe( + 'Add/edit exception from rule details', + { tags: ['@ess', '@serverless', '@brokenInServerless'] }, + () => { + const NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS = '1 alert'; + const FIELD_DIFFERENT_FROM_EXISTING_ITEM_FIELD = 'agent.name'; + const ITEM_FIELD = 'unique_value.test'; + + before(() => { + cy.task('esArchiverResetKibana'); + cy.task('esArchiverLoad', { archiveName: 'exceptions' }); + }); + + after(() => { + cy.task('esArchiverUnload', 'exceptions'); + }); + beforeEach(() => { - // create rule with exceptions - createExceptionList(exceptionList, exceptionList.list_id).then((response) => { - createExceptionListItem(exceptionList.list_id, { - list_id: exceptionList.list_id, - item_id: 'simple_list_item', - tags: [], - type: 'simple', - description: 'Test exception item 2', - name: 'Sample Exception List Item 2', - namespace_type: 'single', - entries: [ - { - field: ITEM_FIELD, - operator: 'included', - type: 'match_any', - value: ['foo'], - }, - ], - }); + login(); + deleteAlertsAndRules(); - createRule( - getNewRule({ - query: 'agent.name:*', - index: ['exceptions*'], - exceptions_list: [ + const exceptionList = getExceptionList(); + deleteExceptionList(exceptionList.list_id, exceptionList.namespace_type); + }); + + describe('existing list and items', () => { + const exceptionList = getExceptionList(); + beforeEach(() => { + // create rule with exceptions + createExceptionList(exceptionList, exceptionList.list_id).then((response) => { + createExceptionListItem(exceptionList.list_id, { + list_id: exceptionList.list_id, + item_id: 'simple_list_item', + tags: [], + type: 'simple', + description: 'Test exception item 2', + name: 'Sample Exception List Item 2', + namespace_type: 'single', + entries: [ { - id: response.body.id, - list_id: exceptionList.list_id, - type: exceptionList.type, - namespace_type: exceptionList.namespace_type, + field: ITEM_FIELD, + operator: 'included', + type: 'match_any', + value: ['foo'], }, ], - rule_id: '2', - }) - ).then((rule) => visitWithoutDateRange(ruleDetailsUrl(rule.body.id, 'rule_exceptions'))); + }); + + createRule( + getNewRule({ + query: 'agent.name:*', + index: ['exceptions*'], + exceptions_list: [ + { + id: response.body.id, + list_id: exceptionList.list_id, + type: exceptionList.type, + namespace_type: exceptionList.namespace_type, + }, + ], + rule_id: '2', + }) + ).then((rule) => visitWithoutDateRange(ruleDetailsUrl(rule.body.id, 'rule_exceptions'))); + }); }); - }); - it('Edits an exception item', () => { - const NEW_ITEM_NAME = 'Exception item-EDITED'; - const ITEM_NAME = 'Sample Exception List Item 2'; + it('Edits an exception item', () => { + const NEW_ITEM_NAME = 'Exception item-EDITED'; + const ITEM_NAME = 'Sample Exception List Item 2'; - // displays existing exception items - cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 1); - cy.get(NO_EXCEPTIONS_EXIST_PROMPT).should('not.exist'); - cy.get(EXCEPTION_CARD_ITEM_NAME).should('have.text', ITEM_NAME); - cy.get(EXCEPTION_CARD_ITEM_CONDITIONS).should('have.text', ' unique_value.testis one of foo'); + // displays existing exception items + cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 1); + cy.get(NO_EXCEPTIONS_EXIST_PROMPT).should('not.exist'); + cy.get(EXCEPTION_CARD_ITEM_NAME).should('have.text', ITEM_NAME); + cy.get(EXCEPTION_CARD_ITEM_CONDITIONS).should( + 'have.text', + ' unique_value.testis one of foo' + ); - // open edit exception modal - openEditException(); + // open edit exception modal + openEditException(); - // edit exception item name - editExceptionFlyoutItemName(NEW_ITEM_NAME); + // edit exception item name + editExceptionFlyoutItemName(NEW_ITEM_NAME); - // check that the existing item's field is being populated - cy.get(EXCEPTION_ITEM_CONTAINER) - .eq(0) - .find(FIELD_INPUT_PARENT) - .eq(0) - .should('have.text', ITEM_FIELD); - cy.get(VALUES_MATCH_ANY_INPUT).should('have.text', 'foo'); + // check that the existing item's field is being populated + cy.get(EXCEPTION_ITEM_CONTAINER) + .eq(0) + .find(FIELD_INPUT_PARENT) + .eq(0) + .should('have.text', ITEM_FIELD); + cy.get(VALUES_MATCH_ANY_INPUT).should('have.text', 'foo'); - // edit conditions - editException(FIELD_DIFFERENT_FROM_EXISTING_ITEM_FIELD, 0, 0); + // edit conditions + editException(FIELD_DIFFERENT_FROM_EXISTING_ITEM_FIELD, 0, 0); - // submit - submitEditedExceptionItem(); + // submit + submitEditedExceptionItem(); - // new exception item displays - cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 1); + // new exception item displays + cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 1); - // check that updates stuck - cy.get(EXCEPTION_CARD_ITEM_NAME).should('have.text', NEW_ITEM_NAME); - cy.get(EXCEPTION_CARD_ITEM_CONDITIONS).should('have.text', ' agent.nameIS foo'); - }); + // check that updates stuck + cy.get(EXCEPTION_CARD_ITEM_NAME).should('have.text', NEW_ITEM_NAME); + cy.get(EXCEPTION_CARD_ITEM_CONDITIONS).should('have.text', ' agent.nameIS foo'); + }); - describe('rule with existing shared exceptions', () => { - it('Creates an exception item to add to shared list', () => { - // displays existing exception items - cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 1); - cy.get(NO_EXCEPTIONS_EXIST_PROMPT).should('not.exist'); + describe('rule with existing shared exceptions', () => { + it('Creates an exception item to add to shared list', () => { + // displays existing exception items + cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 1); + cy.get(NO_EXCEPTIONS_EXIST_PROMPT).should('not.exist'); - // open add exception modal - addExceptionFlyoutFromViewerHeader(); + // open add exception modal + addExceptionFlyoutFromViewerHeader(); - // add exception item conditions - addExceptionConditions(getException()); + // add exception item conditions + addExceptionConditions(getException()); - // Name is required so want to check that submit is still disabled - cy.get(CONFIRM_BTN).should('have.attr', 'disabled'); + // Name is required so want to check that submit is still disabled + cy.get(CONFIRM_BTN).should('have.attr', 'disabled'); - // add exception item name - addExceptionFlyoutItemName('My item name'); + // add exception item name + addExceptionFlyoutItemName('My item name'); - // select to add exception item to a shared list - selectSharedListToAddExceptionTo(1); + // select to add exception item to a shared list + selectSharedListToAddExceptionTo(1); - // not testing close alert functionality here, just ensuring that the options appear as expected - cy.get(CLOSE_ALERTS_CHECKBOX).should('exist'); - cy.get(CLOSE_ALERTS_CHECKBOX).should('not.have.attr', 'disabled'); + // not testing close alert functionality here, just ensuring that the options appear as expected + cy.get(CLOSE_ALERTS_CHECKBOX).should('exist'); + cy.get(CLOSE_ALERTS_CHECKBOX).should('not.have.attr', 'disabled'); - // submit - submitNewExceptionItem(); + // submit + submitNewExceptionItem(); - // new exception item displays - cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 2); - }); + // new exception item displays + cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 2); + }); - it('Creates an exception item to add to rule only', () => { - // displays existing exception items - cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 1); - cy.get(NO_EXCEPTIONS_EXIST_PROMPT).should('not.exist'); + it('Creates an exception item to add to rule only', () => { + // displays existing exception items + cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 1); + cy.get(NO_EXCEPTIONS_EXIST_PROMPT).should('not.exist'); - // open add exception modal - addExceptionFlyoutFromViewerHeader(); + // open add exception modal + addExceptionFlyoutFromViewerHeader(); - // add exception item conditions - addExceptionConditions(getException()); + // add exception item conditions + addExceptionConditions(getException()); - // Name is required so want to check that submit is still disabled - cy.get(CONFIRM_BTN).should('have.attr', 'disabled'); + // Name is required so want to check that submit is still disabled + cy.get(CONFIRM_BTN).should('have.attr', 'disabled'); - // add exception item name - addExceptionFlyoutItemName('My item name'); + // add exception item name + addExceptionFlyoutItemName('My item name'); - // select to add exception item to rule only - selectAddToRuleRadio(); + // select to add exception item to rule only + selectAddToRuleRadio(); - // not testing close alert functionality here, just ensuring that the options appear as expected - cy.get(CLOSE_ALERTS_CHECKBOX).should('exist'); - cy.get(CLOSE_ALERTS_CHECKBOX).should('not.have.attr', 'disabled'); + // not testing close alert functionality here, just ensuring that the options appear as expected + cy.get(CLOSE_ALERTS_CHECKBOX).should('exist'); + cy.get(CLOSE_ALERTS_CHECKBOX).should('not.have.attr', 'disabled'); - // submit - submitNewExceptionItem(); + // submit + submitNewExceptionItem(); - // new exception item displays - cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 2); - }); + // new exception item displays + cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 2); + }); - // Trying to figure out with EUI why the search won't trigger - it('Can search for items', () => { - // displays existing exception items - cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 1); - cy.get(NO_EXCEPTIONS_EXIST_PROMPT).should('not.exist'); + // Trying to figure out with EUI why the search won't trigger + it('Can search for items', () => { + // displays existing exception items + cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 1); + cy.get(NO_EXCEPTIONS_EXIST_PROMPT).should('not.exist'); - // can search for an exception value - searchForExceptionItem('foo'); + // can search for an exception value + searchForExceptionItem('foo'); - // new exception item displays - cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 1); + // new exception item displays + cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 1); - // displays empty search result view if no matches found - searchForExceptionItem('abc'); + // displays empty search result view if no matches found + searchForExceptionItem('abc'); - // new exception item displays - cy.get(NO_EXCEPTIONS_SEARCH_RESULTS_PROMPT).should('exist'); + // new exception item displays + cy.get(NO_EXCEPTIONS_SEARCH_RESULTS_PROMPT).should('exist'); + }); }); }); - }); - describe('rule without existing exceptions', () => { - beforeEach(() => { - createRule( - getNewRule({ - query: 'agent.name:*', - index: ['exceptions*'], - interval: '10s', - rule_id: 'rule_testing', - }) - ).then((rule) => visitWithoutDateRange(ruleDetailsUrl(rule.body.id, 'rule_exceptions'))); - }); + describe('rule without existing exceptions', () => { + beforeEach(() => { + createRule( + getNewRule({ + query: 'agent.name:*', + index: ['exceptions*'], + interval: '10s', + rule_id: 'rule_testing', + }) + ).then((rule) => visitWithoutDateRange(ruleDetailsUrl(rule.body.id, 'rule_exceptions'))); + }); - afterEach(() => { - cy.task('esArchiverUnload', 'exceptions_2'); - }); + afterEach(() => { + cy.task('esArchiverUnload', 'exceptions_2'); + }); - it('Cannot create an item to add to rule but not shared list as rule has no lists attached', () => { - // when no exceptions exist, empty component shows with action to add exception - cy.get(NO_EXCEPTIONS_EXIST_PROMPT).should('exist'); + it('Cannot create an item to add to rule but not shared list as rule has no lists attached', () => { + // when no exceptions exist, empty component shows with action to add exception + cy.get(NO_EXCEPTIONS_EXIST_PROMPT).should('exist'); - // open add exception modal - openExceptionFlyoutFromEmptyViewerPrompt(); + // open add exception modal + openExceptionFlyoutFromEmptyViewerPrompt(); - // add exception item conditions - addExceptionConditions({ - field: 'agent.name', - operator: 'is', - values: ['foo'], - }); + // add exception item conditions + addExceptionConditions({ + field: 'agent.name', + operator: 'is', + values: ['foo'], + }); - // Name is required so want to check that submit is still disabled - cy.get(CONFIRM_BTN).should('have.attr', 'disabled'); + // Name is required so want to check that submit is still disabled + cy.get(CONFIRM_BTN).should('have.attr', 'disabled'); - // add exception item name - addExceptionFlyoutItemName('My item name'); + // add exception item name + addExceptionFlyoutItemName('My item name'); - // select to add exception item to rule only - selectAddToRuleRadio(); + // select to add exception item to rule only + selectAddToRuleRadio(); - // Check that add to shared list is disabled, should be unless - // rule has shared lists attached to it already - cy.get(ADD_TO_SHARED_LIST_RADIO_INPUT).should('have.attr', 'disabled'); + // Check that add to shared list is disabled, should be unless + // rule has shared lists attached to it already + cy.get(ADD_TO_SHARED_LIST_RADIO_INPUT).should('have.attr', 'disabled'); - // Close matching alerts - selectBulkCloseAlerts(); + // Close matching alerts + selectBulkCloseAlerts(); - // submit - submitNewExceptionItem(); + // submit + submitNewExceptionItem(); - // new exception item displays - cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 1); + // new exception item displays + cy.get(EXCEPTION_ITEM_VIEWER_CONTAINER).should('have.length', 1); - // Alerts table should now be empty from having added exception and closed - // matching alert - goToAlertsTab(); - cy.get(EMPTY_ALERT_TABLE).should('exist'); + // Alerts table should now be empty from having added exception and closed + // matching alert + goToAlertsTab(); + cy.get(EMPTY_ALERT_TABLE).should('exist'); - // Closed alert should appear in table - goToClosedAlertsOnRuleDetailsPage(); - cy.get(ALERTS_COUNT).should('exist'); - cy.get(ALERTS_COUNT).should('have.text', `${NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS}`); + // Closed alert should appear in table + goToClosedAlertsOnRuleDetailsPage(); + cy.get(ALERTS_COUNT).should('exist'); + cy.get(ALERTS_COUNT).should('have.text', `${NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS}`); - // Remove the exception and load an event that would have matched that exception - // to show that said exception now starts to show up again - goToExceptionsTab(); + // Remove the exception and load an event that would have matched that exception + // to show that said exception now starts to show up again + goToExceptionsTab(); - // when removing exception and again, no more exist, empty screen shows again - removeException(); - cy.get(NO_EXCEPTIONS_EXIST_PROMPT).should('exist'); + // when removing exception and again, no more exist, empty screen shows again + removeException(); + cy.get(NO_EXCEPTIONS_EXIST_PROMPT).should('exist'); - // load more docs - cy.task('esArchiverLoad', { archiveName: 'exceptions_2' }); + // load more docs + cy.task('esArchiverLoad', { archiveName: 'exceptions_2' }); - // now that there are no more exceptions, the docs should match and populate alerts - goToAlertsTab(); - waitForAlertsToPopulate(); - goToOpenedAlertsOnRuleDetailsPage(); - waitForTheRuleToBeExecuted(); - waitForAlertsToPopulate(); + // now that there are no more exceptions, the docs should match and populate alerts + goToAlertsTab(); + waitForAlertsToPopulate(); + goToOpenedAlertsOnRuleDetailsPage(); + waitForTheRuleToBeExecuted(); + waitForAlertsToPopulate(); - cy.get(ALERTS_COUNT).should('exist'); - cy.get(ALERTS_COUNT).should('have.text', '2 alerts'); + cy.get(ALERTS_COUNT).should('exist'); + cy.get(ALERTS_COUNT).should('have.text', '2 alerts'); + }); }); - }); -}); + } +); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_exception_data_view.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_exception_data_view.cy.ts index a1e3e17db597..07fd7dd56e5c 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_exception_data_view.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_exception_data_view.cy.ts @@ -40,9 +40,10 @@ import { } from '../../../screens/exceptions'; import { waitForAlertsToPopulate } from '../../../tasks/create_new_rule'; +// TODO: https://github.com/elastic/kibana/issues/161539 describe( 'Add exception using data views from rule details', - { tags: ['@ess', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { const NUMBER_OF_AUDITBEAT_EXCEPTIONS_ALERTS = '1 alert'; const ITEM_NAME = 'Sample Exception List Item'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/read_only_view.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/read_only_view.cy.ts index d6e5637e1737..85f0a2012838 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/read_only_view.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/read_only_view.cy.ts @@ -26,7 +26,8 @@ import { deleteExceptionList, } from '../../../tasks/api_calls/exceptions'; -describe('Exceptions viewer read only', { tags: '@ess' }, () => { +// TODO: https://github.com/elastic/kibana/issues/161539 Do we need this to run in Serverless? +describe('Exceptions viewer read only', { tags: ['@ess', '@skipInServerless'] }, () => { const exceptionList = getExceptionList(); beforeEach(() => { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/list_detail_page/list_details.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/list_detail_page/list_details.cy.ts index 74c47b853d95..2c5ccd93f3ca 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/list_detail_page/list_details.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/list_detail_page/list_details.cy.ts @@ -40,10 +40,11 @@ const getExceptionList1 = () => ({ const EXCEPTION_LIST_NAME = 'Newly created list'; +// TODO: https://github.com/elastic/kibana/issues/161539 // FLAKY: https://github.com/elastic/kibana/issues/165640 describe( 'Exception list detail page', - { tags: ['@ess', '@serverless', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { before(() => { cy.task('esArchiverResetKibana'); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/manage_exceptions.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/manage_exceptions.cy.ts index c5cf8a5de942..0c5523e42a9e 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/manage_exceptions.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/manage_exceptions.cy.ts @@ -37,10 +37,11 @@ import { waitForExceptionsTableToBeLoaded, } from '../../../tasks/exceptions_table'; +// TODO: https://github.com/elastic/kibana/issues/161539 // FLAKY: https://github.com/elastic/kibana/issues/165795 describe( 'Add, edit and delete exception', - { tags: ['@ess', '@serverless', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { beforeEach(() => { cy.task('esArchiverResetKibana'); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/duplicate_lists.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/duplicate_lists.cy.ts index b296ff05e3b5..f28b1fc2ed25 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/duplicate_lists.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/duplicate_lists.cy.ts @@ -40,8 +40,9 @@ const getExceptionList2 = () => ({ list_id: 'exception_list_2', }); +// TODO: https://github.com/elastic/kibana/issues/161539 // Flaky in serverless tests -describe('Duplicate List', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { +describe('Duplicate List', { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { beforeEach(() => { cy.task('esArchiverResetKibana'); login(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/filter_table.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/filter_table.cy.ts index 8fc3acdb2c7e..6f8411c2d5ad 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/filter_table.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/filter_table.cy.ts @@ -35,7 +35,9 @@ const getExceptionList2 = () => ({ name: EXCEPTION_LIST_NAME_TWO, list_id: 'exception_list_2', }); -describe('Filter Lists', { tags: ['@ess', '@serverless'] }, () => { + +// TODO: https://github.com/elastic/kibana/issues/161539 +describe('Filter Lists', { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { beforeEach(() => { cy.task('esArchiverResetKibana'); login(); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/import_lists.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/import_lists.cy.ts index ac10e916d762..7d24c9009e31 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/import_lists.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/import_lists.cy.ts @@ -20,8 +20,9 @@ import { import { login, visitWithoutDateRange } from '../../../../tasks/login'; import { EXCEPTIONS_URL } from '../../../../urls/navigation'; +// TODO: https://github.com/elastic/kibana/issues/161539 // Flaky in serverless -describe('Import Lists', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => { +describe('Import Lists', { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { const LIST_TO_IMPORT_FILENAME = 'cypress/fixtures/7_16_exception_list.ndjson'; before(() => { cy.task('esArchiverResetKibana'); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/manage_lists.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/manage_lists.cy.ts index 9f2b655fdfbb..b740eb5d9d63 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/manage_lists.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/manage_lists.cy.ts @@ -47,10 +47,11 @@ const getExceptionList2 = () => ({ let exceptionListResponse: Cypress.Response; +// TODO: https://github.com/elastic/kibana/issues/161539 // FLAKY: https://github.com/elastic/kibana/issues/165690 describe( 'Manage lists from "Shared Exception Lists" page', - { tags: ['@ess', '@serverless', '@brokenInServerless'] }, + { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { describe('Create/Export/Delete List', () => { before(() => { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/read_only.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/read_only.cy.ts index c6ac43547fad..d028f5a3949c 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/read_only.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/read_only.cy.ts @@ -21,7 +21,8 @@ import { import { login, visitWithoutDateRange } from '../../../../tasks/login'; import { EXCEPTIONS_URL } from '../../../../urls/navigation'; -describe('Shared exception lists - read only', { tags: '@ess' }, () => { +// TODO: https://github.com/elastic/kibana/issues/161539 Do we need to run it in Serverless? +describe('Shared exception lists - read only', { tags: ['@ess', '@skipInServerless'] }, () => { before(() => { cy.task('esArchiverResetKibana'); }); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/overview/cti_link_panel.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/overview/cti_link_panel.cy.ts index fa99225543e8..6fed0acc748c 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/overview/cti_link_panel.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/overview/cti_link_panel.cy.ts @@ -15,8 +15,9 @@ import { import { login, visit } from '../../tasks/login'; import { OVERVIEW_URL } from '../../urls/navigation'; +// TODO: https://github.com/elastic/kibana/issues/161539 // FLAKY: https://github.com/elastic/kibana/issues/165709 -describe.skip('CTI Link Panel', { tags: ['@ess', '@serverless'] }, () => { +describe.skip('CTI Link Panel', { tags: ['@ess', '@serverless', '@skipInServerless'] }, () => { beforeEach(() => { login(); }); @@ -31,35 +32,40 @@ describe.skip('CTI Link Panel', { tags: ['@ess', '@serverless'] }, () => { .and('match', /app\/integrations\/browse\/threat_intel/); }); - describe('enabled threat intel module', { tags: ['@brokenInServerless'] }, () => { - before(() => { - // illegal_argument_exception: unknown setting [index.lifecycle.name] - cy.task('esArchiverLoad', { archiveName: 'threat_indicator' }); - }); + // TODO: https://github.com/elastic/kibana/issues/161539 + describe( + 'enabled threat intel module', + { tags: ['@ess', '@serverless', '@brokenInServerless'] }, + () => { + before(() => { + // illegal_argument_exception: unknown setting [index.lifecycle.name] + cy.task('esArchiverLoad', { archiveName: 'threat_indicator' }); + }); - beforeEach(() => { - login(); - }); + beforeEach(() => { + login(); + }); - after(() => { - cy.task('esArchiverUnload', 'threat_indicator'); - }); + after(() => { + cy.task('esArchiverUnload', 'threat_indicator'); + }); - it('renders disabled dashboard module as expected when there are no events in the selected time period', () => { - visit( - `${OVERVIEW_URL}?sourcerer=(timerange:(from:%272021-07-08T04:00:00.000Z%27,kind:absolute,to:%272021-07-09T03:59:59.999Z%27))` - ); - cy.get(`${OVERVIEW_CTI_LINKS}`).should('exist'); - cy.get(`${OVERVIEW_CTI_TOTAL_EVENT_COUNT}`).should('have.text', 'Showing: 0 indicators'); - }); + it('renders disabled dashboard module as expected when there are no events in the selected time period', () => { + visit( + `${OVERVIEW_URL}?sourcerer=(timerange:(from:%272021-07-08T04:00:00.000Z%27,kind:absolute,to:%272021-07-09T03:59:59.999Z%27))` + ); + cy.get(`${OVERVIEW_CTI_LINKS}`).should('exist'); + cy.get(`${OVERVIEW_CTI_TOTAL_EVENT_COUNT}`).should('have.text', 'Showing: 0 indicators'); + }); - it('renders dashboard module as expected when there are events in the selected time period', () => { - visit(OVERVIEW_URL); + it('renders dashboard module as expected when there are events in the selected time period', () => { + visit(OVERVIEW_URL); - cy.get(`${OVERVIEW_CTI_LINKS}`).should('exist'); - cy.get(OVERVIEW_CTI_LINKS).should('not.contain.text', 'Anomali'); - cy.get(OVERVIEW_CTI_LINKS).should('contain.text', 'AbuseCH malware'); - cy.get(`${OVERVIEW_CTI_TOTAL_EVENT_COUNT}`).should('have.text', 'Showing: 1 indicator'); - }); - }); + cy.get(`${OVERVIEW_CTI_LINKS}`).should('exist'); + cy.get(OVERVIEW_CTI_LINKS).should('not.contain.text', 'Anomali'); + cy.get(OVERVIEW_CTI_LINKS).should('contain.text', 'AbuseCH malware'); + cy.get(`${OVERVIEW_CTI_TOTAL_EVENT_COUNT}`).should('have.text', 'Showing: 1 indicator'); + }); + } + ); }); diff --git a/x-pack/test/security_solution_cypress/package.json b/x-pack/test/security_solution_cypress/package.json index 140cd99b3df4..ba28de108ccf 100644 --- a/x-pack/test/security_solution_cypress/package.json +++ b/x-pack/test/security_solution_cypress/package.json @@ -19,7 +19,7 @@ "junit:transform": "node ../../plugins/security_solution/scripts/junit_transformer --pathPattern '../../../target/kibana-security-solution/cypress/results/*.xml' --rootDirectory ../../../ --reportName 'Security Solution Cypress' --writeInPlace", "cypress:serverless": "TZ=UTC node ../../plugins/security_solution/scripts/start_cypress_parallel --config-file ../../test/security_solution_cypress/cypress/cypress_ci_serverless.config.ts --ftr-config-file ../../test/security_solution_cypress/serverless_config", "cypress:open:serverless": "yarn cypress:serverless open --config-file ../../test/security_solution_cypress/cypress/cypress_serverless.config.ts --spec './cypress/e2e/**/*.cy.ts'", - "cypress:run:serverless": "yarn cypress:serverless --spec '**/cypress/e2e/!(investigations|explore)/**/*.cy.ts'", + "cypress:run:serverless": "yarn cypress:serverless --spec './cypress/e2e/!(investigations|explore)/**/*.cy.ts'", "cypress:investigations:run:serverless": "yarn cypress:serverless --spec './cypress/e2e/investigations/**/*.cy.ts'", "cypress:explore:run:serverless": "yarn cypress:serverless --spec './cypress/e2e/explore/**/*.cy.ts'", "cypress:changed-specs-only:serverless": "yarn cypress:serverless --changed-specs-only --env burn=2",