mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
> [!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:
parent
65d84cf276
commit
feab4ef51b
30 changed files with 2099 additions and 723 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
2022
.github/CODEOWNERS
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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),
|
||||
});
|
||||
};
|
|
@ -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 {
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
35
x-pack/test/osquery_cypress/serverless_config.base.ts
Normal file
35
x-pack/test/osquery_cypress/serverless_config.base.ts
Normal 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',
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"plugins": ["cypress"],
|
||||
"extends": [
|
||||
"plugin:cypress/recommended"
|
||||
],
|
||||
"env": {
|
||||
"cypress/globals": true
|
||||
},
|
||||
"rules": {
|
||||
"cypress/no-force": "warn",
|
||||
"import/no-extraneous-dependencies": "off"
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
videos
|
||||
screenshots
|
||||
downloads
|
|
@ -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`
|
|
@ -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, {});
|
||||
},
|
||||
},
|
||||
});
|
|
@ -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>;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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');
|
||||
});
|
||||
});
|
|
@ -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/"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
};
|
||||
}
|
|
@ -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';
|
|
@ -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"]';
|
|
@ -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),
|
||||
};
|
||||
}
|
|
@ -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) => { ... })
|
|
@ -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;
|
||||
});
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
},
|
||||
};
|
||||
});
|
||||
};
|
|
@ -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);
|
||||
};
|
|
@ -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');
|
||||
};
|
|
@ -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",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue