diff --git a/x-pack/plugins/security_solution/cypress/cypress_ci.config.ts b/x-pack/plugins/security_solution/cypress/cypress_ci.config.ts index 107736e45759f..41cbcd85addd4 100644 --- a/x-pack/plugins/security_solution/cypress/cypress_ci.config.ts +++ b/x-pack/plugins/security_solution/cypress/cypress_ci.config.ts @@ -25,6 +25,9 @@ export default defineCypressConfig({ e2e: { baseUrl: 'http://localhost:5601', experimentalMemoryManagement: true, - specPattern: './cypress/e2e/**/*.cy.ts', + specPattern: [ + './cypress/e2e/**/*.cy.ts', + '../../test/security_solution_cypress/e2e/**/*.cy.ts', + ], }, }); diff --git a/x-pack/plugins/security_solution/cypress/e2e/detection_rules/bulk_edit_rules.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/bulk_edit_rules.cy.ts index b07555156b351..0df184f944482 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/detection_rules/bulk_edit_rules.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/bulk_edit_rules.cy.ts @@ -77,7 +77,12 @@ import { login, visitWithoutDateRange } from '../../tasks/login'; import { SECURITY_DETECTIONS_RULES_URL } from '../../urls/navigation'; import { createRule } from '../../tasks/api_calls/rules'; import { loadPrepackagedTimelineTemplates } from '../../tasks/api_calls/timelines'; -import { cleanKibana, resetRulesTableState, deleteAlertsAndRules } from '../../tasks/common'; +import { + cleanKibana, + resetRulesTableState, + deleteAlertsAndRules, + waitForPageToBeLoaded, +} from '../../tasks/common'; import { getEqlRule, @@ -136,7 +141,7 @@ describe('Detection rules, bulk edit', () => { createRule(getNewTermsRule({ ...defaultRuleData, rule_id: '6' })); visitWithoutDateRange(SECURITY_DETECTIONS_RULES_URL); - + waitForPageToBeLoaded(); waitForRulesTableToBeLoaded(); }); diff --git a/x-pack/plugins/security_solution/cypress/e2e/explore/users/user_details.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/explore/users/user_details.cy.ts deleted file mode 100644 index 90a44a514ce7c..0000000000000 --- a/x-pack/plugins/security_solution/cypress/e2e/explore/users/user_details.cy.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { ALERT_FLYOUT } from '../../../screens/alerts_details'; -import { createRule } from '../../../tasks/api_calls/rules'; -import { cleanKibana } from '../../../tasks/common'; -import { waitForAlertsToPopulate } from '../../../tasks/create_new_rule'; -import { login, visitWithoutDateRange } from '../../../tasks/login'; -import { refreshPage } from '../../../tasks/security_header'; -import { getNewRule } from '../../../objects/rule'; -import { ALERTS_URL } from '../../../urls/navigation'; -import { - expandAlertTableCellValue, - openUserDetailsFlyout, - scrollAlertTableColumnIntoView, -} from '../../../tasks/alerts'; -import { USER_COLUMN } from '../../../screens/alerts'; - -describe('user details flyout', () => { - beforeEach(() => { - cleanKibana(); - login(); - }); - - it('shows user detail flyout from alert table', () => { - visitWithoutDateRange(ALERTS_URL); - createRule(getNewRule({ query: 'user.name:*' })); - refreshPage(); - waitForAlertsToPopulate(); - - scrollAlertTableColumnIntoView(USER_COLUMN); - expandAlertTableCellValue(USER_COLUMN); - openUserDetailsFlyout(); - - cy.get(ALERT_FLYOUT).should('be.visible'); - }); -}); diff --git a/x-pack/plugins/security_solution/cypress/e2e/header/search_bar.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/header/search_bar.cy.ts index a138849a8a934..f6cfe8cb7dbb4 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/header/search_bar.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/header/search_bar.cy.ts @@ -20,12 +20,14 @@ import { import { getHostIpFilter } from '../../objects/filter'; import { HOSTS_URL } from '../../urls/navigation'; +import { waitForPageToBeLoaded } from '../../tasks/common'; import { waitForAllHostsToBeLoaded } from '../../tasks/hosts/all_hosts'; describe('SearchBar', () => { beforeEach(() => { login(); visit(HOSTS_URL); + waitForPageToBeLoaded(); waitForAllHostsToBeLoaded(); }); diff --git a/x-pack/plugins/security_solution/cypress/e2e/inspect/inspect_button.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/inspect/inspect_button.cy.ts index bc6ebf679ee2d..0c9d94008ed58 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/inspect/inspect_button.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/inspect/inspect_button.cy.ts @@ -17,11 +17,7 @@ import { openTableInspectModal, } from '../../tasks/inspect'; import { login, visit } from '../../tasks/login'; -import { - postDataView, - waitForPageToBeLoaded, - waitForWelcomePanelToBeLoaded, -} from '../../tasks/common'; +import { postDataView, waitForWelcomePanelToBeLoaded } from '../../tasks/common'; import { esArchiverLoad, esArchiverUnload } from '../../tasks/es_archiver'; import { selectDataView } from '../../tasks/sourcerer'; @@ -52,7 +48,6 @@ describe('Inspect Explore pages', () => { visit(url, { onLoad: () => { waitForWelcomePanelToBeLoaded(); - waitForPageToBeLoaded(); selectDataView(DATA_VIEW); }, }); diff --git a/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/row_renderers.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/row_renderers.cy.ts index 9ae5993f8b80c..abba937f522a6 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/row_renderers.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/row_renderers.cy.ts @@ -15,12 +15,7 @@ import { TIMELINE_ROW_RENDERERS_SURICATA_SIGNATURE_TOOLTIP, TIMELINE_ROW_RENDERERS_SURICATA_LINK_TOOLTIP, } from '../../../screens/timeline'; -import { - cleanKibana, - deleteTimelines, - waitForPageToBeLoaded, - waitForWelcomePanelToBeLoaded, -} from '../../../tasks/common'; +import { cleanKibana, deleteTimelines, waitForWelcomePanelToBeLoaded } from '../../../tasks/common'; import { waitForAllHostsToBeLoaded } from '../../../tasks/hosts/all_hosts'; import { login, visit } from '../../../tasks/login'; @@ -40,7 +35,6 @@ describe('Row renderers', () => { visit(HOSTS_URL, { onLoad: () => { waitForWelcomePanelToBeLoaded(); - waitForPageToBeLoaded(); waitForAllHostsToBeLoaded(); }, }); diff --git a/x-pack/plugins/security_solution/cypress/tasks/all_cases.ts b/x-pack/plugins/security_solution/cypress/tasks/all_cases.ts index 5485a47214ac3..90d41a92c8f16 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/all_cases.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/all_cases.ts @@ -10,15 +10,12 @@ import { ALL_CASES_CREATE_NEW_CASE_BTN, EDIT_EXTERNAL_CONNECTION, } from '../screens/all_cases'; -import { waitForPageToBeLoaded } from './common'; export const goToCreateNewCase = () => { cy.get(ALL_CASES_CREATE_NEW_CASE_BTN, { timeout: 60000 }).click({ force: true }); - waitForPageToBeLoaded(); }; export const goToCaseDetails = () => { - waitForPageToBeLoaded(); cy.get(ALL_CASES_NAME).click({ force: true }); }; diff --git a/x-pack/plugins/security_solution/cypress/tasks/common.ts b/x-pack/plugins/security_solution/cypress/tasks/common.ts index fc6a7096e1814..716dc27c2e3be 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/common.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/common.ts @@ -102,6 +102,8 @@ export const cleanKibana = () => { export const deleteAlertsAndRules = () => { cy.log('Delete all alerts and rules'); + cy.log(Cypress.env('ELASTICSEARCH_URL')); + cy.log('GLOOOOOO'); const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_\*`; rootRequest({ diff --git a/x-pack/plugins/security_solution/cypress/tasks/login.ts b/x-pack/plugins/security_solution/cypress/tasks/login.ts index 065779ae95fe6..f3b61f1d6f20f 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/login.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/login.ts @@ -13,7 +13,6 @@ import Url from 'url'; import type { ROLES } from '../../common/test'; import { NEW_FEATURES_TOUR_STORAGE_KEYS } from '../../common/constants'; import { hostDetailsUrl, LOGOUT_URL, userDetailsUrl } from '../urls/navigation'; -import { waitForPageToBeLoaded } from './common'; /** * Credentials in the `kibana.dev.yml` config file will be used to authenticate @@ -314,13 +313,6 @@ const disableNewFeaturesTours = (window: Window) => { * Kibana global nav to be displayed before continuing */ -export const waitForPage = (url: string) => { - cy.visit( - `${url}?timerange=(global:(linkTo:!(timeline),timerange:(from:1547914976217,fromStr:'2019-01-19T16:22:56.217Z',kind:relative,to:1579537385745,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1547914976217,fromStr:'2019-01-19T16:22:56.217Z',kind:relative,to:1579537385745,toStr:now)))` - ); - waitForPageToBeLoaded(); -}; - export const visit = (url: string, options: Partial = {}, role?: ROLES) => { const timerangeConfig = { from: 1547914976217, @@ -356,21 +348,18 @@ export const visit = (url: string, options: Partial = {}, options.onLoad?.(win); }, }); - waitForPageToBeLoaded(); }; export const visitWithoutDateRange = (url: string, role?: ROLES) => { cy.visit(role ? getUrlWithRoute(role, url) : url, { onBeforeLoad: disableNewFeaturesTours, }); - waitForPageToBeLoaded(); }; export const visitWithUser = (url: string, user: User) => { cy.visit(constructUrlWithUser(user, url), { onBeforeLoad: disableNewFeaturesTours, }); - waitForPageToBeLoaded(); }; export const visitTimeline = (timelineId: string, role?: ROLES) => { @@ -378,7 +367,6 @@ export const visitTimeline = (timelineId: string, role?: ROLES) => { cy.visit(role ? getUrlWithRoute(role, route) : route, { onBeforeLoad: disableNewFeaturesTours, }); - waitForPageToBeLoaded(); }; export const visitHostDetailsPage = (hostName = 'suricata-iowa') => { @@ -393,7 +381,6 @@ export const visitUserDetailsPage = (userName = 'test') => { export const waitForPageWithoutDateRange = (url: string, role?: ROLES) => { cy.visit(role ? getUrlWithRoute(role, url) : url); - waitForPageToBeLoaded(); }; export const logout = () => { diff --git a/x-pack/plugins/security_solution/cypress/tasks/sourcerer.ts b/x-pack/plugins/security_solution/cypress/tasks/sourcerer.ts index 00fa6b1152201..d0cee60b3dc53 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/sourcerer.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/sourcerer.ts @@ -7,7 +7,7 @@ import { HOSTS_STAT, SOURCERER } from '../screens/sourcerer'; import { HOSTS_URL } from '../urls/navigation'; -import { visit, waitForPage } from './login'; +import { visit } from './login'; import { openTimelineUsingToggle } from './security_main'; import { DEFAULT_ALERTS_INDEX } from '../../common/constants'; import { rootRequest } from './common'; @@ -110,7 +110,7 @@ export const addIndexToDefault = (index: string) => { cy.get('button[data-test-subj="advancedSetting-saveButton"]').click(); cy.get('button[data-test-subj="windowReloadButton"]').click(); - waitForPage(HOSTS_URL); + visit(HOSTS_URL); }); }; diff --git a/x-pack/plugins/security_solution/cypress/upgrade_e2e/detections/detection_rules/custom_query_rule.cy.ts b/x-pack/plugins/security_solution/cypress/upgrade_e2e/detections/detection_rules/custom_query_rule.cy.ts index a9950f840fa72..370c9f55b718b 100644 --- a/x-pack/plugins/security_solution/cypress/upgrade_e2e/detections/detection_rules/custom_query_rule.cy.ts +++ b/x-pack/plugins/security_solution/cypress/upgrade_e2e/detections/detection_rules/custom_query_rule.cy.ts @@ -36,7 +36,6 @@ import { } from '../../../screens/rule_details'; import { getDetails } from '../../../tasks/rule_details'; -import { waitForPageToBeLoaded } from '../../../tasks/common'; import { waitForRulesTableToBeLoaded, goToTheRuleDetailsOf, @@ -81,7 +80,6 @@ describe('After an upgrade, the custom query rule', () => { visit(DETECTIONS_RULE_MANAGEMENT_URL); waitForRulesTableToBeLoaded(); goToTheRuleDetailsOf(rule.name); - waitForPageToBeLoaded(); // Possible bug on first attempt sometimes redirects page back to alerts // Going to retry the block once cy.url().then((url) => { @@ -92,7 +90,6 @@ describe('After an upgrade, the custom query rule', () => { visit(DETECTIONS_RULE_MANAGEMENT_URL); waitForRulesTableToBeLoaded(); goToTheRuleDetailsOf(rule.name); - waitForPageToBeLoaded(); } }); cy.url().should('include', DETECTIONS_RULE_MANAGEMENT_URL); diff --git a/x-pack/plugins/security_solution/cypress/upgrade_e2e/detections/detection_rules/threshold_rule.cy.ts b/x-pack/plugins/security_solution/cypress/upgrade_e2e/detections/detection_rules/threshold_rule.cy.ts index 78c34dfd43a7e..a964ef4411e6a 100644 --- a/x-pack/plugins/security_solution/cypress/upgrade_e2e/detections/detection_rules/threshold_rule.cy.ts +++ b/x-pack/plugins/security_solution/cypress/upgrade_e2e/detections/detection_rules/threshold_rule.cy.ts @@ -26,7 +26,6 @@ import { import { getDetails } from '../../../tasks/rule_details'; import { expandFirstAlert } from '../../../tasks/alerts'; -import { waitForPageToBeLoaded } from '../../../tasks/common'; import { goToTheRuleDetailsOf, waitForRulesTableToBeLoaded, @@ -76,7 +75,6 @@ describe('After an upgrade, the threshold rule', () => { visit(DETECTIONS_RULE_MANAGEMENT_URL); waitForRulesTableToBeLoaded(); goToTheRuleDetailsOf(rule.name); - waitForPageToBeLoaded(); }); it('Has the expected alerts number', () => { diff --git a/x-pack/plugins/security_solution/package.json b/x-pack/plugins/security_solution/package.json index 01419bb09e470..765117d10011d 100644 --- a/x-pack/plugins/security_solution/package.json +++ b/x-pack/plugins/security_solution/package.json @@ -8,7 +8,7 @@ "extract-mitre-attacks": "node scripts/extract_tactics_techniques_mitre.js && node ../../../scripts/eslint ./public/detections/mitre/mitre_tactics_techniques.ts --fix", "build-beat-doc": "node scripts/beat_docs/build.js && node ../../../scripts/eslint ../timelines/server/utils/beat_schema/fields.ts --fix", "cypress": "../../../node_modules/.bin/cypress", - "cypress:open": "TZ=UTC node ./scripts/start_cypress_parallel open --spec './cypress/e2e/**/*.cy.ts' --config-file ./cypress/cypress.config.ts --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config", + "cypress:open": "TZ=UTC node ./scripts/start_cypress_parallel open --config-file ./cypress/cypress.config.ts --spec '../../{plugins/security_solution/cypress,test/security_solution_cypress}/e2e/**/*.cy.ts' --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config", "cypress:open:ccs": "yarn cypress:open --config specPattern=./cypress/ccs_e2e/**/*.cy.ts", "cypress:open:upgrade": "yarn cypress:open --config specPattern=./cypress/upgrade_e2e/**/*.cy.ts", "cypress:run": "yarn cypress:run:reporter --browser chrome --spec './cypress/e2e/{,!(investigations,explore)/**/}*.cy.ts'; status=$?; yarn junit:merge && exit $status", @@ -24,7 +24,7 @@ "cypress:dw:endpoint:run": "node ./scripts/start_cypress_parallel run --config-file ./public/management/cypress_endpoint.config.ts --ftr-config-file ../../../../../../x-pack/test/defend_workflows_cypress/endpoint_config --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json --concurrency 1; status=$?; yarn junit:merge && exit $status", "cypress:dw:endpoint:open": "node ./scripts/start_cypress_parallel open --config-file ./public/management/cypress_endpoint.config.ts ts --ftr-config-file ../../../../../../x-pack/test/defend_workflows_cypress/endpoint_config", "cypress:investigations:run": "yarn cypress:run:reporter --browser chrome --spec './cypress/e2e/investigations/**/*.cy.ts' --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config; status=$?; yarn junit:merge && exit $status", - "cypress:explore:run": "yarn cypress:run:reporter --browser chrome --spec './cypress/e2e/explore/**/*.cy.ts' --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config; status=$?; yarn junit:merge && exit $status", + "cypress:explore:run": "yarn cypress:run:reporter --browser chrome --spec '../../{plugins/security_solution/cypress,test/security_solution_cypress}/e2e/**/*.cy.ts' --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config; status=$?; yarn junit:merge && exit $status", "junit:merge": "../../../node_modules/.bin/mochawesome-merge ../../../target/kibana-security-solution/cypress/results/mochawesome*.json > ../../../target/kibana-security-solution/cypress/results/output.json && ../../../node_modules/.bin/marge ../../../target/kibana-security-solution/cypress/results/output.json --reportDir ../../../target/kibana-security-solution/cypress/results && mkdir -p ../../../target/junit && cp ../../../target/kibana-security-solution/cypress/results/*.xml ../../../target/junit/", "test:generate": "node scripts/endpoint/resolver_generator", "mappings:generate": "node scripts/mappings/mappings_generator", 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 f18a36656ead8..c297dcd69e7fe 100644 --- a/x-pack/plugins/security_solution/scripts/run_cypress/parallel.ts +++ b/x-pack/plugins/security_solution/scripts/run_cypress/parallel.ts @@ -360,6 +360,7 @@ export const cli = () => { config: { e2e: { baseUrl: `http://localhost:${kibanaPort}`, + specPattern: files, }, env: customEnv, }, diff --git a/x-pack/test/security_solution_cypress/e2e/user_details.cy.ts b/x-pack/test/security_solution_cypress/e2e/user_details.cy.ts new file mode 100644 index 0000000000000..31931c39e5fca --- /dev/null +++ b/x-pack/test/security_solution_cypress/e2e/user_details.cy.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ALERT_FLYOUT } from '@kbn/security-solution-plugin/cypress/screens/alerts_details'; +import { createRule } from '@kbn/security-solution-plugin/cypress/tasks/api_calls/rules'; +import { cleanKibana } from '@kbn/security-solution-plugin/cypress/tasks/common'; +import { waitForAlertsToPopulate } from '@kbn/security-solution-plugin/cypress/tasks/create_new_rule'; +import { login, visitWithoutDateRange } from '@kbn/security-solution-plugin/cypress/tasks/login'; +import { refreshPage } from '@kbn/security-solution-plugin/cypress/tasks/security_header'; +import { getNewRule } from '@kbn/security-solution-plugin/cypress/objects/rule'; +import { ALERTS_URL } from '@kbn/security-solution-plugin/cypress/urls/navigation'; +import { + expandAlertTableCellValue, + openUserDetailsFlyout, + scrollAlertTableColumnIntoView, +} from '@kbn/security-solution-plugin/cypress/tasks/alerts'; +import { USER_COLUMN } from '@kbn/security-solution-plugin/cypress/screens/alerts'; + +describe('user details flyout', () => { + beforeEach(() => { + cleanKibana(); + login(); + }); + + it('shows user detail flyout from alert table', () => { + visitWithoutDateRange(ALERTS_URL); + createRule(getNewRule({ query: 'user.name:*' })); + refreshPage(); + waitForAlertsToPopulate(); + + scrollAlertTableColumnIntoView(USER_COLUMN); + expandAlertTableCellValue(USER_COLUMN); + openUserDetailsFlyout(); + + cy.get(ALERT_FLYOUT).should('be.visible'); + }); +}); diff --git a/x-pack/test/tsconfig.json b/x-pack/test/tsconfig.json index 5cda7fbbdf8fd..ce54e10c31e6c 100644 --- a/x-pack/test/tsconfig.json +++ b/x-pack/test/tsconfig.json @@ -135,6 +135,7 @@ "@kbn/profiling-plugin", "@kbn/observability-onboarding-plugin", "@kbn/bfetch-plugin", - "@kbn/uptime-plugin" + "@kbn/uptime-plugin", + "@kbn/security-solution-plugin/cypress" ] } diff --git a/x-pack/test_serverless/functional/test_suites/security/cypress/cypress.config.ts b/x-pack/test_serverless/functional/test_suites/security/cypress/cypress.config.ts index 5791794ce0c19..662d984c64fc9 100644 --- a/x-pack/test_serverless/functional/test_suites/security/cypress/cypress.config.ts +++ b/x-pack/test_serverless/functional/test_suites/security/cypress/cypress.config.ts @@ -8,9 +8,9 @@ import { defineCypressConfig } from '@kbn/cypress-config'; export default defineCypressConfig({ - defaultCommandTimeout: 60000, - execTimeout: 60000, - pageLoadTimeout: 60000, + defaultCommandTimeout: 150000, + execTimeout: 150000, + pageLoadTimeout: 150000, responseTimeout: 60000, screenshotsFolder: '../../../../../../target/kibana-security-solution/cypress/screenshots', trashAssetsBeforeRuns: false, @@ -23,6 +23,9 @@ export default defineCypressConfig({ experimentalRunAllSpecs: true, experimentalMemoryManagement: true, supportFile: './support/e2e.js', - specPattern: './e2e/**/*.cy.ts', + specPattern: [ + './e2e/**/*.cy.ts', + '../../../../../test/security_solution_cypress/e2e/**/*.cy.ts', + ], }, }); diff --git a/x-pack/test_serverless/functional/test_suites/security/cypress/runner.ts b/x-pack/test_serverless/functional/test_suites/security/cypress/runner.ts index 16119e4869ef1..9f370157ab83c 100644 --- a/x-pack/test_serverless/functional/test_suites/security/cypress/runner.ts +++ b/x-pack/test_serverless/functional/test_suites/security/cypress/runner.ts @@ -7,6 +7,7 @@ import { resolve } from 'path'; import { withProcRunner } from '@kbn/dev-proc-runner'; +import Url from 'url'; import { FtrProviderContext } from '../../../ftr_provider_context'; @@ -17,6 +18,10 @@ export async function SecuritySolutionCypressTestRunner( command: string ) { const log = getService('log'); + const config = getService('config'); + const esArchiver = getService('esArchiver'); + + await esArchiver.load('x-pack/test/security_solution_cypress/es_archives/auditbeat'); await withProcRunner(log, async (procs) => { await procs.run('cypress', { @@ -25,6 +30,11 @@ export async function SecuritySolutionCypressTestRunner( cwd: resolve(__dirname), env: { ...process.env, + FORCE_COLOR: '1', + CYPRESS_BASE_URL: Url.format(config.get('servers.kibana')), + CYPRESS_ELASTICSEARCH_URL: Url.format(config.get('servers.elasticsearch')), + CYPRESS_ELASTICSEARCH_USERNAME: config.get('servers.elasticsearch.username'), + CYPRESS_ELASTICSEARCH_PASSWORD: config.get('servers.elasticsearch.password'), }, wait: true, }); diff --git a/x-pack/test_serverless/functional/test_suites/security/cypress/security_config.base.ts b/x-pack/test_serverless/functional/test_suites/security/cypress/security_config.base.ts index 515ea0c52efee..1c9af3f011b17 100644 --- a/x-pack/test_serverless/functional/test_suites/security/cypress/security_config.base.ts +++ b/x-pack/test_serverless/functional/test_suites/security/cypress/security_config.base.ts @@ -28,6 +28,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { ...svlSharedConfig.get('kbnTestServer.serverArgs'), '--csp.strict=false', '--csp.warnLegacyBrowsers=false', + '--xpack.encryptedSavedObjects.encryptionKey="abcdefghijklmnopqrstuvwxyz123456"', '--serverless=security', ], }, diff --git a/x-pack/test_serverless/functional/test_suites/security/cypress/support/commands.js b/x-pack/test_serverless/functional/test_suites/security/cypress/support/commands.js index 73895fbbec589..ecee00b106be1 100644 --- a/x-pack/test_serverless/functional/test_suites/security/cypress/support/commands.js +++ b/x-pack/test_serverless/functional/test_suites/security/cypress/support/commands.js @@ -30,3 +30,57 @@ // // -- This is will overwrite an existing command -- // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) + +import 'cypress-file-upload'; +import 'cypress-recurse/commands'; + +Cypress.Commands.add( + 'attachFile', + { + prevSubject: 'element', + }, + (input, fileName, fileType = 'text/plain') => { + cy.fixture(fileName).then((content) => { + const blob = Cypress.Blob.base64StringToBlob(btoa(content), fileType); + const testFile = new File([blob], fileName, { type: fileType }); + const dataTransfer = new DataTransfer(); + + dataTransfer.items.add(testFile); + input[0].files = dataTransfer.files; + return input; + }); + } +); + +const waitUntil = (subject, fn, options = {}) => { + const { interval = 200, timeout = 5000 } = options; + let attempts = Math.floor(timeout / interval); + + const completeOrRetry = (result) => { + if (result) { + return result; + } + if (attempts < 1) { + throw new Error(`Timed out while retrying, last result was: {${result}}`); + } + cy.wait(interval, { log: false }).then(() => { + attempts--; + // eslint-disable-next-line no-use-before-define + return evaluate(); + }); + }; + + const evaluate = () => { + const result = fn(subject); + + if (result && result.then) { + return result.then(completeOrRetry); + } else { + return completeOrRetry(result); + } + }; + + return evaluate(); +}; + +Cypress.Commands.add('waitUntil', { prevSubject: 'optional' }, waitUntil);