From 14410e0c79bdced1e402c3a303729f7328207efb Mon Sep 17 00:00:00 2001
From: Paul Tavares <56442535+paul-tavares@users.noreply.github.com>
Date: Tue, 9 Jun 2020 13:47:00 -0400
Subject: [PATCH] [Endpoint] Re-enable Functional test case for Endpoint
related pages (#68445)
* Improve Policy test service provider
- Added `getFullAgentConfig()` to Endpoint Policy Test data provider service
* enable Policy List functional tests
* Added Policy Details Tests
* Add test ids to policy detail Max and Linux forms
* Added page objects utilities and moved `clickOnEuiCheckbox` there
---
.../pages/policy/view/policy_details.tsx | 14 +-
.../view/policy_forms/events/checkbox.tsx | 17 +-
.../policy/view/policy_forms/events/linux.tsx | 1 +
.../policy/view/policy_forms/events/mac.tsx | 1 +
.../view/policy_forms/events/windows.tsx | 1 +
x-pack/scripts/functional_tests.js | 1 +
.../{host_list.ts => endpoint_list.ts} | 43 ++--
.../feature_controls/endpoint_spaces.ts | 76 ------
.../apps/endpoint/feature_controls/index.ts | 13 -
.../apps/endpoint/header_nav.ts | 55 -----
.../apps/endpoint/index.ts | 11 +-
.../apps/endpoint/landing_page.ts | 29 ---
.../apps/endpoint/policy_details.ts | 225 ++++++++++++++++++
.../apps/endpoint/policy_list.ts | 46 ++--
.../page_objects/endpoint_page.ts | 17 +-
.../functional_endpoint/page_objects/index.ts | 4 +
.../page_objects/page_utils.ts | 30 +++
.../page_objects/policy_page.ts | 59 +++++
.../services/endpoint_policy.ts | 163 +++++++++----
19 files changed, 522 insertions(+), 284 deletions(-)
rename x-pack/test/functional_endpoint/apps/endpoint/{host_list.ts => endpoint_list.ts} (84%)
delete mode 100644 x-pack/test/functional_endpoint/apps/endpoint/feature_controls/endpoint_spaces.ts
delete mode 100644 x-pack/test/functional_endpoint/apps/endpoint/feature_controls/index.ts
delete mode 100644 x-pack/test/functional_endpoint/apps/endpoint/header_nav.ts
delete mode 100644 x-pack/test/functional_endpoint/apps/endpoint/landing_page.ts
create mode 100644 x-pack/test/functional_endpoint/apps/endpoint/policy_details.ts
create mode 100644 x-pack/test/functional_endpoint/page_objects/page_utils.ts
create mode 100644 x-pack/test/functional_endpoint/page_objects/policy_page.ts
diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx
index f4c4b36ce153f..d1f7da91bd6fa 100644
--- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx
@@ -68,11 +68,13 @@ export const PolicyDetails = React.memo(() => {
}
),
body: (
-
+
+
+
),
});
} else {
@@ -116,7 +118,7 @@ export const PolicyDetails = React.memo(() => {
) : policyApiError ? (
- {policyApiError?.message}
+ {policyApiError?.message}
) : null}
diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/checkbox.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/checkbox.tsx
index e5f3b2c7e8b7e..9ceade5d0264c 100644
--- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/checkbox.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/checkbox.tsx
@@ -5,23 +5,25 @@
*/
import React, { useCallback, useMemo } from 'react';
-import { EuiCheckbox, htmlIdGenerator } from '@elastic/eui';
+import { EuiCheckbox, EuiCheckboxProps, htmlIdGenerator } from '@elastic/eui';
import { useDispatch } from 'react-redux';
-
import { usePolicyDetailsSelector } from '../../policy_hooks';
import { policyConfig } from '../../../store/policy_details/selectors';
import { PolicyDetailsAction } from '../../../store/policy_details';
import { UIPolicyConfig } from '../../../../../../../common/endpoint/types';
+type EventsCheckboxProps = Omit & {
+ name: string;
+ setter: (config: UIPolicyConfig, checked: boolean) => UIPolicyConfig;
+ getter: (config: UIPolicyConfig) => boolean;
+};
+
export const EventsCheckbox = React.memo(function ({
name,
setter,
getter,
-}: {
- name: string;
- setter: (config: UIPolicyConfig, checked: boolean) => UIPolicyConfig;
- getter: (config: UIPolicyConfig) => boolean;
-}) {
+ ...otherProps
+}: EventsCheckboxProps) {
const policyDetailsConfig = usePolicyDetailsSelector(policyConfig);
const selected = getter(policyDetailsConfig);
const dispatch = useDispatch<(action: PolicyDetailsAction) => void>();
@@ -44,6 +46,7 @@ export const EventsCheckbox = React.memo(function ({
label={name}
checked={selected}
onChange={handleCheckboxChange}
+ {...otherProps}
/>
);
});
diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/linux.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/linux.tsx
index d0ddd5cb6fe2f..d7bae0d2e6bad 100644
--- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/linux.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/linux.tsx
@@ -73,6 +73,7 @@ export const LinuxEvents = React.memo(() => {
setIn(config)(item.os)('events')(item.protectionField)(checked)
}
diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/mac.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/mac.tsx
index e2d6b70d33415..37709ff608857 100644
--- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/mac.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/mac.tsx
@@ -73,6 +73,7 @@ export const MacEvents = React.memo(() => {
setIn(config)(item.os)('events')(item.protectionField)(checked)
}
diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/windows.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/windows.tsx
index 23f33cb6fd86f..3c7ecae0d9b4e 100644
--- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/windows.tsx
+++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/events/windows.tsx
@@ -113,6 +113,7 @@ export const WindowsEvents = React.memo(() => {
setIn(config)(item.os)('events')(item.protectionField)(checked)
}
diff --git a/x-pack/scripts/functional_tests.js b/x-pack/scripts/functional_tests.js
index 4392299a78e72..c120e1f780761 100644
--- a/x-pack/scripts/functional_tests.js
+++ b/x-pack/scripts/functional_tests.js
@@ -6,6 +6,7 @@
const alwaysImportedTests = [
require.resolve('../test/functional/config.js'),
+ require.resolve('../test/functional_endpoint/config.ts'),
require.resolve('../test/functional_with_es_ssl/config.ts'),
require.resolve('../test/functional/config_security_basic.ts'),
require.resolve('../test/functional/config_security_trial.ts'),
diff --git a/x-pack/test/functional_endpoint/apps/endpoint/host_list.ts b/x-pack/test/functional_endpoint/apps/endpoint/endpoint_list.ts
similarity index 84%
rename from x-pack/test/functional_endpoint/apps/endpoint/host_list.ts
rename to x-pack/test/functional_endpoint/apps/endpoint/endpoint_list.ts
index 029953f113a9c..c5338e2a35765 100644
--- a/x-pack/test/functional_endpoint/apps/endpoint/host_list.ts
+++ b/x-pack/test/functional_endpoint/apps/endpoint/endpoint_list.ts
@@ -13,68 +13,71 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
const testSubjects = getService('testSubjects');
// FLAKY: https://github.com/elastic/kibana/issues/63621
- describe.skip('host list', function () {
+ describe.skip('endpoint list', function () {
this.tags('ciGroup7');
const sleep = (ms = 100) => new Promise((resolve) => setTimeout(resolve, ms));
before(async () => {
await esArchiver.load('endpoint/metadata/api_feature');
- await pageObjects.common.navigateToUrlWithBrowserHistory('endpoint', '/hosts');
- await pageObjects.header.waitUntilLoadingHasFinished();
+ await pageObjects.endpoint.navigateToEndpointList();
});
it('finds title', async () => {
- const title = await testSubjects.getVisibleText('hostListTitle');
- expect(title).to.equal('Hosts');
+ const title = await testSubjects.getVisibleText('pageViewHeaderLeftTitle');
+ expect(title).to.equal('Endpoints');
});
it('displays table data', async () => {
const expectedData = [
[
'Hostname',
+ 'Host Status',
'Policy',
'Policy Status',
'Alerts',
'Operating System',
'IP Address',
- 'Sensor Version',
+ 'Version',
'Last Active',
],
[
'cadmann-4.example.com',
+ 'Error',
'Policy Name',
'Policy Status',
'0',
'windows 10.0',
'10.192.213.130, 10.70.28.129',
- 'version',
- 'xxxx',
+ '6.6.1',
+ 'Jan 24, 2020 @ 16:06:09.541',
],
[
'thurlow-9.example.com',
+ 'Error',
'Policy Name',
'Policy Status',
'0',
'windows 10.0',
'10.46.229.234',
- 'version',
- 'xxxx',
+ '6.0.0',
+ 'Jan 24, 2020 @ 16:06:09.541',
],
[
'rezzani-7.example.com',
+ 'Error',
'Policy Name',
'Policy Status',
'0',
'windows 10.0',
'10.101.149.26, 2606:a000:ffc0:39:11ef:37b9:3371:578c',
- 'version',
- 'xxxx',
+ '6.8.0',
+ 'Jan 24, 2020 @ 16:06:09.541',
],
];
const tableData = await pageObjects.endpoint.getEndpointAppTableData('hostListTable');
expect(tableData).to.eql(expectedData);
});
- it('no details flyout when host page displayed', async () => {
+ it('no details flyout when endpoint page displayed', async () => {
await testSubjects.missingOrFail('hostDetailsFlyout');
});
@@ -108,22 +111,21 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await (await testSubjects.findAll('hostnameCellLink'))[1].click();
await sleep(500); // give page time to refresh and verify it did not change
const hostDetailTitleNew = await testSubjects.getVisibleText('hostDetailsFlyoutTitle');
- expect(hostDetailTitleNew).to.eql(hostDetailTitleInitial);
+ expect(hostDetailTitleNew).to.equal(hostDetailTitleInitial);
});
describe('no data', () => {
before(async () => {
// clear out the data and reload the page
await esArchiver.unload('endpoint/metadata/api_feature');
- await pageObjects.common.navigateToUrlWithBrowserHistory('endpoint', '/hosts');
- await pageObjects.header.waitUntilLoadingHasFinished();
+ await pageObjects.endpoint.navigateToEndpointList();
});
after(async () => {
// reload the data so the other tests continue to pass
await esArchiver.load('endpoint/metadata/api_feature');
});
it('displays no items found when empty', async () => {
- // get the host list table data and verify message
+ // get the endpoint list table data and verify message
const [, [noItemsFoundMessage]] = await pageObjects.endpoint.getEndpointAppTableData(
'hostListTable'
);
@@ -133,12 +135,9 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
describe('has a url with a host id', () => {
before(async () => {
- await pageObjects.common.navigateToUrlWithBrowserHistory(
- 'endpoint',
- '/hosts',
+ await pageObjects.endpoint.navigateToEndpointList(
'selected_host=fc0ff548-feba-41b6-8367-65e8790d0eaf'
);
- await pageObjects.header.waitUntilLoadingHasFinished();
});
it('shows a flyout', async () => {
@@ -168,7 +167,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
'',
'0',
'00000000-0000-0000-0000-000000000000',
- 'Successful',
+ 'Unknown',
'10.101.149.262606:a000:ffc0:39:11ef:37b9:3371:578c',
'rezzani-7.example.com',
'6.8.0',
diff --git a/x-pack/test/functional_endpoint/apps/endpoint/feature_controls/endpoint_spaces.ts b/x-pack/test/functional_endpoint/apps/endpoint/feature_controls/endpoint_spaces.ts
deleted file mode 100644
index 27fabb515757a..0000000000000
--- a/x-pack/test/functional_endpoint/apps/endpoint/feature_controls/endpoint_spaces.ts
+++ /dev/null
@@ -1,76 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-import expect from '@kbn/expect';
-import { FtrProviderContext } from '../../../ftr_provider_context';
-
-export default function ({ getPageObjects, getService }: FtrProviderContext) {
- const pageObjects = getPageObjects(['common']);
- const spacesService = getService('spaces');
- const testSubjects = getService('testSubjects');
- const appsMenu = getService('appsMenu');
-
- describe('spaces', () => {
- describe('space with no features disabled', () => {
- before(async () => {
- await spacesService.create({
- id: 'custom_space',
- name: 'custom_space',
- disabledFeatures: [],
- });
- });
-
- after(async () => {
- await spacesService.delete('custom_space');
- });
-
- it('shows endpoint navlink', async () => {
- await pageObjects.common.navigateToApp('home', {
- basePath: '/s/custom_space',
- });
- const navLinks = (await appsMenu.readLinks()).map((link) => link.text);
- expect(navLinks).to.contain('Endpoint');
- });
-
- it(`endpoint app shows 'Hello World'`, async () => {
- await pageObjects.common.navigateToApp('endpoint', {
- basePath: '/s/custom_space',
- });
- await testSubjects.existOrFail('welcomeTitle');
- });
-
- it(`endpoint hosts shows hosts lists page`, async () => {
- await pageObjects.common.navigateToUrlWithBrowserHistory('endpoint', '/hosts', undefined, {
- basePath: '/s/custom_space',
- ensureCurrentUrl: false,
- shouldLoginIfPrompted: false,
- });
- await testSubjects.existOrFail('hostPage');
- });
- });
-
- describe('space with endpoint disabled', () => {
- before(async () => {
- await spacesService.create({
- id: 'custom_space',
- name: 'custom_space',
- disabledFeatures: ['endpoint'],
- });
- });
-
- after(async () => {
- await spacesService.delete('custom_space');
- });
-
- it(`doesn't show endpoint navlink`, async () => {
- await pageObjects.common.navigateToApp('home', {
- basePath: '/s/custom_space',
- });
- const navLinks = (await appsMenu.readLinks()).map((link) => link.text);
- expect(navLinks).not.to.contain('Endpoint');
- });
- });
- });
-}
diff --git a/x-pack/test/functional_endpoint/apps/endpoint/feature_controls/index.ts b/x-pack/test/functional_endpoint/apps/endpoint/feature_controls/index.ts
deleted file mode 100644
index da0919d7c39f3..0000000000000
--- a/x-pack/test/functional_endpoint/apps/endpoint/feature_controls/index.ts
+++ /dev/null
@@ -1,13 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-import { FtrProviderContext } from '../../../ftr_provider_context';
-
-export default function ({ loadTestFile }: FtrProviderContext) {
- describe('feature controls', function () {
- this.tags('skipFirefox');
- loadTestFile(require.resolve('./endpoint_spaces'));
- });
-}
diff --git a/x-pack/test/functional_endpoint/apps/endpoint/header_nav.ts b/x-pack/test/functional_endpoint/apps/endpoint/header_nav.ts
deleted file mode 100644
index 48cdd6aec5b1a..0000000000000
--- a/x-pack/test/functional_endpoint/apps/endpoint/header_nav.ts
+++ /dev/null
@@ -1,55 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import expect from '@kbn/expect';
-import { FtrProviderContext } from '../../ftr_provider_context';
-
-export default ({ getPageObjects, getService }: FtrProviderContext) => {
- const pageObjects = getPageObjects(['common', 'endpoint']);
- const testSubjects = getService('testSubjects');
-
- describe('Header nav', function () {
- this.tags('ciGroup7');
- before(async () => {
- await pageObjects.common.navigateToApp('endpoint');
- });
-
- it('renders the tabs when the app loads', async () => {
- const homeTabText = await testSubjects.getVisibleText('homeEndpointTab');
- const hostsTabText = await testSubjects.getVisibleText('hostsEndpointTab');
- const alertsTabText = await testSubjects.getVisibleText('alertsEndpointTab');
- const policiesTabText = await testSubjects.getVisibleText('policiesEndpointTab');
-
- expect(homeTabText.trim()).to.be('Home');
- expect(hostsTabText.trim()).to.be('Hosts');
- expect(alertsTabText.trim()).to.be('Alerts');
- expect(policiesTabText.trim()).to.be('Policies');
- });
-
- it('renders the hosts page when the Hosts tab is selected', async () => {
- await (await testSubjects.find('hostsEndpointTab')).click();
- await testSubjects.existOrFail('hostPage');
- });
-
- it('renders the alerts page when the Alerts tab is selected', async () => {
- await (await testSubjects.find('alertsEndpointTab')).click();
- await testSubjects.existOrFail('alertListPage');
- });
-
- it('renders the policy page when Policy tab is selected', async () => {
- await (await testSubjects.find('policiesEndpointTab')).click();
- await testSubjects.existOrFail('policyListPage');
- });
-
- it('renders the home page when Home tab is selected after selecting another tab', async () => {
- await (await testSubjects.find('hostsEndpointTab')).click();
- await testSubjects.existOrFail('hostPage');
-
- await (await testSubjects.find('homeEndpointTab')).click();
- await testSubjects.existOrFail('welcomeTitle');
- });
- });
-};
diff --git a/x-pack/test/functional_endpoint/apps/endpoint/index.ts b/x-pack/test/functional_endpoint/apps/endpoint/index.ts
index 296ee45ff181c..199d138d1c450 100644
--- a/x-pack/test/functional_endpoint/apps/endpoint/index.ts
+++ b/x-pack/test/functional_endpoint/apps/endpoint/index.ts
@@ -9,12 +9,11 @@ export default function ({ loadTestFile }: FtrProviderContext) {
describe('endpoint', function () {
this.tags('ciGroup7');
- loadTestFile(require.resolve('./feature_controls'));
- loadTestFile(require.resolve('./landing_page'));
- loadTestFile(require.resolve('./header_nav'));
- loadTestFile(require.resolve('./host_list'));
+ loadTestFile(require.resolve('./endpoint_list'));
loadTestFile(require.resolve('./policy_list'));
- loadTestFile(require.resolve('./alerts'));
- loadTestFile(require.resolve('./resolver'));
+ loadTestFile(require.resolve('./policy_details'));
+
+ // loadTestFile(require.resolve('./alerts'));
+ // loadTestFile(require.resolve('./resolver'));
});
}
diff --git a/x-pack/test/functional_endpoint/apps/endpoint/landing_page.ts b/x-pack/test/functional_endpoint/apps/endpoint/landing_page.ts
deleted file mode 100644
index f2a55df56421a..0000000000000
--- a/x-pack/test/functional_endpoint/apps/endpoint/landing_page.ts
+++ /dev/null
@@ -1,29 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import expect from '@kbn/expect';
-import { FtrProviderContext } from '../../ftr_provider_context';
-
-export default ({ getPageObjects, getService }: FtrProviderContext) => {
- const pageObjects = getPageObjects(['common', 'endpoint']);
- const testSubjects = getService('testSubjects');
-
- describe('Endpoint landing page', function () {
- this.tags('ciGroup7');
- before(async () => {
- await pageObjects.common.navigateToApp('endpoint');
- });
-
- it('Loads the endpoint app', async () => {
- const welcomeEndpointMessage = await pageObjects.endpoint.welcomeEndpointTitle();
- expect(welcomeEndpointMessage).to.be('Hello World');
- });
-
- it('Does not display a toast indicating that the ingest manager failed to initialize', async () => {
- await testSubjects.missingOrFail('euiToastHeader');
- });
- });
-};
diff --git a/x-pack/test/functional_endpoint/apps/endpoint/policy_details.ts b/x-pack/test/functional_endpoint/apps/endpoint/policy_details.ts
new file mode 100644
index 0000000000000..25fb477b5a99a
--- /dev/null
+++ b/x-pack/test/functional_endpoint/apps/endpoint/policy_details.ts
@@ -0,0 +1,225 @@
+/*
+ * 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 expect from '@kbn/expect';
+import { FtrProviderContext } from '../../ftr_provider_context';
+import { PolicyTestResourceInfo } from '../../services/endpoint_policy';
+
+export default function ({ getPageObjects, getService }: FtrProviderContext) {
+ const pageObjects = getPageObjects(['common', 'endpoint', 'policy', 'endpointPageUtils']);
+ const testSubjects = getService('testSubjects');
+ const policyTestResources = getService('policyTestResources');
+
+ describe('When on the Endpoint Policy Details Page', function () {
+ this.tags(['ciGroup7']);
+
+ describe('with an invalid policy id', () => {
+ it('should display an error', async () => {
+ await pageObjects.policy.navigateToPolicyDetails('invalid-id');
+ await testSubjects.existOrFail('policyDetailsIdNotFoundMessage');
+ expect(await testSubjects.getVisibleText('policyDetailsIdNotFoundMessage')).to.equal(
+ 'Saved object [ingest-datasources/invalid-id] not found'
+ );
+ });
+ });
+
+ describe('with a valid policy id', () => {
+ let policyInfo: PolicyTestResourceInfo;
+
+ before(async () => {
+ policyInfo = await policyTestResources.createPolicy();
+ await pageObjects.policy.navigateToPolicyDetails(policyInfo.datasource.id);
+ });
+
+ after(async () => {
+ if (policyInfo) {
+ await policyInfo.cleanup();
+ }
+ });
+
+ it('should display policy view', async () => {
+ expect(await testSubjects.getVisibleText('pageViewHeaderLeftTitle')).to.equal(
+ policyInfo.datasource.name
+ );
+ });
+ });
+
+ describe('and the save button is clicked', () => {
+ let policyInfo: PolicyTestResourceInfo;
+
+ beforeEach(async () => {
+ policyInfo = await policyTestResources.createPolicy();
+ await pageObjects.policy.navigateToPolicyDetails(policyInfo.datasource.id);
+ });
+
+ afterEach(async () => {
+ if (policyInfo) {
+ await policyInfo.cleanup();
+ }
+ });
+
+ it('should display success toast on successful save', async () => {
+ await pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyWindowsEvent_dns');
+ await pageObjects.policy.confirmAndSave();
+
+ await testSubjects.existOrFail('policyDetailsSuccessMessage');
+ expect(await testSubjects.getVisibleText('policyDetailsSuccessMessage')).to.equal(
+ `Policy ${policyInfo.datasource.name} has been updated.`
+ );
+ });
+ it('should persist update on the screen', async () => {
+ await pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyWindowsEvent_process');
+ await pageObjects.policy.confirmAndSave();
+
+ await testSubjects.existOrFail('policyDetailsSuccessMessage');
+ await pageObjects.policy.navigateToPolicyList();
+ await pageObjects.policy.navigateToPolicyDetails(policyInfo.datasource.id);
+
+ expect(await (await testSubjects.find('policyWindowsEvent_process')).isSelected()).to.equal(
+ false
+ );
+ });
+ it('should have updated policy data in overall agent configuration', async () => {
+ // This test ensures that updates made to the Endpoint Policy are carried all the way through
+ // to the generated Agent Configuration that is dispatch down to the Elastic Agent.
+
+ await Promise.all([
+ pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyWindowsEvent_file'),
+ pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyLinuxEvent_file'),
+ pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyMacEvent_file'),
+ ]);
+ await pageObjects.policy.confirmAndSave();
+ await testSubjects.existOrFail('policyDetailsSuccessMessage');
+
+ const agentFullConfig = await policyTestResources.getFullAgentConfig(
+ policyInfo.agentConfig.id
+ );
+
+ expect(agentFullConfig).to.eql({
+ datasources: [
+ {
+ enabled: true,
+ id: policyInfo.datasource.id,
+ inputs: [
+ {
+ enabled: true,
+ policy: {
+ linux: {
+ advanced: {
+ elasticsearch: {
+ indices: {
+ control: 'control-index',
+ event: 'event-index',
+ logging: 'logging-index',
+ },
+ kernel: {
+ connect: true,
+ process: true,
+ },
+ },
+ },
+ events: {
+ file: false,
+ network: true,
+ process: true,
+ },
+ logging: {
+ file: 'info',
+ stdout: 'debug',
+ },
+ },
+ mac: {
+ advanced: {
+ elasticsearch: {
+ indices: {
+ control: 'control-index',
+ event: 'event-index',
+ logging: 'logging-index',
+ },
+ kernel: {
+ connect: true,
+ process: true,
+ },
+ },
+ },
+ events: {
+ file: false,
+ network: true,
+ process: true,
+ },
+ logging: {
+ file: 'info',
+ stdout: 'debug',
+ },
+ malware: {
+ mode: 'detect',
+ },
+ },
+ windows: {
+ advanced: {
+ elasticsearch: {
+ indices: {
+ control: 'control-index',
+ event: 'event-index',
+ logging: 'logging-index',
+ },
+ kernel: {
+ connect: true,
+ process: true,
+ },
+ },
+ },
+ events: {
+ dll_and_driver_load: true,
+ dns: true,
+ file: false,
+ network: true,
+ process: true,
+ registry: true,
+ security: true,
+ },
+ logging: {
+ file: 'info',
+ stdout: 'debug',
+ },
+ malware: {
+ mode: 'prevent',
+ },
+ },
+ },
+ streams: [],
+ type: 'endpoint',
+ },
+ ],
+ name: 'Protect East Coast',
+ namespace: 'default',
+ package: {
+ name: 'endpoint',
+ version: policyInfo.packageInfo.version,
+ },
+ use_output: 'default',
+ },
+ ],
+ id: policyInfo.agentConfig.id,
+ outputs: {
+ default: {
+ hosts: ['http://localhost:9200'],
+ type: 'elasticsearch',
+ },
+ },
+ revision: 3,
+ settings: {
+ monitoring: {
+ enabled: false,
+ logs: false,
+ metrics: false,
+ },
+ },
+ });
+ });
+ });
+ });
+}
diff --git a/x-pack/test/functional_endpoint/apps/endpoint/policy_list.ts b/x-pack/test/functional_endpoint/apps/endpoint/policy_list.ts
index 11b1b8e718ff7..9f87f884b327e 100644
--- a/x-pack/test/functional_endpoint/apps/endpoint/policy_list.ts
+++ b/x-pack/test/functional_endpoint/apps/endpoint/policy_list.ts
@@ -8,15 +8,15 @@ import { FtrProviderContext } from '../../ftr_provider_context';
import { PolicyTestResourceInfo } from '../../services/endpoint_policy';
export default function ({ getPageObjects, getService }: FtrProviderContext) {
- const pageObjects = getPageObjects(['common', 'endpoint']);
+ const pageObjects = getPageObjects(['common', 'endpoint', 'policy']);
const testSubjects = getService('testSubjects');
const policyTestResources = getService('policyTestResources');
+ const RELATIVE_DATE_FORMAT = /\d (?:seconds|minutes) ago/i;
- // FLAKY: https://github.com/elastic/kibana/issues/66579
- describe.skip('When on the Endpoint Policy List', function () {
+ describe('When on the Endpoint Policy List', function () {
this.tags(['ciGroup7']);
before(async () => {
- await pageObjects.common.navigateToUrlWithBrowserHistory('endpoint', '/policy');
+ await pageObjects.policy.navigateToPolicyList();
});
it('loads the Policy List Page', async () => {
@@ -34,10 +34,12 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
const allHeaderCells = await pageObjects.endpoint.tableHeaderVisibleText('policyTable');
expect(allHeaderCells).to.eql([
'Policy Name',
- 'Revision',
+ 'Created By',
+ 'Created Date',
+ 'Last Updated By',
+ 'Last Updated',
'Version',
- 'Description',
- 'Agent Configuration',
+ 'Actions',
]);
});
it('should show empty table results message', async () => {
@@ -47,13 +49,13 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
expect(noItemsFoundMessage).to.equal('No items found');
});
- xdescribe('and policies exists', () => {
+ describe('and policies exists', () => {
let policyInfo: PolicyTestResourceInfo;
before(async () => {
// load/create a policy and then navigate back to the policy view so that the list is refreshed
policyInfo = await policyTestResources.createPolicy();
- await pageObjects.common.navigateToUrlWithBrowserHistory('endpoint', '/policy');
+ await pageObjects.policy.navigateToPolicyList();
await pageObjects.endpoint.waitForTableToHaveData('policyTable');
});
after(async () => {
@@ -64,26 +66,24 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
it('should show policy on the list', async () => {
const [, policyRow] = await pageObjects.endpoint.getEndpointAppTableData('policyTable');
- expect(policyRow).to.eql([
- 'Protect East Coast',
- '1',
- 'Elastic Endpoint v1.0.0',
- 'Protect the worlds data - but in the East Coast',
- policyInfo.agentConfig.id,
+ // Validate row data with the exception of the Date columns - since those are initially
+ // shown as relative.
+ expect([policyRow[0], policyRow[1], policyRow[3], policyRow[5], policyRow[6]]).to.eql([
+ 'Protect East Coastrev. 1',
+ 'elastic',
+ 'elastic',
+ `${policyInfo.datasource.package?.title} v${policyInfo.datasource.package?.version}`,
+ '',
]);
+ [policyRow[2], policyRow[4]].forEach((relativeDate) => {
+ expect(relativeDate).to.match(RELATIVE_DATE_FORMAT);
+ });
});
it('should show policy name as link', async () => {
const policyNameLink = await testSubjects.find('policyNameLink');
expect(await policyNameLink.getTagName()).to.equal('a');
expect(await policyNameLink.getAttribute('href')).to.match(
- new RegExp(`\/endpoint\/policy\/${policyInfo.datasource.id}$`)
- );
- });
- it('should show agent configuration as link', async () => {
- const agentConfigLink = await testSubjects.find('agentConfigLink');
- expect(await agentConfigLink.getTagName()).to.equal('a');
- expect(await agentConfigLink.getAttribute('href')).to.match(
- new RegExp(`\/app\/ingestManager\#\/configs\/${policyInfo.datasource.config_id}$`)
+ new RegExp(`\/management\/policy\/${policyInfo.datasource.id}$`)
);
});
});
diff --git a/x-pack/test/functional_endpoint/page_objects/endpoint_page.ts b/x-pack/test/functional_endpoint/page_objects/endpoint_page.ts
index 7f78bd6b804f7..3234169e7265e 100644
--- a/x-pack/test/functional_endpoint/page_objects/endpoint_page.ts
+++ b/x-pack/test/functional_endpoint/page_objects/endpoint_page.ts
@@ -7,11 +7,22 @@
import { WebElementWrapper } from 'test/functional/services/lib/web_element_wrapper';
import { FtrProviderContext } from '../ftr_provider_context';
-export function EndpointPageProvider({ getService }: FtrProviderContext) {
+export function EndpointPageProvider({ getService, getPageObjects }: FtrProviderContext) {
const testSubjects = getService('testSubjects');
+ const pageObjects = getPageObjects(['common', 'header']);
const retry = getService('retry');
return {
+ /**
+ * Navigate to the Endpoints list page
+ */
+ async navigateToEndpointList(searchParams?: string) {
+ await pageObjects.common.navigateToApp('securitySolution', {
+ hash: `/management/endpoints${searchParams ? `?${searchParams}` : ''}`,
+ });
+ await pageObjects.header.waitUntilLoadingHasFinished();
+ },
+
/**
* Finds the Table with the given `selector` (test subject) and returns
* back an array containing the table's header column text
@@ -31,10 +42,6 @@ export function EndpointPageProvider({ getService }: FtrProviderContext) {
);
},
- async welcomeEndpointTitle() {
- return await testSubjects.getVisibleText('welcomeTitle');
- },
-
/**
* Finds a table and returns the data in a nested array with row 0 is the headers if they exist.
* It uses euiTableCellContent to avoid poluting the array data with the euiTableRowCell__mobileHeader data.
diff --git a/x-pack/test/functional_endpoint/page_objects/index.ts b/x-pack/test/functional_endpoint/page_objects/index.ts
index 8138ce2eeccb3..5b550bea5b55d 100644
--- a/x-pack/test/functional_endpoint/page_objects/index.ts
+++ b/x-pack/test/functional_endpoint/page_objects/index.ts
@@ -7,9 +7,13 @@
import { pageObjects as xpackFunctionalPageObjects } from '../../functional/page_objects';
import { EndpointPageProvider } from './endpoint_page';
import { EndpointAlertsPageProvider } from './endpoint_alerts_page';
+import { EndpointPolicyPageProvider } from './policy_page';
+import { EndpointPageUtils } from './page_utils';
export const pageObjects = {
...xpackFunctionalPageObjects,
endpoint: EndpointPageProvider,
+ policy: EndpointPolicyPageProvider,
+ endpointPageUtils: EndpointPageUtils,
endpointAlerts: EndpointAlertsPageProvider,
};
diff --git a/x-pack/test/functional_endpoint/page_objects/page_utils.ts b/x-pack/test/functional_endpoint/page_objects/page_utils.ts
new file mode 100644
index 0000000000000..daf66464f7e1e
--- /dev/null
+++ b/x-pack/test/functional_endpoint/page_objects/page_utils.ts
@@ -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.
+ */
+
+import { FtrProviderContext } from '../ftr_provider_context';
+
+export function EndpointPageUtils({ getService }: FtrProviderContext) {
+ const find = getService('find');
+
+ return {
+ /**
+ * Finds a given EuiCheckbox by test subject and clicks on it
+ *
+ * @param euiCheckBoxTestId
+ */
+ async clickOnEuiCheckbox(euiCheckBoxTestId: string) {
+ // This utility is needed because EuiCheckbox forwards the test subject on to
+ // the actual `` which is not actually visible/accessible on the page.
+ // In order to actually cause the state of the checkbox to change, the `