[8.x] [Security Solution] Removing cypress folder (#197273) (#199260)

> [!Warning]
> `.github/CODEOWNERS` and
`.buildkite/pipelines/pull_request/security_solution/defend_workflows.yml`
were updated as part of merge conflicts so would need a thorough review.

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Security Solution] Removing cypress folder
(#197273)](https://github.com/elastic/kibana/pull/197273)

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Gloria
Hornero","email":"gloria.hornero@elastic.co"},"sourceCommit":{"committedDate":"2024-10-24T15:26:33Z","message":"[Security
Solution] Removing cypress folder (#197273)\n\n##
Summary\r\n\r\nDeleting the Cypress folder that was added in
`test_serverless` as a\r\nPOC.\r\n\r\nCurrently is not used and this can
create misunderstandings regarding\r\nownership of
it.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"86e6c74f7c39a512eaa43cc025434dc6a53d55f6","branchLabelMapping":{"^v9.0.0$":"main","^v8.17.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","backport
missing","v9.0.0","Team:
SecuritySolution","v8.16.0","backport:version","v8.17.0"],"number":197273,"url":"https://github.com/elastic/kibana/pull/197273","mergeCommit":{"message":"[Security
Solution] Removing cypress folder (#197273)\n\n##
Summary\r\n\r\nDeleting the Cypress folder that was added in
`test_serverless` as a\r\nPOC.\r\n\r\nCurrently is not used and this can
create misunderstandings regarding\r\nownership of
it.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"86e6c74f7c39a512eaa43cc025434dc6a53d55f6"}},"sourceBranch":"main","suggestedTargetBranches":["8.16","8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","labelRegex":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/197273","number":197273,"mergeCommit":{"message":"[Security
Solution] Removing cypress folder (#197273)\n\n##
Summary\r\n\r\nDeleting the Cypress folder that was added in
`test_serverless` as a\r\nPOC.\r\n\r\nCurrently is not used and this can
create misunderstandings regarding\r\nownership of
it.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<42973632+kibanamachine@users.noreply.github.com>","sha":"86e6c74f7c39a512eaa43cc025434dc6a53d55f6"}},{"branch":"8.16","label":"v8.16.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.x","label":"v8.17.0","labelRegex":"^v8.17.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

---------

Co-authored-by: Gloria Hornero <gloria.hornero@elastic.co>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Ash 2024-11-07 11:16:34 +01:00 committed by GitHub
parent 65d84cf276
commit feab4ef51b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 2099 additions and 723 deletions

View file

@ -1,17 +1,17 @@
disabled:
# Base config files, only necessary to inform config finding script
- x-pack/test_serverless/functional/test_suites/security/cypress/security_config.base.ts
- x-pack/test_serverless/functional/test_suites/security/cypress/cypress.config.ts
- x-pack/test/security_solution_api_integration/config/serverless/config.base.ts
- x-pack/test/security_solution_api_integration/config/serverless/config.base.essentials.ts
- x-pack/test/security_solution_api_integration/config/serverless/config.base.edr_workflows.ts
- x-pack/test/defend_workflows_cypress/serverless_config.base.ts
- x-pack/test/osquery_cypress/serverless_config.base.ts
# Cypress configs, for now these are still run manually
- x-pack/test/defend_workflows_cypress/serverless_config.ts
- x-pack/test/osquery_cypress/serverless_cli_config.ts
- x-pack/test_serverless/functional/test_suites/security/cypress/security_config.ts
- x-pack/test/security_solution_cypress/serverless_config.ts
# Playwright
- x-pack/test/security_solution_playwright/serverless_config.ts

View file

@ -18,3 +18,20 @@ steps:
automatic:
- exit_status: '-1'
limit: 1
- command: .buildkite/scripts/steps/functional/defend_workflows_serverless.sh
label: 'Defend Workflows Cypress Tests on Serverless'
agents:
enableNestedVirtualization: true
localSsds: 1
localSsdInterface: nvme
machineType: n2-standard-4
depends_on:
- build
- quick_checks
timeout_in_minutes: 60
parallelism: 14
retry:
automatic:
- exit_status: '-1'
limit: 1

View file

@ -1,12 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
source .buildkite/scripts/steps/functional/common.sh
export JOB=kibana-serverless-security-cypress
export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION}
echo "--- Security Defend Workflows Serverless Cypress"
yarn --cwd x-pack/test_serverless/functional/test_suites/security/cypress cypress:run

2022
.github/CODEOWNERS vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -10,8 +10,8 @@ import path from 'path';
import { safeLoad as loadYaml } from 'js-yaml';
import { readFileSync } from 'fs';
import type { YamlRoleDefinitions } from '@kbn/test-suites-serverless/shared/lib';
import { setupUserDataLoader } from '@kbn/test-suites-serverless/functional/test_suites/security/cypress/support/setup_data_loader_tasks';
import { samlAuthentication } from '@kbn/security-solution-plugin/public/management/cypress/support/saml_authentication';
import { setupUserDataLoader } from './support/setup_data_loader_tasks';
import { getFailedSpecVideos } from './support/filter_videos';
const ROLES_YAML_FILE_PATH = path.join(

View file

@ -34,11 +34,16 @@ registerCypressGrep();
import type { SecuritySolutionDescribeBlockFtrConfig } from '@kbn/security-solution-plugin/scripts/run_cypress/utils';
import { login } from '@kbn/security-solution-plugin/public/management/cypress/tasks/login';
import type { LoadedRoleAndUser } from '@kbn/test-suites-serverless/shared/lib';
import type { ServerlessRoleName } from './roles';
import { waitUntil } from '../tasks/wait_until';
import { isCloudServerless, isServerless } from '../tasks/serverless';
export interface LoadUserAndRoleCyTaskOptions {
name: ServerlessRoleName;
}
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
@ -49,6 +54,12 @@ declare global {
}
interface Chainable {
task(
name: 'loadUserAndRole',
arg: LoadUserAndRoleCyTaskOptions,
options?: Partial<Loggable & Timeoutable>
): Chainable<LoadedRoleAndUser>;
getBySel(...args: Parameters<Cypress.Chainable['get']>): Chainable<JQuery<HTMLElement>>;
getBySelContains(

View file

@ -6,12 +6,12 @@
*/
import { createRuntimeServices } from '@kbn/security-solution-plugin/scripts/endpoint/common/stack_services';
import { LoadUserAndRoleCyTaskOptions } from '../cypress';
import {
import { SecurityRoleAndUserLoader } from '@kbn/test-suites-serverless/shared/lib';
import type {
LoadedRoleAndUser,
SecurityRoleAndUserLoader,
YamlRoleDefinitions,
} from '../../../../../shared/lib';
} from '@kbn/test-suites-serverless/shared/lib';
import type { LoadUserAndRoleCyTaskOptions } from './e2e';
interface AdditionalDefinitions {
roleDefinitions?: YamlRoleDefinitions;
@ -33,9 +33,7 @@ export const setupUserDataLoader = (
});
const roleAndUserLoaderPromise: Promise<SecurityRoleAndUserLoader> = stackServicesPromise.then(
({ kbnClient, log }) => {
return new SecurityRoleAndUserLoader(kbnClient, log, roleDefinitions);
}
({ kbnClient, log }) => new SecurityRoleAndUserLoader(kbnClient, log, roleDefinitions)
);
on('task', {
@ -43,8 +41,7 @@ export const setupUserDataLoader = (
* Loads a user/role into Kibana. Used from `login()` task.
* @param name
*/
loadUserAndRole: async ({ name }: LoadUserAndRoleCyTaskOptions): Promise<LoadedRoleAndUser> => {
return (await roleAndUserLoaderPromise).load(name, additionalRoleName);
},
loadUserAndRole: async ({ name }: LoadUserAndRoleCyTaskOptions): Promise<LoadedRoleAndUser> =>
(await roleAndUserLoaderPromise).load(name, additionalRoleName),
});
};

View file

@ -9,7 +9,7 @@ import { FtrConfigProviderContext } from '@kbn/test';
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const svlSharedConfig = await readConfigFile(
require.resolve('../../../../shared/config.base.ts')
require.resolve('@kbn/test-suites-serverless/shared/config.base')
);
return {

View file

@ -14,9 +14,7 @@ import { DefendWorkflowsCypressCliTestRunner } from './runner';
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const defendWorkflowsCypressConfig = await readConfigFile(
require.resolve(
'@kbn/test-suites-serverless/functional/test_suites/security/cypress/security_config.base'
)
require.resolve('./serverless_config.base.ts')
);
const config = defendWorkflowsCypressConfig.getAll();
const hostIp = getLocalhostRealIp();

View file

@ -12,9 +12,7 @@ import { startOsqueryCypress } from './runner';
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const securitySolutionCypressConfig = await readConfigFile(
require.resolve(
'@kbn/test-suites-serverless/functional/test_suites/security/cypress/security_config.base'
)
require.resolve('./serverless_config.base.ts')
);
return {

View file

@ -0,0 +1,35 @@
/*
* 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 { FtrConfigProviderContext } from '@kbn/test';
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const svlSharedConfig = await readConfigFile(
require.resolve('@kbn/test-suites-serverless/shared/config.base')
);
return {
...svlSharedConfig.getAll(),
esTestCluster: {
...svlSharedConfig.get('esTestCluster'),
serverArgs: [
...svlSharedConfig.get('esTestCluster.serverArgs'),
// define custom es server here
// API Keys is enabled at the top level
],
},
kbnTestServer: {
...svlSharedConfig.get('kbnTestServer'),
serverArgs: [
...svlSharedConfig.get('kbnTestServer.serverArgs'),
'--csp.strict=false',
'--csp.warnLegacyBrowsers=false',
'--serverless=security',
],
},
};
}

View file

@ -1,13 +0,0 @@
{
"plugins": ["cypress"],
"extends": [
"plugin:cypress/recommended"
],
"env": {
"cypress/globals": true
},
"rules": {
"cypress/no-force": "warn",
"import/no-extraneous-dependencies": "off"
}
}

View file

@ -1,3 +0,0 @@
videos
screenshots
downloads

View file

@ -1,65 +0,0 @@
# Security Serverless Tests
Before considering adding a new Cypress tests, please make sure you have added unit and API tests first and the behaviour can only be exercised with Cypress.
Note that, the aim of Cypress is to test that the user interface operates as expected, hence, you should not be using this tool to test REST API or data contracts.
## Folder Structure
Below you can find the folder structure used on our Cypress tests.
### e2e/
Cypress convention starting version 10 (previously known as integration). Contains the specs that are going to be executed.
### fixtures/
Cypress convention. Fixtures are used as external pieces of static data when we stub responses.
### screens/
Contains the elements we want to interact with in our tests.
Each file inside the screens folder represents a screen in our application. When the screens are complex, e.g. Hosts with its multiple tabs, the page is represented by a folder and the different important parts are represented by files.
Example:
- screens
- hosts
- all_hosts.ts
- authentications.ts
- events.ts
- main.ts
- uncommon_processes.ts
### tasks/
_Tasks_ are functions that may be reused across tests.
Each file inside the tasks folder represents a screen of our application. When the screens are complex, e.g. Hosts with its multiple tabs, the page is represented by a folder and the different important parts are represented by files.
Example:
- tasks
- hosts
- all_hosts.ts
- authentications.ts
- events.ts
- main.ts
- uncommon_processes.ts
## Run tests
Currently serverless tests are not included in any pipeline, so the execution for now should be done in our local machines.
### Visual mode
- Navigate to `x-pack/test_serverless/functional/test_suites/security/cypress`
- Execute `yarn cypress:serverless:open`
- Select `E2E testing`
- Click on `Start E2E testing in chrome`
- Click on the test
### Headless mode
- Navigate to `x-pack/test_serverless/functional/test_suites/security/cypress`
- Execute `yarn cypress:serverless:run`

View file

@ -1,40 +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 { defineCypressConfig } from '@kbn/cypress-config';
import { dataLoaders as setupEndpointDataLoaders } from '@kbn/security-solution-plugin/public/management/cypress/support/data_loaders';
import { setupUserDataLoader } from './support/setup_data_loader_tasks';
export default defineCypressConfig({
defaultCommandTimeout: 60000,
execTimeout: 60000,
pageLoadTimeout: 60000,
responseTimeout: 60000,
screenshotsFolder: '../../../../../../target/kibana-security-solution/cypress/screenshots',
trashAssetsBeforeRuns: false,
video: false,
viewportHeight: 946,
viewportWidth: 1680,
numTestsKeptInMemory: 10,
env: {
KIBANA_USERNAME: 'system_indices_superuser',
KIBANA_PASSWORD: 'changeme',
ELASTICSEARCH_USERNAME: 'system_indices_superuser',
ELASTICSEARCH_PASSWORD: 'changeme',
},
e2e: {
experimentalRunAllSpecs: true,
experimentalMemoryManagement: true,
supportFile: './support/e2e.js',
specPattern: './e2e/**/*.cy.ts',
setupNodeEvents: (on, config) => {
// Reuse data loaders from endpoint management cypress setup
setupEndpointDataLoaders(on, config);
setupUserDataLoader(on, config, {});
},
},
});

View file

@ -1,207 +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.
*/
// / <reference types="cypress" />
import { SecuritySolutionDescribeBlockFtrConfig } from '@kbn/security-solution-plugin/scripts/run_cypress/utils';
import {
DeleteIndexedFleetEndpointPoliciesResponse,
IndexedFleetEndpointPolicyResponse,
} from '@kbn/security-solution-plugin/common/endpoint/data_loaders/index_fleet_endpoint_policy';
import { CasePostRequest } from '@kbn/cases-plugin/common/api';
import {
DeletedIndexedCase,
IndexedCase,
} from '@kbn/security-solution-plugin/common/endpoint/data_loaders/index_case';
import {
HostActionResponse,
IndexEndpointHostsCyTaskOptions,
} from '@kbn/security-solution-plugin/public/management/cypress/types';
import { IndexedHostsAndAlertsResponse } from '@kbn/security-solution-plugin/common/endpoint/index_data';
import { DeleteIndexedEndpointHostsResponse } from '@kbn/security-solution-plugin/common/endpoint/data_loaders/index_endpoint_hosts';
import {
DeletedIndexedEndpointRuleAlerts,
IndexedEndpointRuleAlerts,
} from '@kbn/security-solution-plugin/common/endpoint/data_loaders/index_endpoint_rule_alerts';
import {
HostPolicyResponse,
LogsEndpointActionResponse,
} from '@kbn/security-solution-plugin/common/endpoint/types';
import { IndexedEndpointPolicyResponse } from '@kbn/security-solution-plugin/common/endpoint/data_loaders/index_endpoint_policy_response';
import { DeleteAllEndpointDataResponse } from '@kbn/security-solution-plugin/scripts/endpoint/common/delete_all_endpoint_data';
import { LoadedRoleAndUser, ServerlessRoleName } from '../../../../shared/lib';
export interface LoadUserAndRoleCyTaskOptions {
name: ServerlessRoleName;
}
declare global {
namespace Cypress {
interface SuiteConfigOverrides {
env?: {
ftrConfig: SecuritySolutionDescribeBlockFtrConfig;
};
}
interface Chainable<Subject = any> {
/**
* Get Elements by `data-test-subj`. Note that his is a parent query and can only be used
* from `cy`
*
* @param args
*
* @example
* // Correct:
* cy.getByTestSubj('some-subject);
*
* // Incorrect:
* cy.get('someElement').getByTestSubj('some-subject);
*/
getByTestSubj<E extends Node = HTMLElement>(
...args: Parameters<Cypress.Chainable<E>['get']>
): Chainable<JQuery<E>>;
/**
* Finds elements by `data-test-subj` from within another. Can not be used directly from `cy`.
*
* @example
* // Correct:
* cy.get('someElement').findByTestSubj('some-subject);
*
* // Incorrect:
* cy.findByTestSubj('some-subject);
*/
findByTestSubj<E extends Node = HTMLElement>(
...args: Parameters<Cypress.Chainable<E>['find']>
): Chainable<JQuery<E>>;
/**
* Continuously call provided callback function until it either return `true`
* or fail if `timeout` is reached.
* @param fn
* @param options
*/
waitUntil(
fn: (subject?: any) => boolean | Promise<boolean> | Chainable<boolean>,
options?: Partial<{
interval: number;
timeout: number;
}>
): Chainable<Subject>;
// ----------------------------------------------------
//
// TASKS
//
// ----------------------------------------------------
task(
name: 'loadUserAndRole',
arg: LoadUserAndRoleCyTaskOptions,
options?: Partial<Loggable & Timeoutable>
): Chainable<LoadedRoleAndUser>;
task(
name: 'indexFleetEndpointPolicy',
arg: {
policyName: string;
endpointPackageVersion: string;
},
options?: Partial<Loggable & Timeoutable>
): Chainable<IndexedFleetEndpointPolicyResponse>;
task(
name: 'deleteIndexedFleetEndpointPolicies',
arg: IndexedFleetEndpointPolicyResponse,
options?: Partial<Loggable & Timeoutable>
): Chainable<DeleteIndexedFleetEndpointPoliciesResponse>;
task(
name: 'indexCase',
arg?: Partial<CasePostRequest>,
options?: Partial<Loggable & Timeoutable>
): Chainable<IndexedCase['data']>;
task(
name: 'deleteIndexedCase',
arg: IndexedCase['data'],
options?: Partial<Loggable & Timeoutable>
): Chainable<DeletedIndexedCase>;
task(
name: 'indexEndpointHosts',
arg?: IndexEndpointHostsCyTaskOptions,
options?: Partial<Loggable & Timeoutable>
): Chainable<IndexedHostsAndAlertsResponse>;
task(
name: 'deleteIndexedEndpointHosts',
arg: IndexedHostsAndAlertsResponse,
options?: Partial<Loggable & Timeoutable>
): Chainable<DeleteIndexedEndpointHostsResponse>;
task(
name: 'indexEndpointRuleAlerts',
arg?: { endpointAgentId: string; count?: number },
options?: Partial<Loggable & Timeoutable>
): Chainable<IndexedEndpointRuleAlerts['alerts']>;
task(
name: 'deleteIndexedEndpointRuleAlerts',
arg: IndexedEndpointRuleAlerts['alerts'],
options?: Partial<Loggable & Timeoutable>
): Chainable<DeletedIndexedEndpointRuleAlerts>;
task(
name: 'indexEndpointPolicyResponse',
arg: HostPolicyResponse,
options?: Partial<Loggable & Timeoutable>
): Chainable<IndexedEndpointPolicyResponse>;
task(
name: 'deleteIndexedEndpointPolicyResponse',
arg: IndexedEndpointPolicyResponse,
options?: Partial<Loggable & Timeoutable>
): Chainable<null>;
task(
name: 'sendHostActionResponse',
arg: HostActionResponse,
options?: Partial<Loggable & Timeoutable>
): Chainable<LogsEndpointActionResponse>;
task(
name: 'deleteAllEndpointData',
arg: { endpointAgentIds: string[] },
options?: Partial<Loggable & Timeoutable>
): Chainable<DeleteAllEndpointDataResponse>;
task(
name: 'createFileOnEndpoint',
arg: { hostname: string; path: string; content: string },
options?: Partial<Loggable & Timeoutable>
): Chainable<null>;
task(
name: 'uploadFileToEndpoint',
arg: { hostname: string; srcPath: string; destPath: string },
options?: Partial<Loggable & Timeoutable>
): Chainable<null>;
task(
name: 'installPackagesOnEndpoint',
arg: { hostname: string; packages: string[] },
options?: Partial<Loggable & Timeoutable>
): Chainable<null>;
task(
name: 'readZippedFileContentOnEndpoint',
arg: { hostname: string; path: string; password?: string },
options?: Partial<Loggable & Timeoutable>
): Chainable<string>;
}
}
}

View file

@ -1,22 +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 { LEFT_NAVIGATION } from '../screens/landing_page';
import { navigatesToLandingPage } from '../tasks/navigation';
describe('Serverless', () => {
it('Should navigate to the landing page', () => {
cy.visit('/', {
auth: {
username: 'elastic_serverless',
password: 'changeme',
},
});
navigatesToLandingPage();
cy.get(LEFT_NAVIGATION).should('exist');
});
});

View file

@ -1,13 +0,0 @@
{
"author": "Elastic",
"name": "@kbn/security-solution-serverless",
"version": "1.0.0",
"private": true,
"license": "Elastic License 2.0",
"scripts": {
"cypress": "NODE_OPTIONS=--openssl-legacy-provider node ../../../../../../node_modules/.bin/cypress",
"cypress:open": "NODE_OPTIONS=--openssl-legacy-provider node ../../../../../plugins/security_solution/scripts/start_cypress_parallel open --config-file ../../../x-pack/test_serverless/functional/test_suites/security/cypress/cypress.config.ts --ftr-config-file ../../../../../../x-pack/test_serverless/functional/test_suites/security/cypress/security_config",
"cypress:run": "NODE_OPTIONS=--openssl-legacy-provider node ../../../../../plugins/security_solution/scripts/start_cypress_parallel run --browser chrome --config-file ../../../x-pack/test_serverless/functional/test_suites/security/cypress/cypress.config.ts --ftr-config-file ../../../../../../x-pack/test_serverless/functional/test_suites/security/cypress/security_config --reporter ../../../../../../node_modules/cypress-multi-reporters --reporter-options configFile=./reporter_config.json; status=$?; yarn junit:merge && exit $status",
"junit:merge": "../../../../../../node_modules/.bin/mochawesome-merge ../../../../../../target/kibana-security-serverless/cypress/results/mochawesome*.json > ../../../../../../target/kibana-security-serverless/cypress/results/output.json && ../../../../../../node_modules/.bin/marge ../../../../../../target/kibana-security-serverless/cypress/results/output.json --reportDir ../../../../../../target/kibana-security-serverless/cypress/results && mkdir -p ../../../../../../target/junit && cp ../../../../../../target/kibana-security-serverless/cypress/results/*.xml ../../../../../../target/junit/"
}
}

View file

@ -1,10 +0,0 @@
{
"reporterEnabled": "mochawesome, mocha-junit-reporter",
"reporterOptions": {
"html": false,
"json": true,
"mochaFile": "../../../../../../target/kibana-security-serverless/cypress/results/TEST-security-solution-cypress-[hash].xml",
"overwrite": false,
"reportDir": "../../../../../../target/kibana-security-serverless/cypress/results"
}
}

View file

@ -1,24 +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 { FtrProviderContext } from '../../../ftr_provider_context';
export type { FtrProviderContext } from '../../../ftr_provider_context';
export async function SecuritySolutionCypressTestRunner(
{ getService }: FtrProviderContext,
envVars?: Record<string, string>
) {
const config = getService('config');
return {
FORCE_COLOR: '1',
ELASTICSEARCH_USERNAME: config.get('servers.elasticsearch.username'),
ELASTICSEARCH_PASSWORD: config.get('servers.elasticsearch.password'),
...envVars,
};
}

View file

@ -1,8 +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.
*/
export * from './landing_page';

View file

@ -1,8 +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.
*/
export const LEFT_NAVIGATION = '[data-test-subj="securitySolutionNavHeading"]';

View file

@ -1,31 +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 { FtrConfigProviderContext } from '@kbn/test';
import { ES_RESOURCES } from '@kbn/security-solution-plugin/scripts/endpoint/common/roles_users/serverless';
import type { FtrProviderContext } from './runner';
import { SecuritySolutionCypressTestRunner } from './runner';
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const securitySolutionCypressConfig = await readConfigFile(
require.resolve('./security_config.base.ts')
);
return {
...securitySolutionCypressConfig.getAll(),
esServerlessOptions: {
...(securitySolutionCypressConfig.has('esServerlessOptions')
? securitySolutionCypressConfig.get('esServerlessOptions') ?? {}
: {}),
resources: Object.values(ES_RESOURCES),
},
testRunner: (context: FtrProviderContext) => SecuritySolutionCypressTestRunner(context),
};
}

View file

@ -1,32 +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.
*/
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })

View file

@ -1,29 +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.
*/
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
import './commands';
import 'cypress-real-events/support';
import '@kbn/security-solution-plugin/public/management/cypress/support/e2e';
Cypress.on('uncaught:exception', () => {
return false;
});

View file

@ -1,52 +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.
*/
declare namespace Cypress {
interface Chainable<Subject> {
promisify(): Promise<Subject>;
attachFile(fileName: string, fileType?: string): Chainable<JQuery>;
waitUntil(
fn: (subject: Subject) => boolean | Chainable<boolean>,
options?: {
interval: number;
timeout: number;
}
): Chainable<Subject>;
}
}
declare namespace Mocha {
interface SuiteFunction {
(title: string, ftrConfig: Record<string, string | number>, fn: (this: Suite) => void): Suite;
(
title: string,
ftrConfig?: Record<string, string | number>,
config: Cypress.TestConfigOverrides,
fn: (this: Suite) => void
): Suite;
}
interface ExclusiveSuiteFunction {
(title: string, ftrConfig: Record<string, string | number>, fn: (this: Suite) => void): Suite;
(
title: string,
ftrConfig?: Record<string, string | number>,
config: Cypress.TestConfigOverrides,
fn: (this: Suite) => void
): Suite;
}
interface PendingSuiteFunction {
(title: string, ftrConfig: Record<string, string | number>, fn: (this: Suite) => void): Suite;
(
title: string,
ftrConfig?: Record<string, string | number>,
config: Cypress.TestConfigOverrides,
fn: (this: Suite) => void
): Suite | void;
}
}

View file

@ -1,35 +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 {
DeleteIndexedHostsAndAlertsResponse,
IndexedHostsAndAlertsResponse,
} from '@kbn/security-solution-plugin/common/endpoint/index_data';
import { IndexEndpointHostsCyTaskOptions } from '@kbn/security-solution-plugin/public/management/cypress/types';
export interface CyIndexEndpointHosts {
data: IndexedHostsAndAlertsResponse;
cleanup: () => Cypress.Chainable<DeleteIndexedHostsAndAlertsResponse>;
}
export const indexEndpointHosts = (
options: IndexEndpointHostsCyTaskOptions = {}
): Cypress.Chainable<CyIndexEndpointHosts> => {
return cy.task('indexEndpointHosts', options, { timeout: 240000 }).then((indexHosts) => {
return {
data: indexHosts,
cleanup: () => {
cy.log(
'Deleting Endpoint Host data',
indexHosts.hosts.map((host) => `${host.host.name} (${host.host.id})`)
);
return cy.task('deleteIndexedEndpointHosts', indexHosts);
},
};
});
};

View file

@ -1,87 +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 { request } from '@kbn/security-solution-plugin/public/management/cypress/tasks/common';
import { LoginState } from '@kbn/security-plugin/common/login_state';
import type { ServerlessRoleName } from '../../../../../shared/lib';
import { ServerlessRoleName as RoleName } from '../../../../../shared/lib/security/types';
import { STANDARD_HTTP_HEADERS } from '../../../../../shared/lib/security/default_http_headers';
/**
* Send login via API
* @param username
* @param password
*
* @private
*/
const sendApiLoginRequest = (
username: string,
password: string
): Cypress.Chainable<{ username: string; password: string }> => {
const baseUrl = Cypress.config().baseUrl;
cy.log(`Authenticating [${username}] via ${baseUrl}`);
const headers = { ...STANDARD_HTTP_HEADERS };
return request<LoginState>({ headers, url: `${baseUrl}/internal/security/login_state` })
.then((loginState) => {
const basicProvider = loginState.body.selector.providers.find(
(provider) => provider.type === 'basic'
);
return request({
url: `${baseUrl}/internal/security/login`,
method: 'POST',
headers,
body: {
providerType: basicProvider?.type,
providerName: basicProvider?.name,
currentURL: '/',
params: { username, password },
},
});
})
.then(() => ({ username, password }));
};
interface CyLoginTask {
(user?: ServerlessRoleName | 'elastic'): ReturnType<typeof sendApiLoginRequest>;
/**
* Login using any username/password
* @param username
* @param password
*/
with(username: string, password: string): ReturnType<typeof sendApiLoginRequest>;
}
/**
* Login to Kibana using API (not login page). By default, user will be logged in using
* the username and password defined via `KIBANA_USERNAME` and `KIBANA_PASSWORD` cypress env
* variables.
* @param user Defaults to `soc_manager`
*/
export const login: CyLoginTask = (
user: ServerlessRoleName | 'elastic' = RoleName.SOC_MANAGER
): ReturnType<typeof sendApiLoginRequest> => {
let username = Cypress.env('KIBANA_USERNAME');
let password = Cypress.env('KIBANA_PASSWORD');
if (user && user !== 'elastic') {
return cy.task('loadUserAndRole', { name: user }).then((loadedUser) => {
username = loadedUser.username;
password = loadedUser.password;
return sendApiLoginRequest(username, password);
});
} else {
return sendApiLoginRequest(username, password);
}
};
login.with = (username: string, password: string): ReturnType<typeof sendApiLoginRequest> => {
return sendApiLoginRequest(username, password);
};

View file

@ -1,10 +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.
*/
export const navigatesToLandingPage = () => {
cy.visit('/app/security/get_started');
};

View file

@ -37,7 +37,6 @@
"@kbn/server-route-repository",
"@kbn/core-chrome-browser",
"@kbn/security-plugin",
"@kbn/security-solution-plugin",
"@kbn/security-solution-plugin/public/management/cypress",
"@kbn/tooling-log",
"@kbn/cases-plugin",