-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Security Solution] [Sourcerer] Cypress tests (#80410)
- Loading branch information
1 parent
8279c2d
commit 59b18a2
Showing
4 changed files
with
281 additions
and
7 deletions.
There are no files selected for viewing
105 changes: 105 additions & 0 deletions
105
x-pack/plugins/security_solution/cypress/integration/sourcerer.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/* | ||
* 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 { loginAndWaitForPage } from '../tasks/login'; | ||
|
||
import { HOSTS_URL } from '../urls/navigation'; | ||
import { waitForAllHostsToBeLoaded } from '../tasks/hosts/all_hosts'; | ||
import { | ||
clickOutOfSourcererTimeline, | ||
clickTimelineRadio, | ||
deselectSourcererOptions, | ||
isCustomRadio, | ||
isHostsStatValue, | ||
isNotCustomRadio, | ||
isNotSourcererSelection, | ||
isSourcererOptions, | ||
isSourcererSelection, | ||
openSourcerer, | ||
resetSourcerer, | ||
setSourcererOption, | ||
unsetSourcererOption, | ||
} from '../tasks/sourcerer'; | ||
import { openTimelineUsingToggle } from '../tasks/security_main'; | ||
import { populateTimeline } from '../tasks/timeline'; | ||
import { SERVER_SIDE_EVENT_COUNT } from '../screens/timeline'; | ||
|
||
describe('Sourcerer', () => { | ||
beforeEach(() => { | ||
loginAndWaitForPage(HOSTS_URL); | ||
}); | ||
describe('Default scope', () => { | ||
it('has SIEM index patterns selected on initial load', () => { | ||
openSourcerer(); | ||
isSourcererSelection(`auditbeat-*`); | ||
}); | ||
|
||
it('has Kibana index patterns in the options', () => { | ||
openSourcerer(); | ||
isSourcererOptions([`metrics-*`, `logs-*`]); | ||
}); | ||
it('selected KIP gets added to sourcerer', () => { | ||
setSourcererOption(`metrics-*`); | ||
openSourcerer(); | ||
isSourcererSelection(`metrics-*`); | ||
}); | ||
|
||
it('does not return data without correct pattern selected', () => { | ||
waitForAllHostsToBeLoaded(); | ||
isHostsStatValue('4 '); | ||
setSourcererOption(`metrics-*`); | ||
unsetSourcererOption(`auditbeat-*`); | ||
isHostsStatValue('0 '); | ||
}); | ||
|
||
it('reset button restores to original state', () => { | ||
setSourcererOption(`metrics-*`); | ||
openSourcerer(); | ||
isSourcererSelection(`metrics-*`); | ||
resetSourcerer(); | ||
openSourcerer(); | ||
isNotSourcererSelection(`metrics-*`); | ||
}); | ||
}); | ||
describe('Timeline scope', () => { | ||
const alertPatterns = ['.siem-signals-default']; | ||
const rawPatterns = ['auditbeat-*']; | ||
const allPatterns = [...alertPatterns, ...rawPatterns]; | ||
it('Radio buttons select correct sourcerer patterns', () => { | ||
openTimelineUsingToggle(); | ||
openSourcerer('timeline'); | ||
allPatterns.forEach((ss) => isSourcererSelection(ss, 'timeline')); | ||
clickTimelineRadio('raw'); | ||
rawPatterns.forEach((ss) => isSourcererSelection(ss, 'timeline')); | ||
alertPatterns.forEach((ss) => isNotSourcererSelection(ss, 'timeline')); | ||
clickTimelineRadio('alert'); | ||
alertPatterns.forEach((ss) => isSourcererSelection(ss, 'timeline')); | ||
rawPatterns.forEach((ss) => isNotSourcererSelection(ss, 'timeline')); | ||
}); | ||
it('Adding an option results in the custom radio becoming active', () => { | ||
openTimelineUsingToggle(); | ||
openSourcerer('timeline'); | ||
isNotCustomRadio(); | ||
clickOutOfSourcererTimeline(); | ||
const luckyOption = 'logs-*'; | ||
setSourcererOption(luckyOption, 'timeline'); | ||
openSourcerer('timeline'); | ||
isCustomRadio(); | ||
}); | ||
it('Selected index patterns are properly queried', () => { | ||
openTimelineUsingToggle(); | ||
populateTimeline(); | ||
openSourcerer('timeline'); | ||
deselectSourcererOptions(rawPatterns, 'timeline'); | ||
cy.get(SERVER_SIDE_EVENT_COUNT) | ||
.invoke('text') | ||
.then((strCount) => { | ||
const intCount = +strCount; | ||
cy.wrap(intCount).should('eq', 0); | ||
}); | ||
}); | ||
}); | ||
}); |
30 changes: 30 additions & 0 deletions
30
x-pack/plugins/security_solution/cypress/screens/sourcerer.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* 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 const SOURCERER_TRIGGER = '[data-test-subj="sourcerer-trigger"]'; | ||
export const SOURCERER_INPUT = | ||
'[data-test-subj="indexPattern-switcher"] [data-test-subj="comboBoxInput"]'; | ||
export const SOURCERER_OPTIONS = | ||
'[data-test-subj="comboBoxOptionsList indexPattern-switcher-optionsList"]'; | ||
export const SOURCERER_SAVE_BUTTON = 'button[data-test-subj="add-index"]'; | ||
export const SOURCERER_RESET_BUTTON = 'button[data-test-subj="sourcerer-reset"]'; | ||
export const SOURCERER_POPOVER_TITLE = '.euiPopoverTitle'; | ||
export const HOSTS_STAT = '[data-test-subj="stat-hosts"] [data-test-subj="stat-title"]'; | ||
|
||
export const SOURCERER_TIMELINE = { | ||
trigger: '[data-test-subj="sourcerer-timeline-trigger"]', | ||
advancedSettings: '[data-test-subj="advanced-settings"]', | ||
sourcerer: '[data-test-subj="timeline-sourcerer"]', | ||
sourcererInput: '[data-test-subj="timeline-sourcerer"] [data-test-subj="comboBoxInput"]', | ||
sourcererOptions: '[data-test-subj="comboBoxOptionsList timeline-sourcerer-optionsList"]', | ||
radioRaw: '[data-test-subj="timeline-sourcerer-radio"] label.euiRadio__label[for="raw"]', | ||
radioAlert: '[data-test-subj="timeline-sourcerer-radio"] label.euiRadio__label[for="alert"]', | ||
radioAll: '[data-test-subj="timeline-sourcerer-radio"] label.euiRadio__label[for="all"]', | ||
radioCustom: '[data-test-subj="timeline-sourcerer-radio"] input.euiRadio__input[id="custom"]', | ||
radioCustomLabel: | ||
'[data-test-subj="timeline-sourcerer-radio"] label.euiRadio__label[for="custom"]', | ||
}; | ||
export const SOURCERER_TIMELINE_ADVANCED = '[data-test-subj="advanced-settings"]'; |
136 changes: 136 additions & 0 deletions
136
x-pack/plugins/security_solution/cypress/tasks/sourcerer.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
/* | ||
* 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 { | ||
HOSTS_STAT, | ||
SOURCERER_INPUT, | ||
SOURCERER_OPTIONS, | ||
SOURCERER_POPOVER_TITLE, | ||
SOURCERER_RESET_BUTTON, | ||
SOURCERER_SAVE_BUTTON, | ||
SOURCERER_TIMELINE, | ||
SOURCERER_TRIGGER, | ||
} from '../screens/sourcerer'; | ||
import { TIMELINE_TITLE } from '../screens/timeline'; | ||
|
||
export const openSourcerer = (sourcererScope?: string) => { | ||
if (sourcererScope != null && sourcererScope === 'timeline') { | ||
return openTimelineSourcerer(); | ||
} | ||
cy.get(SOURCERER_TRIGGER).should('be.enabled'); | ||
cy.get(SOURCERER_TRIGGER).should('be.visible'); | ||
cy.get(SOURCERER_TRIGGER).click(); | ||
}; | ||
export const openTimelineSourcerer = () => { | ||
cy.get(SOURCERER_TIMELINE.trigger).should('be.enabled'); | ||
cy.get(SOURCERER_TIMELINE.trigger).should('be.visible'); | ||
cy.get(SOURCERER_TIMELINE.trigger).click(); | ||
cy.get(SOURCERER_TIMELINE.advancedSettings).should(($div) => { | ||
if ($div.text() === 'Show Advanced') { | ||
$div.click(); | ||
} | ||
expect(true).to.eq(true); | ||
}); | ||
}; | ||
export const openAdvancedSettings = () => {}; | ||
|
||
export const clickOutOfSelector = () => { | ||
return cy.get(SOURCERER_POPOVER_TITLE).first().click(); | ||
}; | ||
|
||
const getScopedSelectors = (sourcererScope?: string): { input: string; options: string } => | ||
sourcererScope != null && sourcererScope === 'timeline' | ||
? { input: SOURCERER_TIMELINE.sourcererInput, options: SOURCERER_TIMELINE.sourcererOptions } | ||
: { input: SOURCERER_INPUT, options: SOURCERER_OPTIONS }; | ||
|
||
export const isSourcererSelection = (patternName: string, sourcererScope?: string) => { | ||
const { input } = getScopedSelectors(sourcererScope); | ||
return cy.get(input).find(`span[title="${patternName}"]`).should('exist'); | ||
}; | ||
|
||
export const isHostsStatValue = (value: string) => { | ||
return cy.get(HOSTS_STAT).first().should('have.text', value); | ||
}; | ||
|
||
export const isNotSourcererSelection = (patternName: string, sourcererScope?: string) => { | ||
const { input } = getScopedSelectors(sourcererScope); | ||
return cy.get(input).find(`span[title="${patternName}"]`).should('not.exist'); | ||
}; | ||
|
||
export const isSourcererOptions = (patternNames: string[], sourcererScope?: string) => { | ||
const { input, options } = getScopedSelectors(sourcererScope); | ||
cy.get(input).click(); | ||
return patternNames.every((patternName) => { | ||
return cy | ||
.get(options) | ||
.find(`button.euiFilterSelectItem[title="${patternName}"]`) | ||
.its('length') | ||
.should('eq', 1); | ||
}); | ||
}; | ||
|
||
export const selectSourcererOption = (patternName: string, sourcererScope?: string) => { | ||
const { input, options } = getScopedSelectors(sourcererScope); | ||
cy.get(input).click(); | ||
cy.get(options).find(`button.euiFilterSelectItem[title="${patternName}"]`).click(); | ||
clickOutOfSelector(); | ||
return cy.get(SOURCERER_SAVE_BUTTON).click({ force: true }); | ||
}; | ||
|
||
export const deselectSourcererOption = (patternName: string, sourcererScope?: string) => { | ||
const { input } = getScopedSelectors(sourcererScope); | ||
cy.get(input).find(`span[title="${patternName}"] button`).click(); | ||
clickOutOfSelector(); | ||
return cy.get(SOURCERER_SAVE_BUTTON).click({ force: true }); | ||
}; | ||
|
||
export const deselectSourcererOptions = (patternNames: string[], sourcererScope?: string) => { | ||
const { input } = getScopedSelectors(sourcererScope); | ||
patternNames.forEach((patternName) => | ||
cy.get(input).find(`span[title="${patternName}"] button`).click() | ||
); | ||
clickOutOfSelector(); | ||
return cy.get(SOURCERER_SAVE_BUTTON).click({ force: true }); | ||
}; | ||
|
||
export const resetSourcerer = () => { | ||
cy.get(SOURCERER_RESET_BUTTON).click(); | ||
clickOutOfSelector(); | ||
return cy.get(SOURCERER_SAVE_BUTTON).click({ force: true }); | ||
}; | ||
|
||
export const setSourcererOption = (patternName: string, sourcererScope?: string) => { | ||
openSourcerer(sourcererScope); | ||
isNotSourcererSelection(patternName, sourcererScope); | ||
selectSourcererOption(patternName, sourcererScope); | ||
}; | ||
|
||
export const unsetSourcererOption = (patternName: string, sourcererScope?: string) => { | ||
openSourcerer(sourcererScope); | ||
isSourcererSelection(patternName, sourcererScope); | ||
deselectSourcererOption(patternName, sourcererScope); | ||
}; | ||
|
||
export const clickTimelineRadio = (radioName: string) => { | ||
let theRadio = SOURCERER_TIMELINE.radioAll; | ||
if (radioName === 'alert') { | ||
theRadio = SOURCERER_TIMELINE.radioAlert; | ||
} | ||
if (radioName === 'raw') { | ||
theRadio = SOURCERER_TIMELINE.radioRaw; | ||
} | ||
return cy.get(theRadio).first().click(); | ||
}; | ||
|
||
export const isCustomRadio = () => { | ||
return cy.get(SOURCERER_TIMELINE.radioCustom).should('be.enabled'); | ||
}; | ||
|
||
export const isNotCustomRadio = () => { | ||
return cy.get(SOURCERER_TIMELINE.radioCustom).should('be.disabled'); | ||
}; | ||
|
||
export const clickOutOfSourcererTimeline = () => cy.get(TIMELINE_TITLE).first().click(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters