Skip to content
Closed
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { getNewRule } from '../../objects/rule';
import { FIELDS_BROWSER_BTN } from '../../screens/rule_details';
import {
DATA_GRID_COLUMN_ORDER_BTN,
DATA_GRID_FIELDS,
DATA_GRID_FULL_SCREEN,
GET_DATA_GRID_HEADER,
GET_DATA_GRID_HEADER_CELL_ACTION_GROUP,
} from '../../screens/shared';
import { createCustomRuleEnabled } from '../../tasks/api_calls/rules';
import { cleanKibana } from '../../tasks/common';
import { waitForAlertsToPopulate } from '../../tasks/create_new_rule';
import { login, visit } from '../../tasks/login';
import { ALERTS_URL } from '../../urls/navigation';

describe('Alert Table Contorls', { testIsolation: false }, () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this structure confused me at first: I've never seen Cypress tests that don't check user actions. I feel like some of the tests here would be better as Jest unit tests as you don't really check user interactions, but just existence of dom elements...

before(() => {
cleanKibana();
login();
createCustomRuleEnabled(getNewRule());
visit(ALERTS_URL);
waitForAlertsToPopulate();
});

it('full screen', () => {
cy.get(DATA_GRID_FULL_SCREEN)
.should('have.attr', 'aria-label', 'Enter fullscreen')
.trigger('click')
.should('have.attr', 'aria-label', 'Exit fullscreen')
.trigger('click');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this trigger here is not useful, you're not testing anything after clicking

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@PhilippeOberti , if you see the describe clause, there is a option called testIsolation: false which makes sure that the page does not refresh after every test so as to save time. Since, page does not refresh, test has to cleanup after itself.

Also, since all tests are different, cleanup cannot same and in afterEach clause.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ok that makes sense! I wonder if it would make it more readable to extract this into a method like exitFullScreen(). But if we only use it once here, not sure its valuable...

});

it('column sorting control exists', () => {
cy.get(DATA_GRID_COLUMN_ORDER_BTN).should('be.visible');
});

it('field Browser Exists', () => {
cy.get(FIELDS_BROWSER_BTN).should('be.visible');
});
Comment on lines +40 to +46
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

these really feel like Jest unit test and not Cypress tests to me, there isn't any user interaction


context('Sorting', () => {
it('Date Column', () => {
const timestampField = DATA_GRID_FIELDS.TIMESTAMP.fieldName;
cy.get(GET_DATA_GRID_HEADER(timestampField)).trigger('click');
cy.get(GET_DATA_GRID_HEADER_CELL_ACTION_GROUP(timestampField))
.should('be.visible')
.should('contain.text', 'Sort Old-New');
cy.get(GET_DATA_GRID_HEADER(timestampField)).trigger('click');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this isn't testing anything

});

it('Number column', () => {
const riskScoreField = DATA_GRID_FIELDS.RISK_SCORE.fieldName;
cy.get(GET_DATA_GRID_HEADER(riskScoreField)).trigger('click');
cy.get(GET_DATA_GRID_HEADER_CELL_ACTION_GROUP(riskScoreField))
.should('be.visible')
.should('contain.text', 'Sort Low-High');
cy.get(GET_DATA_GRID_HEADER(riskScoreField)).trigger('click');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

same here

});

it('Text Column', () => {
const ruleField = DATA_GRID_FIELDS.RULE.fieldName;
cy.get(GET_DATA_GRID_HEADER(ruleField)).trigger('click');
cy.get(GET_DATA_GRID_HEADER_CELL_ACTION_GROUP(ruleField))
.should('be.visible')
.should('contain.text', 'Sort A-Z');
cy.get(GET_DATA_GRID_HEADER(ruleField)).trigger('click');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

and here

});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { getNewRule } from '../../objects/rule';
import { HOST_NAME, USER_NAME } from '../../screens/alerts';
import {
ALERT_FLYOUT,
ALERT_FLYOUT_CLOSE_BTN,
CELL_EXPAND_VALUE,
CELL_EXPANSION_POPOVER,
} from '../../screens/alerts_details';
import {
GLOBAL_SEARCH_BAR_FILTER_ITEM,
GLOBAL_SEARCH_BAR_FILTER_ITEM_DELETE,
} from '../../screens/search_bar';
import {
DATA_GRID_FIELDS,
GET_DATA_GRID_HEADER,
ID_COLUMN_VALUES,
TOP_N_ALERT_HISTOGRAM,
TOP_N_CONTAINER_CLOSE_BTN,
} from '../../screens/shared';
import { HOVER_ACTIONS, TIMELINE_DATA_PROVIDERS_CONTAINER } from '../../screens/timeline';
import { waitForAlerts, waitForTopNHistogramToLoad } from '../../tasks/alerts';
import { createCustomRuleEnabled } from '../../tasks/api_calls/rules';
import { cleanKibana } from '../../tasks/common';
import { waitForAlertsToPopulate } from '../../tasks/create_new_rule';
import { login, visit } from '../../tasks/login';
import { addsFieldsToTimeline } from '../../tasks/rule_details';
import { closeTimelineUsingCloseButton } from '../../tasks/security_main';
import { openActiveTimeline } from '../../tasks/timeline';
import { ALERTS_URL } from '../../urls/navigation';

describe('Alerts Table : Hover Actions', () => {
before(() => {
cleanKibana();
login();
createCustomRuleEnabled(getNewRule(), 'new custom rule');
});

context('Id Column', { testIsolation: false }, () => {
before(() => {
visit(ALERTS_URL);
waitForAlertsToPopulate();
const idColName = DATA_GRID_FIELDS.ID.fieldName;
addsFieldsToTimeline(idColName, [idColName]);
cy.get(GET_DATA_GRID_HEADER(DATA_GRID_FIELDS.ID.fieldName)).should('be.visible');
});
beforeEach(() => {
/*
*
* Since now alert table is different from the tables being used
* in events, we have to create different set of tests for hover actions
* for alerts table.
*
* These tests will be done on `_id` column since there can be difference
* in how `_id` is supplied to the security solution by trigger actions table
*
* */
waitForAlerts();
cy.get(ID_COLUMN_VALUES).first().trigger('mouseover', { timeout: 5000 });
});

it('Filter For', () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

similar comment I made on Christine PR, I feel like the filter in and out tests could be combined into one that test the filter functionality?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

these 2 tests are failing locally for me btw

cannot find [data-test-subj="filter-for-value"]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@PhilippeOberti yes.. it is because of new PR that has merged. I will resolve conflicts soon.

cy.get(ID_COLUMN_VALUES)
.eq(0)
.then(($el) => {
const idTextValue = $el.text();
cy.get(HOVER_ACTIONS.FILTER_FOR).should('exist');
cy.get(HOVER_ACTIONS.FILTER_FOR).trigger('click', { force: true });
cy.get(GLOBAL_SEARCH_BAR_FILTER_ITEM).should('contain.text', `_id: ${idTextValue}`);
cy.get(GLOBAL_SEARCH_BAR_FILTER_ITEM_DELETE).trigger('click');
cy.get(GLOBAL_SEARCH_BAR_FILTER_ITEM).should('not.exist');
});
});

it('Filter Out', () => {
cy.get(ID_COLUMN_VALUES)
.eq(0)
.then(($el) => {
const idTextValue = $el.text();
cy.get(HOVER_ACTIONS.FILTER_OUT).should('exist');
cy.get(HOVER_ACTIONS.FILTER_OUT).trigger('click', { force: true });
cy.get(GLOBAL_SEARCH_BAR_FILTER_ITEM).should('contain.text', `NOT _id: ${idTextValue}`);
cy.get(GLOBAL_SEARCH_BAR_FILTER_ITEM_DELETE).trigger('click');
cy.get(GLOBAL_SEARCH_BAR_FILTER_ITEM).should('not.exist');
});
});

it('Add To Timeline', () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

and this one got stuck in a weird loop checking the same thing over and over again, then finally failed

Screenshot 2023-02-14 at 4 29 38 PM

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@PhilippeOberti , I will check why this is happening, thanks for checking it out.

cy.get(ID_COLUMN_VALUES)
.eq(0)
.then(($el) => {
const idTextValue = $el.text();
cy.get(HOVER_ACTIONS.ADD_TO_TIMELINE).should('exist');
cy.get(HOVER_ACTIONS.ADD_TO_TIMELINE).trigger('click', { force: true });
openActiveTimeline();
cy.get(TIMELINE_DATA_PROVIDERS_CONTAINER).should('be.visible');
cy.get(TIMELINE_DATA_PROVIDERS_CONTAINER).should('contain.text', idTextValue);
closeTimelineUsingCloseButton();
});
});
});

context('Host Column', { testIsolation: false }, () => {
before(() => {
visit(ALERTS_URL);
waitForAlerts();
});
beforeEach(() => {
cy.get(HOST_NAME).first().trigger('mouseover', { timeout: 5000 });
// we want to trigger second set of hover actions on host column
// first is on _id column
cy.get(CELL_EXPAND_VALUE).first().should('exist');
cy.get(CELL_EXPAND_VALUE).first().trigger('click', { force: true });
cy.get(CELL_EXPANSION_POPOVER).should('be.visible');
});

it('TopN', () => {
cy.get(HOVER_ACTIONS.SHOW_TOP).should('be.visible').trigger('click');
waitForTopNHistogramToLoad();
cy.get(TOP_N_ALERT_HISTOGRAM).should('be.visible');
cy.get(TOP_N_CONTAINER_CLOSE_BTN).trigger('click', { force: true });
cy.get(TOP_N_ALERT_HISTOGRAM).should('not.exist');
// close the expanded popover
cy.get(CELL_EXPAND_VALUE).first().click({ force: true });
});

it('Host Summary', () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

if I understand correctly, this test is basically testing that the flyout shows up when clicking on an hover action, then that it disappears when clicking on the close (cross) button?

I feel like testing the closing is unnecessary as it's being handled by the EuiFlyout isn't it?

Also I feel like testing the opening when clicking on the hover action could be bundled with a test that actually tests something within the flyout?

cy.get(HOVER_ACTIONS.VIEW_HOST_SUMMARY).should('be.visible').trigger('click');
cy.get(ALERT_FLYOUT).should('exist');
/*
*
* Currently hover actions popover does not close automatically when clicked
* on an action when using cypress
*
* */
cy.get(ALERT_FLYOUT).trigger('click');
cy.get(ALERT_FLYOUT_CLOSE_BTN).trigger('click');
cy.get(ALERT_FLYOUT).should('not.exist');
});
});

context('User Column', { testIsolation: false }, () => {
before(() => {
visit(ALERTS_URL);
waitForAlerts();
});
beforeEach(() => {
cy.get('.euiDataGrid__virtualized').scrollTo('right');
cy.get(USER_NAME).first().trigger('mouseover', { timeout: 5000 });
// we want to trigger second set of hover actions on host column
// first is on _id column
cy.get(CELL_EXPAND_VALUE).first().should('exist');
cy.get(CELL_EXPAND_VALUE).first().trigger('click', { force: true });
cy.get(CELL_EXPANSION_POPOVER).should('be.visible');
});

it('User Summary', () => {
cy.get(HOVER_ACTIONS.VIEW_USER_SUMMARY).should('be.visible').trigger('click');
cy.get(ALERT_FLYOUT).should('exist');
/*
*
* Currently hover actions popover does not close automatically when clicked
* on an action when using cypress
*
* */
cy.get(ALERT_FLYOUT).trigger('click');
cy.get(ALERT_FLYOUT_CLOSE_BTN).trigger('click');
cy.get(ALERT_FLYOUT).should('not.exist');
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { getNewRule } from '../../objects/rule';
import { EVENT_SUMMARY_ALERT_RENDERER_CONTENT, EVENT_SUMMARY_COLUMN } from '../../screens/alerts';
import { ALERT_RENDERER_HOST_NAME } from '../../screens/common/event_renderer';
import { FIELDS_BROWSER_VIEW_BUTTON } from '../../screens/fields_browser';
import {
DATA_GRID_COLUMN_ORDER_BTN,
DATA_GRID_FIELD_SORT_BTN,
TOP_N_ALERT_HISTOGRAM,
TOP_N_CONTAINER_CLOSE_BTN,
} from '../../screens/shared';
import { HOVER_ACTIONS } from '../../screens/timeline';
import {
switchAlertTableToEventRenderedView,
waitForAlerts,
waitForTopNHistogramToLoad,
} from '../../tasks/alerts';
import { createCustomRuleEnabled } from '../../tasks/api_calls/rules';
import { cleanKibana } from '../../tasks/common';
import { login, visit } from '../../tasks/login';
import { ALERTS_URL } from '../../urls/navigation';

describe('Test Event Rendered View', { testIsolation: false }, () => {
before(() => {
cleanKibana();
login();
createCustomRuleEnabled(getNewRule(), 'new custom rule');
visit(ALERTS_URL);
waitForAlerts();
switchAlertTableToEventRenderedView();
});

it('Field Browser is not visible', () => {
cy.get(FIELDS_BROWSER_VIEW_BUTTON).should('not.exist');
});

it('Sorting control is not visible', () => {
cy.get(DATA_GRID_FIELD_SORT_BTN).should('not.be.visible');
});

it('Column Order button is not visible', () => {
cy.get(DATA_GRID_COLUMN_ORDER_BTN).should('not.exist');
});

it('Event Summary Column + Hover Actions', () => {
cy.get(EVENT_SUMMARY_COLUMN).should('be.visible');
cy.get(EVENT_SUMMARY_ALERT_RENDERER_CONTENT).should('be.visible');

cy.get(ALERT_RENDERER_HOST_NAME).first().trigger('mouseover');

cy.get(HOVER_ACTIONS.SHOW_TOP).trigger('click');
waitForTopNHistogramToLoad();
cy.get(TOP_N_ALERT_HISTOGRAM).should('be.visible');
cy.get(TOP_N_CONTAINER_CLOSE_BTN).trigger('click');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import type { CustomRule } from '../../objects/rule';
import { getNewThreatIndicatorRule } from '../../objects/rule';
import {
ALERTS_COUNT,
ALERT_TABLE_ADDITIONAL_CONTROLS,
ALERT_TABLE_SHOW_THREAT_INDICATOR,
} from '../../screens/alerts';
import { goToRuleDetails } from '../../tasks/alerts_detection_rules';
import { cleanKibana } from '../../tasks/common';
import {
createAndEnableRule,
fillAboutRuleAndContinue,
fillDefineIndicatorMatchRuleAndContinue,
fillScheduleRuleAndContinue,
selectIndicatorMatchType,
waitForAlertsToPopulate,
} from '../../tasks/create_new_rule';
import { esArchiverLoad, esArchiverUnload } from '../../tasks/es_archiver';
import { login, visit, visitWithoutDateRange } from '../../tasks/login';
import { ALERTS_URL, RULE_CREATION } from '../../urls/navigation';

describe('Threat Indicator', () => {
before(() => {
cleanKibana();
esArchiverLoad('threat_indicator');
esArchiverLoad('suspicious_source_event');
login();
const rule = getNewThreatIndicatorRule();
visitWithoutDateRange(RULE_CREATION);
selectIndicatorMatchType();
fillDefineIndicatorMatchRuleAndContinue(rule);
fillAboutRuleAndContinue({ name: rule.name, description: rule.description } as CustomRule);
fillScheduleRuleAndContinue(rule);
createAndEnableRule();
});

after(() => {
esArchiverUnload('threat_indicator');
esArchiverUnload('suspicious_source_event');
});

it('Rule Details Page', () => {
goToRuleDetails();
waitForAlertsToPopulate();
cy.get(ALERTS_COUNT).should('have.text', '1 alert');
cy.get(ALERT_TABLE_ADDITIONAL_CONTROLS).trigger('click');
cy.get(ALERT_TABLE_SHOW_THREAT_INDICATOR)
.pipe(($el) => $el.trigger('click'))
.should('be.checked');
waitForAlertsToPopulate();
cy.get(ALERTS_COUNT).should('have.text', '1 alert');
});

it('Alert Page', () => {
visit(ALERTS_URL);
waitForAlertsToPopulate();
cy.get(ALERTS_COUNT).should('have.text', '1 alert');
cy.get(ALERT_TABLE_ADDITIONAL_CONTROLS).trigger('click');
cy.get(ALERT_TABLE_SHOW_THREAT_INDICATOR)
.pipe(($el) => $el.trigger('click'))
.should('be.checked');
waitForAlertsToPopulate();
cy.get(ALERTS_COUNT).should('have.text', '1 alert');
});
});
Loading