From 8fda395575b0e4c71cf31c078de934dc6d9c6c17 Mon Sep 17 00:00:00 2001 From: Gloria Hornero Date: Wed, 6 Dec 2023 10:58:06 +0100 Subject: [PATCH 01/12] integrating SAML authentication in Cypress --- .../cypress/cypress_ci_serverless.config.ts | 2 + .../cypress_ci_serverless_qa.config.ts | 2 + .../cypress/cypress_serverless.config.ts | 2 + .../cypress/support/saml_auth.ts | 81 +++++++++++++++++++ .../cypress/support/setup_users.ts | 2 +- .../cypress/tasks/login.ts | 25 +++++- 6 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 x-pack/test/security_solution_cypress/cypress/support/saml_auth.ts 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 3a1be3ed0221a..62aec8c49e787 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 @@ -7,6 +7,7 @@ import { defineCypressConfig } from '@kbn/cypress-config'; import { esArchiver } from './support/es_archiver'; +import { samlAuthentication } from './support/saml_auth'; // eslint-disable-next-line import/no-default-export export default defineCypressConfig({ @@ -39,6 +40,7 @@ export default defineCypressConfig({ specPattern: './cypress/e2e/**/*.cy.ts', setupNodeEvents(on, config) { esArchiver(on, config); + samlAuthentication(on, config); // eslint-disable-next-line @typescript-eslint/no-var-requires require('@cypress/grep/src/plugin')(config); return config; diff --git a/x-pack/test/security_solution_cypress/cypress/cypress_ci_serverless_qa.config.ts b/x-pack/test/security_solution_cypress/cypress/cypress_ci_serverless_qa.config.ts index 342c3da34bef6..c88faf0d9cfe3 100644 --- a/x-pack/test/security_solution_cypress/cypress/cypress_ci_serverless_qa.config.ts +++ b/x-pack/test/security_solution_cypress/cypress/cypress_ci_serverless_qa.config.ts @@ -7,6 +7,7 @@ import { defineCypressConfig } from '@kbn/cypress-config'; import { esArchiver } from './support/es_archiver'; +import { samlAuthentication } from './support/saml_auth'; // eslint-disable-next-line import/no-default-export export default defineCypressConfig({ @@ -41,6 +42,7 @@ export default defineCypressConfig({ specPattern: './cypress/e2e/**/*.cy.ts', setupNodeEvents(on, config) { esArchiver(on, config); + samlAuthentication(on, config); process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; // eslint-disable-next-line @typescript-eslint/no-var-requires require('@cypress/grep/src/plugin')(config); 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 b925e18a83478..b76c7ff22bcbc 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 @@ -7,6 +7,7 @@ import { defineCypressConfig } from '@kbn/cypress-config'; import { esArchiver } from './support/es_archiver'; +import { samlAuthentication } from './support/saml_auth'; // eslint-disable-next-line import/no-default-export export default defineCypressConfig({ @@ -31,6 +32,7 @@ export default defineCypressConfig({ experimentalMemoryManagement: true, setupNodeEvents(on, config) { esArchiver(on, config); + samlAuthentication(on, config); // eslint-disable-next-line @typescript-eslint/no-var-requires require('@cypress/grep/src/plugin')(config); return config; diff --git a/x-pack/test/security_solution_cypress/cypress/support/saml_auth.ts b/x-pack/test/security_solution_cypress/cypress/support/saml_auth.ts new file mode 100644 index 0000000000000..b74302ce5efeb --- /dev/null +++ b/x-pack/test/security_solution_cypress/cypress/support/saml_auth.ts @@ -0,0 +1,81 @@ +/* + * 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 { ToolingLog } from '@kbn/tooling-log'; +import { REPO_ROOT } from '@kbn/repo-info'; +import { resolve } from 'path'; + +import axios from 'axios'; + +import * as fs from 'fs'; + +import { SecurityRoleName } from '@kbn/security-solution-plugin/common/test'; +import { User } from '../../../../test_serverless/shared/services/user_manager/svl_user_manager'; +import { + createCloudSAMLSession, + CloudSamlSessionParams, + LocalSamlSessionParams, + createLocalSAMLSession, +} from '../../../../test_serverless/shared/services/user_manager/saml_auth'; + +export const samlAuthentication = async ( + on: Cypress.PluginEvents, + config: Cypress.PluginConfigOptions +): Promise => { + const log = new ToolingLog({ level: 'verbose', writeTo: process.stdout }); + + const kbnHost = config.env.KIBANA_URL || config.env.BASE_URL; + + const auth = btoa(`${config.env.ELASTICSEARCH_USERNAME}:${config.env.ELASTICSEARCH_PASSWORD}`); + + const response = await axios.get(`${kbnHost}/api/status`, { + headers: { + Authorization: `Basic ${auth}`, + }, + }); + const kbnVersion = response.data.version.number; + + const cloudRoleUsersFilePath = resolve(REPO_ROOT, '.ftr', 'role_users.json'); + + const roleToUserMap: Map = new Map(); + + const getCloudUserByRole = (role: string) => { + const data = fs.readFileSync(cloudRoleUsersFilePath, 'utf8'); + if (data.length === 0) { + throw new Error(`'${cloudRoleUsersFilePath}' is empty: no roles are defined`); + } + for (const [roleName, user] of Object.entries(JSON.parse(data)) as Array<[string, User]>) { + roleToUserMap.set(roleName, user); + } + return roleToUserMap.get(role)!; + }; + + on('task', { + createCloudSAMLSession: async (role: string | SecurityRoleName): Promise => { + const samlSessionParams: CloudSamlSessionParams = { + ...getCloudUserByRole(role), + kbnHost, + kbnVersion, + log, + }; + const session = await createCloudSAMLSession(samlSessionParams); + return session.getCookieValue(); + }, + createLocalSAMLSession: async (role: string | SecurityRoleName): Promise => { + const localSamlSessionParams: LocalSamlSessionParams = { + username: role, + email: `${role}@elastic.co`, + fullname: role, + role, + kbnHost, + log, + }; + const session = await createLocalSAMLSession(localSamlSessionParams); + return session.getCookieValue(); + }, + }); +}; diff --git a/x-pack/test/security_solution_cypress/cypress/support/setup_users.ts b/x-pack/test/security_solution_cypress/cypress/support/setup_users.ts index 02ebebb6c10ea..73d17b26ab93b 100644 --- a/x-pack/test/security_solution_cypress/cypress/support/setup_users.ts +++ b/x-pack/test/security_solution_cypress/cypress/support/setup_users.ts @@ -39,7 +39,7 @@ function createUser(username: string, password: string, roles: string[] = []): v password, roles, full_name: username, - email: '', + email: `${username}@elastic.co`, }; rootRequest({ diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/login.ts b/x-pack/test/security_solution_cypress/cypress/tasks/login.ts index fb2a93770f8e7..203fd3a9febce 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/login.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/login.ts @@ -41,8 +41,29 @@ export const getEnvAuth = (role: SecurityRoleName): User => { }; export const login = (role?: SecurityRoleName): void => { - const user = role ? getEnvAuth(role) : defaultUser; - loginWithUser(user); + let testRole = ''; + + if (IS_SERVERLESS) { + if (!role) { + testRole = Cypress.env(CLOUD_SERVERLESS) ? 'admin' : 'system_indices_superuser'; + } else { + testRole = role; + } + const task = Cypress.env(CLOUD_SERVERLESS) + ? 'createCloudSAMLSession' + : 'createLocalSAMLSession'; + + cy.task(task, testRole).then((cookie) => { + cy.setCookie('sid', cookie as string); + }); + + if (Cypress.env(CLOUD_SERVERLESS)) { + cy.visit('/'); + } + } else { + const user = role ? getEnvAuth(role) : defaultUser; + loginWithUser(user); + } }; export const loginWithUser = (user: User): void => { From 75001bc382156ea621d8fd7cefd6c6d2767b98cb Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 6 Dec 2023 10:06:20 +0000 Subject: [PATCH 02/12] [CI] Auto-commit changed files from 'node scripts/lint_ts_projects --fix' --- x-pack/test/security_solution_cypress/cypress/tsconfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/security_solution_cypress/cypress/tsconfig.json b/x-pack/test/security_solution_cypress/cypress/tsconfig.json index 45b526793e98e..3b413206549c0 100644 --- a/x-pack/test/security_solution_cypress/cypress/tsconfig.json +++ b/x-pack/test/security_solution_cypress/cypress/tsconfig.json @@ -40,6 +40,7 @@ "@kbn/management-settings-ids", "@kbn/es-query", "@kbn/ml-plugin", - "@kbn/license-management-plugin" + "@kbn/license-management-plugin", + "@kbn/repo-info" ] } From 4183b4db0a27100078f01216d26ac354fca0afcd Mon Sep 17 00:00:00 2001 From: Gloria Hornero Date: Wed, 6 Dec 2023 15:23:15 +0100 Subject: [PATCH 03/12] adding missing configuration --- x-pack/test/security_solution_cypress/cypress/cypress.config.ts | 2 ++ .../test/security_solution_cypress/cypress/cypress_ci.config.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/x-pack/test/security_solution_cypress/cypress/cypress.config.ts b/x-pack/test/security_solution_cypress/cypress/cypress.config.ts index d7f0bbc7a0254..7c43e04ce367b 100644 --- a/x-pack/test/security_solution_cypress/cypress/cypress.config.ts +++ b/x-pack/test/security_solution_cypress/cypress/cypress.config.ts @@ -7,6 +7,7 @@ import { defineCypressConfig } from '@kbn/cypress-config'; import { esArchiver } from './support/es_archiver'; +import { samlAuthentication } from './support/saml_auth'; export default defineCypressConfig({ defaultCommandTimeout: 60000, @@ -30,6 +31,7 @@ export default defineCypressConfig({ experimentalCspAllowList: ['default-src', 'script-src', 'script-src-elem'], setupNodeEvents(on, config) { esArchiver(on, config); + samlAuthentication(on, config); // eslint-disable-next-line @typescript-eslint/no-var-requires require('@cypress/grep/src/plugin')(config); return config; diff --git a/x-pack/test/security_solution_cypress/cypress/cypress_ci.config.ts b/x-pack/test/security_solution_cypress/cypress/cypress_ci.config.ts index efb3b64d36f4d..ef30b2243ced6 100644 --- a/x-pack/test/security_solution_cypress/cypress/cypress_ci.config.ts +++ b/x-pack/test/security_solution_cypress/cypress/cypress_ci.config.ts @@ -7,6 +7,7 @@ import { defineCypressConfig } from '@kbn/cypress-config'; import { esArchiver } from './support/es_archiver'; +import { samlAuthentication } from './support/saml_auth'; // eslint-disable-next-line import/no-default-export export default defineCypressConfig({ @@ -39,6 +40,7 @@ export default defineCypressConfig({ specPattern: './cypress/e2e/**/*.cy.ts', setupNodeEvents(on, config) { esArchiver(on, config); + samlAuthentication(on, config); // eslint-disable-next-line @typescript-eslint/no-var-requires require('@cypress/grep/src/plugin')(config); return config; From 8097ab800e6835c1b71865e0669aa6136b87215b Mon Sep 17 00:00:00 2001 From: Gloria Hornero Date: Mon, 11 Dec 2023 10:46:41 +0100 Subject: [PATCH 04/12] fixes typo --- x-pack/test/security_solution_cypress/cypress/tasks/login.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/login.ts b/x-pack/test/security_solution_cypress/cypress/tasks/login.ts index 203fd3a9febce..26af75c5c993d 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/login.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/login.ts @@ -43,7 +43,7 @@ export const getEnvAuth = (role: SecurityRoleName): User => { export const login = (role?: SecurityRoleName): void => { let testRole = ''; - if (IS_SERVERLESS) { + if (Cypress.env(IS_SERVERLESS)) { if (!role) { testRole = Cypress.env(CLOUD_SERVERLESS) ? 'admin' : 'system_indices_superuser'; } else { From 4786b985fd9b24a3ea7569b6106cf846360a96d2 Mon Sep 17 00:00:00 2001 From: Gloria Hornero Date: Mon, 11 Dec 2023 14:57:52 +0100 Subject: [PATCH 05/12] refactors to use the new available changes --- .../run_cypress/parallel_serverless.ts | 1 + .../cypress/support/es_archiver.ts | 4 +- .../cypress/support/saml_auth.ts | 68 ++++--------------- .../cypress/tasks/login.ts | 11 +-- 4 files changed, 19 insertions(+), 65 deletions(-) diff --git a/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts b/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts index 22b51692eb33f..aff8f66b55d80 100644 --- a/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts +++ b/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts @@ -571,6 +571,7 @@ ${JSON.stringify(cypressConfigFile, null, 2)} KIBANA_PASSWORD: credentials.password, CLOUD_SERVERLESS: true, + IS_SERVERLESS: true, }; if (process.env.DEBUG && !process.env.CI) { diff --git a/x-pack/test/security_solution_cypress/cypress/support/es_archiver.ts b/x-pack/test/security_solution_cypress/cypress/support/es_archiver.ts index c9f271265a1d1..a5149b9df1e12 100644 --- a/x-pack/test/security_solution_cypress/cypress/support/es_archiver.ts +++ b/x-pack/test/security_solution_cypress/cypress/support/es_archiver.ts @@ -18,7 +18,7 @@ export const esArchiver = ( ): EsArchiver => { const log = new ToolingLog({ level: 'verbose', writeTo: process.stdout }); - const isSnapshotServerless = config.env.IS_SERVERLESS; + const isServerless = config.env.IS_SERVERLESS; const isCloudServerless = config.env.CLOUD_SERVERLESS; const serverlessCloudUser = { @@ -27,7 +27,7 @@ export const esArchiver = ( }; let authOverride; - if (!isSnapshotServerless) { + if (isServerless) { authOverride = isCloudServerless ? serverlessCloudUser : systemIndicesSuperuser; } diff --git a/x-pack/test/security_solution_cypress/cypress/support/saml_auth.ts b/x-pack/test/security_solution_cypress/cypress/support/saml_auth.ts index b74302ce5efeb..0026f6c91ec27 100644 --- a/x-pack/test/security_solution_cypress/cypress/support/saml_auth.ts +++ b/x-pack/test/security_solution_cypress/cypress/support/saml_auth.ts @@ -6,21 +6,9 @@ */ import { ToolingLog } from '@kbn/tooling-log'; -import { REPO_ROOT } from '@kbn/repo-info'; -import { resolve } from 'path'; - -import axios from 'axios'; - -import * as fs from 'fs'; import { SecurityRoleName } from '@kbn/security-solution-plugin/common/test'; -import { User } from '../../../../test_serverless/shared/services/user_manager/svl_user_manager'; -import { - createCloudSAMLSession, - CloudSamlSessionParams, - LocalSamlSessionParams, - createLocalSAMLSession, -} from '../../../../test_serverless/shared/services/user_manager/saml_auth'; +import { HostOptions, SamlSessionManager } from '@kbn/test'; export const samlAuthentication = async ( on: Cypress.PluginEvents, @@ -30,52 +18,24 @@ export const samlAuthentication = async ( const kbnHost = config.env.KIBANA_URL || config.env.BASE_URL; - const auth = btoa(`${config.env.ELASTICSEARCH_USERNAME}:${config.env.ELASTICSEARCH_PASSWORD}`); - - const response = await axios.get(`${kbnHost}/api/status`, { - headers: { - Authorization: `Basic ${auth}`, - }, - }); - const kbnVersion = response.data.version.number; + const kbnUrl = new URL(kbnHost); - const cloudRoleUsersFilePath = resolve(REPO_ROOT, '.ftr', 'role_users.json'); - - const roleToUserMap: Map = new Map(); - - const getCloudUserByRole = (role: string) => { - const data = fs.readFileSync(cloudRoleUsersFilePath, 'utf8'); - if (data.length === 0) { - throw new Error(`'${cloudRoleUsersFilePath}' is empty: no roles are defined`); - } - for (const [roleName, user] of Object.entries(JSON.parse(data)) as Array<[string, User]>) { - roleToUserMap.set(roleName, user); - } - return roleToUserMap.get(role)!; + const hostOptions: HostOptions = { + protocol: kbnUrl.protocol as 'http' | 'https', + hostname: kbnUrl.hostname, + port: parseInt(kbnUrl.port, 10), + username: config.env.ELASTICSEARCH_USERNAME, + password: config.env.ELASTICSEARCH_PASSWORD, }; on('task', { - createCloudSAMLSession: async (role: string | SecurityRoleName): Promise => { - const samlSessionParams: CloudSamlSessionParams = { - ...getCloudUserByRole(role), - kbnHost, - kbnVersion, - log, - }; - const session = await createCloudSAMLSession(samlSessionParams); - return session.getCookieValue(); - }, - createLocalSAMLSession: async (role: string | SecurityRoleName): Promise => { - const localSamlSessionParams: LocalSamlSessionParams = { - username: role, - email: `${role}@elastic.co`, - fullname: role, - role, - kbnHost, + getSessionCookie: async (role: string | SecurityRoleName): Promise => { + const sessionManager = new SamlSessionManager({ + hostOptions, log, - }; - const session = await createLocalSAMLSession(localSamlSessionParams); - return session.getCookieValue(); + isCloud: config.env.CLOUD_SERVERLESS, + }); + return sessionManager.getSessionCookieForRole(role); }, }); }; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/login.ts b/x-pack/test/security_solution_cypress/cypress/tasks/login.ts index 26af75c5c993d..90c9d245c3bba 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/login.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/login.ts @@ -49,17 +49,10 @@ export const login = (role?: SecurityRoleName): void => { } else { testRole = role; } - const task = Cypress.env(CLOUD_SERVERLESS) - ? 'createCloudSAMLSession' - : 'createLocalSAMLSession'; - - cy.task(task, testRole).then((cookie) => { + cy.task('getSessionCookie', testRole).then((cookie) => { cy.setCookie('sid', cookie as string); }); - - if (Cypress.env(CLOUD_SERVERLESS)) { - cy.visit('/'); - } + cy.visit('/'); } else { const user = role ? getEnvAuth(role) : defaultUser; loginWithUser(user); From 649094b5c29672b9918be8220f64ec98fbae046a Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 11 Dec 2023 14:05:26 +0000 Subject: [PATCH 06/12] [CI] Auto-commit changed files from 'node scripts/lint_ts_projects --fix' --- x-pack/test/security_solution_cypress/cypress/tsconfig.json | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/test/security_solution_cypress/cypress/tsconfig.json b/x-pack/test/security_solution_cypress/cypress/tsconfig.json index 3b413206549c0..d6a08efd3073f 100644 --- a/x-pack/test/security_solution_cypress/cypress/tsconfig.json +++ b/x-pack/test/security_solution_cypress/cypress/tsconfig.json @@ -41,6 +41,5 @@ "@kbn/es-query", "@kbn/ml-plugin", "@kbn/license-management-plugin", - "@kbn/repo-info" ] } From 9eaaa296a1ce3b1708951a97d2668403e6dab3ee Mon Sep 17 00:00:00 2001 From: Gloria Hornero Date: Mon, 11 Dec 2023 15:37:29 +0100 Subject: [PATCH 07/12] refactors configuration --- x-pack/test/security_solution_cypress/cypress/cypress.config.ts | 2 -- .../test/security_solution_cypress/cypress/cypress_ci.config.ts | 2 -- 2 files changed, 4 deletions(-) diff --git a/x-pack/test/security_solution_cypress/cypress/cypress.config.ts b/x-pack/test/security_solution_cypress/cypress/cypress.config.ts index 7c43e04ce367b..d7f0bbc7a0254 100644 --- a/x-pack/test/security_solution_cypress/cypress/cypress.config.ts +++ b/x-pack/test/security_solution_cypress/cypress/cypress.config.ts @@ -7,7 +7,6 @@ import { defineCypressConfig } from '@kbn/cypress-config'; import { esArchiver } from './support/es_archiver'; -import { samlAuthentication } from './support/saml_auth'; export default defineCypressConfig({ defaultCommandTimeout: 60000, @@ -31,7 +30,6 @@ export default defineCypressConfig({ experimentalCspAllowList: ['default-src', 'script-src', 'script-src-elem'], setupNodeEvents(on, config) { esArchiver(on, config); - samlAuthentication(on, config); // eslint-disable-next-line @typescript-eslint/no-var-requires require('@cypress/grep/src/plugin')(config); return config; diff --git a/x-pack/test/security_solution_cypress/cypress/cypress_ci.config.ts b/x-pack/test/security_solution_cypress/cypress/cypress_ci.config.ts index ef30b2243ced6..efb3b64d36f4d 100644 --- a/x-pack/test/security_solution_cypress/cypress/cypress_ci.config.ts +++ b/x-pack/test/security_solution_cypress/cypress/cypress_ci.config.ts @@ -7,7 +7,6 @@ import { defineCypressConfig } from '@kbn/cypress-config'; import { esArchiver } from './support/es_archiver'; -import { samlAuthentication } from './support/saml_auth'; // eslint-disable-next-line import/no-default-export export default defineCypressConfig({ @@ -40,7 +39,6 @@ export default defineCypressConfig({ specPattern: './cypress/e2e/**/*.cy.ts', setupNodeEvents(on, config) { esArchiver(on, config); - samlAuthentication(on, config); // eslint-disable-next-line @typescript-eslint/no-var-requires require('@cypress/grep/src/plugin')(config); return config; From 191ad94ec61b3c6410cde1d43a896838cfd75ac7 Mon Sep 17 00:00:00 2001 From: Gloria Hornero Date: Mon, 11 Dec 2023 20:10:32 +0100 Subject: [PATCH 08/12] adjusting tests --- .../cypress/e2e/explore/cases/creation.cy.ts | 4 ++-- .../cypress/e2e/explore/overview/overview.cy.ts | 12 +++++------- .../cypress/screens/alerts.ts | 11 +++++++++-- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/creation.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/creation.cy.ts index 8891a835b1fd7..698a97df6b5d6 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/creation.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/creation.cy.ts @@ -106,10 +106,10 @@ describe('Cases', { tags: ['@ess', '@serverless'] }, () => { ); cy.get(CASE_DETAILS_USERNAMES) .eq(REPORTER) - .should('have.text', Cypress.env(ELASTICSEARCH_USERNAME)); + .should('contain', Cypress.env(ELASTICSEARCH_USERNAME)); cy.get(CASE_DETAILS_USERNAMES) .eq(PARTICIPANTS) - .should('have.text', Cypress.env(ELASTICSEARCH_USERNAME)); + .should('contain', Cypress.env(ELASTICSEARCH_USERNAME)); cy.get(CASE_DETAILS_TAGS).should('have.text', expectedTags); EXPECTED_METRICS.forEach((metric) => { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/explore/overview/overview.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/overview/overview.cy.ts index f857805462877..da9cf06eb5384 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/explore/overview/overview.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/overview/overview.cy.ts @@ -46,19 +46,17 @@ describe('Overview Page', { tags: ['@ess', '@serverless'] }, () => { }); }); - describe('Favorite Timelines', () => { + describe('Favorite Timelines', { tags: ['@brokenInServerless'] }, () => { it('should appear on overview page', () => { createTimeline(getTimeline()) .then((response) => response.body.data.persistTimeline.timeline.savedObjectId) .then((timelineId: string) => { - favoriteTimeline({ timelineId, timelineType: 'default' }).then(() => { - visitWithTimeRange(OVERVIEW_URL); - cy.get('[data-test-subj="overview-recent-timelines"]').should( - 'contain', - getTimeline().title - ); + favoriteTimeline({ timelineId, timelineType: 'default' }).then((response) => { + expect(response.status).to.eq(200); }); }); + visitWithTimeRange(OVERVIEW_URL); + cy.get('[data-test-subj="overview-recent-timelines"]').should('contain', getTimeline().title); }); }); }); diff --git a/x-pack/test/security_solution_cypress/cypress/screens/alerts.ts b/x-pack/test/security_solution_cypress/cypress/screens/alerts.ts index 0f1a513fc5d86..83de06466f251 100644 --- a/x-pack/test/security_solution_cypress/cypress/screens/alerts.ts +++ b/x-pack/test/security_solution_cypress/cypress/screens/alerts.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { IS_SERVERLESS, CLOUD_SERVERLESS } from '../env_var_names_constants'; import { getDataTestSubjectSelector } from '../helpers/common'; import { GLOBAL_FILTERS_CONTAINER } from './date_picker'; @@ -204,9 +205,15 @@ export const ALERT_ASSIGNEES_SELECT_PANEL = export const ALERT_ASSIGNEES_UPDATE_BUTTON = '[data-test-subj="securitySolutionAssigneesApplyButton"]'; -export const ALERT_USER_AVATAR = (assignee: string) => - `[data-test-subj="securitySolutionUsersAvatar-${assignee}"][title='${assignee}']`; +export const ALERT_USER_AVATAR = (assignee: string) => { + let expectedAssignee = assignee; + if (Cypress.env(IS_SERVERLESS) && !Cypress.env(CLOUD_SERVERLESS)) { + expectedAssignee = `test ${expectedAssignee}`; + } + + return `[data-test-subj^="securitySolutionUsersAvatar-"][title='${expectedAssignee}']`; +}; export const ALERT_AVATARS_PANEL = '[data-test-subj="securitySolutionUsersAvatarsPanel"]'; export const ALERT_ASIGNEES_COLUMN = From 498e8b95c97b89393a1df98e3af3340d50dd9514 Mon Sep 17 00:00:00 2001 From: Gloria Hornero Date: Tue, 12 Dec 2023 11:10:42 +0100 Subject: [PATCH 09/12] adjustments --- .../mki_security_solution_cypress.sh | 3 +++ .../scripts/run_cypress/parallel_serverless.ts | 4 +++- .../cypress/e2e/explore/overview/overview.cy.ts | 10 ++++++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh b/.buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh index 56b44315bf064..9d353b167ea47 100755 --- a/.buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh +++ b/.buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh @@ -16,6 +16,9 @@ export JOB=kibana-security-solution-chrome buildkite-agent meta-data set "${BUILDKITE_JOB_ID}_is_test_execution_step" "true" +mkdir .ftr +retry 5 5 vault kv get -format=json -field=data secret/kibana-issues/dev/security-quality-gate/role-users > .ftr/role_users.json + cd x-pack/test/security_solution_cypress set +e diff --git a/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts b/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts index aff8f66b55d80..f32a190f64146 100644 --- a/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts +++ b/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts @@ -61,7 +61,7 @@ const DEFAULT_CONFIGURATION: Readonly = [ const DEFAULT_REGION = 'aws-eu-west-1'; const PROJECT_NAME_PREFIX = 'kibana-cypress-security-solution-ephemeral'; -const BASE_ENV_URL = 'https://global.qa.cld.elstc.co'; +const BASE_ENV_URL = 'https://console.qa.cld.elstc.co'; let log: ToolingLog; const API_HEADERS = Object.freeze({ 'kbn-xsrf': 'cypress-creds', @@ -585,6 +585,8 @@ ${JSON.stringify(cypressConfigFile, null, 2)} } if (isOpen) { + process.env.TEST_CLOUD_HOST_NAME = new URL(BASE_ENV_URL).hostname; + await cypress.open({ configFile: cypressConfigFilePath, config: { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/explore/overview/overview.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/overview/overview.cy.ts index da9cf06eb5384..1134619e8f6f1 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/explore/overview/overview.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/overview/overview.cy.ts @@ -51,12 +51,14 @@ describe('Overview Page', { tags: ['@ess', '@serverless'] }, () => { createTimeline(getTimeline()) .then((response) => response.body.data.persistTimeline.timeline.savedObjectId) .then((timelineId: string) => { - favoriteTimeline({ timelineId, timelineType: 'default' }).then((response) => { - expect(response.status).to.eq(200); + favoriteTimeline({ timelineId, timelineType: 'default' }).then(() => { + visitWithTimeRange(OVERVIEW_URL); + cy.get('[data-test-subj="overview-recent-timelines"]').should( + 'contain', + getTimeline().title + ); }); }); - visitWithTimeRange(OVERVIEW_URL); - cy.get('[data-test-subj="overview-recent-timelines"]').should('contain', getTimeline().title); }); }); }); From 5215f31646445b9cd8b0220bf8f73f7e97b8fb12 Mon Sep 17 00:00:00 2001 From: Gloria Hornero Date: Tue, 12 Dec 2023 15:14:30 +0100 Subject: [PATCH 10/12] updating readme --- .../cypress/README.md | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/x-pack/test/security_solution_cypress/cypress/README.md b/x-pack/test/security_solution_cypress/cypress/README.md index 16a93f0c3b5d5..0fa6bae6e2164 100644 --- a/x-pack/test/security_solution_cypress/cypress/README.md +++ b/x-pack/test/security_solution_cypress/cypress/README.md @@ -304,8 +304,51 @@ Store the saved key on `~/.elastic/cloud.json` using the following format: } ``` -#### Known limitations -- Currently RBAC cannot be tested. +Store the email and password of the account you used to login in the QA Environment at the root directory of your Kibana project on `.ftr/role_users.json`, using the following format: + +```json +{ + "admin": { + "email": "", + "password": "" + } +} +``` + +#### Testing with different roles + +If you want to execute a test using Cypress on visual mode with MKI, you need to make sure you have the user created in your organization, and add it tot he `.ftr/role_users.json`: + +```json +{ + "admin": { + "email": "", + "password": "" + }, + "": { + "email": "", + "password": "" + } +} +``` + +As role names please use: +- admin +- detections_admin +- editor +- endpoint_operations_analyst +- endpoint_policy_manager +- none +- platform_engineer +- rule_author +- soc_manager +- t1_analyst +- t2_analyst +- t3_analyst +- threat_intelligence_analyst +- viewer + +The above should be the same used on the automation. #### PLIs From fa83e7cc0a5995c4867f11b165dcaf6dc907b0ae Mon Sep 17 00:00:00 2001 From: Gloria Hornero Date: Tue, 12 Dec 2023 16:17:31 +0100 Subject: [PATCH 11/12] fix --- .../scripts/run_cypress/parallel_serverless.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts b/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts index f32a190f64146..f3a7070aa7e33 100644 --- a/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts +++ b/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts @@ -583,10 +583,9 @@ ${JSON.stringify(cypressConfigFile, null, 2)} ---------------------------------------------- `); } + process.env.TEST_CLOUD_HOST_NAME = new URL(BASE_ENV_URL).hostname; if (isOpen) { - process.env.TEST_CLOUD_HOST_NAME = new URL(BASE_ENV_URL).hostname; - await cypress.open({ configFile: cypressConfigFilePath, config: { From 618ad0051ebc6bd1a4de232ce9ef907f3372849d Mon Sep 17 00:00:00 2001 From: Gloria Hornero Date: Tue, 12 Dec 2023 16:19:06 +0100 Subject: [PATCH 12/12] adding a comment tracking the new skipped test --- .../cypress/e2e/explore/overview/overview.cy.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/explore/overview/overview.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/overview/overview.cy.ts index 1134619e8f6f1..b0b1a11bc69e0 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/explore/overview/overview.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/overview/overview.cy.ts @@ -46,6 +46,7 @@ describe('Overview Page', { tags: ['@ess', '@serverless'] }, () => { }); }); + // https://github.com/elastic/kibana/issues/173168 describe('Favorite Timelines', { tags: ['@brokenInServerless'] }, () => { it('should appear on overview page', () => { createTimeline(getTimeline())