Skip to content

Commit

Permalink
[Security Solution] Adds "Creates timeline" Cypress test (elastic#76836
Browse files Browse the repository at this point in the history
…) (elastic#77871)

* adds "Creates timeline" test

* deletes timeline events spec

* completes assertions

* comments assertion

* fixes typecheck error

* waits for all the changes in the timeline to be performed before creating a new timeline and closing the toggle

* fixes failing problem

* fixes loop script

* makes test realiable on visual mode

* fixes merge issue

* makes test more reliable

* fixes typecheck issue

* fixes typecheck

* opens timeline from timeline settings

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
MadameSheema and elasticmachine authored Sep 21, 2020
1 parent e04438a commit ea360ec
Show file tree
Hide file tree
Showing 27 changed files with 307 additions and 95 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
"color": "1.0.3",
"commander": "3.0.2",
"core-js": "^3.6.4",
"cypress-promise": "^1.1.0",
"deep-freeze-strict": "^1.1.1",
"del": "^5.1.0",
"elastic-apm-node": "^3.7.0",
Expand Down
1 change: 1 addition & 0 deletions x-pack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@
"cronstrue": "^1.51.0",
"cypress": "5.0.0",
"cypress-multi-reporters": "^1.2.3",
"cypress-promise": "^1.1.0",
"d3": "3.5.17",
"d3-scale": "1.0.7",
"dragselect": "1.13.1",
Expand Down
3 changes: 3 additions & 0 deletions x-pack/plugins/security_solution/cypress/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@
"plugins": ["cypress"],
"env": {
"cypress/globals": true
},
"rules": {
"import/no-extraneous-dependencies": "off"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
resetFields,
} from '../tasks/fields_browser';
import { loginAndWaitForPage } from '../tasks/login';
import { openTimeline } from '../tasks/security_main';
import { openTimelineUsingToggle } from '../tasks/security_main';
import { openTimelineFieldsBrowser, populateTimeline } from '../tasks/timeline';

import { HOSTS_URL } from '../urls/navigation';
Expand All @@ -48,7 +48,7 @@ describe('Fields Browser', () => {
context('Fields Browser rendering', () => {
before(() => {
loginAndWaitForPage(HOSTS_URL);
openTimeline();
openTimelineUsingToggle();
populateTimeline();
openTimelineFieldsBrowser();
});
Expand Down Expand Up @@ -111,7 +111,7 @@ describe('Fields Browser', () => {
context('Editing the timeline', () => {
before(() => {
loginAndWaitForPage(HOSTS_URL);
openTimeline();
openTimelineUsingToggle();
populateTimeline();
openTimelineFieldsBrowser();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {

import { closesModal, openStatsAndTables } from '../tasks/inspect';
import { loginAndWaitForPage } from '../tasks/login';
import { openTimeline } from '../tasks/security_main';
import { openTimelineUsingToggle } from '../tasks/security_main';
import {
executeTimelineKQL,
openTimelineInspectButton,
Expand Down Expand Up @@ -58,7 +58,7 @@ describe('Inspect', () => {
it('inspects the timeline', () => {
const hostExistsQuery = 'host.name: *';
loginAndWaitForPage(HOSTS_URL);
openTimeline();
openTimelineUsingToggle();
executeTimelineKQL(hostExistsQuery);
openTimelineSettings();
openTimelineInspectButton();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* 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 { timeline } from '../objects/timeline';

import {
FAVORITE_TIMELINE,
LOCKED_ICON,
NOTES,
NOTES_BUTTON,
NOTES_COUNT,
NOTES_TEXT_AREA,
PIN_EVENT,
TIMELINE_DESCRIPTION,
// TIMELINE_FILTER,
TIMELINE_QUERY,
TIMELINE_TITLE,
} from '../screens/timeline';
import {
TIMELINES_DESCRIPTION,
TIMELINES_PINNED_EVENT_COUNT,
TIMELINES_NOTES_COUNT,
TIMELINES_FAVORITE,
} from '../screens/timelines';

import { loginAndWaitForPage } from '../tasks/login';
import { openTimelineUsingToggle } from '../tasks/security_main';
import {
addDescriptionToTimeline,
addFilter,
addNameToTimeline,
addNotesToTimeline,
closeNotes,
closeTimeline,
createNewTimeline,
markAsFavorite,
openTimelineFromSettings,
pinFirstEvent,
populateTimeline,
waitForTimelineChanges,
} from '../tasks/timeline';
import { openTimeline } from '../tasks/timelines';

import { OVERVIEW_URL } from '../urls/navigation';

describe('Timelines', () => {
before(() => {
cy.server();
cy.route('PATCH', '**/api/timeline').as('timeline');
});

it('Creates a timeline', async () => {
loginAndWaitForPage(OVERVIEW_URL);
openTimelineUsingToggle();
populateTimeline();
addFilter(timeline.filter);
pinFirstEvent();

cy.get(PIN_EVENT).should('have.attr', 'aria-label', 'Pinned event');
cy.get(LOCKED_ICON).should('be.visible');

addNameToTimeline(timeline.title);

const response = await cy.wait('@timeline').promisify();
const timelineId = JSON.parse(response.xhr.responseText).data.persistTimeline.timeline
.savedObjectId;

addDescriptionToTimeline(timeline.description);
addNotesToTimeline(timeline.notes);
closeNotes();
markAsFavorite();
waitForTimelineChanges();
createNewTimeline();
closeTimeline();
openTimelineFromSettings();

cy.contains(timeline.title).should('exist');
cy.get(TIMELINES_DESCRIPTION).first().should('have.text', timeline.description);
cy.get(TIMELINES_PINNED_EVENT_COUNT).first().should('have.text', '1');
cy.get(TIMELINES_NOTES_COUNT).first().should('have.text', '1');
cy.get(TIMELINES_FAVORITE).first().should('exist');

openTimeline(timelineId);

cy.get(FAVORITE_TIMELINE).should('exist');
cy.get(TIMELINE_TITLE).should('have.attr', 'value', timeline.title);
cy.get(TIMELINE_DESCRIPTION).should('have.attr', 'value', timeline.description);
cy.get(TIMELINE_QUERY).should('have.text', timeline.query);
// Comments this assertion until we agreed what to do with the filters.
// cy.get(TIMELINE_FILTER(timeline.filter)).should('exist');
cy.get(NOTES_COUNT).should('have.text', '1');
cy.get(PIN_EVENT).should('have.attr', 'aria-label', 'Pinned event');
cy.get(NOTES_BUTTON).click();
cy.get(NOTES_TEXT_AREA).should('have.attr', 'placeholder', 'Add a Note');
cy.get(NOTES).should('have.text', timeline.notes);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from '../tasks/hosts/all_hosts';

import { loginAndWaitForPage } from '../tasks/login';
import { openTimeline } from '../tasks/security_main';
import { openTimelineUsingToggle } from '../tasks/security_main';
import { createNewTimeline } from '../tasks/timeline';

import { HOSTS_URL } from '../urls/navigation';
Expand All @@ -31,7 +31,7 @@ describe('timeline data providers', () => {
});

beforeEach(() => {
openTimeline();
openTimelineUsingToggle();
});

afterEach(() => {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { TIMELINE_FLYOUT_HEADER, TIMELINE_NOT_READY_TO_DROP_BUTTON } from '../sc

import { dragFirstHostToTimeline, waitForAllHostsToBeLoaded } from '../tasks/hosts/all_hosts';
import { loginAndWaitForPage } from '../tasks/login';
import { openTimeline, openTimelineIfClosed } from '../tasks/security_main';
import { openTimelineUsingToggle, openTimelineIfClosed } from '../tasks/security_main';
import { createNewTimeline } from '../tasks/timeline';

import { HOSTS_URL } from '../urls/navigation';
Expand All @@ -25,7 +25,7 @@ describe('timeline flyout button', () => {
});

it('toggles open the timeline', () => {
openTimeline();
openTimelineUsingToggle();
cy.get(TIMELINE_FLYOUT_HEADER).should('have.css', 'visibility', 'visible');
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import { SERVER_SIDE_EVENT_COUNT } from '../screens/timeline';

import { loginAndWaitForPage } from '../tasks/login';
import { openTimeline } from '../tasks/security_main';
import { openTimelineUsingToggle } from '../tasks/security_main';
import { executeTimelineKQL } from '../tasks/timeline';

import { HOSTS_URL } from '../urls/navigation';
Expand All @@ -19,7 +19,7 @@ describe('timeline search or filter KQL bar', () => {

it('executes a KQL query', () => {
const hostExistsQuery = 'host.name: *';
openTimeline();
openTimelineUsingToggle();
executeTimelineKQL(hostExistsQuery);

cy.get(SERVER_SIDE_EVENT_COUNT)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from '../screens/timeline';

import { loginAndWaitForPage } from '../tasks/login';
import { openTimeline } from '../tasks/security_main';
import { openTimelineUsingToggle } from '../tasks/security_main';
import {
checkIdToggleField,
createNewTimeline,
Expand All @@ -30,7 +30,7 @@ describe('toggle column in timeline', () => {
});

beforeEach(() => {
openTimeline();
openTimelineUsingToggle();
populateTimeline();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { exportTimeline, waitForTimelinesPanelToBeLoaded } from '../tasks/timeline';
import { exportTimeline, waitForTimelinesPanelToBeLoaded } from '../tasks/timelines';
import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver';
import { loginAndWaitForPageWithoutDateRange } from '../tasks/login';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { openAllHosts } from '../tasks/hosts/main';

import { waitForIpsTableToBeLoaded } from '../tasks/network/flows';
import { clearSearchBar, kqlSearch, navigateFromHeaderTo } from '../tasks/security_header';
import { openTimeline } from '../tasks/security_main';
import { openTimelineUsingToggle } from '../tasks/security_main';
import {
addDescriptionToTimeline,
addNameToTimeline,
Expand Down Expand Up @@ -82,7 +82,7 @@ describe('url state', () => {

it('sets the timeline start and end dates from the url when locked to global time', () => {
loginAndWaitForPageWithoutDateRange(ABSOLUTE_DATE_RANGE.url);
openTimeline();
openTimelineUsingToggle();

cy.get(DATE_PICKER_START_DATE_POPOVER_BUTTON_TIMELINE).should(
'have.attr',
Expand All @@ -105,7 +105,7 @@ describe('url state', () => {
);
cy.get(DATE_PICKER_END_DATE_POPOVER_BUTTON).should('have.attr', 'title', ABSOLUTE_DATE.endTime);

openTimeline();
openTimelineUsingToggle();

cy.get(DATE_PICKER_START_DATE_POPOVER_BUTTON_TIMELINE).should(
'have.attr',
Expand All @@ -121,7 +121,7 @@ describe('url state', () => {

it('sets the url state when timeline/global date pickers are unlinked and timeline start and end date are set', () => {
loginAndWaitForPageWithoutDateRange(ABSOLUTE_DATE_RANGE.urlUnlinked);
openTimeline();
openTimelineUsingToggle();
setTimelineStartDate(ABSOLUTE_DATE.newStartTimeTyped);
updateTimelineDates();
setTimelineEndDate(ABSOLUTE_DATE.newEndTimeTyped);
Expand Down Expand Up @@ -220,7 +220,7 @@ describe('url state', () => {

it('sets and reads the url state for timeline by id', () => {
loginAndWaitForPage(HOSTS_URL);
openTimeline();
openTimelineUsingToggle();
executeTimelineKQL('host.name: *');

cy.get(SERVER_SIDE_EVENT_COUNT)
Expand Down
24 changes: 24 additions & 0 deletions x-pack/plugins/security_solution/cypress/objects/timeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,30 @@ export interface Timeline {
query: string;
}

export interface CompleteTimeline extends Timeline {
notes: string;
filter: TimelineFilter;
}

export interface TimelineFilter {
field: string;
operator: string;
value?: string;
}

export interface TimelineWithId extends Timeline {
id: string;
}

export const filter: TimelineFilter = {
field: 'host.name',
operator: 'exists',
};

export const timeline: CompleteTimeline = {
title: 'Security Timeline',
description: 'This is the best timeline',
query: 'host.name: * ',
notes: 'Yes, the best timeline',
filter,
};
Loading

0 comments on commit ea360ec

Please sign in to comment.