Skip to content

Commit

Permalink
[Security Solution] Cypress documentation updates (elastic#86835)
Browse files Browse the repository at this point in the history
* Update/refactor some cypress documentation

* Fixes some whitespace/grammar/typos
* Condenses the explanation/instructions for the different modes of
  execution

* Condense Artifacts section

This is a big sprawling file; trying to cut down on the noise.

* Move test-running section to top of README

This is going to be what 90% of readers are looking for, methinks.

* Adds Security Solution's cypress suite to x-pack testing README

* Fix broken link

This file was moved as part of elastic#64368.

* Remove broken link

This file was deleted in elastic#67138.

* Apply suggestions from code review

Co-authored-by: Devin W. Hurley <snowmiser111@gmail.com>

* Fix typo

Co-authored-by: Devin W. Hurley <snowmiser111@gmail.com>
  • Loading branch information
rylnd and dhurley14 committed Jan 5, 2021
1 parent 4856675 commit 5a8c5d0
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 160 deletions.
7 changes: 4 additions & 3 deletions x-pack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ Jest integration tests can be used to test behavior with Elasticsearch and the K
yarn test:jest_integration
```

An example test exists at [test_utils/jest/integration_tests/example_integration.test.ts](test_utils/jest/integration_tests/example_integration.test.ts)

#### Running Reporting functional tests

See [here](test/reporting/README.md) for more information on running reporting tests.
See [here](./test/functional/apps/dashboard/reporting/README.md) for more information on running reporting tests.

#### Running Security Solution Cypress E2E/integration tests
See [here](./plugins/security_solution/cypress/README.md) for information on running this test suite.
272 changes: 115 additions & 157 deletions x-pack/plugins/security_solution/cypress/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,190 +2,177 @@

The `security_solution/cypress` directory contains functional UI tests that execute using [Cypress](https://www.cypress.io/).

## Folder Structure
## Running the tests

### Fixtures (Cypress native folder)
There are currently four ways to run the tests, comprised of two execution modes and two target environments, which will be detailed below.

Fixtures are used as external pieces of static data when we stub responses.
### Execution modes

### Integration (Cypress native folder)
#### Interactive mode

Contains the specs that are going to be executed.
When you run Cypress in interactive mode, an interactive runner is displayed that allows you to see commands as they execute while also viewing the application under test. For more information, please see [cypress documentation](https://docs.cypress.io/guides/core-concepts/test-runner.html#Overview).

### Objects
#### Headless mode

Objects are a representation of data used accross different tests.
A headless browser is a browser simulation program that does not have a user interface. These programs operate like any other browser, but do not display any UI. This is why meanwhile you are executing the tests on this mode you are not going to see the application under test. Just the output of the test is displayed on the terminal once the execution is finished.

### Pluggins (Cypress native folder)
### Target environments

By default Cypress will automatically include the plugins file cypress/plugins/index.js before every single spec file it runs. They do this purely as a convenience mechanism so you don’t have to import this that in every single one of your spec files.
#### FTR (CI)

### Screens
This is the configuration used by CI. It uses the FTR to spawn both a Kibana instance (http://localhost:5620) and an Elasticsearch instance (http://localhost:9220) with a preloaded minimum set of data (see preceding "Test data" section), and then executes cypress against this stack. You can find this configuration in `x-pack/test/security_solution_cypress`

In _screens_ folder we are going to find all the elements we want to interact in our tests.
#### Custom Targets

Each file inside the tasks folder represents a screen of our application. When the screens are complex i.e. Hosts contains multiple tabs, the page is represented by a folder and the different important parts are represented by files.
This configuration runs cypress tests against an arbitrary host.
**WARNING**: When using your own instances you need to take into account that if you already have data on it, the tests may fail, as well as, they can put your instances in an undesired state, since our tests uses es_archive to populate data.

i.e.
- tasks
- hosts
- all_hosts.ts
- authentications.ts
- events.ts
- main.ts
- uncommon_processes.ts

### Tasks
### Test Execution: Examples

_Tasks_ are functions that my be re-used across tests.
#### FTR + Headless

Each file inside the tasks folder represents a screen of our application. When the screens are complex i.e. Hosts contains multiple tabs, the page is represented by a folder and the different important parts are represented by files.
Since this is how tests are run on CI, this will likely be the configuration you want to reproduce failures locally, etc.

i.e.
- tasks
- hosts
- all_hosts.ts
- authentications.ts
- events.ts
- main.ts
- uncommon_processes.ts

### URLs

Represents all the URLs used during the tests execution.

## Test data
```shell
# bootstrap kibana from the project root
yarn kbn bootstrap

The data the tests need:
- Is generated on the fly using our application APIs (preferred way)
- Is ingested on the ELS instance using es_archive
# build the plugins/assets that cypress will execute against
node scripts/build_kibana_platform_plugins

By default when running the tests on Jenkins mode a base set of data is ingested on the ELS instance: an empty kibana index and a set of auditbeat data (the `empty_kibana` and `auditbeat` archives, respectively). This is usually enough to cover most of the scenarios that we are testing.
# launch the cypress test runner
cd x-pack/plugins/security_solution
yarn cypress:run-as-ci
```

### How to generate a new archive
#### FTR + Interactive

We are using es_archiver in order to manage the data that our Cypress tests needs.
This is the preferred mode for developing new tests.

1. Setup if possible a clean instance of kibana and elasticsearch (if not, possible please try to clean the data that you are going to generate).
2. With the kibana and elasticsearch instance up and running, create the data that you need for your test.
3. When you are sure that you have all the data you need run the following command from: `x-pack/plugins/security_solution`
```shell
# bootstrap kibana from the project root
yarn kbn bootstrap

```sh
node ../../../scripts/es_archiver save <nameOfTheFolderWhereDataIsSaved> <indexPatternsToBeSaved> --dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url http://<elasticsearchUsername>:<elasticsearchPassword>@<elasticsearchHost>:<elasticsearchPort>
```
# build the plugins/assets that cypress will execute against
node scripts/build_kibana_platform_plugins

Example:
```sh
node ../../../scripts/es_archiver save custom_rules ".kibana",".siem-signal*" --dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url http://elastic:changeme@localhost:9220
# launch the cypress test runner
cd x-pack/plugins/security_solution
yarn cypress:open-as-ci
```

Note that the command is going to create the folder if does not exist in the directory with the imported data.
#### Custom Target + Headless

## Running the tests
This mode may be useful for testing a release, e.g. spin up a build candidate
and point cypress at it to catch regressions.

You can run the tests in interactive or headless mode, emulating the Jenkins pipeline or using your own instances.
```shell
# bootstrap kibana from the project root
yarn kbn bootstrap

### Interactive vs Headless mode
# load auditbeat data needed for test execution (which FTR normally does for us)
cd x-pack/plugins/security_solution
node ../../../scripts/es_archiver load auditbeat --dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url http(s)://<username>:<password>@<elsUrl> --kibana-url http(s)://<userName>:<password>@<kbnUrl>

#### Interactive
# launch the cypress test runner with overridden environment variables
cd x-pack/plugins/security_solution
CYPRESS_BASE_URL=http(s)://<username>:<password>@<kbnUrl> CYPRESS_ELASTICSEARCH_URL=http(s)://<username>:<password>@<elsUrl> CYPRESS_ELASTICSEARCH_USERNAME=<username> CYPRESS_ELASTICSEARCH_PASSWORD=password yarn cypress:run
```

When you run the Cypress on interactive mode, an interactive runner is displayed that allows you to see commands as they execute while also viewing the application under test.
## Folder Structure

For more information, please visit: https://docs.cypress.io/guides/core-concepts/test-runner.html#Overview
### integration/

#### Headless mode
Cypress convention. Contains the specs that are going to be executed.

A headless browser is a browser simulation program that does not have a user interface. These programs operate like any other browser, but do not display any UI. This is why meanwhile you are executing the tests on this mode you are not going to see the application under test. Just the output of the test is displayed on the terminal once the execution is finished.
### fixtures/

### Emulating Jenkins vs your own instances
Cypress convention. Fixtures are used as external pieces of static data when we stub responses.

#### Emulating Jenkins
### plugins/

With this mode we use the FTR to run the Cypress tests and automatically, a Kibana instance (http://localhost:5620) and Elastic Search instance (http://localhost:9220) with a preloaded minimum set of data.
Cypress convention. As a convenience, by default Cypress will automatically include the plugins file cypress/plugins/index.js before every single spec file it runs.

You can find the configuration of this mode in `x-pack/test/security_solution_cypress`
### objects/

#### Your own instances
Contains representations of data used across different tests; our domain objects.

When using your own instances you need to take into account that if you already have data on it, the tests may fail, as well as, they can put your instances in an undesired state, since our tests uses es_archive to populate data.
### screens/

Contains the elements we want to interact with in our tests.

### Running Cypress in Headless mode as a Jenkins execution (The preferred way when running regressions on your machine)
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.

1. First bootstrap kibana changes from the Kibana root directory:
Example:

```sh
yarn kbn bootstrap
```
- screens
- hosts
- all_hosts.ts
- authentications.ts
- events.ts
- main.ts
- uncommon_processes.ts

2. Build the plugins
### tasks/

```sh
node scripts/build_kibana_platform_plugins
```
_Tasks_ are functions that may be reused across tests.

3. Launch Cypress command line test runner:
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.

```sh
cd x-pack/plugins/security_solution
yarn cypress:run-as-ci
```
Example:

As explained previously, this type of execution you don't need to have running a kibana and elasticsearch instance. This is because the command, as it would happen in the CI, will launch the instances. The elasticsearch instance will be fed data found in: `x-pack/test/security_solution_cypress/es_archives`

### Running Cypress in Interactive mode as a Jenkins execution (The preferred way when developing new cypress tests)
- tasks
- hosts
- all_hosts.ts
- authentications.ts
- events.ts
- main.ts
- uncommon_processes.ts

1. First bootstrap kibana changes from the Kibana root directory:
### urls/

```sh
yarn kbn bootstrap
```
Represents all the URLs used during the tests execution.

2. Build the plugins
## Test data

```sh
node scripts/build_kibana_platform_plugins
```
The data the tests need:

3. Launch Cypress command line test runner:
- Is generated on the fly using our application APIs (preferred way)
- Is ingested on the ELS instance using the `es_archive` utility

```sh
cd x-pack/plugins/security_solution
yarn cypress:open-as-ci
```
By default, when running the tests in Jenkins mode, a base set of data is ingested on the ELS instance: an empty kibana index and a set of auditbeat data (the `empty_kibana` and `auditbeat` archives, respectively). This is usually enough to cover most of the scenarios that we are testing.

As explained previously, this type of execution you don't need to have running a kibana and elasticsearch instance. This is because the command, as it would happen in the CI, will launch the instances. The elasticsearch instance will be fed data found in: `x-pack/test/security_solution_cypress/es_archives`

### Running Cypress in your own instances (Recommended just for releases regressions)
### How to generate a new archive

1. First bootstrap kibana changes from the Kibana root directory:
**Note:** As mentioned above, archives are only meant to contain external data, e.g. beats data. Due to the tendency for archived domain objects (rules, signals) to quickly become out of date, it is strongly suggested that you generate this data within the test, through interaction with either the UI or the API.

```sh
yarn kbn bootstrap
```
We use es_archiver to manage the data that our Cypress tests need.

2. Load the initial auditbeat set of data needed for the test execution:
1. Set up a clean instance of kibana and elasticsearch (if this is not possible, try to clean/minimize the data that you are going to archive).
2. With the kibana and elasticsearch instance up and running, create the data that you need for your test.
3. When you are sure that you have all the data you need run the following command from: `x-pack/plugins/security_solution`

```sh
cd x-pack/plugins/security_solution
node ../../../scripts/es_archiver load auditbeat --dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url http(s)://<username>:<password>@<elsUrl> --kibana-url http(s)://<userName>:<password>@<kbnUrl>
node ../../../scripts/es_archiver save <nameOfTheFolderWhereDataIsSaved> <indexPatternsToBeSaved> --dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url http://<elasticsearchUsername>:<elasticsearchPassword>@<elasticsearchHost>:<elasticsearchPort>
```

3. Launch Cypress overriden some of the environment variables:
Example:

```sh
CYPRESS_BASE_URL=http(s)://<username>:<password>@<kbnUrl> CYPRESS_ELASTICSEARCH_URL=http(s)://<username>:<password>@<elsUrl> CYPRESS_ELASTICSEARCH_USERNAME=<username> CYPRESS_ELASTICSEARCH_PASSWORD=password yarn cypress:run
node ../../../scripts/es_archiver save custom_rules ".kibana",".siem-signal*" --dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.js --es-url http://elastic:changeme@localhost:9220
```

## Best Practices
Note that the command will create the folder if it does not exist.

## Development Best Practices

### Clean up the state

Remember to use the `cleanKibana` method before starting the execution of the test
Remember to clean up the state of the test after its execution, typically with the `cleanKibana` function. Be mindful of failure scenarios, as well: if your test fails, will it leave the environment in a recoverable state?

### Minimize the use of es_archive

When possible, create all the data that you need for executing the tests using the application APIS.
When possible, create all the data that you need for executing the tests using the application APIS or the UI.

### Speed up test execution time

Expand All @@ -194,54 +181,25 @@ taken into consideration until another solution is implemented:

- Group the tests that are similar in different contexts.
- For every context login only once, clean the state between tests if needed without re-loading the page.
- All tests in a spec file must be order-independent.

Remember that minimizing the number of times the web page is loaded, we minimize as well the execution time.

## Reporting

When Cypress tests are run on the command line via non visual mode
reporting artifacts are generated under the `target` directory in the root
of the Kibana, as detailed for each artifact type in the sections below.

### HTML Reports

An HTML report (e.g. for email notifications) is output to:

```
target/kibana-security-solution/cypress/results/output.html
```
- All tests in a spec file must be order-independent.

### Screenshots

Screenshots of failed tests are output to:

```
target/kibana-security-solution/cypress/screenshots
```

### `junit` Reports

The Kibana CI process reports `junit` test results from the `target/junit` directory.

Cypress `junit` reports are generated in `target/kibana-security-solution/cypress/results`
and copied to the `target/junit` directory.

### Videos (optional)
Remember that minimizing the number of times the web page is loaded, we minimize as well the execution time.

Videos are disabled by default, but can optionally be enabled by setting the
`CYPRESS_video=true` environment variable:
## Test Artifacts

```
CYPRESS_video=true yarn cypress:run
```
When Cypress tests are run headless on the command line, artifacts
are generated under the `target` directory in the root of Kibana as follows:

Videos are (optionally) output to:

```
target/kibana-security-solution/cypress/videos
```
- HTML Reports
- location: `target/kibana-security-solution/cypress/results/output.html`
- `junit` Reports
- location: `target/kibana-security-solution/cypress/results`
- Screenshots (of failed tests)
- location: `target/kibana-security-solution/cypress/screenshots`
- Videos
- disabled by default, can be enabled by setting env var `CYPRESS_video=true`
- location: `target/kibana-security-solution/cypress/videos`

## Linting
## Linting

Optional linting rules for Cypress and linting setup can be found [here](https://github.com/cypress-io/eslint-plugin-cypress#usage)

0 comments on commit 5a8c5d0

Please sign in to comment.