Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SIEM] Improves event viewer Cypress tests time execution #54117

Merged
merged 4 commits into from
Jan 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion x-pack/legacy/plugins/siem/cypress/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,23 @@ export const USERNAME = '[data-test-subj="loginUsername"]';
We prefer not to mock API responses in most of our smoke tests, but sometimes
it's necessary because a test must assert that a specific value is rendered,
and it's not possible to derive that value based on the data in the
envrionment where tests are running.
environment where tests are running.

Mocked responses API from the server are located in `siem/cypress/fixtures`.

## Speeding up test execution time

Loading the web page takes a big amount of time, in order to minimize that impact, the following points should be
taken into consideration until another solution is implemented:

- Don't refresh the page for every test to clean the state of it.
- Instead, 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.
- If you need to reload the page to make the tests order-independent, consider to create a new context.

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

## Authentication

When running tests, there are two ways to specify the credentials used to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export const HEADER_SUBTITLE = `${EVENTS_VIEWER_PANEL} [data-test-subj="header-p
/** The inspect query modal */
export const INSPECT_MODAL = '[data-test-subj="modal-inspect-euiModal"]';

export const CLOSE_MODAL = '[data-test-subj="modal-inspect-close"]';

/** The inspect query button that launches the inspect query modal */
export const INSPECT_QUERY = `${EVENTS_VIEWER_PANEL} [data-test-subj="inspect-icon-button"]`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
filterSearchBar,
} from '../../lib/events_viewer/helpers';
import {
CLOSE_MODAL,
EVENTS_VIEWER_PANEL,
HEADER_SUBTITLE,
INSPECT_MODAL,
Expand All @@ -39,162 +40,162 @@ const defaultHeadersInDefaultEcsCategory = [
];

describe('Events Viewer', () => {
beforeEach(() => {
loginAndWaitForPage(HOSTS_PAGE);

clickEventsTab();
});

it('renders the fields browser with the expected title when the Events Viewer Fields Browser button is clicked', () => {
openEventsViewerFieldsBrowser();

cy.get(FIELDS_BROWSER_TITLE)
.invoke('text')
.should('eq', 'Customize Columns');
});
context('Fields rendering', () => {
before(() => {
loginAndWaitForPage(HOSTS_PAGE);
clickEventsTab();
});

it('closes the fields browser when the user clicks outside of it', () => {
openEventsViewerFieldsBrowser();
beforeEach(() => {
openEventsViewerFieldsBrowser();
});

clickOutsideFieldsBrowser();
afterEach(() => {
clickOutsideFieldsBrowser();
cy.get(FIELDS_BROWSER_CONTAINER).should('not.exist');
});

cy.get(FIELDS_BROWSER_CONTAINER).should('not.exist');
});
it('renders the fields browser with the expected title when the Events Viewer Fields Browser button is clicked', () => {
cy.get(FIELDS_BROWSER_TITLE)
.invoke('text')
.should('eq', 'Customize Columns');
});

it('displays the `default ECS` category (by default)', () => {
openEventsViewerFieldsBrowser();
it('displays the `default ECS` category (by default)', () => {
cy.get(FIELDS_BROWSER_SELECTED_CATEGORY_TITLE)
.invoke('text')
.should('eq', 'default ECS');
});

cy.get(FIELDS_BROWSER_SELECTED_CATEGORY_TITLE)
.invoke('text')
.should('eq', 'default ECS');
it('displays a checked checkbox for all of the default events viewer columns that are also in the default ECS category', () => {
defaultHeadersInDefaultEcsCategory.forEach(header =>
cy.get(`[data-test-subj="field-${header.id}-checkbox"]`).should('be.checked')
);
});
});

it('displays a checked checkbox for all of the default events viewer columns that are also in the default ECS category', () => {
openEventsViewerFieldsBrowser();

defaultHeadersInDefaultEcsCategory.forEach(header =>
cy.get(`[data-test-subj="field-${header.id}-checkbox"]`).should('be.checked')
);
});
context('Events viewer query modal', () => {
before(() => {
loginAndWaitForPage(HOSTS_PAGE);
clickEventsTab();
});

it('removes the message field from the timeline when the user un-checks the field', () => {
const toggleField = 'message';
after(() => {
cy.get(CLOSE_MODAL).click();
cy.get(INSPECT_MODAL, { timeout: DEFAULT_TIMEOUT }).should('not.exist');
});

cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="header-text-${toggleField}"]`).should('exist');
it('launches the inspect query modal when the inspect button is clicked', () => {
// wait for data to load
cy.get(SERVER_SIDE_EVENT_COUNT, { timeout: DEFAULT_TIMEOUT })
.should('exist')
.invoke('text', { timeout: DEFAULT_TIMEOUT })
.should('not.equal', '0');

openEventsViewerFieldsBrowser();
cy.get(INSPECT_QUERY, { timeout: DEFAULT_TIMEOUT })
.should('exist')
.trigger('mousemove', { force: true })
.click({ force: true });

cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="field-${toggleField}-checkbox"]`).uncheck({
force: true,
cy.get(INSPECT_MODAL, { timeout: DEFAULT_TIMEOUT }).should('exist');
});

clickOutsideFieldsBrowser();

cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="header-text-${toggleField}"]`).should(
'not.exist'
);
});

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

cy.get(HEADER_SUBTITLE)
.invoke('text')
.then(text1 => {
cy.get(HEADER_SUBTITLE)
.invoke('text', { timeout: DEFAULT_TIMEOUT })
.should('not.equal', 'Showing: 0 events');
context('Events viewer fields behaviour', () => {
before(() => {
loginAndWaitForPage(HOSTS_PAGE);
clickEventsTab();
});

filterSearchBar(filterInput);
beforeEach(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great add! 😄

openEventsViewerFieldsBrowser();
});

cy.get(HEADER_SUBTITLE)
.invoke('text')
.should(text2 => {
expect(text1).not.to.eq(text2);
});
});
});
it('adds a field to the events viewer when the user clicks the checkbox', () => {
const filterInput = 'host.geo.c';
const toggleField = 'host.geo.city_name';

it('adds a field to the events viewer when the user clicks the checkbox', () => {
const filterInput = 'host.geo.c';
const toggleField = 'host.geo.city_name';
filterFieldsBrowser(filterInput);

openEventsViewerFieldsBrowser();
cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="header-text-${toggleField}"]`).should(
'not.exist'
);

filterFieldsBrowser(filterInput);
cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="field-${toggleField}-checkbox"]`).check({
force: true,
});

cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="header-text-${toggleField}"]`).should(
'not.exist'
);
clickOutsideFieldsBrowser();

cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="field-${toggleField}-checkbox"]`).check({
force: true,
cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="header-text-${toggleField}"]`).should(
'exist'
);
});

clickOutsideFieldsBrowser();
it('resets all fields in the events viewer when `Reset Fields` is clicked', () => {
const filterInput = 'host.geo.c';
const toggleField = 'host.geo.country_name';

cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="header-text-${toggleField}"]`).should('exist');
});
filterFieldsBrowser(filterInput);

it('loads more events when the load more button is clicked', () => {
cy.get(LOCAL_EVENTS_COUNT, { timeout: DEFAULT_TIMEOUT })
.invoke('text')
.then(text1 => {
cy.get(LOCAL_EVENTS_COUNT)
.invoke('text')
.should('equal', '25');

cy.get(LOAD_MORE).click({ force: true });

cy.get(LOCAL_EVENTS_COUNT)
.invoke('text')
.should(text2 => {
expect(text1).not.to.eq(text2);
});
});
});
cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="header-text-${toggleField}"]`).should(
'not.exist'
);

it('launches the inspect query modal when the inspect button is clicked', () => {
// wait for data to load
cy.get(SERVER_SIDE_EVENT_COUNT, { timeout: DEFAULT_TIMEOUT })
.should('exist')
.invoke('text', { timeout: DEFAULT_TIMEOUT })
.should('not.equal', '0');
cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="field-${toggleField}-checkbox"]`).check({
force: true,
});

cy.get(INSPECT_QUERY, { timeout: DEFAULT_TIMEOUT })
.should('exist')
.trigger('mousemove', { force: true })
.click({ force: true });
cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="reset-fields"]`).click({ force: true });

cy.get(INSPECT_MODAL, { timeout: DEFAULT_TIMEOUT }).should('exist');
cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="header-text-${toggleField}"]`).should(
'not.exist'
);
});
});

it('resets all fields in the events viewer when `Reset Fields` is clicked', () => {
const filterInput = 'host.geo.c';
const toggleField = 'host.geo.city_name';

openEventsViewerFieldsBrowser();

filterFieldsBrowser(filterInput);

cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="header-text-${toggleField}"]`).should(
'not.exist'
);

cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="field-${toggleField}-checkbox"]`).check({
force: true,
context('Events behaviour', () => {
before(() => {
loginAndWaitForPage(HOSTS_PAGE);
clickEventsTab();
});

clickOutsideFieldsBrowser();
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

cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="header-text-${toggleField}"]`).should('exist');
cy.get(HEADER_SUBTITLE)
.invoke('text')
.then(text1 => {
cy.get(HEADER_SUBTITLE)
.invoke('text', { timeout: DEFAULT_TIMEOUT })
.should('not.equal', 'Showing: 0 events');

openEventsViewerFieldsBrowser();
filterSearchBar(filterInput);

cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="reset-fields"]`).click({ force: true });
cy.get(HEADER_SUBTITLE)
.invoke('text')
.should(text2 => {
expect(text1).not.to.eq(text2);
});
});
});

cy.get(`${EVENTS_VIEWER_PANEL} [data-test-subj="header-text-${toggleField}"]`).should(
'not.exist'
);
it('loads more events when the load more button is clicked', () => {
cy.get(LOCAL_EVENTS_COUNT, { timeout: DEFAULT_TIMEOUT })
.invoke('text')
.then(text1 => {
cy.get(LOCAL_EVENTS_COUNT)
.invoke('text')
.should('equal', '25');

cy.get(LOAD_MORE).click({ force: true });

cy.get(LOCAL_EVENTS_COUNT)
.invoke('text')
.should(text2 => {
expect(text1).not.to.eq(text2);
});
});
});
});
});