mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
* updates events viewer test * updates login tasks * updates ml conditional links * updates url state * updates timeline screen * updates timeline tasks * updates test files * adds jenkins needed files * ignoring isAttached lines due to a known error in Cypress (https://github.com/cypress-io/cypress/issues/4408) * updates loop script * updates readme with new cypress command explanation * removes skip Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
0918c85ad8
commit
30d763accf
20 changed files with 4210 additions and 64 deletions
21
test/scripts/jenkins_siem_cypress.sh
Normal file
21
test/scripts/jenkins_siem_cypress.sh
Normal file
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source test/scripts/jenkins_test_setup.sh
|
||||
|
||||
installDir="$PARENT_DIR/install/kibana"
|
||||
destDir="${installDir}-${CI_WORKER_NUMBER}"
|
||||
cp -R "$installDir" "$destDir"
|
||||
|
||||
export KIBANA_INSTALL_DIR="$destDir"
|
||||
|
||||
echo " -> Running SIEM cypress tests"
|
||||
cd "$XPACK_DIR"
|
||||
|
||||
checks-reporter-with-killswitch "SIEM Cypress Tests" \
|
||||
node scripts/functional_tests \
|
||||
--debug --bail \
|
||||
--kibana-install-dir "$KIBANA_INSTALL_DIR" \
|
||||
--config test/siem_cypress/config.ts
|
||||
|
||||
echo ""
|
||||
echo ""
|
|
@ -210,6 +210,30 @@ cd x-pack/legacy/plugins/siem
|
|||
CYPRESS_baseUrl=http://localhost:5601 CYPRESS_ELASTICSEARCH_USERNAME=elastic CYPRESS_ELASTICSEARCH_PASSWORD=<password> yarn cypress:run
|
||||
```
|
||||
|
||||
## Running (Headless) Tests on the Command Line as a Jenkins execution
|
||||
|
||||
To run (headless) tests as a Jenkins execution.
|
||||
|
||||
1. First bootstrap kibana changes from the Kibana root directory:
|
||||
|
||||
```sh
|
||||
yarn kbn bootstrap
|
||||
```
|
||||
|
||||
2. Launch Cypress command line test runner:
|
||||
|
||||
```sh
|
||||
cd x-pack/legacy/plugins/siem
|
||||
yarn cypress:run-as-ci
|
||||
```
|
||||
|
||||
Note that with 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 with the data
|
||||
placed in: `x-pack/test/siem_cypress/es_archives`.
|
||||
|
||||
As in this case we want to mimic a CI execution we want to execute the tests with the same set of data, this is why
|
||||
in this case does not make sense to override Cypress environment variables.
|
||||
|
||||
## Reporting
|
||||
|
||||
When Cypress tests are run on the command line via `yarn cypress:run`,
|
||||
|
|
|
@ -134,7 +134,7 @@ describe('Events Viewer', () => {
|
|||
});
|
||||
|
||||
it('filters the events by applying filter criteria from the search bar at the top of the page', () => {
|
||||
const filterInput = '4bf34c1c-eaa9-46de-8921-67a4ccc49829'; // this will never match real data
|
||||
const filterInput = 'aa7ca589f1b8220002f2fc61c64cfbf1'; // this will never match real data
|
||||
cy.get(HEADER_SUBTITLE)
|
||||
.invoke('text')
|
||||
.then(initialNumberOfEvents => {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { KQL_INPUT } from '../screens/siem_header';
|
||||
|
||||
import { loginAndWaitForPage } from '../tasks/login';
|
||||
import { loginAndWaitForPageWithoutDateRange } from '../tasks/login';
|
||||
|
||||
import {
|
||||
mlHostMultiHostKqlQuery,
|
||||
|
@ -26,7 +26,7 @@ import {
|
|||
|
||||
describe('ml conditional links', () => {
|
||||
it('sets the KQL from a single IP with a value for the query', () => {
|
||||
loginAndWaitForPage(mlNetworkSingleIpKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlNetworkSingleIpKqlQuery);
|
||||
cy.get(KQL_INPUT).should(
|
||||
'have.attr',
|
||||
'value',
|
||||
|
@ -35,7 +35,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('sets the KQL from a multiple IPs with a null for the query', () => {
|
||||
loginAndWaitForPage(mlNetworkMultipleIpNullKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlNetworkMultipleIpNullKqlQuery);
|
||||
cy.get(KQL_INPUT).should(
|
||||
'have.attr',
|
||||
'value',
|
||||
|
@ -44,7 +44,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('sets the KQL from a multiple IPs with a value for the query', () => {
|
||||
loginAndWaitForPage(mlNetworkMultipleIpKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlNetworkMultipleIpKqlQuery);
|
||||
cy.get(KQL_INPUT).should(
|
||||
'have.attr',
|
||||
'value',
|
||||
|
@ -53,7 +53,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('sets the KQL from a $ip$ with a value for the query', () => {
|
||||
loginAndWaitForPage(mlNetworkKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlNetworkKqlQuery);
|
||||
cy.get(KQL_INPUT).should(
|
||||
'have.attr',
|
||||
'value',
|
||||
|
@ -62,7 +62,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('sets the KQL from a single host name with a value for query', () => {
|
||||
loginAndWaitForPage(mlHostSingleHostKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlHostSingleHostKqlQuery);
|
||||
cy.get(KQL_INPUT).should(
|
||||
'have.attr',
|
||||
'value',
|
||||
|
@ -71,7 +71,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('sets the KQL from a multiple host names with null for query', () => {
|
||||
loginAndWaitForPage(mlHostMultiHostNullKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlHostMultiHostNullKqlQuery);
|
||||
cy.get(KQL_INPUT).should(
|
||||
'have.attr',
|
||||
'value',
|
||||
|
@ -80,7 +80,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('sets the KQL from a multiple host names with a value for query', () => {
|
||||
loginAndWaitForPage(mlHostMultiHostKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlHostMultiHostKqlQuery);
|
||||
cy.get(KQL_INPUT).should(
|
||||
'have.attr',
|
||||
'value',
|
||||
|
@ -89,7 +89,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('sets the KQL from a undefined/null host name but with a value for query', () => {
|
||||
loginAndWaitForPage(mlHostVariableHostKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlHostVariableHostKqlQuery);
|
||||
cy.get(KQL_INPUT).should(
|
||||
'have.attr',
|
||||
'value',
|
||||
|
@ -98,7 +98,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('redirects from a single IP with a null for the query', () => {
|
||||
loginAndWaitForPage(mlNetworkSingleIpNullKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlNetworkSingleIpNullKqlQuery);
|
||||
cy.url().should(
|
||||
'include',
|
||||
'/app/siem#/network/ip/127.0.0.1/source?timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))'
|
||||
|
@ -106,7 +106,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('redirects from a single IP with a value for the query', () => {
|
||||
loginAndWaitForPage(mlNetworkSingleIpKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlNetworkSingleIpKqlQuery);
|
||||
cy.url().should(
|
||||
'include',
|
||||
"/app/siem#/network/ip/127.0.0.1/source?query=(language:kuery,query:'(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)')&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))"
|
||||
|
@ -114,7 +114,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('redirects from a multiple IPs with a null for the query', () => {
|
||||
loginAndWaitForPage(mlNetworkMultipleIpNullKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlNetworkMultipleIpNullKqlQuery);
|
||||
cy.url().should(
|
||||
'include',
|
||||
"app/siem#/network/flows?query=(language:kuery,query:'((source.ip:%20%22127.0.0.1%22%20or%20destination.ip:%20%22127.0.0.1%22)%20or%20(source.ip:%20%22127.0.0.2%22%20or%20destination.ip:%20%22127.0.0.2%22))')&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999))"
|
||||
|
@ -122,7 +122,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('redirects from a multiple IPs with a value for the query', () => {
|
||||
loginAndWaitForPage(mlNetworkMultipleIpKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlNetworkMultipleIpKqlQuery);
|
||||
cy.url().should(
|
||||
'include',
|
||||
"/app/siem#/network/flows?query=(language:kuery,query:'((source.ip:%20%22127.0.0.1%22%20or%20destination.ip:%20%22127.0.0.1%22)%20or%20(source.ip:%20%22127.0.0.2%22%20or%20destination.ip:%20%22127.0.0.2%22))%20and%20((process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22))')&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))"
|
||||
|
@ -130,7 +130,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('redirects from a $ip$ with a null query', () => {
|
||||
loginAndWaitForPage(mlNetworkNullKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlNetworkNullKqlQuery);
|
||||
cy.url().should(
|
||||
'include',
|
||||
'/app/siem#/network/flows?timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))'
|
||||
|
@ -138,7 +138,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('redirects from a $ip$ with a value for the query', () => {
|
||||
loginAndWaitForPage(mlNetworkKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlNetworkKqlQuery);
|
||||
cy.url().should(
|
||||
'include',
|
||||
"/app/siem#/network/flows?query=(language:kuery,query:'(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)')&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))"
|
||||
|
@ -146,7 +146,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('redirects from a single host name with a null for the query', () => {
|
||||
loginAndWaitForPage(mlHostSingleHostNullKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlHostSingleHostNullKqlQuery);
|
||||
cy.url().should(
|
||||
'include',
|
||||
'/app/siem#/hosts/siem-windows/anomalies?timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))'
|
||||
|
@ -154,7 +154,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('redirects from a host name with a variable in the query', () => {
|
||||
loginAndWaitForPage(mlHostSingleHostKqlQueryVariable);
|
||||
loginAndWaitForPageWithoutDateRange(mlHostSingleHostKqlQueryVariable);
|
||||
cy.url().should(
|
||||
'include',
|
||||
'/app/siem#/hosts/siem-windows/anomalies?timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))'
|
||||
|
@ -162,7 +162,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('redirects from a single host name with a value for query', () => {
|
||||
loginAndWaitForPage(mlHostSingleHostKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlHostSingleHostKqlQuery);
|
||||
cy.url().should(
|
||||
'include',
|
||||
"/app/siem#/hosts/siem-windows/anomalies?query=(language:kuery,query:'(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)')&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))"
|
||||
|
@ -170,7 +170,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('redirects from a multiple host names with null for query', () => {
|
||||
loginAndWaitForPage(mlHostMultiHostNullKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlHostMultiHostNullKqlQuery);
|
||||
cy.url().should(
|
||||
'include',
|
||||
"/app/siem#/hosts/anomalies?query=(language:kuery,query:'(host.name:%20%22siem-windows%22%20or%20host.name:%20%22siem-suricata%22)')&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))"
|
||||
|
@ -178,7 +178,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('redirects from a multiple host names with a value for query', () => {
|
||||
loginAndWaitForPage(mlHostMultiHostKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlHostMultiHostKqlQuery);
|
||||
cy.url().should(
|
||||
'include',
|
||||
"/app/siem#/hosts/anomalies?query=(language:kuery,query:'(host.name:%20%22siem-windows%22%20or%20host.name:%20%22siem-suricata%22)%20and%20((process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22))')&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))"
|
||||
|
@ -186,7 +186,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('redirects from a undefined/null host name with a null for the KQL', () => {
|
||||
loginAndWaitForPage(mlHostVariableHostNullKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlHostVariableHostNullKqlQuery);
|
||||
cy.url().should(
|
||||
'include',
|
||||
'/app/siem#/hosts/anomalies?timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))'
|
||||
|
@ -194,7 +194,7 @@ describe('ml conditional links', () => {
|
|||
});
|
||||
|
||||
it('redirects from a undefined/null host name but with a value for query', () => {
|
||||
loginAndWaitForPage(mlHostVariableHostKqlQuery);
|
||||
loginAndWaitForPageWithoutDateRange(mlHostVariableHostKqlQuery);
|
||||
cy.url().should(
|
||||
'include',
|
||||
"/app/siem#/hosts/anomalies?query=(language:kuery,query:'(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)')&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))"
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
DATE_PICKER_APPLY_BUTTON_TIMELINE,
|
||||
DATE_PICKER_END_DATE_POPOVER_BUTTON,
|
||||
DATE_PICKER_END_DATE_POPOVER_BUTTON_TIMELINE,
|
||||
DATE_PICKER_START_DATE_POPOVER_BUTTON,
|
||||
|
@ -15,7 +16,7 @@ import { ANOMALIES_TAB } from '../screens/hosts/main';
|
|||
import { BREADCRUMBS, HOSTS, KQL_INPUT, NETWORK } from '../screens/siem_header';
|
||||
import { SERVER_SIDE_EVENT_COUNT, TIMELINE_TITLE } from '../screens/timeline';
|
||||
|
||||
import { loginAndWaitForPage } from '../tasks/login';
|
||||
import { loginAndWaitForPage, loginAndWaitForPageWithoutDateRange } from '../tasks/login';
|
||||
import {
|
||||
setStartDate,
|
||||
setEndDate,
|
||||
|
@ -30,7 +31,12 @@ import { openAllHosts } from '../tasks/hosts/main';
|
|||
import { waitForIpsTableToBeLoaded } from '../tasks/network/flows';
|
||||
import { clearSearchBar, kqlSearch, navigateFromHeaderTo } from '../tasks/siem_header';
|
||||
import { openTimeline } from '../tasks/siem_main';
|
||||
import { addNameToTimeline, executeTimelineKQL } from '../tasks/timeline';
|
||||
import {
|
||||
addDescriptionToTimeline,
|
||||
addNameToTimeline,
|
||||
closeTimeline,
|
||||
executeTimelineKQL,
|
||||
} from '../tasks/timeline';
|
||||
|
||||
import { HOSTS_PAGE } from '../urls/navigation';
|
||||
import { ABSOLUTE_DATE_RANGE } from '../urls/state';
|
||||
|
@ -58,7 +64,7 @@ const ABSOLUTE_DATE = {
|
|||
|
||||
describe('url state', () => {
|
||||
it('sets the global start and end dates from the url', () => {
|
||||
loginAndWaitForPage(ABSOLUTE_DATE_RANGE.url);
|
||||
loginAndWaitForPageWithoutDateRange(ABSOLUTE_DATE_RANGE.url);
|
||||
cy.get(DATE_PICKER_START_DATE_POPOVER_BUTTON).should(
|
||||
'have.attr',
|
||||
'title',
|
||||
|
@ -72,7 +78,7 @@ describe('url state', () => {
|
|||
});
|
||||
|
||||
it('sets the url state when start and end date are set', () => {
|
||||
loginAndWaitForPage(ABSOLUTE_DATE_RANGE.url);
|
||||
loginAndWaitForPageWithoutDateRange(ABSOLUTE_DATE_RANGE.url);
|
||||
setStartDate(ABSOLUTE_DATE.newStartTimeTyped);
|
||||
updateDates();
|
||||
waitForIpsTableToBeLoaded();
|
||||
|
@ -88,7 +94,7 @@ describe('url state', () => {
|
|||
});
|
||||
|
||||
it('sets the timeline start and end dates from the url when locked to global time', () => {
|
||||
loginAndWaitForPage(ABSOLUTE_DATE_RANGE.url);
|
||||
loginAndWaitForPageWithoutDateRange(ABSOLUTE_DATE_RANGE.url);
|
||||
openTimeline();
|
||||
|
||||
cy.get(DATE_PICKER_START_DATE_POPOVER_BUTTON_TIMELINE).should(
|
||||
|
@ -104,8 +110,7 @@ describe('url state', () => {
|
|||
});
|
||||
|
||||
it('sets the timeline start and end dates independently of the global start and end dates when times are unlocked', () => {
|
||||
loginAndWaitForPage(ABSOLUTE_DATE_RANGE.urlUnlinked);
|
||||
|
||||
loginAndWaitForPageWithoutDateRange(ABSOLUTE_DATE_RANGE.urlUnlinked);
|
||||
cy.get(DATE_PICKER_START_DATE_POPOVER_BUTTON).should(
|
||||
'have.attr',
|
||||
'title',
|
||||
|
@ -132,7 +137,7 @@ describe('url state', () => {
|
|||
});
|
||||
|
||||
it('sets the url state when timeline/global date pickers are unlinked and timeline start and end date are set', () => {
|
||||
loginAndWaitForPage(ABSOLUTE_DATE_RANGE.urlUnlinked);
|
||||
loginAndWaitForPageWithoutDateRange(ABSOLUTE_DATE_RANGE.urlUnlinked);
|
||||
openTimeline();
|
||||
setTimelineStartDate(ABSOLUTE_DATE.newStartTimeTyped);
|
||||
updateTimelineDates();
|
||||
|
@ -148,24 +153,24 @@ describe('url state', () => {
|
|||
});
|
||||
|
||||
it('sets kql on network page', () => {
|
||||
loginAndWaitForPage(ABSOLUTE_DATE_RANGE.urlKqlNetworkNetwork);
|
||||
loginAndWaitForPageWithoutDateRange(ABSOLUTE_DATE_RANGE.urlKqlNetworkNetwork);
|
||||
cy.get(KQL_INPUT).should('have.attr', 'value', 'source.ip: "10.142.0.9"');
|
||||
});
|
||||
|
||||
it('sets kql on hosts page', () => {
|
||||
loginAndWaitForPage(ABSOLUTE_DATE_RANGE.urlKqlHostsHosts);
|
||||
loginAndWaitForPageWithoutDateRange(ABSOLUTE_DATE_RANGE.urlKqlHostsHosts);
|
||||
cy.get(KQL_INPUT).should('have.attr', 'value', 'source.ip: "10.142.0.9"');
|
||||
});
|
||||
|
||||
it('sets the url state when kql is set', () => {
|
||||
loginAndWaitForPage(ABSOLUTE_DATE_RANGE.url);
|
||||
loginAndWaitForPageWithoutDateRange(ABSOLUTE_DATE_RANGE.url);
|
||||
kqlSearch('source.ip: "10.142.0.9" {enter}');
|
||||
|
||||
cy.url().should('include', `query=(language:kuery,query:'source.ip:%20%2210.142.0.9%22%20')`);
|
||||
});
|
||||
|
||||
it('sets the url state when kql is set and check if href reflect this change', () => {
|
||||
loginAndWaitForPage(ABSOLUTE_DATE_RANGE.url);
|
||||
loginAndWaitForPageWithoutDateRange(ABSOLUTE_DATE_RANGE.url);
|
||||
kqlSearch('source.ip: "10.142.0.9" {enter}');
|
||||
navigateFromHeaderTo(HOSTS);
|
||||
|
||||
|
@ -177,7 +182,7 @@ describe('url state', () => {
|
|||
});
|
||||
|
||||
it('sets KQL in host page and detail page and check if href match on breadcrumb, tabs and subTabs', () => {
|
||||
loginAndWaitForPage(ABSOLUTE_DATE_RANGE.urlHostNew);
|
||||
loginAndWaitForPageWithoutDateRange(ABSOLUTE_DATE_RANGE.urlHostNew);
|
||||
kqlSearch('host.name: "siem-kibana" {enter}');
|
||||
openAllHosts();
|
||||
waitForAllHostsToBeLoaded();
|
||||
|
@ -223,7 +228,7 @@ describe('url state', () => {
|
|||
});
|
||||
|
||||
it('Do not clears kql when navigating to a new page', () => {
|
||||
loginAndWaitForPage(ABSOLUTE_DATE_RANGE.urlKqlHostsHosts);
|
||||
loginAndWaitForPageWithoutDateRange(ABSOLUTE_DATE_RANGE.urlKqlHostsHosts);
|
||||
navigateFromHeaderTo(NETWORK);
|
||||
|
||||
cy.get(KQL_INPUT).should('have.attr', 'value', 'source.ip: "10.142.0.9"');
|
||||
|
@ -241,12 +246,23 @@ describe('url state', () => {
|
|||
cy.wrap(intCount).should('be.above', 0);
|
||||
});
|
||||
|
||||
const bestTimelineName = 'The Best Timeline';
|
||||
addNameToTimeline(bestTimelineName);
|
||||
const timelineName = 'SIEM';
|
||||
addNameToTimeline(timelineName);
|
||||
addDescriptionToTimeline('This is the best timeline of the world');
|
||||
|
||||
cy.url().should('include', 'timeline=');
|
||||
cy.visit(
|
||||
`/app/siem#/timelines?timerange=(global:(linkTo:!(),timerange:(from:1565274377369,kind:absolute,to:1565360777369)),timeline:(linkTo:!(),timerange:(from:1565274377369,kind:absolute,to:1565360777369)))`
|
||||
).then(() => cy.get(TIMELINE_TITLE).should('have.attr', 'value', bestTimelineName));
|
||||
cy.url({ timeout: 30000 }).should('match', /\w*-\w*-\w*-\w*-\w*/);
|
||||
cy.url().then(url => {
|
||||
const matched = url.match(/\w*-\w*-\w*-\w*-\w*/);
|
||||
const newTimelineId = matched && matched.length > 0 ? matched[0] : 'null';
|
||||
expect(matched).to.have.lengthOf(1);
|
||||
closeTimeline();
|
||||
cy.visit('/app/kibana');
|
||||
cy.visit(`/app/siem#/overview?timeline\=(id:'${newTimelineId}',isOpen:!t)`);
|
||||
cy.contains('a', 'SIEM');
|
||||
cy.get(DATE_PICKER_APPLY_BUTTON_TIMELINE)
|
||||
.invoke('text')
|
||||
.should('not.equal', 'Updating');
|
||||
cy.get(TIMELINE_TITLE).should('have.attr', 'value', timelineName);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -24,8 +24,9 @@ export const TIMELINE_DATA_PROVIDERS = '[data-test-subj="dataProviders"]';
|
|||
export const TIMELINE_DATA_PROVIDERS_EMPTY =
|
||||
'[data-test-subj="dataProviders"] [data-test-subj="empty"]';
|
||||
|
||||
export const TIMELINE_DROPPED_DATA_PROVIDERS =
|
||||
'[data-test-subj="dataProviders"] [data-test-subj="providerContainer"]';
|
||||
export const TIMELINE_DESCRIPTION = '[data-test-subj="timeline-description"]';
|
||||
|
||||
export const TIMELINE_DROPPED_DATA_PROVIDERS = '[data-test-subj="providerContainer"]';
|
||||
|
||||
export const TIMELINE_FIELDS_BUTTON =
|
||||
'[data-test-subj="timeline"] [data-test-subj="show-field-browser"]';
|
||||
|
@ -43,8 +44,6 @@ export const TIMELINE_TITLE = '[data-test-subj="timeline-title"]';
|
|||
|
||||
export const TIMESTAMP_HEADER_FIELD = '[data-test-subj="header-text-@timestamp"]';
|
||||
|
||||
export const TIMELINE_TOGGLE_BUTTON = '[data-test-subj="flyoutOverlay"]';
|
||||
|
||||
export const TIMESTAMP_TOGGLE_FIELD = '[data-test-subj="toggle-field-@timestamp"]';
|
||||
|
||||
export const TOGGLE_TIMELINE_EXPAND_EVENT = '[data-test-subj="expand-event"]';
|
||||
|
|
|
@ -23,14 +23,14 @@ export const drag = (subject: JQuery<HTMLElement>) => {
|
|||
clientY: subjectLocation.top,
|
||||
force: true,
|
||||
})
|
||||
.wait(1)
|
||||
.wait(5)
|
||||
.trigger('mousemove', {
|
||||
button: primaryButton,
|
||||
clientX: subjectLocation.left + dndSloppyClickDetectionThreshold,
|
||||
clientY: subjectLocation.top,
|
||||
force: true,
|
||||
})
|
||||
.wait(1);
|
||||
.wait(5);
|
||||
};
|
||||
|
||||
/** Drags the subject being dragged on the specified drop target, but does not drop it */
|
||||
|
@ -44,7 +44,7 @@ export const dragWithoutDrop = (dropTarget: JQuery<HTMLElement>) => {
|
|||
export const drop = (dropTarget: JQuery<HTMLElement>) => {
|
||||
cy.wrap(dropTarget)
|
||||
.trigger('mousemove', { button: primaryButton, force: true })
|
||||
.wait(1)
|
||||
.wait(5)
|
||||
.trigger('mouseup', { force: true })
|
||||
.wait(1);
|
||||
.wait(5);
|
||||
};
|
||||
|
|
|
@ -46,7 +46,14 @@ export const setTimelineEndDate = (date: string) => {
|
|||
.first()
|
||||
.click({ force: true });
|
||||
|
||||
cy.get(DATE_PICKER_ABSOLUTE_INPUT).type(`{selectall}{backspace}${date}{enter}`);
|
||||
cy.get(DATE_PICKER_ABSOLUTE_INPUT).click({ force: true });
|
||||
cy.get(DATE_PICKER_ABSOLUTE_INPUT).then($el => {
|
||||
// @ts-ignore
|
||||
if (Cypress.dom.isAttached($el)) {
|
||||
cy.wrap($el).click({ force: true });
|
||||
}
|
||||
cy.wrap($el).type(`{selectall}{backspace}${date}{enter}`);
|
||||
});
|
||||
};
|
||||
|
||||
export const setTimelineStartDate = (date: string) => {
|
||||
|
@ -58,7 +65,14 @@ export const setTimelineStartDate = (date: string) => {
|
|||
.first()
|
||||
.click({ force: true });
|
||||
|
||||
cy.get(DATE_PICKER_ABSOLUTE_INPUT).type(`{selectall}{backspace}${date}{enter}`);
|
||||
cy.get(DATE_PICKER_ABSOLUTE_INPUT).click({ force: true });
|
||||
cy.get(DATE_PICKER_ABSOLUTE_INPUT).then($el => {
|
||||
// @ts-ignore
|
||||
if (Cypress.dom.isAttached($el)) {
|
||||
cy.wrap($el).click({ force: true });
|
||||
}
|
||||
cy.wrap($el).type(`{selectall}{backspace}${date}{enter}`);
|
||||
});
|
||||
};
|
||||
|
||||
export const updateDates = () => {
|
||||
|
@ -69,5 +83,8 @@ export const updateDates = () => {
|
|||
};
|
||||
|
||||
export const updateTimelineDates = () => {
|
||||
cy.get(DATE_PICKER_APPLY_BUTTON_TIMELINE).click({ force: true });
|
||||
cy.get(DATE_PICKER_APPLY_BUTTON_TIMELINE)
|
||||
.click({ force: true })
|
||||
.invoke('text')
|
||||
.should('not.equal', 'Updating');
|
||||
};
|
||||
|
|
|
@ -120,10 +120,16 @@ const loginViaConfig = () => {
|
|||
*/
|
||||
export const loginAndWaitForPage = (url: string) => {
|
||||
login();
|
||||
|
||||
cy.visit(`${Cypress.config().baseUrl}${url}`);
|
||||
|
||||
cy.viewport('macbook-15');
|
||||
|
||||
cy.visit(
|
||||
`${url}?timerange=(global:(linkTo:!(timeline),timerange:(from:1547914976217,fromStr:'2019-01-19T16:22:56.217Z',kind:relative,to:1579537385745,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1547914976217,fromStr:'2019-01-19T16:22:56.217Z',kind:relative,to:1579537385745,toStr:now)))`
|
||||
);
|
||||
cy.contains('a', 'SIEM');
|
||||
};
|
||||
|
||||
export const loginAndWaitForPageWithoutDateRange = (url: string) => {
|
||||
login();
|
||||
cy.viewport('macbook-15');
|
||||
cy.visit(url);
|
||||
cy.contains('a', 'SIEM');
|
||||
};
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { DATE_PICKER_APPLY_BUTTON_TIMELINE } from '../screens/date_picker';
|
||||
|
||||
import {
|
||||
CLOSE_TIMELINE_BTN,
|
||||
CREATE_NEW_TIMELINE,
|
||||
|
@ -12,6 +14,7 @@ import {
|
|||
ID_TOGGLE_FIELD,
|
||||
SEARCH_OR_FILTER_CONTAINER,
|
||||
SERVER_SIDE_EVENT_COUNT,
|
||||
TIMELINE_DESCRIPTION,
|
||||
TIMELINE_FIELDS_BUTTON,
|
||||
TIMELINE_INSPECT_BUTTON,
|
||||
TIMELINE_SETTINGS_ICON,
|
||||
|
@ -24,14 +27,31 @@ import { drag, drop } from '../tasks/common';
|
|||
|
||||
export const hostExistsQuery = 'host.name: *';
|
||||
|
||||
export const addDescriptionToTimeline = (description: string) => {
|
||||
cy.get(TIMELINE_DESCRIPTION).type(`${description}{enter}`);
|
||||
cy.get(DATE_PICKER_APPLY_BUTTON_TIMELINE)
|
||||
.click()
|
||||
.invoke('text')
|
||||
.should('not.equal', 'Updating');
|
||||
};
|
||||
|
||||
export const addNameToTimeline = (name: string) => {
|
||||
cy.get(TIMELINE_TITLE).type(`${name}{enter}`);
|
||||
cy.get(TIMELINE_TITLE).should('have.attr', 'value', name);
|
||||
};
|
||||
|
||||
export const checkIdToggleField = () => {
|
||||
cy.get(ID_TOGGLE_FIELD).should('not.exist');
|
||||
cy.get(ID_HEADER_FIELD).should('not.exist');
|
||||
|
||||
cy.get(ID_TOGGLE_FIELD).check({
|
||||
force: true,
|
||||
});
|
||||
};
|
||||
|
||||
export const closeTimeline = () => {
|
||||
cy.get(CLOSE_TIMELINE_BTN).click({ force: true });
|
||||
};
|
||||
|
||||
export const createNewTimeline = () => {
|
||||
cy.get(TIMELINE_SETTINGS_ICON).click({ force: true });
|
||||
cy.get(CREATE_NEW_TIMELINE).click();
|
||||
|
@ -86,7 +106,3 @@ export const dragAndDropIdToggleFieldToTimeline = () => {
|
|||
drop(headersDropArea)
|
||||
);
|
||||
};
|
||||
|
||||
export const addNameToTimeline = (name: string) => {
|
||||
cy.get(TIMELINE_TITLE).type(name);
|
||||
};
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
"extract-mitre-attacks": "node scripts/extract_tactics_techniques_mitre.js & node ../../../../scripts/eslint ./public/pages/detection_engine/mitre/mitre_tactics_techniques.ts --fix",
|
||||
"build-graphql-types": "node scripts/generate_types_from_graphql.js",
|
||||
"cypress:open": "../../../node_modules/.bin/cypress open",
|
||||
"cypress:run": "../../../node_modules/.bin/cypress run --spec ./cypress/integration/**/*.spec.ts --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=./reporter_config.json; status=$?; ../../../node_modules/.bin/mochawesome-merge --reportDir ../../../../target/kibana-siem/cypress/results > ../../../../target/kibana-siem/cypress/results/output.json; ../../../../node_modules/.bin/marge ../../../../target/kibana-siem/cypress/results/output.json --reportDir ../../../../target/kibana-siem/cypress/results; mkdir -p ../../../../target/junit && cp ../../../../target/kibana-siem/cypress/results/*.xml ../../../../target/junit/ && exit $status;"
|
||||
"cypress:run": "../../../node_modules/.bin/cypress run --spec ./cypress/integration/**/*.spec.ts --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=./reporter_config.json; status=$?; ../../../node_modules/.bin/mochawesome-merge --reportDir ../../../../target/kibana-siem/cypress/results > ../../../../target/kibana-siem/cypress/results/output.json; ../../../../node_modules/.bin/marge ../../../../target/kibana-siem/cypress/results/output.json --reportDir ../../../../target/kibana-siem/cypress/results; mkdir -p ../../../../target/junit && cp ../../../../target/kibana-siem/cypress/results/*.xml ../../../../target/junit/ && exit $status;",
|
||||
"cypress:run-as-ci": "node ../../../../scripts/functional_tests --config ../../../test/siem_cypress/config.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash": "^4.14.110",
|
||||
|
|
83
x-pack/legacy/plugins/siem/scripts/loop_cypress_tests.js
Normal file
83
x-pack/legacy/plugins/siem/scripts/loop_cypress_tests.js
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const process = require('process');
|
||||
const spawn = require('child_process').spawn;
|
||||
/* eslint-disable no-process-exit */
|
||||
const MUST_RUN_FROM_DIR = 'kibana';
|
||||
const OUTPUT_DIR = 'target';
|
||||
const OUTPUT_FILE = `${OUTPUT_DIR}/loop-cypress-tests.txt`;
|
||||
const createOutputDir = () => {
|
||||
fs.mkdir(OUTPUT_DIR, { recursive: true }, err => {
|
||||
if (err) throw err;
|
||||
});
|
||||
};
|
||||
const showUsage = () => {
|
||||
const scriptName = process.argv[1].slice(process.argv[1].lastIndexOf('/') + 1);
|
||||
console.log(`\nUsage: ${scriptName} <times-to-run>`, `\nExample: ${scriptName} 5`);
|
||||
};
|
||||
|
||||
const exitIfIncorrectWorkingDir = () => {
|
||||
if (!process.cwd().endsWith(`/${MUST_RUN_FROM_DIR}`)) {
|
||||
console.error(
|
||||
`\nERROR: This script must be run from the '${MUST_RUN_FROM_DIR}' directory, but it was ran from '${process.cwd()}' instead.`
|
||||
);
|
||||
showUsage();
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
const exitIfTimesToRunIsInvalid = timesToRun => {
|
||||
if (!timesToRun > 0) {
|
||||
console.error(
|
||||
'\nERROR: You must specify a valid number of times to run the SIEM Cypress tests.'
|
||||
);
|
||||
showUsage();
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
const spawnChild = async () => {
|
||||
const child = spawn('node', [
|
||||
'scripts/functional_tests',
|
||||
'--config',
|
||||
'x-pack/test/siem_cypress/config.ts',
|
||||
]);
|
||||
for await (const chunk of child.stdout) {
|
||||
console.log(chunk.toString());
|
||||
fs.appendFileSync(OUTPUT_FILE, chunk.toString());
|
||||
}
|
||||
for await (const chunk of child.stderr) {
|
||||
console.log(chunk.toString());
|
||||
fs.appendFileSync(OUTPUT_FILE, chunk.toString());
|
||||
}
|
||||
const exitCode = await new Promise(resolve => {
|
||||
child.on('close', resolve);
|
||||
});
|
||||
return exitCode;
|
||||
};
|
||||
|
||||
const runNTimes = async timesToRun => {
|
||||
for (let i = 0; i < timesToRun; i++) {
|
||||
const startingRun = `\n\n*** Starting test run ${i +
|
||||
1} of ${timesToRun} on host ${os.hostname()} at ${new Date()} ***\n\n`;
|
||||
console.log(startingRun);
|
||||
fs.appendFileSync(OUTPUT_FILE, startingRun);
|
||||
const exitCode = await spawnChild();
|
||||
const testRunCompleted = `\n\n*** Test run ${i +
|
||||
1} of ${timesToRun} on host ${os.hostname()} exited with code ${exitCode} at ${new Date()} ***`;
|
||||
console.log(testRunCompleted);
|
||||
fs.appendFileSync(OUTPUT_FILE, testRunCompleted);
|
||||
}
|
||||
};
|
||||
|
||||
const timesToRun = Number(process.argv[2]) || 0;
|
||||
exitIfIncorrectWorkingDir();
|
||||
exitIfTimesToRunIsInvalid(timesToRun);
|
||||
console.log(`\nCypress tests will be run ${timesToRun} times`);
|
||||
console.log(`\nTest output will be appended to '${OUTPUT_FILE}'`);
|
||||
createOutputDir();
|
||||
runNTimes(timesToRun);
|
47
x-pack/test/siem_cypress/config.ts
Normal file
47
x-pack/test/siem_cypress/config.ts
Normal file
|
@ -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;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { resolve } from 'path';
|
||||
|
||||
import { FtrConfigProviderContext } from '@kbn/test/types/ftr';
|
||||
|
||||
import { SiemCypressTestRunner } from './runner';
|
||||
|
||||
export default async function({ readConfigFile }: FtrConfigProviderContext) {
|
||||
const kibanaCommonTestsConfig = await readConfigFile(
|
||||
require.resolve('../../../test/common/config.js')
|
||||
);
|
||||
const xpackFunctionalTestsConfig = await readConfigFile(
|
||||
require.resolve('../functional/config.js')
|
||||
);
|
||||
|
||||
return {
|
||||
...kibanaCommonTestsConfig.getAll(),
|
||||
|
||||
testRunner: SiemCypressTestRunner,
|
||||
|
||||
esArchiver: {
|
||||
directory: resolve(__dirname, 'es_archives'),
|
||||
},
|
||||
|
||||
esTestCluster: {
|
||||
...xpackFunctionalTestsConfig.get('esTestCluster'),
|
||||
serverArgs: [
|
||||
...xpackFunctionalTestsConfig.get('esTestCluster.serverArgs'),
|
||||
// define custom es server here
|
||||
],
|
||||
},
|
||||
|
||||
kbnTestServer: {
|
||||
...xpackFunctionalTestsConfig.get('kbnTestServer'),
|
||||
serverArgs: [
|
||||
...xpackFunctionalTestsConfig.get('kbnTestServer.serverArgs'),
|
||||
'--csp.strict=false',
|
||||
// define custom kibana server args here
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
BIN
x-pack/test/siem_cypress/es_archives/auditbeat/data.json.gz
Normal file
BIN
x-pack/test/siem_cypress/es_archives/auditbeat/data.json.gz
Normal file
Binary file not shown.
3577
x-pack/test/siem_cypress/es_archives/auditbeat/mappings.json
Normal file
3577
x-pack/test/siem_cypress/es_archives/auditbeat/mappings.json
Normal file
File diff suppressed because it is too large
Load diff
BIN
x-pack/test/siem_cypress/es_archives/empty_kibana/data.json.gz
Normal file
BIN
x-pack/test/siem_cypress/es_archives/empty_kibana/data.json.gz
Normal file
Binary file not shown.
284
x-pack/test/siem_cypress/es_archives/empty_kibana/mappings.json
Normal file
284
x-pack/test/siem_cypress/es_archives/empty_kibana/mappings.json
Normal file
|
@ -0,0 +1,284 @@
|
|||
{
|
||||
"type": "index",
|
||||
"value": {
|
||||
"index": ".kibana",
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"config": {
|
||||
"dynamic": "true",
|
||||
"properties": {
|
||||
"buildNum": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"dateFormat:tz": {
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"ignore_above": 256,
|
||||
"type": "keyword"
|
||||
}
|
||||
},
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
"dynamic": "strict",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "text"
|
||||
},
|
||||
"hits": {
|
||||
"type": "integer"
|
||||
},
|
||||
"kibanaSavedObjectMeta": {
|
||||
"properties": {
|
||||
"searchSourceJSON": {
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
},
|
||||
"optionsJSON": {
|
||||
"type": "text"
|
||||
},
|
||||
"panelsJSON": {
|
||||
"type": "text"
|
||||
},
|
||||
"refreshInterval": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"pause": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"section": {
|
||||
"type": "integer"
|
||||
},
|
||||
"value": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"timeFrom": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"timeRestore": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"timeTo": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"title": {
|
||||
"type": "text"
|
||||
},
|
||||
"uiStateJSON": {
|
||||
"type": "text"
|
||||
},
|
||||
"version": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"index-pattern": {
|
||||
"dynamic": "strict",
|
||||
"properties": {
|
||||
"fieldFormatMap": {
|
||||
"type": "text"
|
||||
},
|
||||
"fields": {
|
||||
"type": "text"
|
||||
},
|
||||
"intervalName": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"notExpandable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"sourceFilters": {
|
||||
"type": "text"
|
||||
},
|
||||
"timeFieldName": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"title": {
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"dynamic": "strict",
|
||||
"properties": {
|
||||
"columns": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
},
|
||||
"hits": {
|
||||
"type": "integer"
|
||||
},
|
||||
"kibanaSavedObjectMeta": {
|
||||
"properties": {
|
||||
"searchSourceJSON": {
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"title": {
|
||||
"type": "text"
|
||||
},
|
||||
"version": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"server": {
|
||||
"dynamic": "strict",
|
||||
"properties": {
|
||||
"uuid": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"space": {
|
||||
"properties": {
|
||||
"_reserved": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"color": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
},
|
||||
"disabledFeatures": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"initials": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"name": {
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"ignore_above": 2048,
|
||||
"type": "keyword"
|
||||
}
|
||||
},
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
},
|
||||
"spaceId": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"timelion-sheet": {
|
||||
"dynamic": "strict",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "text"
|
||||
},
|
||||
"hits": {
|
||||
"type": "integer"
|
||||
},
|
||||
"kibanaSavedObjectMeta": {
|
||||
"properties": {
|
||||
"searchSourceJSON": {
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
},
|
||||
"timelion_chart_height": {
|
||||
"type": "integer"
|
||||
},
|
||||
"timelion_columns": {
|
||||
"type": "integer"
|
||||
},
|
||||
"timelion_interval": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"timelion_other_interval": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"timelion_rows": {
|
||||
"type": "integer"
|
||||
},
|
||||
"timelion_sheet": {
|
||||
"type": "text"
|
||||
},
|
||||
"title": {
|
||||
"type": "text"
|
||||
},
|
||||
"version": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"url": {
|
||||
"dynamic": "strict",
|
||||
"properties": {
|
||||
"accessCount": {
|
||||
"type": "long"
|
||||
},
|
||||
"accessDate": {
|
||||
"type": "date"
|
||||
},
|
||||
"createDate": {
|
||||
"type": "date"
|
||||
},
|
||||
"url": {
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"ignore_above": 2048,
|
||||
"type": "keyword"
|
||||
}
|
||||
},
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
},
|
||||
"visualization": {
|
||||
"dynamic": "strict",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "text"
|
||||
},
|
||||
"kibanaSavedObjectMeta": {
|
||||
"properties": {
|
||||
"searchSourceJSON": {
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
},
|
||||
"savedSearchId": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"title": {
|
||||
"type": "text"
|
||||
},
|
||||
"uiStateJSON": {
|
||||
"type": "text"
|
||||
},
|
||||
"version": {
|
||||
"type": "integer"
|
||||
},
|
||||
"visState": {
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"index": {
|
||||
"number_of_replicas": "1",
|
||||
"number_of_shards": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
x-pack/test/siem_cypress/ftr_provider_context.d.ts
vendored
Normal file
11
x-pack/test/siem_cypress/ftr_provider_context.d.ts
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { GenericFtrProviderContext } from '@kbn/test/types/ftr';
|
||||
|
||||
import { services } from './services';
|
||||
|
||||
export type FtrProviderContext = GenericFtrProviderContext<typeof services, {}>;
|
37
x-pack/test/siem_cypress/runner.ts
Normal file
37
x-pack/test/siem_cypress/runner.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { resolve } from 'path';
|
||||
import Url from 'url';
|
||||
|
||||
import { withProcRunner } from '@kbn/dev-utils';
|
||||
|
||||
import { FtrProviderContext } from './ftr_provider_context';
|
||||
|
||||
export async function SiemCypressTestRunner({ getService }: FtrProviderContext) {
|
||||
const log = getService('log');
|
||||
const config = getService('config');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
||||
await esArchiver.load('empty_kibana');
|
||||
await esArchiver.load('auditbeat');
|
||||
|
||||
await withProcRunner(log, async procs => {
|
||||
await procs.run('cypress', {
|
||||
cmd: 'yarn',
|
||||
args: ['cypress:run'],
|
||||
cwd: resolve(__dirname, '../../legacy/plugins/siem'),
|
||||
env: {
|
||||
FORCE_COLOR: '1',
|
||||
CYPRESS_baseUrl: Url.format(config.get('servers.kibana')),
|
||||
CYPRESS_ELASTICSEARCH_USERNAME: config.get('servers.elasticsearch.username'),
|
||||
CYPRESS_ELASTICSEARCH_PASSWORD: config.get('servers.elasticsearch.password'),
|
||||
...process.env,
|
||||
},
|
||||
wait: true,
|
||||
});
|
||||
});
|
||||
}
|
7
x-pack/test/siem_cypress/services.ts
Normal file
7
x-pack/test/siem_cypress/services.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export * from '../../../test/common/services';
|
Loading…
Add table
Add a link
Reference in a new issue