mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Defend Workflows] Add tags for mocked and real Endpoint Cypress tests for Serverless (#165094)
## Summary - introduces tags for [Defend Workflows] cypress tests (similarly to https://github.com/elastic/kibana/pull/162698) - adds scripts to Security Solution: - `cypress:dw:serverless:open` and `:run` - `cypress:dw:endpoint:serverless:open` and `:run` - adds CI jobs to run these scripts - so far most of the expected tests got both `@serverless` and `@brokenInServerless` tests, because of other issues to be solved, - one test is able to run against serverless: `x-pack/plugins/security_solution/public/management/cypress/e2e/mocked_data/policy_details.cy.ts`
This commit is contained in:
parent
4270c5e031
commit
aa36fe67ae
44 changed files with 698 additions and 424 deletions
|
@ -28,6 +28,7 @@ disabled:
|
|||
- x-pack/test/defend_workflows_cypress/cli_config.ts
|
||||
- x-pack/test/defend_workflows_cypress/config.ts
|
||||
- x-pack/test/defend_workflows_cypress/endpoint_config.ts
|
||||
- x-pack/test/defend_workflows_cypress/endpoint_serverless_config.ts
|
||||
- x-pack/plugins/observability_onboarding/e2e/ftr_config_open.ts
|
||||
- x-pack/plugins/observability_onboarding/e2e/ftr_config_runner.ts
|
||||
- x-pack/plugins/observability_onboarding/e2e/ftr_config.ts
|
||||
|
|
|
@ -22,3 +22,28 @@ steps:
|
|||
automatic:
|
||||
- exit_status: '*'
|
||||
limit: 1
|
||||
|
||||
- command: .buildkite/scripts/steps/functional/defend_workflows_serverless.sh
|
||||
label: 'Defend Workflows Cypress Tests on Serverless'
|
||||
agents:
|
||||
queue: n2-4-spot
|
||||
depends_on: build
|
||||
timeout_in_minutes: 120
|
||||
parallelism: 2
|
||||
retry:
|
||||
automatic:
|
||||
- exit_status: '*'
|
||||
limit: 1
|
||||
|
||||
- command: .buildkite/scripts/steps/functional/defend_workflows_vagrant_serverless.sh
|
||||
label: 'Defend Workflows Endpoint Cypress Tests on Serverless'
|
||||
agents:
|
||||
queue: n2-4-virt
|
||||
depends_on: build
|
||||
timeout_in_minutes: 120
|
||||
parallelism: 5
|
||||
retry:
|
||||
automatic:
|
||||
- exit_status: '*'
|
||||
limit: 1
|
||||
|
||||
|
|
15
.buildkite/scripts/steps/functional/defend_workflows_serverless.sh
Executable file
15
.buildkite/scripts/steps/functional/defend_workflows_serverless.sh
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source .buildkite/scripts/steps/functional/common.sh
|
||||
source .buildkite/scripts/steps/functional/common_cypress.sh
|
||||
|
||||
export JOB=kibana-defend-workflows-serverless-cypress
|
||||
export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION}
|
||||
|
||||
echo "--- Defend Workflows Cypress tests on Serverless"
|
||||
|
||||
cd x-pack/plugins/security_solution
|
||||
|
||||
yarn cypress:dw:serverless:run; status=$?; yarn junit:merge || :; exit $status
|
15
.buildkite/scripts/steps/functional/defend_workflows_vagrant_serverless.sh
Executable file
15
.buildkite/scripts/steps/functional/defend_workflows_vagrant_serverless.sh
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source .buildkite/scripts/steps/functional/common.sh
|
||||
source .buildkite/scripts/steps/functional/common_cypress.sh
|
||||
|
||||
export JOB=kibana-defend-workflows-endpoint-serverless-cypress
|
||||
export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION}
|
||||
|
||||
echo "--- Defend Workflows Endpoint Cypress tests on Serverless"
|
||||
|
||||
cd x-pack/plugins/security_solution
|
||||
|
||||
yarn cypress:dw:endpoint:serverless:run; status=$?; yarn junit:merge || :; exit $status
|
|
@ -10,12 +10,18 @@
|
|||
"cypress": "NODE_OPTIONS=--openssl-legacy-provider ../../../node_modules/.bin/cypress",
|
||||
"cypress:burn": "yarn cypress:dw run --env burn=2 --headed",
|
||||
"cypress:changed-specs-only": "yarn cypress:dw run --changed-specs-only --env burn=2",
|
||||
"cypress:dw": "NODE_OPTIONS=--openssl-legacy-provider node ./scripts/start_cypress_parallel --config-file ./public/management/cypress.config.ts ts --ftr-config-file ../../test/defend_workflows_cypress/cli_config",
|
||||
"cypress:dw": "NODE_OPTIONS=--openssl-legacy-provider node ./scripts/start_cypress_parallel --config-file ./public/management/cypress/cypress.config.ts --ftr-config-file ../../test/defend_workflows_cypress/cli_config",
|
||||
"cypress:dw:open": "yarn cypress:dw open",
|
||||
"cypress:dw:run": "yarn cypress:dw run",
|
||||
"cypress:dw:endpoint": "NODE_OPTIONS=--openssl-legacy-provider node ./scripts/start_cypress_parallel --config-file ./public/management/cypress_endpoint.config.ts --ftr-config-file ../../test/defend_workflows_cypress/endpoint_config",
|
||||
"cypress:dw:endpoint": "NODE_OPTIONS=--openssl-legacy-provider node ./scripts/start_cypress_parallel --config-file ./public/management/cypress/cypress_endpoint.config.ts --ftr-config-file ../../test/defend_workflows_cypress/endpoint_config",
|
||||
"cypress:dw:endpoint:run": "yarn cypress:dw:endpoint run",
|
||||
"cypress:dw:endpoint:open": "yarn cypress:dw:endpoint open ",
|
||||
"cypress:dw:endpoint:open": "yarn cypress:dw:endpoint open",
|
||||
"cypress:dw:serverless": "NODE_OPTIONS=--openssl-legacy-provider node ./scripts/start_cypress_parallel --config-file ./public/management/cypress/cypress_serverless.config.ts --ftr-config-file ../../../x-pack/test_serverless/functional/test_suites/security/cypress/security_config",
|
||||
"cypress:dw:serverless:open": "yarn cypress:dw:serverless open",
|
||||
"cypress:dw:serverless:run": "yarn cypress:dw:serverless run",
|
||||
"cypress:dw:endpoint:serverless": "NODE_OPTIONS=--openssl-legacy-provider node ./scripts/start_cypress_parallel --config-file ./public/management/cypress/cypress_endpoint_serverless.config.ts --ftr-config-file ../../test/defend_workflows_cypress/endpoint_serverless_config",
|
||||
"cypress:dw:endpoint:serverless:open": "yarn cypress:dw:endpoint:serverless open",
|
||||
"cypress:dw:endpoint:serverless:run": "yarn cypress:dw:endpoint:serverless run",
|
||||
"junit:merge": "../../../node_modules/.bin/mochawesome-merge ../../../target/kibana-security-solution/cypress/results/mochawesome*.json > ../../../target/kibana-security-solution/cypress/results/output.json && ../../../node_modules/.bin/marge ../../../target/kibana-security-solution/cypress/results/output.json --reportDir ../../../target/kibana-security-solution/cypress/results && yarn junit:transform && mkdir -p ../../../target/junit && cp ../../../target/kibana-security-solution/cypress/results/*.xml ../../../target/junit/",
|
||||
"test:generate": "node scripts/endpoint/resolver_generator",
|
||||
"mappings:generate": "node scripts/mappings/mappings_generator",
|
||||
|
@ -24,4 +30,4 @@
|
|||
"openapi:generate": "node scripts/openapi/generate",
|
||||
"openapi:generate:debug": "node --inspect-brk scripts/openapi/generate"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"plugins": ["cypress"],
|
||||
"extends": [
|
||||
"plugin:cypress/recommended"
|
||||
],
|
||||
"env": {
|
||||
"cypress/globals": true
|
||||
},
|
||||
"rules": {
|
||||
"cypress/no-force": "warn",
|
||||
"import/no-extraneous-dependencies": "off"
|
||||
}
|
||||
}
|
|
@ -29,6 +29,16 @@ If you also want to run the tests against real endpoints as on the CI pipeline,
|
|||
See [running interactive tests on real endpoint with vagrant](#cypress-interactive-with-real-endpoints-using-vagrant)
|
||||
for more information.
|
||||
|
||||
## Adding new tests - tagging for ESS vs Serverless
|
||||
|
||||
Similarly to Security Solution cypress tests, we use tags in order to select which tests we want to execute on which environment:
|
||||
|
||||
- `@serverless` includes a test in the Serverless test suite. You need to explicitly add this tag to any test you want to run against a Serverless environment.
|
||||
- `@ess` includes a test in the normal, non-Serverless test suite. You need to explicitly add this tag to any test you want to run against a non-Serverless environment.
|
||||
- `@brokenInServerless` excludes a test from the Serverless test suite (even if it's tagged as `@serverless`). Indicates that a test should run in Serverless, but currently is broken.
|
||||
|
||||
Important: if you don't provide any tag, your test won't be executed.
|
||||
|
||||
## Running the tests
|
||||
|
||||
There are currently three ways to run the tests, comprised of two execution modes and two target environments, which
|
||||
|
@ -102,14 +112,11 @@ failures locally, etc.
|
|||
# bootstrap kibana from the project root and build the plugins/assets that cypress will execute against
|
||||
yarn kbn bootstrap && node scripts/build_kibana_platform_plugins
|
||||
|
||||
# launch the cypress test runner
|
||||
cd x-pack/plugins/security_solution
|
||||
yarn cypress:dw:run-as-ci
|
||||
# launch the cypress test runner against ESS
|
||||
yarn --cwd x-pack/plugins/security_solution cypress:dw:run
|
||||
|
||||
# or
|
||||
|
||||
# launch without changing directory from kibana/
|
||||
yarn --cwd x-pack/plugins/security_solution cypress:dw:run-as-ci
|
||||
# or against Serverless
|
||||
yarn --cwd x-pack/plugins/security_solution cypress:dw:serverless:run
|
||||
```
|
||||
|
||||
#### Cypress
|
||||
|
@ -120,14 +127,11 @@ This is the preferred mode for developing new tests against mocked data
|
|||
# bootstrap kibana from the project root and build the plugins/assets that cypress will execute against
|
||||
yarn kbn bootstrap && node scripts/build_kibana_platform_plugins
|
||||
|
||||
# launch the cypress test runner
|
||||
cd x-pack/plugins/security_solution
|
||||
yarn cypress:dw:open
|
||||
|
||||
# or
|
||||
|
||||
# launch without changing directory from kibana/
|
||||
# launch the cypress test runner against ESS
|
||||
yarn --cwd x-pack/plugins/security_solution cypress:dw:open
|
||||
|
||||
# or against Serverless
|
||||
yarn --cwd x-pack/plugins/security_solution cypress:dw:serverless:open
|
||||
```
|
||||
|
||||
For developing/debugging tests against real endpoint please use:
|
||||
|
@ -138,14 +142,11 @@ Endpoint tests require [Multipass](https://multipass.run/) to be installed on yo
|
|||
# bootstrap kibana from the project root and build the plugins/assets that cypress will execute against
|
||||
yarn kbn bootstrap && node scripts/build_kibana_platform_plugins
|
||||
|
||||
# launch the cypress test runner with real endpoint
|
||||
cd x-pack/plugins/security_solution
|
||||
yarn cypress:dw:endpoint:open
|
||||
|
||||
# or
|
||||
|
||||
# launch without changing directory from kibana/
|
||||
# launch the cypress test runner against ESS
|
||||
yarn --cwd x-pack/plugins/security_solution cypress:dw:endpoint:open
|
||||
|
||||
# or against Serverless
|
||||
yarn --cwd x-pack/plugins/security_solution cypress:dw:endpoint:serverless:open
|
||||
```
|
||||
|
||||
#### Cypress (interactive) with real Endpoints using Vagrant
|
||||
|
@ -172,14 +173,11 @@ Endpoint tests require [Multipass](https://multipass.run/) to be installed on yo
|
|||
# bootstrap kibana from the project root and build the plugins/assets that cypress will execute against
|
||||
yarn kbn bootstrap && node scripts/build_kibana_platform_plugins
|
||||
|
||||
# launch the cypress test runner with real endpoint
|
||||
cd x-pack/plugins/security_solution
|
||||
yarn cypress:dw:endpoint:run
|
||||
|
||||
# or
|
||||
|
||||
# launch without changing directory from kibana/
|
||||
# launch the cypress test runner with real endpoint against ESS
|
||||
yarn --cwd x-pack/plugins/security_solution cypress:dw:endpoint:run
|
||||
|
||||
# or against Serverless
|
||||
yarn --cwd x-pack/plugins/security_solution cypress:dw:endpoint:serverless:run
|
||||
```
|
||||
|
||||
## Folder Structure
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 { getCypressBaseConfig } from './cypress_base.config';
|
||||
|
||||
import { dataLoaders } from './support/data_loaders';
|
||||
|
||||
export default defineCypressConfig({
|
||||
...getCypressBaseConfig(),
|
||||
|
||||
env: {
|
||||
...getCypressBaseConfig().env,
|
||||
|
||||
grepTags: '@ess',
|
||||
},
|
||||
|
||||
e2e: {
|
||||
...getCypressBaseConfig().e2e,
|
||||
|
||||
specPattern: 'public/management/cypress/e2e/mocked_data/',
|
||||
setupNodeEvents: (on, config) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
require('@cypress/grep/src/plugin')(config);
|
||||
|
||||
return dataLoaders(on, config);
|
||||
},
|
||||
},
|
||||
});
|
|
@ -5,11 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { defineCypressConfig } from '@kbn/cypress-config';
|
||||
// eslint-disable-next-line @kbn/imports/no_boundary_crossing
|
||||
import { dataLoaders } from './cypress/support/data_loaders';
|
||||
|
||||
export default defineCypressConfig({
|
||||
export const getCypressBaseConfig = () => ({
|
||||
reporter: '../../../../node_modules/cypress-multi-reporters',
|
||||
reporterOptions: {
|
||||
configFile: './public/management/reporter_config.json',
|
||||
|
@ -36,21 +32,23 @@ export default defineCypressConfig({
|
|||
KIBANA_URL: 'http://localhost:5601',
|
||||
ELASTICSEARCH_URL: 'http://localhost:9200',
|
||||
FLEET_SERVER_URL: 'https://localhost:8220',
|
||||
|
||||
// Username/password used for both elastic and kibana
|
||||
KIBANA_USERNAME: 'system_indices_superuser',
|
||||
KIBANA_PASSWORD: 'changeme',
|
||||
ELASTICSEARCH_USERNAME: 'system_indices_superuser',
|
||||
ELASTICSEARCH_PASSWORD: 'changeme',
|
||||
|
||||
// grep related configs
|
||||
grepFilterSpecs: true,
|
||||
grepOmitFiltered: true,
|
||||
},
|
||||
|
||||
e2e: {
|
||||
// baseUrl: To override, set Env. variable `CYPRESS_BASE_URL`
|
||||
baseUrl: 'http://localhost:5601',
|
||||
|
||||
supportFile: 'public/management/cypress/support/e2e.ts',
|
||||
specPattern: 'public/management/cypress/e2e/mocked_data/',
|
||||
experimentalRunAllSpecs: true,
|
||||
setupNodeEvents: (on, config) => {
|
||||
return dataLoaders(on, config);
|
||||
},
|
||||
},
|
||||
});
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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 { getCypressBaseConfig } from './cypress_base.config';
|
||||
|
||||
import { dataLoaders, dataLoadersForRealEndpoints } from './support/data_loaders';
|
||||
|
||||
import { responseActionTasks } from './support/response_actions';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default defineCypressConfig({
|
||||
...getCypressBaseConfig(),
|
||||
|
||||
env: {
|
||||
...getCypressBaseConfig().env,
|
||||
|
||||
'cypress-react-selector': {
|
||||
root: '#security-solution-app',
|
||||
},
|
||||
|
||||
grepTags: '@ess',
|
||||
},
|
||||
|
||||
e2e: {
|
||||
...getCypressBaseConfig().e2e,
|
||||
|
||||
experimentalMemoryManagement: true,
|
||||
experimentalInteractiveRunEvents: true,
|
||||
specPattern: 'public/management/cypress/e2e/endpoint/*.cy.{js,jsx,ts,tsx}',
|
||||
setupNodeEvents: (on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) => {
|
||||
dataLoaders(on, config);
|
||||
// Data loaders specific to "real" Endpoint testing
|
||||
dataLoadersForRealEndpoints(on, config);
|
||||
responseActionTasks(on, config);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
require('@cypress/grep/src/plugin')(config);
|
||||
|
||||
return config;
|
||||
},
|
||||
},
|
||||
});
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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 { getCypressBaseConfig } from './cypress_base.config';
|
||||
import { dataLoaders } from './support/data_loaders';
|
||||
import { responseActionTasks } from './support/response_actions';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default defineCypressConfig({
|
||||
...getCypressBaseConfig(),
|
||||
|
||||
env: {
|
||||
...getCypressBaseConfig().env,
|
||||
|
||||
IS_SERVERLESS: true,
|
||||
grepTags: '@serverless --@brokenInServerless',
|
||||
|
||||
'cypress-react-selector': {
|
||||
root: '#security-solution-app',
|
||||
},
|
||||
},
|
||||
|
||||
e2e: {
|
||||
...getCypressBaseConfig().e2e,
|
||||
|
||||
experimentalMemoryManagement: true,
|
||||
experimentalInteractiveRunEvents: true,
|
||||
|
||||
specPattern: 'public/management/cypress/e2e/endpoint/*.cy.{js,jsx,ts,tsx}',
|
||||
|
||||
setupNodeEvents: (on, config) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
require('@cypress/grep/src/plugin')(config);
|
||||
|
||||
dataLoaders(on, config);
|
||||
|
||||
// skip dataLoadersForRealEndpoints()
|
||||
// https://github.com/elastic/security-team/issues/7467
|
||||
// Data loaders specific to "real" Endpoint testing
|
||||
// dataLoadersForRealEndpoints(on, config);
|
||||
|
||||
responseActionTasks(on, config);
|
||||
},
|
||||
},
|
||||
});
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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 { getCypressBaseConfig } from './cypress_base.config';
|
||||
import { dataLoaders } from './support/data_loaders';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default defineCypressConfig({
|
||||
...getCypressBaseConfig(),
|
||||
|
||||
env: {
|
||||
...getCypressBaseConfig().env,
|
||||
|
||||
IS_SERVERLESS: true,
|
||||
|
||||
grepTags: '@serverless --@brokenInServerless',
|
||||
},
|
||||
|
||||
e2e: {
|
||||
...getCypressBaseConfig().e2e,
|
||||
|
||||
specPattern: 'public/management/cypress/e2e/mocked_data/',
|
||||
|
||||
setupNodeEvents: (on, config) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
require('@cypress/grep/src/plugin')(config);
|
||||
|
||||
return dataLoaders(on, config);
|
||||
},
|
||||
},
|
||||
});
|
|
@ -36,7 +36,7 @@ const yieldAppliedEndpointRevision = (): Cypress.Chainable<number> =>
|
|||
|
||||
const parseRevNumber = (revString: string) => Number(revString.match(/\d+/)?.[0]);
|
||||
|
||||
describe('Artifact pages', () => {
|
||||
describe('Artifact pages', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => {
|
||||
let indexedPolicy: IndexedFleetEndpointPolicyResponse;
|
||||
let policy: PolicyData;
|
||||
let createdHost: CreateAndEnrollEndpointHostResponse;
|
||||
|
@ -61,6 +61,7 @@ describe('Artifact pages', () => {
|
|||
|
||||
// wait for ManifestManager to pick up artifact changes that happened either here
|
||||
// or in a previous test suite `after`
|
||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||
cy.wait(6000); // packagerTaskInterval + 1s
|
||||
|
||||
yieldEndpointPolicyRevision().then((actualEndpointPolicyRevision) => {
|
||||
|
|
|
@ -20,86 +20,91 @@ import { createEndpointHost } from '../../tasks/create_endpoint_host';
|
|||
import { deleteAllLoadedEndpointData } from '../../tasks/delete_all_endpoint_data';
|
||||
import { enableAllPolicyProtections } from '../../tasks/endpoint_policy';
|
||||
|
||||
describe('Automated Response Actions', () => {
|
||||
let indexedPolicy: IndexedFleetEndpointPolicyResponse;
|
||||
let policy: PolicyData;
|
||||
let createdHost: CreateAndEnrollEndpointHostResponse;
|
||||
|
||||
before(() => {
|
||||
getEndpointIntegrationVersion().then((version) =>
|
||||
createAgentPolicyTask(version, 'automated_response_actions').then((data) => {
|
||||
indexedPolicy = data;
|
||||
policy = indexedPolicy.integrationPolicies[0];
|
||||
|
||||
return enableAllPolicyProtections(policy.id).then(() => {
|
||||
// Create and enroll a new Endpoint host
|
||||
return createEndpointHost(policy.policy_id).then((host) => {
|
||||
createdHost = host as CreateAndEnrollEndpointHostResponse;
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
if (createdHost) {
|
||||
cy.task('destroyEndpointHost', createdHost);
|
||||
}
|
||||
|
||||
if (indexedPolicy) {
|
||||
cy.task('deleteIndexedFleetEndpointPolicies', indexedPolicy);
|
||||
}
|
||||
|
||||
if (createdHost) {
|
||||
deleteAllLoadedEndpointData({ endpointAgentIds: [createdHost.agentId] });
|
||||
}
|
||||
});
|
||||
|
||||
const hostname = new URL(Cypress.env('FLEET_SERVER_URL')).port;
|
||||
const fleetHostname = `dev-fleet-server.${hostname}`;
|
||||
|
||||
beforeEach(() => {
|
||||
login();
|
||||
disableExpandableFlyoutAdvancedSettings();
|
||||
});
|
||||
|
||||
describe('From alerts', () => {
|
||||
let ruleId: string;
|
||||
let ruleName: string;
|
||||
describe(
|
||||
'Automated Response Actions',
|
||||
{ tags: ['@ess', '@serverless', '@brokenInServerless'] },
|
||||
() => {
|
||||
let indexedPolicy: IndexedFleetEndpointPolicyResponse;
|
||||
let policy: PolicyData;
|
||||
let createdHost: CreateAndEnrollEndpointHostResponse;
|
||||
|
||||
before(() => {
|
||||
loadRule().then((data) => {
|
||||
ruleId = data.id;
|
||||
ruleName = data.name;
|
||||
});
|
||||
getEndpointIntegrationVersion().then((version) =>
|
||||
createAgentPolicyTask(version, 'automated_response_actions').then((data) => {
|
||||
indexedPolicy = data;
|
||||
policy = indexedPolicy.integrationPolicies[0];
|
||||
|
||||
return enableAllPolicyProtections(policy.id).then(() => {
|
||||
// Create and enroll a new Endpoint host
|
||||
return createEndpointHost(policy.policy_id).then((host) => {
|
||||
createdHost = host as CreateAndEnrollEndpointHostResponse;
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
if (ruleId) {
|
||||
cleanupRule(ruleId);
|
||||
if (createdHost) {
|
||||
cy.task('destroyEndpointHost', createdHost);
|
||||
}
|
||||
|
||||
if (indexedPolicy) {
|
||||
cy.task('deleteIndexedFleetEndpointPolicies', indexedPolicy);
|
||||
}
|
||||
|
||||
if (createdHost) {
|
||||
deleteAllLoadedEndpointData({ endpointAgentIds: [createdHost.agentId] });
|
||||
}
|
||||
});
|
||||
it.skip('should have generated endpoint and rule', () => {
|
||||
loadPage(APP_ENDPOINTS_PATH);
|
||||
cy.contains(createdHost.hostname).should('exist');
|
||||
|
||||
toggleRuleOffAndOn(ruleName);
|
||||
const hostname = new URL(Cypress.env('FLEET_SERVER_URL')).port;
|
||||
const fleetHostname = `dev-fleet-server.${hostname}`;
|
||||
|
||||
visitRuleAlerts(ruleName);
|
||||
closeAllToasts();
|
||||
|
||||
changeAlertsFilter('event.category: "file"');
|
||||
cy.getByTestSubj('expand-event').first().click();
|
||||
cy.getByTestSubj('responseActionsViewTab').click();
|
||||
cy.getByTestSubj('response-actions-notification').should('not.have.text', '0');
|
||||
|
||||
cy.getByTestSubj(`response-results-${createdHost.hostname}-details-tray`)
|
||||
.should('contain', 'isolate completed successfully')
|
||||
.and('contain', createdHost.hostname);
|
||||
|
||||
cy.getByTestSubj(`response-results-${fleetHostname}-details-tray`)
|
||||
.should('contain', 'The host does not have Elastic Defend integration installed')
|
||||
.and('contain', 'dev-fleet-server');
|
||||
beforeEach(() => {
|
||||
login();
|
||||
disableExpandableFlyoutAdvancedSettings();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('From alerts', () => {
|
||||
let ruleId: string;
|
||||
let ruleName: string;
|
||||
|
||||
before(() => {
|
||||
loadRule().then((data) => {
|
||||
ruleId = data.id;
|
||||
ruleName = data.name;
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
if (ruleId) {
|
||||
cleanupRule(ruleId);
|
||||
}
|
||||
});
|
||||
|
||||
it.skip('should have generated endpoint and rule', () => {
|
||||
loadPage(APP_ENDPOINTS_PATH);
|
||||
cy.contains(createdHost.hostname).should('exist');
|
||||
|
||||
toggleRuleOffAndOn(ruleName);
|
||||
|
||||
visitRuleAlerts(ruleName);
|
||||
closeAllToasts();
|
||||
|
||||
changeAlertsFilter('event.category: "file"');
|
||||
cy.getByTestSubj('expand-event').first().click();
|
||||
cy.getByTestSubj('responseActionsViewTab').click();
|
||||
cy.getByTestSubj('response-actions-notification').should('not.have.text', '0');
|
||||
|
||||
cy.getByTestSubj(`response-results-${createdHost.hostname}-details-tray`)
|
||||
.should('contain', 'isolate completed successfully')
|
||||
.and('contain', createdHost.hostname);
|
||||
|
||||
cy.getByTestSubj(`response-results-${fleetHostname}-details-tray`)
|
||||
.should('contain', 'The host does not have Elastic Defend integration installed')
|
||||
.and('contain', 'dev-fleet-server');
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
@ -19,79 +19,80 @@ import { login } from '../../tasks/login';
|
|||
import { EXECUTE_ROUTE } from '../../../../../common/endpoint/constants';
|
||||
import { waitForActionToComplete } from '../../tasks/response_actions';
|
||||
|
||||
describe('Endpoint generated alerts', () => {
|
||||
let indexedPolicy: IndexedFleetEndpointPolicyResponse;
|
||||
let policy: PolicyData;
|
||||
let createdHost: CreateAndEnrollEndpointHostResponse;
|
||||
describe(
|
||||
'Endpoint generated alerts',
|
||||
{ tags: ['@ess', '@serverless', '@brokenInServerless'] },
|
||||
() => {
|
||||
let indexedPolicy: IndexedFleetEndpointPolicyResponse;
|
||||
let policy: PolicyData;
|
||||
let createdHost: CreateAndEnrollEndpointHostResponse;
|
||||
|
||||
before(() => {
|
||||
getEndpointIntegrationVersion().then((version) => {
|
||||
createAgentPolicyTask(version, 'alerts test').then((data) => {
|
||||
indexedPolicy = data;
|
||||
policy = indexedPolicy.integrationPolicies[0];
|
||||
before(() => {
|
||||
getEndpointIntegrationVersion().then((version) => {
|
||||
createAgentPolicyTask(version, 'alerts test').then((data) => {
|
||||
indexedPolicy = data;
|
||||
policy = indexedPolicy.integrationPolicies[0];
|
||||
|
||||
return enableAllPolicyProtections(policy.id).then(() => {
|
||||
// Create and enroll a new Endpoint host
|
||||
return createEndpointHost(policy.policy_id).then((host) => {
|
||||
createdHost = host as CreateAndEnrollEndpointHostResponse;
|
||||
return enableAllPolicyProtections(policy.id).then(() => {
|
||||
// Create and enroll a new Endpoint host
|
||||
return createEndpointHost(policy.policy_id).then((host) => {
|
||||
createdHost = host as CreateAndEnrollEndpointHostResponse;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
if (createdHost) {
|
||||
cy.task('destroyEndpointHost', createdHost);
|
||||
}
|
||||
after(() => {
|
||||
if (createdHost) {
|
||||
cy.task('destroyEndpointHost', createdHost);
|
||||
}
|
||||
|
||||
if (indexedPolicy) {
|
||||
cy.task('deleteIndexedFleetEndpointPolicies', indexedPolicy);
|
||||
}
|
||||
if (indexedPolicy) {
|
||||
cy.task('deleteIndexedFleetEndpointPolicies', indexedPolicy);
|
||||
}
|
||||
|
||||
if (createdHost) {
|
||||
deleteAllLoadedEndpointData({ endpointAgentIds: [createdHost.agentId] });
|
||||
}
|
||||
});
|
||||
if (createdHost) {
|
||||
deleteAllLoadedEndpointData({ endpointAgentIds: [createdHost.agentId] });
|
||||
}
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
login();
|
||||
});
|
||||
beforeEach(() => {
|
||||
login();
|
||||
});
|
||||
|
||||
it('should create a Detection Engine alert from an endpoint alert', () => {
|
||||
// Triggers a Malicious Behaviour alert on Linux system (`grep *` was added only to identify this specific alert)
|
||||
const executeMaliciousCommand = `bash -c cat /dev/tcp/foo | grep ${Math.random()
|
||||
.toString(16)
|
||||
.substring(2)}`;
|
||||
it('should create a Detection Engine alert from an endpoint alert', () => {
|
||||
// Triggers a Malicious Behaviour alert on Linux system (`grep *` was added only to identify this specific alert)
|
||||
const executeMaliciousCommand = `bash -c cat /dev/tcp/foo | grep ${Math.random()
|
||||
.toString(16)
|
||||
.substring(2)}`;
|
||||
|
||||
// Send `execute` command that triggers malicious behaviour using the `execute` response action
|
||||
request<ResponseActionApiResponse>({
|
||||
method: 'POST',
|
||||
url: EXECUTE_ROUTE,
|
||||
body: {
|
||||
endpoint_ids: [createdHost.agentId],
|
||||
parameters: {
|
||||
command: executeMaliciousCommand,
|
||||
},
|
||||
},
|
||||
headers: {
|
||||
'Elastic-Api-Version': '2023-10-31',
|
||||
},
|
||||
})
|
||||
.then((response) => waitForActionToComplete(response.body.data.id))
|
||||
.then(() => {
|
||||
return waitForEndpointAlerts(createdHost.agentId, [
|
||||
{
|
||||
term: { 'process.group_leader.args': executeMaliciousCommand },
|
||||
// Send `execute` command that triggers malicious behaviour using the `execute` response action
|
||||
request<ResponseActionApiResponse>({
|
||||
method: 'POST',
|
||||
url: EXECUTE_ROUTE,
|
||||
body: {
|
||||
endpoint_ids: [createdHost.agentId],
|
||||
parameters: {
|
||||
command: executeMaliciousCommand,
|
||||
},
|
||||
]);
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
return navigateToAlertsList(
|
||||
`query=(language:kuery,query:'agent.id: "${createdHost.agentId}" ')`
|
||||
);
|
||||
});
|
||||
.then((response) => waitForActionToComplete(response.body.data.id))
|
||||
.then(() => {
|
||||
return waitForEndpointAlerts(createdHost.agentId, [
|
||||
{
|
||||
term: { 'process.group_leader.args': executeMaliciousCommand },
|
||||
},
|
||||
]);
|
||||
})
|
||||
.then(() => {
|
||||
return navigateToAlertsList(
|
||||
`query=(language:kuery,query:'agent.id: "${createdHost.agentId}" ')`
|
||||
);
|
||||
});
|
||||
|
||||
getAlertsTableRows().should('have.length.greaterThan', 0);
|
||||
});
|
||||
});
|
||||
getAlertsTableRows().should('have.length.greaterThan', 0);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
@ -32,7 +32,7 @@ import { createEndpointHost } from '../../tasks/create_endpoint_host';
|
|||
import { deleteAllLoadedEndpointData } from '../../tasks/delete_all_endpoint_data';
|
||||
import { enableAllPolicyProtections } from '../../tasks/endpoint_policy';
|
||||
|
||||
describe('Endpoints page', () => {
|
||||
describe('Endpoints page', { tags: '@ess' }, () => {
|
||||
let indexedPolicy: IndexedFleetEndpointPolicyResponse;
|
||||
let policy: PolicyData;
|
||||
let createdHost: CreateAndEnrollEndpointHostResponse;
|
||||
|
@ -109,24 +109,26 @@ describe('Endpoints page', () => {
|
|||
|
||||
it('User can reassign a single endpoint to a different Agent Configuration', () => {
|
||||
loadPage(APP_ENDPOINTS_PATH);
|
||||
const hostname = cy
|
||||
.getByTestSubj(AGENT_HOSTNAME_CELL)
|
||||
.filter(`:contains("${createdHost.hostname}")`);
|
||||
const tableRow = hostname.parents('tr');
|
||||
tableRow.findByTestSubj(TABLE_ROW_ACTIONS).click();
|
||||
cy.getByTestSubj(TABLE_ROW_ACTIONS_MENU).contains('Reassign agent policy').click();
|
||||
cy.getByTestSubj(FLEET_REASSIGN_POLICY_MODAL)
|
||||
.find('select')
|
||||
.select(response.agentPolicies[0].name);
|
||||
cy.getByTestSubj(FLEET_REASSIGN_POLICY_MODAL_CONFIRM_BUTTON).click();
|
||||
cy.getByTestSubj(AGENT_HOSTNAME_CELL)
|
||||
.filter(`:contains("${createdHost.hostname}")`)
|
||||
.should('exist');
|
||||
cy.getByTestSubj(AGENT_HOSTNAME_CELL)
|
||||
.filter(`:contains("${createdHost.hostname}")`)
|
||||
.parents('tr')
|
||||
.findByTestSubj(AGENT_POLICY_CELL)
|
||||
.should('have.text', response.agentPolicies[0].name);
|
||||
.then((hostname) => {
|
||||
const tableRow = hostname.parents('tr');
|
||||
|
||||
tableRow.find(`[data-test-subj=${TABLE_ROW_ACTIONS}`).trigger('click');
|
||||
cy.getByTestSubj(TABLE_ROW_ACTIONS_MENU).contains('Reassign agent policy').click();
|
||||
cy.getByTestSubj(FLEET_REASSIGN_POLICY_MODAL)
|
||||
.find('select')
|
||||
.select(response.agentPolicies[0].name);
|
||||
cy.getByTestSubj(FLEET_REASSIGN_POLICY_MODAL_CONFIRM_BUTTON).click();
|
||||
cy.getByTestSubj(AGENT_HOSTNAME_CELL)
|
||||
.filter(`:contains("${createdHost.hostname}")`)
|
||||
.should('exist');
|
||||
cy.getByTestSubj(AGENT_HOSTNAME_CELL)
|
||||
.filter(`:contains("${createdHost.hostname}")`)
|
||||
.parents('tr')
|
||||
.findByTestSubj(AGENT_POLICY_CELL)
|
||||
.should('have.text', response.agentPolicies[0].name);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ import { createEndpointHost } from '../../tasks/create_endpoint_host';
|
|||
import { deleteAllLoadedEndpointData } from '../../tasks/delete_all_endpoint_data';
|
||||
import { enableAllPolicyProtections } from '../../tasks/endpoint_policy';
|
||||
|
||||
describe.skip('Isolate command', () => {
|
||||
describe.skip('Isolate command', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => {
|
||||
let isolateComment: string;
|
||||
let releaseComment: string;
|
||||
let indexedPolicy: IndexedFleetEndpointPolicyResponse;
|
||||
|
@ -84,7 +84,7 @@ describe.skip('Isolate command', () => {
|
|||
|
||||
filterOutIsolatedHosts();
|
||||
cy.contains('No items found');
|
||||
cy.getByTestSubj('adminSearchBar').click().type('{selectall}{backspace}');
|
||||
cy.getByTestSubj('adminSearchBar').type('{selectall}{backspace}');
|
||||
cy.getByTestSubj('querySubmitButton').click();
|
||||
cy.getByTestSubj('endpointTableRowActions').click();
|
||||
cy.getByTestSubj('isolateLink').click();
|
||||
|
@ -105,7 +105,7 @@ describe.skip('Isolate command', () => {
|
|||
releaseHostWithComment(releaseComment, createdHost.hostname);
|
||||
cy.contains('Confirm').click();
|
||||
cy.getByTestSubj('euiFlyoutCloseButton').click();
|
||||
cy.getByTestSubj('adminSearchBar').click().type('{selectall}{backspace}');
|
||||
cy.getByTestSubj('adminSearchBar').type('{selectall}{backspace}');
|
||||
cy.getByTestSubj('querySubmitButton').click();
|
||||
checkEndpointListForOnlyUnIsolatedHosts();
|
||||
});
|
||||
|
|
|
@ -19,6 +19,7 @@ import { disableExpandableFlyoutAdvancedSettings, loadPage } from '../../tasks/c
|
|||
describe(
|
||||
'Policy Details',
|
||||
{
|
||||
tags: '@ess',
|
||||
env: { ftrConfig: { enableExperimental: ['protectionUpdatesEnabled'] } },
|
||||
},
|
||||
() => {
|
||||
|
@ -175,7 +176,8 @@ describe(
|
|||
it('should update note on save', () => {
|
||||
loadProtectionUpdatesUrl(policy.id);
|
||||
cy.getByTestSubj('protection-updates-manifest-note').contains(testNote);
|
||||
cy.getByTestSubj('protection-updates-manifest-note').clear().type(updatedTestNote);
|
||||
cy.getByTestSubj('protection-updates-manifest-note').clear();
|
||||
cy.getByTestSubj('protection-updates-manifest-note').type(updatedTestNote);
|
||||
|
||||
cy.intercept('POST', `/api/endpoint/protection_updates_note/*`).as('note_updated');
|
||||
cy.getByTestSubj('policyDetailsSaveButton').click();
|
||||
|
|
|
@ -27,7 +27,7 @@ import { enableAllPolicyProtections } from '../../tasks/endpoint_policy';
|
|||
import { createEndpointHost } from '../../tasks/create_endpoint_host';
|
||||
import { deleteAllLoadedEndpointData } from '../../tasks/delete_all_endpoint_data';
|
||||
|
||||
describe('Response console', () => {
|
||||
describe('Response console', { tags: ['@ess', '@serverless', '@brokenInServerless'] }, () => {
|
||||
beforeEach(() => {
|
||||
login();
|
||||
});
|
||||
|
|
|
@ -63,162 +63,166 @@ const visitArtifactTab = (tabId: string) => {
|
|||
cy.get(`#${tabId}`).click();
|
||||
};
|
||||
|
||||
describe('Artifact tabs in Policy Details page', () => {
|
||||
before(() => {
|
||||
login();
|
||||
loadEndpointDataForEventFiltersIfNeeded();
|
||||
});
|
||||
describe(
|
||||
'Artifact tabs in Policy Details page',
|
||||
{ tags: ['@ess', '@serverless', '@brokenInServerless'] }, // broken due to disabled Native Role Management
|
||||
() => {
|
||||
before(() => {
|
||||
login();
|
||||
loadEndpointDataForEventFiltersIfNeeded();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
login();
|
||||
removeAllArtifacts();
|
||||
});
|
||||
after(() => {
|
||||
login();
|
||||
removeAllArtifacts();
|
||||
});
|
||||
|
||||
for (const testData of getArtifactsListTestsData()) {
|
||||
describe(`${testData.title} tab`, () => {
|
||||
beforeEach(() => {
|
||||
login();
|
||||
removeExceptionsList(testData.createRequestBody.list_id);
|
||||
});
|
||||
|
||||
it(`[NONE] User cannot see the tab for ${testData.title}`, () => {
|
||||
loginWithPrivilegeNone(testData.privilegePrefix);
|
||||
visitPolicyDetailsPage();
|
||||
|
||||
cy.get(`#${testData.tabId}`).should('not.exist');
|
||||
});
|
||||
|
||||
context(`Given there are no ${testData.title} entries`, () => {
|
||||
it(`[READ] User CANNOT add ${testData.title} artifact`, () => {
|
||||
loginWithPrivilegeRead(testData.privilegePrefix);
|
||||
visitArtifactTab(testData.tabId);
|
||||
|
||||
cy.getByTestSubj('policy-artifacts-empty-unexisting').should('exist');
|
||||
|
||||
cy.getByTestSubj('unexisting-manage-artifacts-button').should('not.exist');
|
||||
});
|
||||
|
||||
it(`[ALL] User can add ${testData.title} artifact`, () => {
|
||||
loginWithPrivilegeAll();
|
||||
visitArtifactTab(testData.tabId);
|
||||
|
||||
cy.getByTestSubj('policy-artifacts-empty-unexisting').should('exist');
|
||||
|
||||
cy.getByTestSubj('unexisting-manage-artifacts-button').should('exist').click();
|
||||
|
||||
const { formActions, checkResults } = testData.create;
|
||||
|
||||
performUserActions(formActions);
|
||||
|
||||
// Add a per policy artifact - but not assign it to any policy
|
||||
cy.get('[data-test-subj$="-perPolicy"]').click(); // test-subjects are generated in different formats, but all ends with -perPolicy
|
||||
cy.getByTestSubj(`${testData.pagePrefix}-flyout-submitButton`).click();
|
||||
|
||||
// Check new artifact is in the list
|
||||
for (const checkResult of checkResults) {
|
||||
cy.getByTestSubj(checkResult.selector).should('have.text', checkResult.value);
|
||||
}
|
||||
|
||||
cy.getByTestSubj('policyDetailsPage').should('not.exist');
|
||||
cy.getByTestSubj('backToOrigin').contains(/^Back to .+ policy$/);
|
||||
|
||||
cy.getByTestSubj('backToOrigin').click();
|
||||
cy.getByTestSubj('policyDetailsPage').should('exist');
|
||||
});
|
||||
});
|
||||
|
||||
context(`Given there are no assigned ${testData.title} entries`, () => {
|
||||
for (const testData of getArtifactsListTestsData()) {
|
||||
describe(`${testData.title} tab`, () => {
|
||||
beforeEach(() => {
|
||||
login();
|
||||
createArtifactList(testData.createRequestBody.list_id);
|
||||
createPerPolicyArtifact(testData.artifactName, testData.createRequestBody);
|
||||
removeExceptionsList(testData.createRequestBody.list_id);
|
||||
});
|
||||
|
||||
it(`[READ] User CANNOT Manage or Assign ${testData.title} artifacts`, () => {
|
||||
loginWithPrivilegeRead(testData.privilegePrefix);
|
||||
visitArtifactTab(testData.tabId);
|
||||
it(`[NONE] User cannot see the tab for ${testData.title}`, () => {
|
||||
loginWithPrivilegeNone(testData.privilegePrefix);
|
||||
visitPolicyDetailsPage();
|
||||
|
||||
cy.getByTestSubj('policy-artifacts-empty-unassigned').should('exist');
|
||||
|
||||
cy.getByTestSubj('unassigned-manage-artifacts-button').should('not.exist');
|
||||
cy.getByTestSubj('unassigned-assign-artifacts-button').should('not.exist');
|
||||
cy.get(`#${testData.tabId}`).should('not.exist');
|
||||
});
|
||||
|
||||
it(`[ALL] User can Manage and Assign ${testData.title} artifacts`, () => {
|
||||
loginWithPrivilegeAll();
|
||||
visitArtifactTab(testData.tabId);
|
||||
context(`Given there are no ${testData.title} entries`, () => {
|
||||
it(`[READ] User CANNOT add ${testData.title} artifact`, () => {
|
||||
loginWithPrivilegeRead(testData.privilegePrefix);
|
||||
visitArtifactTab(testData.tabId);
|
||||
|
||||
cy.getByTestSubj('policy-artifacts-empty-unassigned').should('exist');
|
||||
cy.getByTestSubj('policy-artifacts-empty-unexisting').should('exist');
|
||||
|
||||
// Manage artifacts
|
||||
cy.getByTestSubj('unassigned-manage-artifacts-button').should('exist').click();
|
||||
cy.location('pathname').should(
|
||||
'equal',
|
||||
`/app/security/administration/${testData.urlPath}`
|
||||
);
|
||||
cy.getByTestSubj('backToOrigin').click();
|
||||
cy.getByTestSubj('unexisting-manage-artifacts-button').should('not.exist');
|
||||
});
|
||||
|
||||
// Assign artifacts
|
||||
cy.getByTestSubj('unassigned-assign-artifacts-button').should('exist').click();
|
||||
it(`[ALL] User can add ${testData.title} artifact`, () => {
|
||||
loginWithPrivilegeAll();
|
||||
visitArtifactTab(testData.tabId);
|
||||
|
||||
cy.getByTestSubj('artifacts-assign-flyout').should('exist');
|
||||
cy.getByTestSubj('artifacts-assign-confirm-button').should('be.disabled');
|
||||
cy.getByTestSubj('policy-artifacts-empty-unexisting').should('exist');
|
||||
|
||||
cy.getByTestSubj(`${testData.artifactName}_checkbox`).click();
|
||||
cy.getByTestSubj('artifacts-assign-confirm-button').click();
|
||||
});
|
||||
});
|
||||
cy.getByTestSubj('unexisting-manage-artifacts-button').should('exist').click();
|
||||
|
||||
context(`Given there are assigned ${testData.title} entries`, () => {
|
||||
beforeEach(() => {
|
||||
login();
|
||||
createArtifactList(testData.createRequestBody.list_id);
|
||||
yieldFirstPolicyID().then((policyID) => {
|
||||
createPerPolicyArtifact(testData.artifactName, testData.createRequestBody, policyID);
|
||||
const { formActions, checkResults } = testData.create;
|
||||
|
||||
performUserActions(formActions);
|
||||
|
||||
// Add a per policy artifact - but not assign it to any policy
|
||||
cy.get('[data-test-subj$="-perPolicy"]').click(); // test-subjects are generated in different formats, but all ends with -perPolicy
|
||||
cy.getByTestSubj(`${testData.pagePrefix}-flyout-submitButton`).click();
|
||||
|
||||
// Check new artifact is in the list
|
||||
for (const checkResult of checkResults) {
|
||||
cy.getByTestSubj(checkResult.selector).should('have.text', checkResult.value);
|
||||
}
|
||||
|
||||
cy.getByTestSubj('policyDetailsPage').should('not.exist');
|
||||
cy.getByTestSubj('backToOrigin').contains(/^Back to .+ policy$/);
|
||||
|
||||
cy.getByTestSubj('backToOrigin').click();
|
||||
cy.getByTestSubj('policyDetailsPage').should('exist');
|
||||
});
|
||||
});
|
||||
|
||||
it(`[READ] User can see ${testData.title} artifacts but CANNOT assign or remove from policy`, () => {
|
||||
loginWithPrivilegeRead(testData.privilegePrefix);
|
||||
visitArtifactTab(testData.tabId);
|
||||
context(`Given there are no assigned ${testData.title} entries`, () => {
|
||||
beforeEach(() => {
|
||||
login();
|
||||
createArtifactList(testData.createRequestBody.list_id);
|
||||
createPerPolicyArtifact(testData.artifactName, testData.createRequestBody);
|
||||
});
|
||||
|
||||
// List of artifacts
|
||||
cy.getByTestSubj('artifacts-collapsed-list-card').should('have.length', 1);
|
||||
cy.getByTestSubj('artifacts-collapsed-list-card-header-titleHolder').contains(
|
||||
testData.artifactName
|
||||
);
|
||||
it(`[READ] User CANNOT Manage or Assign ${testData.title} artifacts`, () => {
|
||||
loginWithPrivilegeRead(testData.privilegePrefix);
|
||||
visitArtifactTab(testData.tabId);
|
||||
|
||||
// Cannot assign artifacts
|
||||
cy.getByTestSubj('artifacts-assign-button').should('not.exist');
|
||||
cy.getByTestSubj('policy-artifacts-empty-unassigned').should('exist');
|
||||
|
||||
// Cannot remove from policy
|
||||
cy.getByTestSubj('artifacts-collapsed-list-card-header-actions-button').click();
|
||||
cy.getByTestSubj('remove-from-policy-action').should('not.exist');
|
||||
cy.getByTestSubj('unassigned-manage-artifacts-button').should('not.exist');
|
||||
cy.getByTestSubj('unassigned-assign-artifacts-button').should('not.exist');
|
||||
});
|
||||
|
||||
it(`[ALL] User can Manage and Assign ${testData.title} artifacts`, () => {
|
||||
loginWithPrivilegeAll();
|
||||
visitArtifactTab(testData.tabId);
|
||||
|
||||
cy.getByTestSubj('policy-artifacts-empty-unassigned').should('exist');
|
||||
|
||||
// Manage artifacts
|
||||
cy.getByTestSubj('unassigned-manage-artifacts-button').should('exist').click();
|
||||
cy.location('pathname').should(
|
||||
'equal',
|
||||
`/app/security/administration/${testData.urlPath}`
|
||||
);
|
||||
cy.getByTestSubj('backToOrigin').click();
|
||||
|
||||
// Assign artifacts
|
||||
cy.getByTestSubj('unassigned-assign-artifacts-button').should('exist').click();
|
||||
|
||||
cy.getByTestSubj('artifacts-assign-flyout').should('exist');
|
||||
cy.getByTestSubj('artifacts-assign-confirm-button').should('be.disabled');
|
||||
|
||||
cy.getByTestSubj(`${testData.artifactName}_checkbox`).click();
|
||||
cy.getByTestSubj('artifacts-assign-confirm-button').click();
|
||||
});
|
||||
});
|
||||
|
||||
it(`[ALL] User can see ${testData.title} artifacts and can assign or remove artifacts from policy`, () => {
|
||||
loginWithPrivilegeAll();
|
||||
visitArtifactTab(testData.tabId);
|
||||
context(`Given there are assigned ${testData.title} entries`, () => {
|
||||
beforeEach(() => {
|
||||
login();
|
||||
createArtifactList(testData.createRequestBody.list_id);
|
||||
yieldFirstPolicyID().then((policyID) => {
|
||||
createPerPolicyArtifact(testData.artifactName, testData.createRequestBody, policyID);
|
||||
});
|
||||
});
|
||||
|
||||
// List of artifacts
|
||||
cy.getByTestSubj('artifacts-collapsed-list-card').should('have.length', 1);
|
||||
cy.getByTestSubj('artifacts-collapsed-list-card-header-titleHolder').contains(
|
||||
testData.artifactName
|
||||
);
|
||||
it(`[READ] User can see ${testData.title} artifacts but CANNOT assign or remove from policy`, () => {
|
||||
loginWithPrivilegeRead(testData.privilegePrefix);
|
||||
visitArtifactTab(testData.tabId);
|
||||
|
||||
// Assign artifacts
|
||||
cy.getByTestSubj('artifacts-assign-button').should('exist').click();
|
||||
cy.getByTestSubj('artifacts-assign-flyout').should('exist');
|
||||
cy.getByTestSubj('artifacts-assign-cancel-button').click();
|
||||
// List of artifacts
|
||||
cy.getByTestSubj('artifacts-collapsed-list-card').should('have.length', 1);
|
||||
cy.getByTestSubj('artifacts-collapsed-list-card-header-titleHolder').contains(
|
||||
testData.artifactName
|
||||
);
|
||||
|
||||
// Remove from policy
|
||||
cy.getByTestSubj('artifacts-collapsed-list-card-header-actions-button').click();
|
||||
cy.getByTestSubj('remove-from-policy-action').click();
|
||||
cy.getByTestSubj('confirmModalConfirmButton').click();
|
||||
// Cannot assign artifacts
|
||||
cy.getByTestSubj('artifacts-assign-button').should('not.exist');
|
||||
|
||||
cy.contains('Successfully removed');
|
||||
// Cannot remove from policy
|
||||
cy.getByTestSubj('artifacts-collapsed-list-card-header-actions-button').click();
|
||||
cy.getByTestSubj('remove-from-policy-action').should('not.exist');
|
||||
});
|
||||
|
||||
it(`[ALL] User can see ${testData.title} artifacts and can assign or remove artifacts from policy`, () => {
|
||||
loginWithPrivilegeAll();
|
||||
visitArtifactTab(testData.tabId);
|
||||
|
||||
// List of artifacts
|
||||
cy.getByTestSubj('artifacts-collapsed-list-card').should('have.length', 1);
|
||||
cy.getByTestSubj('artifacts-collapsed-list-card-header-titleHolder').contains(
|
||||
testData.artifactName
|
||||
);
|
||||
|
||||
// Assign artifacts
|
||||
cy.getByTestSubj('artifacts-assign-button').should('exist').click();
|
||||
cy.getByTestSubj('artifacts-assign-flyout').should('exist');
|
||||
cy.getByTestSubj('artifacts-assign-cancel-button').click();
|
||||
|
||||
// Remove from policy
|
||||
cy.getByTestSubj('artifacts-collapsed-list-card-header-actions-button').click();
|
||||
cy.getByTestSubj('remove-from-policy-action').click();
|
||||
cy.getByTestSubj('confirmModalConfirmButton').click();
|
||||
|
||||
cy.contains('Successfully removed');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
|
|
|
@ -35,7 +35,7 @@ const loginWithoutAccess = (url: string) => {
|
|||
loadPage(url);
|
||||
};
|
||||
|
||||
describe('Artifacts pages', () => {
|
||||
describe('Artifacts pages', { tags: '@ess' }, () => {
|
||||
before(() => {
|
||||
login();
|
||||
loadEndpointDataForEventFiltersIfNeeded();
|
||||
|
|
|
@ -18,7 +18,7 @@ import { cleanupRule, generateRandomStringName, loadRule } from '../../../tasks/
|
|||
import { RESPONSE_ACTION_TYPES } from '../../../../../../common/api/detection_engine';
|
||||
import { loginWithRole, ROLE } from '../../../tasks/login';
|
||||
|
||||
describe('Form', () => {
|
||||
describe('Form', { tags: '@ess' }, () => {
|
||||
describe('User with no access can not create an endpoint response action', () => {
|
||||
before(() => {
|
||||
loginWithRole(ROLE.endpoint_response_actions_no_access);
|
||||
|
|
|
@ -12,7 +12,7 @@ import { indexEndpointRuleAlerts } from '../../../tasks/index_endpoint_rule_aler
|
|||
|
||||
import { login, ROLE } from '../../../tasks/login';
|
||||
|
||||
describe('Response actions history page', () => {
|
||||
describe('Response actions history page', { tags: '@ess' }, () => {
|
||||
let endpointData: ReturnTypeFromChainable<typeof indexEndpointHosts> | undefined;
|
||||
let endpointDataWithAutomated: ReturnTypeFromChainable<typeof indexEndpointHosts> | undefined;
|
||||
let alertData: ReturnTypeFromChainable<typeof indexEndpointRuleAlerts> | undefined;
|
||||
|
|
|
@ -15,7 +15,7 @@ import type { ReturnTypeFromChainable } from '../../../types';
|
|||
import { indexEndpointHosts } from '../../../tasks/index_endpoint_hosts';
|
||||
import { indexEndpointRuleAlerts } from '../../../tasks/index_endpoint_rule_alerts';
|
||||
|
||||
describe('No License', { env: { ftrConfig: { license: 'basic' } } }, () => {
|
||||
describe('No License', { tags: '@ess', env: { ftrConfig: { license: 'basic' } } }, () => {
|
||||
describe('User cannot use endpoint action in form', () => {
|
||||
const [ruleName, ruleDescription] = generateRandomStringName(2);
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import { indexEndpointRuleAlerts } from '../../../tasks/index_endpoint_rule_aler
|
|||
|
||||
import { login, ROLE } from '../../../tasks/login';
|
||||
|
||||
describe('Results', () => {
|
||||
describe('Results', { tags: '@ess' }, () => {
|
||||
let endpointData: ReturnTypeFromChainable<typeof indexEndpointHosts> | undefined;
|
||||
let alertData: ReturnTypeFromChainable<typeof indexEndpointRuleAlerts> | undefined;
|
||||
const [endpointAgentId, endpointHostname] = generateRandomStringName(2);
|
||||
|
|
|
@ -9,7 +9,7 @@ import { closeAllToasts } from '../../tasks/toasts';
|
|||
import { login } from '../../tasks/login';
|
||||
import { loadPage } from '../../tasks/common';
|
||||
|
||||
describe('When defining a kibana role for Endpoint security access', () => {
|
||||
describe('When defining a kibana role for Endpoint security access', { tags: '@ess' }, () => {
|
||||
const getAllSubFeatureRows = (): Cypress.Chainable<JQuery<HTMLElement>> => {
|
||||
return cy
|
||||
.get('#featurePrivilegeControls_siem')
|
||||
|
|
|
@ -13,7 +13,7 @@ import { indexEndpointHosts } from '../../tasks/index_endpoint_hosts';
|
|||
import { login } from '../../tasks/login';
|
||||
import { loadPage } from '../../tasks/common';
|
||||
|
||||
describe('Endpoints page', () => {
|
||||
describe('Endpoints page', { tags: '@ess' }, () => {
|
||||
let endpointData: ReturnTypeFromChainable<typeof indexEndpointHosts>;
|
||||
|
||||
before(() => {
|
||||
|
|
|
@ -29,7 +29,7 @@ import { indexNewCase } from '../../tasks/index_new_case';
|
|||
import { indexEndpointHosts } from '../../tasks/index_endpoint_hosts';
|
||||
import { indexEndpointRuleAlerts } from '../../tasks/index_endpoint_rule_alerts';
|
||||
|
||||
describe('Isolate command', () => {
|
||||
describe('Isolate command', { tags: '@ess' }, () => {
|
||||
describe('from Manage', () => {
|
||||
let endpointData: ReturnTypeFromChainable<typeof indexEndpointHosts> | undefined;
|
||||
let isolatedEndpointData: ReturnTypeFromChainable<typeof indexEndpointHosts> | undefined;
|
||||
|
@ -165,6 +165,7 @@ describe('Isolate command', () => {
|
|||
cy.contains(`Isolation on host ${hostname} successfully submitted`);
|
||||
|
||||
cy.getByTestSubj('euiFlyoutCloseButton').click();
|
||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||
cy.wait(1000);
|
||||
openAlertDetails();
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ import type { CyIndexEndpointHosts } from '../../tasks/index_endpoint_hosts';
|
|||
import { indexEndpointHosts } from '../../tasks/index_endpoint_hosts';
|
||||
import { login } from '../../tasks/login';
|
||||
|
||||
describe('Policy Details', () => {
|
||||
describe('Policy Details', { tags: ['@ess', '@serverless'] }, () => {
|
||||
const packagePolicyBackupHelper = new PackagePolicyBackupHelper();
|
||||
let indexedHostsData: CyIndexEndpointHosts;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import { navigateToFleetAgentDetails } from '../../screens/fleet';
|
|||
import { EndpointPolicyResponseGenerator } from '../../../../../common/endpoint/data_generators/endpoint_policy_response_generator';
|
||||
import { descriptions } from '../../../components/policy_response/policy_response_friendly_names';
|
||||
|
||||
describe.skip('Endpoint Policy Response', () => {
|
||||
describe.skip('Endpoint Policy Response', { tags: '@ess' }, () => {
|
||||
let loadedEndpoint: CyIndexEndpointHosts;
|
||||
let endpointMetadata: HostMetadata;
|
||||
let loadedPolicyResponse: IndexedEndpointPolicyResponse;
|
||||
|
|
|
@ -10,7 +10,7 @@ import { indexEndpointHosts } from '../../tasks/index_endpoint_hosts';
|
|||
import { login } from '../../tasks/login';
|
||||
import { loadPage } from '../../tasks/common';
|
||||
|
||||
describe('Response actions history page', () => {
|
||||
describe('Response actions history page', { tags: '@ess' }, () => {
|
||||
let endpointData: ReturnTypeFromChainable<typeof indexEndpointHosts>;
|
||||
// let actionData: ReturnTypeFromChainable<typeof indexActionResponses>;
|
||||
|
||||
|
@ -54,16 +54,16 @@ describe('Response actions history page', () => {
|
|||
it('collapses expanded tray with a single click', () => {
|
||||
loadPage(`/app/security/administration/response_actions_history`);
|
||||
// 2nd row on 1st page
|
||||
const row = cy.getByTestSubj('response-actions-list-expand-button').eq(1);
|
||||
cy.getByTestSubj('response-actions-list-expand-button').eq(1).as('2nd-row');
|
||||
|
||||
// expand the row
|
||||
row.click();
|
||||
cy.get('@2nd-row').click();
|
||||
cy.getByTestSubj('response-actions-list-details-tray').should('exist');
|
||||
cy.url().should('include', 'withOutputs');
|
||||
|
||||
// collapse the row
|
||||
cy.intercept('GET', '/api/endpoint/action*').as('getResponses');
|
||||
row.click();
|
||||
cy.get('@2nd-row').click();
|
||||
// wait for the API response to come back
|
||||
// and then see if the tray is actually closed
|
||||
cy.wait('@getResponses', { timeout: 500 }).then(() => {
|
||||
|
|
|
@ -21,7 +21,7 @@ import { indexNewCase } from '../../tasks/index_new_case';
|
|||
import { indexEndpointHosts } from '../../tasks/index_endpoint_hosts';
|
||||
import { indexEndpointRuleAlerts } from '../../tasks/index_endpoint_rule_alerts';
|
||||
|
||||
describe('When accessing Endpoint Response Console', () => {
|
||||
describe('When accessing Endpoint Response Console', { tags: '@ess' }, () => {
|
||||
const performResponderSanityChecks = () => {
|
||||
openResponderActionLogFlyout();
|
||||
// Ensure the popover in the action log date quick select picker is accessible
|
||||
|
|
|
@ -24,7 +24,7 @@ import {
|
|||
} from '../../tasks/isolate';
|
||||
import { login } from '../../tasks/login';
|
||||
|
||||
describe('Response console', () => {
|
||||
describe('Response console', { tags: '@ess' }, () => {
|
||||
beforeEach(() => {
|
||||
login();
|
||||
});
|
||||
|
|
|
@ -13,7 +13,8 @@ export const navigateToAlertsList = (urlQueryParams: string = '') => {
|
|||
};
|
||||
|
||||
export const clickAlertListRefreshButton = (): Cypress.Chainable => {
|
||||
return cy.getByTestSubj('querySubmitButton').click().should('be.enabled');
|
||||
cy.getByTestSubj('querySubmitButton').click();
|
||||
return cy.getByTestSubj('querySubmitButton').should('be.enabled');
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,11 +24,13 @@
|
|||
|
||||
import { subj as testSubjSelector } from '@kbn/test-subj-selector';
|
||||
|
||||
// force ESM in this module
|
||||
export {};
|
||||
|
||||
import 'cypress-react-selector';
|
||||
|
||||
// @ts-ignore
|
||||
import registerCypressGrep from '@cypress/grep';
|
||||
|
||||
registerCypressGrep();
|
||||
|
||||
Cypress.Commands.addQuery<'getByTestSubj'>(
|
||||
'getByTestSubj',
|
||||
function getByTestSubj(selector, options) {
|
||||
|
|
|
@ -181,7 +181,7 @@ export const getEndpointDetectionAlertsQueryForAgentId = (endpointAgentId: strin
|
|||
|
||||
export const changeAlertsFilter = (text: string) => {
|
||||
cy.getByTestSubj('filters-global-container').within(() => {
|
||||
cy.getByTestSubj('queryInput').click().type(text);
|
||||
cy.getByTestSubj('queryInput').type(text);
|
||||
cy.getByTestSubj('querySubmitButton').click();
|
||||
});
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@ export const API_AUTH = Object.freeze({
|
|||
export const COMMON_API_HEADERS = Object.freeze({
|
||||
'kbn-xsrf': 'cypress',
|
||||
'x-elastic-internal-origin': 'security-solution',
|
||||
'Elastic-Api-Version': '2023-10-31',
|
||||
});
|
||||
|
||||
export const waitForPageToBeLoaded = () => {
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
/* eslint-disable cypress/no-unnecessary-waiting */
|
||||
|
||||
import type { ActionDetails } from '../../../../common/endpoint/types';
|
||||
import { loadPage } from './common';
|
||||
|
||||
|
@ -114,7 +116,7 @@ export const filterOutEndpoints = (endpointHostname: string): void => {
|
|||
};
|
||||
|
||||
export const filterOutIsolatedHosts = (): void => {
|
||||
cy.getByTestSubj('adminSearchBar').click().type('united.endpoint.Endpoint.state.isolation: true');
|
||||
cy.getByTestSubj('adminSearchBar').type('united.endpoint.Endpoint.state.isolation: true');
|
||||
cy.getByTestSubj('querySubmitButton').click();
|
||||
};
|
||||
|
||||
|
|
|
@ -84,9 +84,6 @@ export const waitForActionToComplete = (
|
|||
return request<ActionDetailsApiResponse>({
|
||||
method: 'GET',
|
||||
url: resolvePathVariables(ACTION_DETAILS_ROUTE, { action_id: actionId || 'undefined' }),
|
||||
headers: {
|
||||
'Elastic-Api-Version': '2023-10-31',
|
||||
},
|
||||
}).then((response) => {
|
||||
if (response.body.data.isCompleted) {
|
||||
action = response.body.data;
|
||||
|
|
|
@ -22,13 +22,11 @@ export const openResponseConsoleFromEndpointList = (): void => {
|
|||
};
|
||||
|
||||
export const inputConsoleCommand = (command: string): void => {
|
||||
cy.getByTestSubj('endpointResponseActionsConsole-inputCapture').click().type(command);
|
||||
cy.getByTestSubj('endpointResponseActionsConsole-inputCapture').type(command);
|
||||
};
|
||||
|
||||
export const clearConsoleCommandInput = (): void => {
|
||||
cy.getByTestSubj('endpointResponseActionsConsole-inputCapture')
|
||||
.click()
|
||||
.type(`{selectall}{backspace}`);
|
||||
cy.getByTestSubj('endpointResponseActionsConsole-inputCapture').type(`{selectall}{backspace}`);
|
||||
};
|
||||
|
||||
export const selectCommandFromHelpMenu = (command: string): void => {
|
||||
|
|
|
@ -6,8 +6,13 @@
|
|||
*/
|
||||
|
||||
export const runEndpointLoaderScript = () => {
|
||||
const { ELASTICSEARCH_USERNAME, ELASTICSEARCH_PASSWORD, ELASTICSEARCH_URL, KIBANA_URL } =
|
||||
Cypress.env();
|
||||
const {
|
||||
ELASTICSEARCH_USERNAME,
|
||||
ELASTICSEARCH_PASSWORD,
|
||||
ELASTICSEARCH_URL,
|
||||
KIBANA_URL,
|
||||
IS_SERVERLESS,
|
||||
} = Cypress.env();
|
||||
|
||||
const ES_URL = new URL(ELASTICSEARCH_URL);
|
||||
ES_URL.username = ELASTICSEARCH_USERNAME;
|
||||
|
@ -16,8 +21,23 @@ export const runEndpointLoaderScript = () => {
|
|||
const KBN_URL = new URL(KIBANA_URL);
|
||||
KBN_URL.username = ELASTICSEARCH_USERNAME;
|
||||
KBN_URL.password = ELASTICSEARCH_PASSWORD;
|
||||
|
||||
// FIXME: remove use of cli script and use instead data loaders
|
||||
const script = `node scripts/endpoint/resolver_generator.js --node="${ES_URL.toString()}" --kibana="${KBN_URL.toString()}" --delete --numHosts=1 --numDocs=1 --fleet --withNewUser=santaEndpoint:changeme --anc=1 --gen=1 --ch=1 --related=1 --relAlerts=1`;
|
||||
const script =
|
||||
`node scripts/endpoint/resolver_generator.js ` +
|
||||
`--node="${ES_URL.toString()}" ` +
|
||||
`--kibana="${KBN_URL.toString()}" ` +
|
||||
`--delete ` +
|
||||
`--numHosts=1 ` +
|
||||
`--numDocs=1 ` +
|
||||
`--fleet ` +
|
||||
`--withNewUser=santaEndpoint:changeme ` +
|
||||
`--anc=1 ` +
|
||||
`--gen=1 ` +
|
||||
`--ch=1 ` +
|
||||
`--related=1 ` +
|
||||
`--relAlerts=1 ` +
|
||||
`--ssl=${IS_SERVERLESS}`;
|
||||
|
||||
cy.exec(script, { env: { NODE_TLS_REJECT_UNAUTHORIZED: 1 }, timeout: 180000 });
|
||||
};
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
"extends": "../../../../../../tsconfig.base.json",
|
||||
"include": [
|
||||
"**/*",
|
||||
"../cypress_endpoint.config.ts",
|
||||
"../cypress.config.ts",
|
||||
"./cypress.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*"
|
||||
|
|
|
@ -1,62 +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';
|
||||
// eslint-disable-next-line @kbn/imports/no_boundary_crossing
|
||||
import { dataLoaders, dataLoadersForRealEndpoints } from './cypress/support/data_loaders';
|
||||
// eslint-disable-next-line @kbn/imports/no_boundary_crossing
|
||||
import { responseActionTasks } from './cypress/support/response_actions';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default defineCypressConfig({
|
||||
reporter: '../../../../node_modules/cypress-multi-reporters',
|
||||
reporterOptions: {
|
||||
configFile: './public/management/reporter_config.json',
|
||||
},
|
||||
|
||||
defaultCommandTimeout: 60000,
|
||||
execTimeout: 120000,
|
||||
pageLoadTimeout: 12000,
|
||||
|
||||
retries: {
|
||||
runMode: 1,
|
||||
openMode: 0,
|
||||
},
|
||||
|
||||
screenshotsFolder:
|
||||
'../../../target/kibana-security-solution/public/management/cypress/screenshots',
|
||||
trashAssetsBeforeRuns: false,
|
||||
video: false,
|
||||
viewportHeight: 900,
|
||||
viewportWidth: 1440,
|
||||
experimentalStudio: true,
|
||||
|
||||
env: {
|
||||
'cypress-react-selector': {
|
||||
root: '#security-solution-app',
|
||||
},
|
||||
KIBANA_USERNAME: 'system_indices_superuser',
|
||||
KIBANA_PASSWORD: 'changeme',
|
||||
ELASTICSEARCH_USERNAME: 'system_indices_superuser',
|
||||
ELASTICSEARCH_PASSWORD: 'changeme',
|
||||
},
|
||||
|
||||
e2e: {
|
||||
experimentalMemoryManagement: true,
|
||||
experimentalInteractiveRunEvents: true,
|
||||
baseUrl: 'http://localhost:5620',
|
||||
supportFile: 'public/management/cypress/support/e2e.ts',
|
||||
specPattern: 'public/management/cypress/e2e/endpoint/*.cy.{js,jsx,ts,tsx}',
|
||||
experimentalRunAllSpecs: true,
|
||||
setupNodeEvents: (on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) => {
|
||||
dataLoaders(on, config);
|
||||
// Data loaders specific to "real" Endpoint testing
|
||||
dataLoadersForRealEndpoints(on, config);
|
||||
responseActionTasks(on, config);
|
||||
},
|
||||
},
|
||||
});
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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 { getLocalhostRealIp } from '@kbn/security-solution-plugin/scripts/endpoint/common/localhost_services';
|
||||
import { FtrConfigProviderContext } from '@kbn/test';
|
||||
|
||||
import { ExperimentalFeatures } from '@kbn/security-solution-plugin/common/experimental_features';
|
||||
import { DefendWorkflowsCypressCliTestRunner } from './runner';
|
||||
|
||||
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
||||
const defendWorkflowsCypressConfig = await readConfigFile(require.resolve('./config.ts'));
|
||||
const svlSharedConfig = await readConfigFile(
|
||||
require.resolve('../../test_serverless/shared/config.base.ts')
|
||||
);
|
||||
|
||||
const hostIp = getLocalhostRealIp();
|
||||
|
||||
const enabledFeatureFlags: Array<keyof ExperimentalFeatures> = [];
|
||||
|
||||
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
|
||||
],
|
||||
},
|
||||
servers: {
|
||||
...svlSharedConfig.get('servers'),
|
||||
fleetserver: {
|
||||
protocol: 'https',
|
||||
hostname: hostIp,
|
||||
port: 8220,
|
||||
},
|
||||
},
|
||||
kbnTestServer: {
|
||||
...svlSharedConfig.get('kbnTestServer'),
|
||||
serverArgs: [
|
||||
...svlSharedConfig.get('kbnTestServer.serverArgs'),
|
||||
'--csp.strict=false',
|
||||
'--csp.warnLegacyBrowsers=false',
|
||||
'--serverless=security',
|
||||
'--xpack.encryptedSavedObjects.encryptionKey="abcdefghijklmnopqrstuvwxyz123456"',
|
||||
|
||||
'--xpack.security.enabled=true',
|
||||
`--xpack.fleet.agents.fleet_server.hosts=["https://${hostIp}:8220"]`,
|
||||
`--xpack.fleet.agents.elasticsearch.host=http://${hostIp}:${defendWorkflowsCypressConfig.get(
|
||||
'servers.elasticsearch.port'
|
||||
)}`,
|
||||
|
||||
// set the packagerTaskInterval to 5s in order to speed up test executions when checking fleet artifacts
|
||||
'--xpack.securitySolution.packagerTaskInterval=5s',
|
||||
|
||||
`--xpack.securitySolution.enableExperimental=${JSON.stringify(enabledFeatureFlags)}`,
|
||||
],
|
||||
},
|
||||
testRunner: DefendWorkflowsCypressCliTestRunner,
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue