mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Cloud Security] fix rules flaky test suite (#212198)
## Summary This PR fixes the flakiness of of rules page test suite - https://github.com/elastic/kibana/issues/178413 Issues there were handled are: 1. Removing the set up of fleet server before every test which caused flakiness.  2. Fixing race conditions. 3. Use retry.try function to re-execute in places where flakiness was observed due to not waiting enough time before doing the action. ### Checklist Reviewers should verify this PR satisfies this list as well. - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
This commit is contained in:
parent
f5c4f203fc
commit
14e7f6007e
6 changed files with 554 additions and 284 deletions
|
@ -25,6 +25,8 @@ export const RULE_NUMBER_FILTER = 'options-filter-popover-button-rule-number-mul
|
|||
export const RULE_NUMBER_FILTER_SEARCH_FIELD = 'rule-number-search-input';
|
||||
export const RULES_FLYOUT_SWITCH_BUTTON = 'rule-flyout-switch-button';
|
||||
export const TAKE_ACTION_BUTTON = 'csp:take_action';
|
||||
export const CLOSE_FLYOUT_BUTTON = 'euiFlyoutCloseButton';
|
||||
export const CLOSE_TOAST_BUTTON = 'toastCloseButton';
|
||||
|
||||
export function RulePagePageProvider({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
@ -131,6 +133,29 @@ export function RulePagePageProvider({ getService, getPageObjects }: FtrProvider
|
|||
const rulesFlyoutEnableSwitchButton = await testSubjects.find(RULES_FLYOUT_SWITCH_BUTTON);
|
||||
return await rulesFlyoutEnableSwitchButton.getAttribute('aria-checked');
|
||||
},
|
||||
closeToasts: async () => {
|
||||
const toasts = await testSubjects.findAll(CLOSE_TOAST_BUTTON);
|
||||
for (const toast of toasts) {
|
||||
await toast.click();
|
||||
}
|
||||
},
|
||||
togglEnableRulesRowSwitchButton: async (index: number, filterType: 'enable' | 'disable') => {
|
||||
const enableRulesRowSwitches = await testSubjects.findAll(RULES_ROWS_ENABLE_SWITCH_BUTTON);
|
||||
const checked = await enableRulesRowSwitches[index].getAttribute('aria-checked');
|
||||
|
||||
if (filterType === 'enable' && checked) {
|
||||
return;
|
||||
}
|
||||
if (filterType === 'disable' && !checked) {
|
||||
return;
|
||||
}
|
||||
await enableRulesRowSwitches[index].click();
|
||||
},
|
||||
|
||||
clickCloseFlyoutButton: async () => {
|
||||
const closeFlyoutButton = await testSubjects.find(CLOSE_FLYOUT_BUTTON);
|
||||
await closeFlyoutButton.click();
|
||||
},
|
||||
|
||||
clickTakeActionButton: async () => {
|
||||
const takeActionButton = await testSubjects.find(TAKE_ACTION_BUTTON);
|
||||
|
@ -162,10 +187,17 @@ export function RulePagePageProvider({ getService, getPageObjects }: FtrProvider
|
|||
},
|
||||
|
||||
clickIntegrationsEvaluatedButton: async () => {
|
||||
const integrationsEvaluatedButton = await testSubjects.find(
|
||||
'rules-counters-integrations-evaluated-button'
|
||||
);
|
||||
await integrationsEvaluatedButton.click();
|
||||
await retry.try(async () => {
|
||||
const integrationsEvaluatedButton = await testSubjects.find(
|
||||
'rules-counters-integrations-evaluated-button'
|
||||
);
|
||||
// Check that href exists and is not empty
|
||||
const href = await integrationsEvaluatedButton.getAttribute('href');
|
||||
if (!href) {
|
||||
throw new Error('Integration link is not ready yet - href is empty');
|
||||
}
|
||||
await integrationsEvaluatedButton.click();
|
||||
});
|
||||
},
|
||||
|
||||
getFailedFindingsCounter: async () => {
|
||||
|
|
|
@ -19,7 +19,9 @@ export default function ({ getPageObjects, loadTestFile }: FtrProviderContext) {
|
|||
await cspSecurity.createUsers();
|
||||
});
|
||||
|
||||
loadTestFile(require.resolve('./rules'));
|
||||
loadTestFile(require.resolve('./rules/rules_counters'));
|
||||
loadTestFile(require.resolve('./rules/rules_table'));
|
||||
loadTestFile(require.resolve('./rules/rules_table_headers'));
|
||||
loadTestFile(require.resolve('./findings_onboarding'));
|
||||
loadTestFile(require.resolve('./findings'));
|
||||
loadTestFile(require.resolve('./findings_grouping'));
|
||||
|
|
|
@ -1,279 +0,0 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
|
||||
import { createPackagePolicy } from '../../api_integration/apis/cloud_security_posture/helper';
|
||||
import type { FtrProviderContext } from '../ftr_provider_context';
|
||||
import {
|
||||
RULES_BULK_ACTION_OPTION_DISABLE,
|
||||
RULES_BULK_ACTION_OPTION_ENABLE,
|
||||
} from '../page_objects/rule_page';
|
||||
import { k8sFindingsMock } from '../mocks/latest_findings_mock';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
const pageObjects = getPageObjects([
|
||||
'common',
|
||||
'cloudPostureDashboard',
|
||||
'rule',
|
||||
'header',
|
||||
'findings',
|
||||
]);
|
||||
|
||||
// FLAKY: https://github.com/elastic/kibana/issues/178413
|
||||
describe.skip('Cloud Posture Rules Page', function () {
|
||||
this.tags(['cloud_security_posture_rules_page']);
|
||||
let rule: typeof pageObjects.rule;
|
||||
let findings: typeof pageObjects.findings;
|
||||
let agentPolicyId: string;
|
||||
|
||||
beforeEach(async () => {
|
||||
rule = pageObjects.rule;
|
||||
findings = pageObjects.findings;
|
||||
|
||||
await kibanaServer.savedObjects.cleanStandardList();
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
|
||||
|
||||
const { body: agentPolicyResponse } = await supertest
|
||||
.post(`/api/fleet/agent_policies`)
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.send({
|
||||
name: 'Test policy',
|
||||
namespace: 'default',
|
||||
});
|
||||
|
||||
agentPolicyId = agentPolicyResponse.item.id;
|
||||
|
||||
await createPackagePolicy(
|
||||
supertest,
|
||||
agentPolicyId,
|
||||
'kspm',
|
||||
'cloudbeat/cis_k8s',
|
||||
'vanilla',
|
||||
'kspm'
|
||||
);
|
||||
await rule.waitForPluginInitialized();
|
||||
await findings.index.add(k8sFindingsMock);
|
||||
await rule.navigateToRulePage('cis_k8s', '1.0.1');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await kibanaServer.savedObjects.cleanStandardList();
|
||||
await esArchiver.unload('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
|
||||
await findings.index.remove();
|
||||
});
|
||||
|
||||
describe('Rules Page - Rules Counters', () => {
|
||||
it('Shows posture score when there are findings', async () => {
|
||||
const isEmptyStateVisible = await rule.rulePage.getCountersEmptyState();
|
||||
expect(isEmptyStateVisible).to.be(false);
|
||||
|
||||
const postureScoreCounter = await rule.rulePage.getPostureScoreCounter();
|
||||
expect((await postureScoreCounter.getVisibleText()).includes('33%')).to.be(true);
|
||||
});
|
||||
|
||||
it('Clicking the posture score button leads to the dashboard', async () => {
|
||||
await rule.rulePage.clickPostureScoreButton();
|
||||
await pageObjects.common.waitUntilUrlIncludes('cloud_security_posture/dashboard');
|
||||
});
|
||||
|
||||
it('Shows integrations count when there are findings', async () => {
|
||||
const integrationsCounter = await rule.rulePage.getIntegrationsEvaluatedCounter();
|
||||
expect((await integrationsCounter.getVisibleText()).includes('1')).to.be(true);
|
||||
});
|
||||
|
||||
it('Clicking the integrations counter button leads to the integration page', async () => {
|
||||
await rule.rulePage.clickIntegrationsEvaluatedButton();
|
||||
await pageObjects.common.waitUntilUrlIncludes('add-integration/kspm');
|
||||
});
|
||||
|
||||
it('Shows the failed findings counter when there are findings', async () => {
|
||||
const failedFindingsCounter = await rule.rulePage.getFailedFindingsCounter();
|
||||
expect((await failedFindingsCounter.getVisibleText()).includes('2')).to.be(true);
|
||||
});
|
||||
|
||||
it('Clicking the failed findings button leads to the findings page', async () => {
|
||||
await rule.rulePage.clickFailedFindingsButton();
|
||||
await pageObjects.common.waitUntilUrlIncludes(
|
||||
'cloud_security_posture/findings/configurations'
|
||||
);
|
||||
});
|
||||
|
||||
it('Shows the disabled rules count', async () => {
|
||||
const disabledRulesCounter = await rule.rulePage.getDisabledRulesCounter();
|
||||
expect((await disabledRulesCounter.getVisibleText()).includes('0')).to.be(true);
|
||||
|
||||
// disable rule 1.1.1 (k8s findings mock contains a findings from that rule)
|
||||
await rule.rulePage.clickEnableRulesRowSwitchButton(0);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
expect((await disabledRulesCounter.getVisibleText()).includes('1')).to.be(true);
|
||||
|
||||
const postureScoreCounter = await rule.rulePage.getPostureScoreCounter();
|
||||
expect((await postureScoreCounter.getVisibleText()).includes('0%')).to.be(true);
|
||||
|
||||
// enable rule back
|
||||
await rule.rulePage.clickEnableRulesRowSwitchButton(0);
|
||||
});
|
||||
|
||||
it('Clicking the disabled rules button shows enables the disabled filter', async () => {
|
||||
await rule.rulePage.clickEnableRulesRowSwitchButton(0);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
|
||||
await rule.rulePage.clickDisabledRulesButton();
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
expect((await rule.rulePage.getEnableRulesRowSwitchButton()) === 1).to.be(true);
|
||||
});
|
||||
|
||||
it('Shows empty state when there are no findings', async () => {
|
||||
// Ensure there are no findings initially
|
||||
await findings.index.remove();
|
||||
await rule.navigateToRulePage('cis_k8s', '1.0.1');
|
||||
|
||||
const isEmptyStateVisible = await rule.rulePage.getCountersEmptyState();
|
||||
expect(isEmptyStateVisible).to.be(true);
|
||||
await rule.rulePage.clickEnableRulesRowSwitchButton(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Rules Page - Bulk Action buttons', () => {
|
||||
it('It should disable Enable option when there are all rules selected are already enabled ', async () => {
|
||||
await rule.rulePage.clickSelectAllRules();
|
||||
await rule.rulePage.toggleBulkActionButton();
|
||||
expect(
|
||||
(await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_ENABLE)) ===
|
||||
'true'
|
||||
).to.be(true);
|
||||
expect(
|
||||
(await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_DISABLE)) ===
|
||||
'true'
|
||||
).to.be(false);
|
||||
});
|
||||
|
||||
it('It should disable both Enable and Disable options when there are no rules selected', async () => {
|
||||
await rule.rulePage.toggleBulkActionButton();
|
||||
expect(
|
||||
(await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_ENABLE)) ===
|
||||
'true'
|
||||
).to.be(true);
|
||||
expect(
|
||||
(await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_DISABLE)) ===
|
||||
'true'
|
||||
).to.be(true);
|
||||
});
|
||||
|
||||
it('It should disable Disable option when there are all rules selected are already Disabled', async () => {
|
||||
await rule.rulePage.clickSelectAllRules();
|
||||
await rule.rulePage.toggleBulkActionButton();
|
||||
await rule.rulePage.clickBulkActionOption(RULES_BULK_ACTION_OPTION_DISABLE);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
await rule.rulePage.clickSelectAllRules();
|
||||
await rule.rulePage.toggleBulkActionButton();
|
||||
expect(
|
||||
(await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_ENABLE)) ===
|
||||
'true'
|
||||
).to.be(false);
|
||||
expect(
|
||||
(await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_DISABLE)) ===
|
||||
'true'
|
||||
).to.be(true);
|
||||
});
|
||||
|
||||
it('Both option should not be disabled if selected rules contains both enabled and disabled rules', async () => {
|
||||
await rule.rulePage.clickEnableRulesRowSwitchButton(0);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
await rule.rulePage.clickSelectAllRules();
|
||||
await rule.rulePage.toggleBulkActionButton();
|
||||
expect(
|
||||
(await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_ENABLE)) ===
|
||||
'true'
|
||||
).to.be(false);
|
||||
expect(
|
||||
(await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_DISABLE)) ===
|
||||
'true'
|
||||
).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Rules Page - Enable Rules and Disabled Rules Filter Toggle', () => {
|
||||
it('Should only display Enabled rules when Enabled Rules filter is ON', async () => {
|
||||
await rule.rulePage.clickFilterButton('enabled');
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
expect((await rule.rulePage.getEnableRulesRowSwitchButton()) === 1).to.be(true);
|
||||
});
|
||||
|
||||
it('Should only display Disabled rules when Disabled Rules filter is ON', async () => {
|
||||
await rule.rulePage.clickFilterButton('disabled');
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
expect((await rule.rulePage.getEnableRulesRowSwitchButton()) > 1).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Rules Page - CIS Section & Rule Number filters', () => {
|
||||
it('Table should only show result that has the same section as in the Section filter', async () => {
|
||||
await rule.rulePage.clickFilterPopover('section');
|
||||
await rule.rulePage.clickFilterPopOverOption('etcd');
|
||||
await rule.rulePage.clickFilterPopOverOption('Scheduler');
|
||||
expect((await rule.rulePage.getEnableRulesRowSwitchButton()) < 10).to.be(true);
|
||||
});
|
||||
|
||||
it('Table should only show result that has the same section as in the Rule number filter', async () => {
|
||||
await rule.rulePage.clickFilterPopover('ruleNumber');
|
||||
await rule.rulePage.clickFilterPopOverOption('1.1.1');
|
||||
await rule.rulePage.clickFilterPopOverOption('1.1.2');
|
||||
expect((await rule.rulePage.getEnableRulesRowSwitchButton()) === 2).to.be(true);
|
||||
});
|
||||
|
||||
it('Table should only show result that passes both Section and Rule number filter', async () => {
|
||||
await rule.rulePage.clickFilterPopover('section');
|
||||
await rule.rulePage.clickFilterPopOverOption('Control-Plane-Node-Configuration-Files');
|
||||
await rule.rulePage.clickFilterPopover('section');
|
||||
await rule.rulePage.clickFilterPopover('ruleNumber');
|
||||
await rule.rulePage.clickFilterPopOverOption('1.1.5');
|
||||
expect((await rule.rulePage.getEnableRulesRowSwitchButton()) === 1).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Rules Page - Flyout', () => {
|
||||
it('Users are able to Enable/Disable Rule from Switch on Rule Flyout', async () => {
|
||||
await rule.rulePage.clickRulesNames(0);
|
||||
await rule.rulePage.clickFlyoutEnableSwitchButton();
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
expect((await rule.rulePage.getEnableSwitchButtonState()) === 'false').to.be(true);
|
||||
});
|
||||
it('Alerts section of Rules Flyout shows Disabled text when Rules are disabled', async () => {
|
||||
await rule.rulePage.clickRulesNames(0);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
expect(
|
||||
(await rule.rulePage.doesElementExist(
|
||||
'csp:findings-flyout-create-detection-rule-link'
|
||||
)) === false
|
||||
).to.be(true);
|
||||
});
|
||||
it('Users are able to Enable/Disable Rule from Take Action on Rule Flyout', async () => {
|
||||
await rule.rulePage.clickRulesNames(0);
|
||||
await rule.rulePage.clickTakeActionButton();
|
||||
await rule.rulePage.clickTakeActionButtonOption('enable');
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
expect((await rule.rulePage.getEnableSwitchButtonState()) === 'true').to.be(true);
|
||||
});
|
||||
it('Alerts section of Rules Flyout shows Detection Rule Counter component when Rules are enabled', async () => {
|
||||
await rule.rulePage.clickRulesNames(0);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
expect(
|
||||
(await rule.rulePage.doesElementExist(
|
||||
'csp:findings-flyout-create-detection-rule-link'
|
||||
)) === true
|
||||
).to.be(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
|
||||
import { createPackagePolicy } from '../../../api_integration/apis/cloud_security_posture/helper';
|
||||
import type { FtrProviderContext } from '../../ftr_provider_context';
|
||||
import { k8sFindingsMock } from '../../mocks/latest_findings_mock';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
const pageObjects = getPageObjects([
|
||||
'common',
|
||||
'cloudPostureDashboard',
|
||||
'rule',
|
||||
'header',
|
||||
'findings',
|
||||
]);
|
||||
const retryService = getService('retry');
|
||||
|
||||
describe('Cloud Posture Rules Page - Counters', function () {
|
||||
this.tags(['cloud_security_posture_rules_page_counters']);
|
||||
let rule: typeof pageObjects.rule;
|
||||
let findings: typeof pageObjects.findings;
|
||||
let agentPolicyId: string;
|
||||
|
||||
before(async () => {
|
||||
rule = pageObjects.rule;
|
||||
findings = pageObjects.findings;
|
||||
await findings.index.remove();
|
||||
|
||||
// cleanup agent and package policies
|
||||
await kibanaServer.savedObjects.clean({
|
||||
types: [
|
||||
'ingest-agent-policies',
|
||||
'fleet-agent-policies',
|
||||
'ingest-package-policies',
|
||||
'fleet-package-policies',
|
||||
'cloud-security-posture-settings',
|
||||
],
|
||||
});
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
|
||||
|
||||
const { body: agentPolicyResponse } = await supertest
|
||||
.post(`/api/fleet/agent_policies`)
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.send({
|
||||
name: 'Test policy',
|
||||
namespace: 'default',
|
||||
});
|
||||
|
||||
agentPolicyId = agentPolicyResponse.item.id;
|
||||
|
||||
await createPackagePolicy(
|
||||
supertest,
|
||||
agentPolicyId,
|
||||
'kspm',
|
||||
'cloudbeat/cis_k8s',
|
||||
'vanilla',
|
||||
'kspm'
|
||||
);
|
||||
await rule.waitForPluginInitialized();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await findings.index.add(k8sFindingsMock);
|
||||
await rule.navigateToRulePage('cis_k8s', '1.0.1');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await kibanaServer.savedObjects.clean({
|
||||
types: [
|
||||
'ingest-agent-policies',
|
||||
'fleet-agent-policies',
|
||||
'ingest-package-policies',
|
||||
'fleet-package-policies',
|
||||
'cloud-security-posture-settings',
|
||||
],
|
||||
});
|
||||
await esArchiver.unload('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await findings.index.remove();
|
||||
});
|
||||
|
||||
describe('Rules Page - Rules Counters', () => {
|
||||
it('Shows posture score when there are findings', async () => {
|
||||
const isEmptyStateVisible = await rule.rulePage.getCountersEmptyState();
|
||||
expect(isEmptyStateVisible).to.be(false);
|
||||
|
||||
const postureScoreCounter = await rule.rulePage.getPostureScoreCounter();
|
||||
expect((await postureScoreCounter.getVisibleText()).includes('33%')).to.be(true);
|
||||
});
|
||||
|
||||
it('Clicking the posture score button leads to the dashboard', async () => {
|
||||
await retryService.tryForTime(5000, async () => {
|
||||
await rule.rulePage.clickPostureScoreButton();
|
||||
await pageObjects.common.waitUntilUrlIncludes('cloud_security_posture/dashboard');
|
||||
});
|
||||
});
|
||||
|
||||
it('Shows integrations count when there are findings', async () => {
|
||||
const integrationsCounter = await rule.rulePage.getIntegrationsEvaluatedCounter();
|
||||
expect((await integrationsCounter.getVisibleText()).includes('1')).to.be(true);
|
||||
});
|
||||
|
||||
it('Clicking the integrations counter button leads to the integration page', async () => {
|
||||
await rule.rulePage.clickIntegrationsEvaluatedButton();
|
||||
await pageObjects.common.waitUntilUrlIncludes('add-integration/kspm');
|
||||
});
|
||||
|
||||
it('Shows the failed findings counter when there are findings', async () => {
|
||||
const failedFindingsCounter = await rule.rulePage.getFailedFindingsCounter();
|
||||
expect((await failedFindingsCounter.getVisibleText()).includes('2')).to.be(true);
|
||||
});
|
||||
|
||||
it('Clicking the failed findings button leads to the findings page', async () => {
|
||||
await rule.rulePage.clickFailedFindingsButton();
|
||||
await pageObjects.common.waitUntilUrlIncludes(
|
||||
'cloud_security_posture/findings/configurations'
|
||||
);
|
||||
});
|
||||
|
||||
it('Shows the disabled rules count', async () => {
|
||||
const disabledRulesCounter = await rule.rulePage.getDisabledRulesCounter();
|
||||
expect((await disabledRulesCounter.getVisibleText()).includes('0')).to.be(true);
|
||||
|
||||
// disable rule 1.1.1 (k8s findings mock contains a findings from that rule)
|
||||
await rule.rulePage.clickEnableRulesRowSwitchButton(0);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
expect((await disabledRulesCounter.getVisibleText()).includes('1')).to.be(true);
|
||||
|
||||
const postureScoreCounter = await rule.rulePage.getPostureScoreCounter();
|
||||
expect((await postureScoreCounter.getVisibleText()).includes('0%')).to.be(true);
|
||||
|
||||
// enable rule back
|
||||
await rule.rulePage.clickEnableRulesRowSwitchButton(0);
|
||||
});
|
||||
|
||||
it('Clicking the disabled rules button shows enables the disabled filter', async () => {
|
||||
await rule.rulePage.clickEnableRulesRowSwitchButton(0);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
|
||||
await rule.rulePage.clickDisabledRulesButton();
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
expect((await rule.rulePage.getEnableRulesRowSwitchButton()) === 1).to.be(true);
|
||||
});
|
||||
|
||||
it('Shows empty state when there are no findings', async () => {
|
||||
// Ensure there are no findings initially
|
||||
await findings.index.remove();
|
||||
await rule.navigateToRulePage('cis_k8s', '1.0.1');
|
||||
|
||||
const isEmptyStateVisible = await rule.rulePage.getCountersEmptyState();
|
||||
expect(isEmptyStateVisible).to.be(true);
|
||||
await rule.rulePage.clickEnableRulesRowSwitchButton(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
|
||||
import { createPackagePolicy } from '../../../api_integration/apis/cloud_security_posture/helper';
|
||||
import type { FtrProviderContext } from '../../ftr_provider_context';
|
||||
import { k8sFindingsMock } from '../../mocks/latest_findings_mock';
|
||||
import {
|
||||
RULES_BULK_ACTION_OPTION_DISABLE,
|
||||
RULES_BULK_ACTION_OPTION_ENABLE,
|
||||
} from '../../page_objects/rule_page';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
const pageObjects = getPageObjects([
|
||||
'common',
|
||||
'cloudPostureDashboard',
|
||||
'rule',
|
||||
'header',
|
||||
'findings',
|
||||
]);
|
||||
const retryService = getService('retry');
|
||||
|
||||
describe('Cloud Posture Rules Page - Table', function () {
|
||||
this.tags(['cloud_security_posture_rules_page_table']);
|
||||
let rule: typeof pageObjects.rule;
|
||||
let findings: typeof pageObjects.findings;
|
||||
let agentPolicyId: string;
|
||||
|
||||
before(async () => {
|
||||
rule = pageObjects.rule;
|
||||
findings = pageObjects.findings;
|
||||
await findings.index.remove();
|
||||
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
|
||||
|
||||
const { body: agentPolicyResponse } = await supertest
|
||||
.post(`/api/fleet/agent_policies`)
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.send({
|
||||
name: 'Test policy',
|
||||
namespace: 'default',
|
||||
});
|
||||
|
||||
agentPolicyId = agentPolicyResponse.item.id;
|
||||
|
||||
await createPackagePolicy(
|
||||
supertest,
|
||||
agentPolicyId,
|
||||
'kspm',
|
||||
'cloudbeat/cis_k8s',
|
||||
'vanilla',
|
||||
'kspm'
|
||||
);
|
||||
await rule.waitForPluginInitialized();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
// cleanup agent and package policies
|
||||
await kibanaServer.savedObjects.clean({
|
||||
types: [
|
||||
'ingest-agent-policies',
|
||||
'fleet-agent-policies',
|
||||
'ingest-package-policies',
|
||||
'fleet-package-policies',
|
||||
'cloud-security-posture-settings',
|
||||
],
|
||||
});
|
||||
await findings.index.add(k8sFindingsMock);
|
||||
await rule.navigateToRulePage('cis_k8s', '1.0.1');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await kibanaServer.savedObjects.clean({
|
||||
types: [
|
||||
'ingest-agent-policies',
|
||||
'fleet-agent-policies',
|
||||
'ingest-package-policies',
|
||||
'fleet-package-policies',
|
||||
'cloud-security-posture-settings',
|
||||
],
|
||||
});
|
||||
await findings.index.remove();
|
||||
});
|
||||
|
||||
describe('Rules Page - Bulk Action buttons', () => {
|
||||
it('It should disable Enable option when there are all rules selected are already enabled ', async () => {
|
||||
await rule.rulePage.clickSelectAllRules();
|
||||
await rule.rulePage.toggleBulkActionButton();
|
||||
expect(
|
||||
(await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_ENABLE)) ===
|
||||
'true'
|
||||
).to.be(true);
|
||||
expect(
|
||||
(await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_DISABLE)) ===
|
||||
'true'
|
||||
).to.be(false);
|
||||
});
|
||||
|
||||
it('It should disable both Enable and Disable options when there are no rules selected', async () => {
|
||||
await rule.rulePage.toggleBulkActionButton();
|
||||
expect(
|
||||
(await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_ENABLE)) ===
|
||||
'true'
|
||||
).to.be(true);
|
||||
expect(
|
||||
(await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_DISABLE)) ===
|
||||
'true'
|
||||
).to.be(true);
|
||||
});
|
||||
|
||||
it('It should disable Disable option when there are all rules selected are already Disabled', async () => {
|
||||
await rule.rulePage.clickSelectAllRules();
|
||||
await rule.rulePage.toggleBulkActionButton();
|
||||
await rule.rulePage.clickBulkActionOption(RULES_BULK_ACTION_OPTION_DISABLE);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
await rule.rulePage.clickSelectAllRules();
|
||||
await rule.rulePage.toggleBulkActionButton();
|
||||
expect(
|
||||
(await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_ENABLE)) ===
|
||||
'true'
|
||||
).to.be(false);
|
||||
expect(
|
||||
(await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_DISABLE)) ===
|
||||
'true'
|
||||
).to.be(true);
|
||||
});
|
||||
|
||||
it('Both option should not be disabled if selected rules contains both enabled and disabled rules', async () => {
|
||||
await rule.rulePage.clickEnableRulesRowSwitchButton(0);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
await rule.rulePage.clickSelectAllRules();
|
||||
await rule.rulePage.toggleBulkActionButton();
|
||||
expect(
|
||||
(await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_ENABLE)) ===
|
||||
'true'
|
||||
).to.be(false);
|
||||
expect(
|
||||
(await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_DISABLE)) ===
|
||||
'true'
|
||||
).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Rules Page - Flyout', () => {
|
||||
it('Users are able to Enable/Disable Rule from Switch on Rule Flyout', async () => {
|
||||
// Ensure that the first rule is enabled
|
||||
await rule.rulePage.togglEnableRulesRowSwitchButton(0, 'enable');
|
||||
await rule.rulePage.closeToasts();
|
||||
|
||||
await rule.rulePage.clickRulesNames(0);
|
||||
await rule.rulePage.clickFlyoutEnableSwitchButton();
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
|
||||
expect((await rule.rulePage.getEnableSwitchButtonState()) === 'false').to.be(true);
|
||||
await rule.rulePage.clickCloseFlyoutButton();
|
||||
});
|
||||
it('Alerts section of Rules Flyout shows Disabled text when Rules are disabled', async () => {
|
||||
await rule.rulePage.togglEnableRulesRowSwitchButton(0, 'disable');
|
||||
await rule.rulePage.closeToasts();
|
||||
|
||||
await rule.rulePage.clickRulesNames(0);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
expect(
|
||||
(await rule.rulePage.doesElementExist(
|
||||
'csp:findings-flyout-create-detection-rule-link'
|
||||
)) === false
|
||||
).to.be(true);
|
||||
|
||||
await rule.rulePage.clickCloseFlyoutButton();
|
||||
});
|
||||
it('Users are able to Enable/Disable Rule from Take Action on Rule Flyout', async () => {
|
||||
await rule.rulePage.togglEnableRulesRowSwitchButton(0, 'disable');
|
||||
await rule.rulePage.closeToasts();
|
||||
|
||||
await rule.rulePage.clickRulesNames(0);
|
||||
await retryService.try(async () => {
|
||||
await rule.rulePage.clickTakeActionButton();
|
||||
await rule.rulePage.clickTakeActionButtonOption('enable');
|
||||
});
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
expect((await rule.rulePage.getEnableSwitchButtonState()) === 'true').to.be(true);
|
||||
|
||||
await rule.rulePage.clickCloseFlyoutButton();
|
||||
});
|
||||
it('Alerts section of Rules Flyout shows Detection Rule Counter component when Rules are enabled', async () => {
|
||||
await rule.rulePage.clickRulesNames(0);
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
expect(
|
||||
(await rule.rulePage.doesElementExist(
|
||||
'csp:findings-flyout-create-detection-rule-link'
|
||||
)) === true
|
||||
).to.be(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -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
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
|
||||
import { createPackagePolicy } from '../../../api_integration/apis/cloud_security_posture/helper';
|
||||
import type { FtrProviderContext } from '../../ftr_provider_context';
|
||||
import { k8sFindingsMock } from '../../mocks/latest_findings_mock';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
const pageObjects = getPageObjects([
|
||||
'common',
|
||||
'cloudPostureDashboard',
|
||||
'rule',
|
||||
'header',
|
||||
'findings',
|
||||
]);
|
||||
|
||||
describe('Cloud Posture Rules Page - Table Headers', function () {
|
||||
this.tags(['cloud_security_posture_rules_page_table_headers']);
|
||||
let rule: typeof pageObjects.rule;
|
||||
let findings: typeof pageObjects.findings;
|
||||
let agentPolicyId: string;
|
||||
|
||||
before(async () => {
|
||||
rule = pageObjects.rule;
|
||||
findings = pageObjects.findings;
|
||||
await findings.index.remove();
|
||||
|
||||
// cleanup agent and package policies
|
||||
await kibanaServer.savedObjects.clean({
|
||||
types: [
|
||||
'ingest-agent-policies',
|
||||
'fleet-agent-policies',
|
||||
'ingest-package-policies',
|
||||
'fleet-package-policies',
|
||||
'cloud-security-posture-settings',
|
||||
],
|
||||
});
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
|
||||
|
||||
const { body: agentPolicyResponse } = await supertest
|
||||
.post(`/api/fleet/agent_policies`)
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.send({
|
||||
name: 'Test policy',
|
||||
namespace: 'default',
|
||||
});
|
||||
|
||||
agentPolicyId = agentPolicyResponse.item.id;
|
||||
|
||||
await createPackagePolicy(
|
||||
supertest,
|
||||
agentPolicyId,
|
||||
'kspm',
|
||||
'cloudbeat/cis_k8s',
|
||||
'vanilla',
|
||||
'kspm'
|
||||
);
|
||||
await rule.waitForPluginInitialized();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await findings.index.add(k8sFindingsMock);
|
||||
await rule.navigateToRulePage('cis_k8s', '1.0.1');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await kibanaServer.savedObjects.clean({
|
||||
types: [
|
||||
'ingest-agent-policies',
|
||||
'fleet-agent-policies',
|
||||
'ingest-package-policies',
|
||||
'fleet-package-policies',
|
||||
'cloud-security-posture-settings',
|
||||
],
|
||||
});
|
||||
await esArchiver.unload('x-pack/test/functional/es_archives/fleet/empty_fleet_server');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await findings.index.remove();
|
||||
});
|
||||
|
||||
describe('Rules Page - Enable Rules and Disabled Rules Filter Toggle', () => {
|
||||
it('Should only display Enabled rules when Enabled Rules filter is ON', async () => {
|
||||
await rule.rulePage.clickFilterButton('enabled');
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
expect((await rule.rulePage.getEnableRulesRowSwitchButton()) === 25).to.be(true);
|
||||
});
|
||||
|
||||
it('Should only display Disabled rules when Disabled Rules filter is ON', async () => {
|
||||
await rule.rulePage.clickFilterButton('disabled');
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
expect((await rule.rulePage.getEnableRulesRowSwitchButton()) === 0).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Rules Page - CIS Section & Rule Number filters', () => {
|
||||
it('Table should only show result that has the same section as in the Section filter', async () => {
|
||||
await rule.rulePage.closeToasts();
|
||||
await rule.rulePage.clickFilterPopover('section');
|
||||
await rule.rulePage.clickFilterPopOverOption('etcd');
|
||||
await rule.rulePage.clickFilterPopOverOption('Scheduler');
|
||||
expect((await rule.rulePage.getEnableRulesRowSwitchButton()) < 10).to.be(true);
|
||||
});
|
||||
|
||||
it('Table should only show result that has the same section as in the Rule number filter', async () => {
|
||||
await rule.rulePage.closeToasts();
|
||||
await rule.rulePage.clickFilterPopover('ruleNumber');
|
||||
await rule.rulePage.clickFilterPopOverOption('1.1.1');
|
||||
await rule.rulePage.clickFilterPopOverOption('1.1.2');
|
||||
expect((await rule.rulePage.getEnableRulesRowSwitchButton()) === 2).to.be(true);
|
||||
});
|
||||
|
||||
it('Table should only show result that passes both Section and Rule number filter', async () => {
|
||||
await rule.rulePage.closeToasts();
|
||||
await rule.rulePage.clickFilterPopover('section');
|
||||
await rule.rulePage.clickFilterPopOverOption('Control-Plane-Node-Configuration-Files');
|
||||
await rule.rulePage.clickFilterPopover('section');
|
||||
await rule.rulePage.clickFilterPopover('ruleNumber');
|
||||
await rule.rulePage.clickFilterPopOverOption('1.1.5');
|
||||
expect((await rule.rulePage.getEnableRulesRowSwitchButton()) === 1).to.be(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue