From ff6b30dba4646fd4646b146bf442f49756bdb18b Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Fri, 5 Jun 2020 16:11:27 -0400 Subject: [PATCH 01/14] Improve Policy test service provider --- .../services/endpoint_policy.ts | 136 ++++++++++++------ 1 file changed, 96 insertions(+), 40 deletions(-) diff --git a/x-pack/test/functional_endpoint/services/endpoint_policy.ts b/x-pack/test/functional_endpoint/services/endpoint_policy.ts index 29f72cf0fa962..e978ee8d7b69c 100644 --- a/x-pack/test/functional_endpoint/services/endpoint_policy.ts +++ b/x-pack/test/functional_endpoint/services/endpoint_policy.ts @@ -6,17 +6,25 @@ import { FtrProviderContext } from '../ftr_provider_context'; import { + CreateAgentConfigRequest, CreateAgentConfigResponse, + CreateDatasourceRequest, CreateDatasourceResponse, + DeleteAgentConfigRequest, + DeleteDatasourcesRequest, + GetPackagesResponse, } from '../../../plugins/ingest_manager/common'; -import { Immutable } from '../../../plugins/security_solution/common/endpoint/types'; import { factory as policyConfigFactory } from '../../../plugins/security_solution/common/endpoint/models/policy_config'; +import { Immutable } from '../../../plugins/security_solution/common/endpoint/types'; const INGEST_API_ROOT = '/api/ingest_manager'; const INGEST_API_AGENT_CONFIGS = `${INGEST_API_ROOT}/agent_configs`; const INGEST_API_AGENT_CONFIGS_DELETE = `${INGEST_API_AGENT_CONFIGS}/delete`; const INGEST_API_DATASOURCES = `${INGEST_API_ROOT}/datasources`; const INGEST_API_DATASOURCES_DELETE = `${INGEST_API_DATASOURCES}/delete`; +const INGEST_API_EPM_PACKAGES = `${INGEST_API_ROOT}/epm/packages`; + +const SECURITY_PACKAGES_ROUTE = `${INGEST_API_EPM_PACKAGES}?category=security`; /** * Holds information about the test resources created to support an Endpoint Policy @@ -34,6 +42,15 @@ export interface PolicyTestResourceInfo { export function EndpointPolicyTestResourcesProvider({ getService }: FtrProviderContext) { const supertest = getService('supertest'); + const log = getService('log'); + + const logSupertestApiErrorAndThrow = (message: string, error: any) => { + const responseBody = error?.response?.body; + const responseText = error?.response?.text; + log.error(JSON.stringify(responseBody || responseText, null, 2)); + log.error(error); + throw new Error(message); + }; return { /** @@ -41,43 +58,58 @@ export function EndpointPolicyTestResourcesProvider({ getService }: FtrProviderC * stores the Policy configuration data */ async createPolicy(): Promise { - // FIXME: Refactor after https://github.com/elastic/kibana/issues/64822 is fixed. `isInitialized` setup below should be deleted - // Due to an issue in Ingest API, we first create the Fleet user. This avoids the Agent Config api throwing a 500 - const isFleetSetupResponse = await supertest - .get('/api/ingest_manager/fleet/setup') + // Retrieve information about the Endpoint security package + // EPM does not currently have an API to get the "lastest" information for a page given its name, + // so we'll retrieve a list of packages for a category of Security, and will then find the + // endpoint package info. in the list. The request is kicked off here, but handled below after + // agent config creation so that they can be executed concurrently + const secPackagesRequest = supertest + .get(SECURITY_PACKAGES_ROUTE) .set('kbn-xsrf', 'xxx') .expect(200); - if (!isFleetSetupResponse.body.isInitialized) { - await supertest - .post('/api/ingest_manager/fleet/setup') + + // create agent config + let agentConfig: CreateAgentConfigResponse['item']; + try { + const newAgentconfigData: CreateAgentConfigRequest['body'] = { + name: 'East Coast', + description: 'East Coast call center', + namespace: 'default', + }; + const { body: createResponse }: { body: CreateAgentConfigResponse } = await supertest + .post(INGEST_API_AGENT_CONFIGS) .set('kbn-xsrf', 'xxx') - .send() + .send(newAgentconfigData) .expect(200); + agentConfig = createResponse.item; + } catch (error) { + logSupertestApiErrorAndThrow(`Unable to create Agent Config via Ingest!`, error); } - // create agent config - const { - body: { item: agentConfig }, - }: { body: CreateAgentConfigResponse } = await supertest - .post(INGEST_API_AGENT_CONFIGS) - .set('kbn-xsrf', 'xxx') - .send({ name: 'East Coast', description: 'East Coast call center', namespace: '' }) - .expect(200); + // Retrieve the Endpoint package information + let endpointPackageInfo: GetPackagesResponse['response'][0] | undefined; + try { + const { body: secPackages }: { body: GetPackagesResponse } = await secPackagesRequest; + endpointPackageInfo = secPackages.response.find( + (epmPackage) => epmPackage.name === 'endpoint' + ); + if (!endpointPackageInfo) { + throw new Error(`Endpoint package was not found via ${SECURITY_PACKAGES_ROUTE}`); + } + } catch (error) { + logSupertestApiErrorAndThrow(`Unable to retrieve Endpoint package via Ingest!`, error); + } // create datasource and associated it to agent config - const { - body: { item: datasource }, - }: { body: CreateDatasourceResponse } = await supertest - .post(INGEST_API_DATASOURCES) - .set('kbn-xsrf', 'xxx') - .send({ + let datasource: CreateDatasourceResponse['item']; + try { + const newDatasourceData: CreateDatasourceRequest['body'] = { name: 'Protect East Coast', description: 'Protect the worlds data - but in the East Coast', - config_id: agentConfig.id, + config_id: agentConfig!.id, enabled: true, output_id: '', inputs: [ - // TODO: should we retrieve the latest Endpoint Package and build the input (policy) from that? { type: 'endpoint', enabled: true, @@ -89,32 +121,56 @@ export function EndpointPolicyTestResourcesProvider({ getService }: FtrProviderC }, }, ], - namespace: '', + namespace: 'default', package: { name: 'endpoint', - title: 'Elastic Endpoint', - version: '1.0.0', + title: endpointPackageInfo?.title ?? '', + version: endpointPackageInfo?.version ?? '', }, - }) - .expect(200); + }; + const { body: createResponse }: { body: CreateDatasourceResponse } = await supertest + .post(INGEST_API_DATASOURCES) + .set('kbn-xsrf', 'xxx') + .send(newDatasourceData) + .expect(200); + datasource = createResponse.item; + } catch (error) { + logSupertestApiErrorAndThrow(`Unable to create Datasource via Ingest!`, error); + } return { + // @ts-ignore agentConfig, + // @ts-ignore datasource, async cleanup() { // Delete Datasource - await supertest - .post(INGEST_API_DATASOURCES_DELETE) - .set('kbn-xsrf', 'xxx') - .send({ datasourceIds: [datasource.id] }) - .expect(200); + try { + const deleteDatasourceData: DeleteDatasourcesRequest['body'] = { + datasourceIds: [datasource.id], + }; + await supertest + .post(INGEST_API_DATASOURCES_DELETE) + .set('kbn-xsrf', 'xxx') + .send(deleteDatasourceData) + .expect(200); + } catch (error) { + logSupertestApiErrorAndThrow('Unable to delete Datasource via Ingest!', error); + } // Delete Agent config - await supertest - .post(INGEST_API_AGENT_CONFIGS_DELETE) - .set('kbn-xsrf', 'xxx') - .send({ agentConfigId: agentConfig.id }) - .expect(200); + try { + const deleteAgentConfigData: DeleteAgentConfigRequest['body'] = { + agentConfigId: agentConfig.id, + }; + await supertest + .post(INGEST_API_AGENT_CONFIGS_DELETE) + .set('kbn-xsrf', 'xxx') + .send(deleteAgentConfigData) + .expect(200); + } catch (error) { + logSupertestApiErrorAndThrow('Unable to delete Agent Config via Ingest!', error); + } }, }; }, From 7f181d6f4886775d106c3e373b87ad8550ffbf8d Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Fri, 5 Jun 2020 16:11:59 -0400 Subject: [PATCH 02/14] enable Policy List functional tests --- x-pack/scripts/functional_tests.js | 1 + .../apps/endpoint/index.ts | 20 +++++++++++++------ .../apps/endpoint/policy_list.ts | 17 ++++++++-------- 3 files changed, 24 insertions(+), 14 deletions(-) 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/index.ts b/x-pack/test/functional_endpoint/apps/endpoint/index.ts index 296ee45ff181c..59d271c88e486 100644 --- a/x-pack/test/functional_endpoint/apps/endpoint/index.ts +++ b/x-pack/test/functional_endpoint/apps/endpoint/index.ts @@ -9,12 +9,20 @@ 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')); + // TODO: Delete + // We are under SIEM now, so I don't think we need these Feature control tests + // loadTestFile(require.resolve('./feature_controls')); + + // TODO: Delete + // No more Endpoint app, so no more landing page or header nav + // loadTestFile(require.resolve('./landing_page')); + // loadTestFile(require.resolve('./header_nav')); + + // loadTestFile(require.resolve('./host_list')); loadTestFile(require.resolve('./policy_list')); - loadTestFile(require.resolve('./alerts')); - loadTestFile(require.resolve('./resolver')); + + // loadTestFile(require.resolve('./alerts')); + + // loadTestFile(require.resolve('./resolver')); }); } 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..dd8ecbe2a8669 100644 --- a/x-pack/test/functional_endpoint/apps/endpoint/policy_list.ts +++ b/x-pack/test/functional_endpoint/apps/endpoint/policy_list.ts @@ -12,11 +12,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const policyTestResources = getService('policyTestResources'); - // 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.common.navigateToApp('securitySolution', { hash: '/management/policy' }); }); it('loads the Policy List Page', async () => { @@ -34,10 +33,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,7 +48,7 @@ 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 () => { @@ -67,7 +68,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect(policyRow).to.eql([ 'Protect East Coast', '1', - 'Elastic Endpoint v1.0.0', + `${policyInfo.datasource.package?.title} v${policyInfo.datasource.package?.version}`, 'Protect the worlds data - but in the East Coast', policyInfo.agentConfig.id, ]); From b45963f5d9bd2468873fdac71f84fb78e88a5048 Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Mon, 8 Jun 2020 10:24:47 -0400 Subject: [PATCH 03/14] Fix Policy list failures --- .../apps/endpoint/policy_list.ts | 29 +++++++++---------- .../page_objects/endpoint_page.ts | 10 ++++++- 2 files changed, 23 insertions(+), 16 deletions(-) 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 dd8ecbe2a8669..70a4ae6c95e85 100644 --- a/x-pack/test/functional_endpoint/apps/endpoint/policy_list.ts +++ b/x-pack/test/functional_endpoint/apps/endpoint/policy_list.ts @@ -11,11 +11,12 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const pageObjects = getPageObjects(['common', 'endpoint']); const testSubjects = getService('testSubjects'); const policyTestResources = getService('policyTestResources'); + const RELATIVE_DATE_FORMAT = /\d (?:seconds|minutes) ago/i; describe('When on the Endpoint Policy List', function () { this.tags(['ciGroup7']); before(async () => { - await pageObjects.common.navigateToApp('securitySolution', { hash: '/management/policy' }); + await pageObjects.endpoint.navigateToEndpointList(); }); it('loads the Policy List Page', async () => { @@ -54,7 +55,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { 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.endpoint.navigateToEndpointList(); await pageObjects.endpoint.waitForTableToHaveData('policyTable'); }); after(async () => { @@ -65,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', + // 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}`, - 'Protect the worlds data - but in the East Coast', - policyInfo.agentConfig.id, + '', ]); + [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..a67828028f3ba 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,19 @@ 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']); const retry = getService('retry'); return { + /** + * Navigates to the Endpoints list + */ + async navigateToEndpointList() { + await pageObjects.common.navigateToApp('securitySolution', { hash: '/management/policy' }); + }, + /** * Finds the Table with the given `selector` (test subject) and returns * back an array containing the table's header column text From 9f536e138b05ff8ae5cf8109b95e436dbb020d85 Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Mon, 8 Jun 2020 11:31:28 -0400 Subject: [PATCH 04/14] Refactor and move Policy related pages objects to its own module --- .../apps/endpoint/policy_list.ts | 6 +++--- .../page_objects/endpoint_page.ts | 4 ++-- .../functional_endpoint/page_objects/index.ts | 2 ++ .../page_objects/policy_page.ts | 20 +++++++++++++++++++ 4 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 x-pack/test/functional_endpoint/page_objects/policy_page.ts 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 70a4ae6c95e85..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,7 +8,7 @@ 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; @@ -16,7 +16,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { describe('When on the Endpoint Policy List', function () { this.tags(['ciGroup7']); before(async () => { - await pageObjects.endpoint.navigateToEndpointList(); + await pageObjects.policy.navigateToPolicyList(); }); it('loads the Policy List Page', async () => { @@ -55,7 +55,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { 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.endpoint.navigateToEndpointList(); + await pageObjects.policy.navigateToPolicyList(); await pageObjects.endpoint.waitForTableToHaveData('policyTable'); }); after(async () => { 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 a67828028f3ba..4579a3a916c5f 100644 --- a/x-pack/test/functional_endpoint/page_objects/endpoint_page.ts +++ b/x-pack/test/functional_endpoint/page_objects/endpoint_page.ts @@ -14,10 +14,10 @@ export function EndpointPageProvider({ getService, getPageObjects }: FtrProvider return { /** - * Navigates to the Endpoints list + * Navigate to the Endpoints list page */ async navigateToEndpointList() { - await pageObjects.common.navigateToApp('securitySolution', { hash: '/management/policy' }); + await pageObjects.common.navigateToApp('securitySolution', { hash: '/management/endpoints' }); }, /** diff --git a/x-pack/test/functional_endpoint/page_objects/index.ts b/x-pack/test/functional_endpoint/page_objects/index.ts index 8138ce2eeccb3..ced331be0b256 100644 --- a/x-pack/test/functional_endpoint/page_objects/index.ts +++ b/x-pack/test/functional_endpoint/page_objects/index.ts @@ -7,9 +7,11 @@ import { pageObjects as xpackFunctionalPageObjects } from '../../functional/page_objects'; import { EndpointPageProvider } from './endpoint_page'; import { EndpointAlertsPageProvider } from './endpoint_alerts_page'; +import { EndpointPolicyPageProvider } from './policy'; export const pageObjects = { ...xpackFunctionalPageObjects, endpoint: EndpointPageProvider, + policy: EndpointPolicyPageProvider, endpointAlerts: EndpointAlertsPageProvider, }; diff --git a/x-pack/test/functional_endpoint/page_objects/policy_page.ts b/x-pack/test/functional_endpoint/page_objects/policy_page.ts new file mode 100644 index 0000000000000..a1dc17ad3b261 --- /dev/null +++ b/x-pack/test/functional_endpoint/page_objects/policy_page.ts @@ -0,0 +1,20 @@ +/* + * 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 EndpointPolicyPageProvider({ getService, getPageObjects }: FtrProviderContext) { + const pageObjects = getPageObjects(['common']); + + return { + /** + * Navigates to the Endpoint Policy List + */ + async navigateToPolicyList() { + await pageObjects.common.navigateToApp('securitySolution', { hash: '/management/policy' }); + }, + }; +} From 14c9b2fcedffee3996aa690def3286558abf0388 Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Mon, 8 Jun 2020 11:59:34 -0400 Subject: [PATCH 05/14] Fix Hosts tests --- .../apps/endpoint/host_list.ts | 37 +++++++++---------- .../apps/endpoint/index.ts | 2 +- .../page_objects/endpoint_page.ts | 9 +++-- .../functional_endpoint/page_objects/index.ts | 2 +- .../page_objects/policy_page.ts | 3 +- 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/x-pack/test/functional_endpoint/apps/endpoint/host_list.ts b/x-pack/test/functional_endpoint/apps/endpoint/host_list.ts index 029953f113a9c..637f8b97f968d 100644 --- a/x-pack/test/functional_endpoint/apps/endpoint/host_list.ts +++ b/x-pack/test/functional_endpoint/apps/endpoint/host_list.ts @@ -18,56 +18,59 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { 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'); @@ -108,15 +111,14 @@ 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 @@ -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/index.ts b/x-pack/test/functional_endpoint/apps/endpoint/index.ts index 59d271c88e486..7c8ccdc54d9a1 100644 --- a/x-pack/test/functional_endpoint/apps/endpoint/index.ts +++ b/x-pack/test/functional_endpoint/apps/endpoint/index.ts @@ -18,7 +18,7 @@ export default function ({ loadTestFile }: FtrProviderContext) { // loadTestFile(require.resolve('./landing_page')); // loadTestFile(require.resolve('./header_nav')); - // loadTestFile(require.resolve('./host_list')); + loadTestFile(require.resolve('./host_list')); loadTestFile(require.resolve('./policy_list')); // loadTestFile(require.resolve('./alerts')); 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 4579a3a916c5f..4a2649d53852e 100644 --- a/x-pack/test/functional_endpoint/page_objects/endpoint_page.ts +++ b/x-pack/test/functional_endpoint/page_objects/endpoint_page.ts @@ -9,15 +9,18 @@ import { FtrProviderContext } from '../ftr_provider_context'; export function EndpointPageProvider({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); - const pageObjects = getPageObjects(['common']); + const pageObjects = getPageObjects(['common', 'header']); const retry = getService('retry'); return { /** * Navigate to the Endpoints list page */ - async navigateToEndpointList() { - await pageObjects.common.navigateToApp('securitySolution', { hash: '/management/endpoints' }); + async navigateToEndpointList(searchParams?: string) { + await pageObjects.common.navigateToApp('securitySolution', { + hash: `/management/endpoints${searchParams ? `?${searchParams}` : ''}`, + }); + await pageObjects.header.waitUntilLoadingHasFinished(); }, /** diff --git a/x-pack/test/functional_endpoint/page_objects/index.ts b/x-pack/test/functional_endpoint/page_objects/index.ts index ced331be0b256..d9e33443ed7d1 100644 --- a/x-pack/test/functional_endpoint/page_objects/index.ts +++ b/x-pack/test/functional_endpoint/page_objects/index.ts @@ -7,7 +7,7 @@ import { pageObjects as xpackFunctionalPageObjects } from '../../functional/page_objects'; import { EndpointPageProvider } from './endpoint_page'; import { EndpointAlertsPageProvider } from './endpoint_alerts_page'; -import { EndpointPolicyPageProvider } from './policy'; +import { EndpointPolicyPageProvider } from './policy_page'; export const pageObjects = { ...xpackFunctionalPageObjects, diff --git a/x-pack/test/functional_endpoint/page_objects/policy_page.ts b/x-pack/test/functional_endpoint/page_objects/policy_page.ts index a1dc17ad3b261..758b6552545f4 100644 --- a/x-pack/test/functional_endpoint/page_objects/policy_page.ts +++ b/x-pack/test/functional_endpoint/page_objects/policy_page.ts @@ -7,7 +7,7 @@ import { FtrProviderContext } from '../ftr_provider_context'; export function EndpointPolicyPageProvider({ getService, getPageObjects }: FtrProviderContext) { - const pageObjects = getPageObjects(['common']); + const pageObjects = getPageObjects(['common', 'header']); return { /** @@ -15,6 +15,7 @@ export function EndpointPolicyPageProvider({ getService, getPageObjects }: FtrPr */ async navigateToPolicyList() { await pageObjects.common.navigateToApp('securitySolution', { hash: '/management/policy' }); + await pageObjects.header.waitUntilLoadingHasFinished(); }, }; } From cbb24b175847579ec786c20bed330f27cf845d6b Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Mon, 8 Jun 2020 12:10:05 -0400 Subject: [PATCH 06/14] Delete unneeded files --- .../feature_controls/endpoint_spaces.ts | 76 ------------------- .../apps/endpoint/feature_controls/index.ts | 13 ---- .../apps/endpoint/header_nav.ts | 55 -------------- .../apps/endpoint/index.ts | 10 --- .../apps/endpoint/landing_page.ts | 29 ------- 5 files changed, 183 deletions(-) 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 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 7c8ccdc54d9a1..66a023a1997da 100644 --- a/x-pack/test/functional_endpoint/apps/endpoint/index.ts +++ b/x-pack/test/functional_endpoint/apps/endpoint/index.ts @@ -9,20 +9,10 @@ export default function ({ loadTestFile }: FtrProviderContext) { describe('endpoint', function () { this.tags('ciGroup7'); - // TODO: Delete - // We are under SIEM now, so I don't think we need these Feature control tests - // loadTestFile(require.resolve('./feature_controls')); - - // TODO: Delete - // No more Endpoint app, so no more landing page or header nav - // loadTestFile(require.resolve('./landing_page')); - // loadTestFile(require.resolve('./header_nav')); - loadTestFile(require.resolve('./host_list')); loadTestFile(require.resolve('./policy_list')); // 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'); - }); - }); -}; From 82ea70ebbfd9ddfdfc0bcdeea365cf9a59106304 Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Mon, 8 Jun 2020 12:17:30 -0400 Subject: [PATCH 07/14] renamed `host_list` to `endpoint_list` --- .../apps/endpoint/{host_list.ts => endpoint_list.ts} | 6 +++--- x-pack/test/functional_endpoint/apps/endpoint/index.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename x-pack/test/functional_endpoint/apps/endpoint/{host_list.ts => endpoint_list.ts} (97%) 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 97% 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 637f8b97f968d..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,7 +13,7 @@ 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 () => { @@ -77,7 +77,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { 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'); }); @@ -125,7 +125,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { 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' ); diff --git a/x-pack/test/functional_endpoint/apps/endpoint/index.ts b/x-pack/test/functional_endpoint/apps/endpoint/index.ts index 66a023a1997da..eb70d24e75c42 100644 --- a/x-pack/test/functional_endpoint/apps/endpoint/index.ts +++ b/x-pack/test/functional_endpoint/apps/endpoint/index.ts @@ -9,7 +9,7 @@ export default function ({ loadTestFile }: FtrProviderContext) { describe('endpoint', function () { this.tags('ciGroup7'); - loadTestFile(require.resolve('./host_list')); + loadTestFile(require.resolve('./endpoint_list')); loadTestFile(require.resolve('./policy_list')); // loadTestFile(require.resolve('./alerts')); From 7cb39f1d57e4c0543f2da7fa38bc79c73a085b3d Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Mon, 8 Jun 2020 12:47:51 -0400 Subject: [PATCH 08/14] Fixed Policy Details Tests --- .../pages/policy/view/policy_details.tsx | 14 ++-- .../view/policy_forms/events/checkbox.tsx | 17 +++-- .../view/policy_forms/events/windows.tsx | 1 + .../apps/endpoint/index.ts | 1 + .../apps/endpoint/policy_details.ts | 74 +++++++++++++++++++ .../page_objects/endpoint_page.ts | 32 ++++++++ .../page_objects/policy_page.ts | 38 ++++++++++ 7 files changed, 164 insertions(+), 13 deletions(-) create mode 100644 x-pack/test/functional_endpoint/apps/endpoint/policy_details.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/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/test/functional_endpoint/apps/endpoint/index.ts b/x-pack/test/functional_endpoint/apps/endpoint/index.ts index eb70d24e75c42..199d138d1c450 100644 --- a/x-pack/test/functional_endpoint/apps/endpoint/index.ts +++ b/x-pack/test/functional_endpoint/apps/endpoint/index.ts @@ -11,6 +11,7 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./endpoint_list')); loadTestFile(require.resolve('./policy_list')); + loadTestFile(require.resolve('./policy_details')); // loadTestFile(require.resolve('./alerts')); // loadTestFile(require.resolve('./resolver')); 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..d1ba8f012d1f9 --- /dev/null +++ b/x-pack/test/functional_endpoint/apps/endpoint/policy_details.ts @@ -0,0 +1,74 @@ +/* + * 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']); + 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', () => { + it('should display success toast on successful save', async () => { + await pageObjects.endpoint.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', async () => { + await pageObjects.endpoint.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); + }); + }); + }); + }); +} 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 4a2649d53852e..38ce566dc557e 100644 --- a/x-pack/test/functional_endpoint/page_objects/endpoint_page.ts +++ b/x-pack/test/functional_endpoint/page_objects/endpoint_page.ts @@ -10,6 +10,8 @@ import { FtrProviderContext } from '../ftr_provider_context'; export function EndpointPageProvider({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const pageObjects = getPageObjects(['common', 'header']); + const find = getService('find'); + const log = getService('log'); const retry = getService('retry'); return { @@ -118,5 +120,35 @@ export function EndpointPageProvider({ getService, getPageObjects }: FtrProvider .trim(); }); }, + + async clickOnEuiCheckbox(euiCheckBoxTestId: string) { + const checkboxes = await find.allByCssSelector('.euiCheckbox'); + const silentCatch = () => {}; + + log.debug(`Found ${checkboxes.length} EuiCheckbox's`); + + for (const checkbox of checkboxes) { + log.debug('Checking EuiCheckBox'); + const checkBoxInput: WebElementWrapper | void = await checkbox + .findByTestSubject(euiCheckBoxTestId) + .catch(silentCatch); + if (checkBoxInput !== undefined) { + log.debug(`Found EuiCheckBox with data-test-subj=${euiCheckBoxTestId}`); + + const labelElement = await checkbox.findByCssSelector('.euiCheckbox__label'); + + // Want to ensure that the Click actually did an update - case the internals of + // EuiCheckbox change in the future + const beforeClickIsChecked = await checkBoxInput.isSelected(); + await labelElement.click(); + const afterClickIsChecked = await checkBoxInput.isSelected(); + if (beforeClickIsChecked === afterClickIsChecked) { + throw new Error('click did not update checkbox!'); + } + return checkbox; + } + } + throw new Error(`EuiCheckbox with data-test-subj of [${euiCheckBoxTestId}] not found!`); + }, }; } diff --git a/x-pack/test/functional_endpoint/page_objects/policy_page.ts b/x-pack/test/functional_endpoint/page_objects/policy_page.ts index 758b6552545f4..aa9c5361de846 100644 --- a/x-pack/test/functional_endpoint/page_objects/policy_page.ts +++ b/x-pack/test/functional_endpoint/page_objects/policy_page.ts @@ -8,6 +8,7 @@ import { FtrProviderContext } from '../ftr_provider_context'; export function EndpointPolicyPageProvider({ getService, getPageObjects }: FtrProviderContext) { const pageObjects = getPageObjects(['common', 'header']); + const testSubjects = getService('testSubjects'); return { /** @@ -17,5 +18,42 @@ export function EndpointPolicyPageProvider({ getService, getPageObjects }: FtrPr await pageObjects.common.navigateToApp('securitySolution', { hash: '/management/policy' }); await pageObjects.header.waitUntilLoadingHasFinished(); }, + + /** + * Navigates to the Endpoint Policy Details page + * + * @param policyId + */ + async navigateToPolicyDetails(policyId: string) { + await pageObjects.common.navigateToApp('securitySolution', { + hash: `/management/policy/${policyId}`, + }); + await pageObjects.header.waitUntilLoadingHasFinished(); + }, + + /** + * Finds and returns the Policy Details Page Save button + */ + async findSaveButton() { + await this.ensureIsOnDetailsPage(); + return await testSubjects.find('policyDetailsSaveButton'); + }, + + /** + * ensures that the Details Page is the currently display view + */ + async ensureIsOnDetailsPage() { + await testSubjects.existOrFail('policyDetailsPage'); + }, + + /** + * Clicks Save button and confirms update on the Policy Details page + */ + async confirmAndSave() { + await this.ensureIsOnDetailsPage(); + await (await this.findSaveButton()).click(); + await testSubjects.existOrFail('policyDetailsConfirmModal'); + await pageObjects.common.clickConfirmOnModal(); + }, }; } From a7891ba1d78317be0ce9d03b8d38332417c8d8ba Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Mon, 8 Jun 2020 15:38:29 -0400 Subject: [PATCH 09/14] Add test ids to policy detail Max and Linux forms --- .../management/pages/policy/view/policy_forms/events/linux.tsx | 1 + .../management/pages/policy/view/policy_forms/events/mac.tsx | 1 + 2 files changed, 2 insertions(+) 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) } From cdc8a1c22b5cbea1106d3a35183311be1b49da70 Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Mon, 8 Jun 2020 15:48:28 -0400 Subject: [PATCH 10/14] Added `getFullAgentConfig()` to Endpoint Policy Test data provider service --- .../services/endpoint_policy.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/x-pack/test/functional_endpoint/services/endpoint_policy.ts b/x-pack/test/functional_endpoint/services/endpoint_policy.ts index e978ee8d7b69c..039baded5d0a1 100644 --- a/x-pack/test/functional_endpoint/services/endpoint_policy.ts +++ b/x-pack/test/functional_endpoint/services/endpoint_policy.ts @@ -12,6 +12,7 @@ import { CreateDatasourceResponse, DeleteAgentConfigRequest, DeleteDatasourcesRequest, + GetFullAgentConfigResponse, GetPackagesResponse, } from '../../../plugins/ingest_manager/common'; import { factory as policyConfigFactory } from '../../../plugins/security_solution/common/endpoint/models/policy_config'; @@ -53,6 +54,26 @@ export function EndpointPolicyTestResourcesProvider({ getService }: FtrProviderC }; return { + /** + * Retrieves the full Agent configuration, which mirrors what the Elastic Agent would get + * once they checkin. + */ + async getFullAgentConfig(agentConfigId: string): Promise { + let fullAgentConfig: GetFullAgentConfigResponse['item']; + try { + const apiResponse: { body: GetFullAgentConfigResponse } = await supertest + .get(`${INGEST_API_AGENT_CONFIGS}/${agentConfigId}/full`) + .expect(200); + + fullAgentConfig = apiResponse.body.item; + } catch (error) { + logSupertestApiErrorAndThrow('Unable to get full Agent Configuration', error); + } + + // @ts-ignore + return fullAgentConfig; + }, + /** * Creates an Ingest Agent Configuration and adds to it the Endpoint Datasource that * stores the Policy configuration data From 39f5ef47a5665de0786aa470fa1d37497a735ecb Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Mon, 8 Jun 2020 15:54:08 -0400 Subject: [PATCH 11/14] Added page objects utilities and moved `clickOnEuiCheckbox` there --- .../page_objects/endpoint_page.ts | 36 ------------- .../functional_endpoint/page_objects/index.ts | 2 + .../page_objects/page_utils.ts | 51 +++++++++++++++++++ 3 files changed, 53 insertions(+), 36 deletions(-) create mode 100644 x-pack/test/functional_endpoint/page_objects/page_utils.ts 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 38ce566dc557e..3234169e7265e 100644 --- a/x-pack/test/functional_endpoint/page_objects/endpoint_page.ts +++ b/x-pack/test/functional_endpoint/page_objects/endpoint_page.ts @@ -10,8 +10,6 @@ import { FtrProviderContext } from '../ftr_provider_context'; export function EndpointPageProvider({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const pageObjects = getPageObjects(['common', 'header']); - const find = getService('find'); - const log = getService('log'); const retry = getService('retry'); return { @@ -44,10 +42,6 @@ export function EndpointPageProvider({ getService, getPageObjects }: FtrProvider ); }, - 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. @@ -120,35 +114,5 @@ export function EndpointPageProvider({ getService, getPageObjects }: FtrProvider .trim(); }); }, - - async clickOnEuiCheckbox(euiCheckBoxTestId: string) { - const checkboxes = await find.allByCssSelector('.euiCheckbox'); - const silentCatch = () => {}; - - log.debug(`Found ${checkboxes.length} EuiCheckbox's`); - - for (const checkbox of checkboxes) { - log.debug('Checking EuiCheckBox'); - const checkBoxInput: WebElementWrapper | void = await checkbox - .findByTestSubject(euiCheckBoxTestId) - .catch(silentCatch); - if (checkBoxInput !== undefined) { - log.debug(`Found EuiCheckBox with data-test-subj=${euiCheckBoxTestId}`); - - const labelElement = await checkbox.findByCssSelector('.euiCheckbox__label'); - - // Want to ensure that the Click actually did an update - case the internals of - // EuiCheckbox change in the future - const beforeClickIsChecked = await checkBoxInput.isSelected(); - await labelElement.click(); - const afterClickIsChecked = await checkBoxInput.isSelected(); - if (beforeClickIsChecked === afterClickIsChecked) { - throw new Error('click did not update checkbox!'); - } - return checkbox; - } - } - throw new Error(`EuiCheckbox with data-test-subj of [${euiCheckBoxTestId}] not found!`); - }, }; } diff --git a/x-pack/test/functional_endpoint/page_objects/index.ts b/x-pack/test/functional_endpoint/page_objects/index.ts index d9e33443ed7d1..5b550bea5b55d 100644 --- a/x-pack/test/functional_endpoint/page_objects/index.ts +++ b/x-pack/test/functional_endpoint/page_objects/index.ts @@ -8,10 +8,12 @@ import { pageObjects as xpackFunctionalPageObjects } from '../../functional/page 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..0b310a7cdd84b --- /dev/null +++ b/x-pack/test/functional_endpoint/page_objects/page_utils.ts @@ -0,0 +1,51 @@ +/* + * 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 { WebElementWrapper } from '../../../../test/functional/services/lib/web_element_wrapper'; +import { FtrProviderContext } from '../ftr_provider_context'; + +export function EndpointPageUtils({ getService }: FtrProviderContext) { + const find = getService('find'); + const log = getService('log'); + + return { + /** + * Finds a given EuiCheckbox by test subject and clicks on it + * + * @param euiCheckBoxTestId + */ + async clickOnEuiCheckbox(euiCheckBoxTestId: string) { + // FIXME: this method is extreemly slow - fix it + const checkboxes = await find.allByCssSelector('.euiCheckbox'); + const silentCatch = () => {}; + + log.debug(`Found ${checkboxes.length} EuiCheckbox's`); + + for (const checkbox of checkboxes) { + log.debug('Checking EuiCheckBox'); + const checkBoxInput: WebElementWrapper | void = await checkbox + .findByTestSubject(euiCheckBoxTestId) + .catch(silentCatch); + if (checkBoxInput !== undefined) { + log.debug(`Found EuiCheckBox with data-test-subj=${euiCheckBoxTestId}`); + + const labelElement = await checkbox.findByCssSelector('.euiCheckbox__label'); + + // Want to ensure that the Click actually did an update - case the internals of + // EuiCheckbox change in the future + const beforeClickIsChecked = await checkBoxInput.isSelected(); + await labelElement.click(); + const afterClickIsChecked = await checkBoxInput.isSelected(); + if (beforeClickIsChecked === afterClickIsChecked) { + throw new Error('click did not update checkbox!'); + } + return checkbox; + } + } + throw new Error(`EuiCheckbox with data-test-subj of [${euiCheckBoxTestId}] not found!`); + }, + }; +} From 194cd703500846a08251faca27e9f7988e0420ea Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Mon, 8 Jun 2020 15:55:31 -0400 Subject: [PATCH 12/14] Added additional test case to verify policy makes it to Agent Config --- .../apps/endpoint/policy_details.ts | 187 ++++++++++++++++-- 1 file changed, 168 insertions(+), 19 deletions(-) diff --git a/x-pack/test/functional_endpoint/apps/endpoint/policy_details.ts b/x-pack/test/functional_endpoint/apps/endpoint/policy_details.ts index d1ba8f012d1f9..e0f84dc6a969d 100644 --- a/x-pack/test/functional_endpoint/apps/endpoint/policy_details.ts +++ b/x-pack/test/functional_endpoint/apps/endpoint/policy_details.ts @@ -9,7 +9,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; import { PolicyTestResourceInfo } from '../../services/endpoint_policy'; export default function ({ getPageObjects, getService }: FtrProviderContext) { - const pageObjects = getPageObjects(['common', 'endpoint', 'policy']); + const pageObjects = getPageObjects(['common', 'endpoint', 'policy', 'endpointPageUtils']); const testSubjects = getService('testSubjects'); const policyTestResources = getService('policyTestResources'); @@ -45,28 +45,177 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { policyInfo.datasource.name ); }); + }); - describe('and the save button is clicked', () => { - it('should display success toast on successful save', async () => { - await pageObjects.endpoint.clickOnEuiCheckbox('policyWindowsEvent_dns'); - await pageObjects.policy.confirmAndSave(); + describe('and the save button is clicked', () => { + let policyInfo: PolicyTestResourceInfo; - await testSubjects.existOrFail('policyDetailsSuccessMessage'); - expect(await testSubjects.getVisibleText('policyDetailsSuccessMessage')).to.equal( - `Policy ${policyInfo.datasource.name} has been updated.` - ); - }); - it('should persist update', async () => { - await pageObjects.endpoint.clickOnEuiCheckbox('policyWindowsEvent_process'); - await pageObjects.policy.confirmAndSave(); + beforeEach(async () => { + policyInfo = await policyTestResources.createPolicy(); + await pageObjects.policy.navigateToPolicyDetails(policyInfo.datasource.id); + }); + + afterEach(async () => { + if (policyInfo) { + await policyInfo.cleanup(); + } + }); - await testSubjects.existOrFail('policyDetailsSuccessMessage'); - await pageObjects.policy.navigateToPolicyList(); - await pageObjects.policy.navigateToPolicyDetails(policyInfo.datasource.id); + 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 () => { + // Turn off file events. + await Promise.all([ + pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyWindowsEvent_file'), + pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyLinuxEvent_file'), + pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyMaxEvent_file'), + ]); + await pageObjects.policy.confirmAndSave(); + await testSubjects.existOrFail('policyDetailsSuccessMessage'); + + const agentFullConfig = await policyTestResources.getFullAgentConfig( + policyInfo.agentConfig.id + ); - expect( - await (await testSubjects.find('policyWindowsEvent_process')).isSelected() - ).to.equal(false); + expect(agentFullConfig).to.eql({ + datasources: [ + { + enabled: true, + id: 'e5cfd120-a9b8-11ea-8cdc-f3228a168e40', + inputs: [ + { + enabled: true, + policy: { + linux: { + advanced: { + elasticsearch: { + indices: { + control: 'control-index', + event: 'event-index', + logging: 'logging-index', + }, + kernel: { + connect: true, + process: true, + }, + }, + }, + events: { + file: true, + 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: true, + 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: false, + file: true, + 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: '0.2.0', + }, + use_output: 'default', + }, + ], + id: 'e59252f0-a9b8-11ea-8cdc-f3228a168e40', + outputs: { + default: { + hosts: ['http://localhost:9200'], + type: 'elasticsearch', + }, + }, + revision: 5, + settings: { + monitoring: { + enabled: false, + logs: false, + metrics: false, + }, + }, }); }); }); From efdcc0c682f5714a8e8a51dfba9c131a1d1cb003 Mon Sep 17 00:00:00 2001 From: Paul Tavares Date: Mon, 8 Jun 2020 17:08:27 -0400 Subject: [PATCH 13/14] More efficient `clickOnEuiCheckbox` utility + fix policy details test --- .../apps/endpoint/policy_details.ts | 22 ++++++----- .../page_objects/page_utils.ts | 37 ++++--------------- .../services/endpoint_policy.ts | 11 ++++-- 3 files changed, 27 insertions(+), 43 deletions(-) diff --git a/x-pack/test/functional_endpoint/apps/endpoint/policy_details.ts b/x-pack/test/functional_endpoint/apps/endpoint/policy_details.ts index e0f84dc6a969d..25fb477b5a99a 100644 --- a/x-pack/test/functional_endpoint/apps/endpoint/policy_details.ts +++ b/x-pack/test/functional_endpoint/apps/endpoint/policy_details.ts @@ -83,11 +83,13 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { ); }); it('should have updated policy data in overall agent configuration', async () => { - // Turn off file events. + // 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('policyMaxEvent_file'), + pageObjects.endpointPageUtils.clickOnEuiCheckbox('policyMacEvent_file'), ]); await pageObjects.policy.confirmAndSave(); await testSubjects.existOrFail('policyDetailsSuccessMessage'); @@ -100,7 +102,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { datasources: [ { enabled: true, - id: 'e5cfd120-a9b8-11ea-8cdc-f3228a168e40', + id: policyInfo.datasource.id, inputs: [ { enabled: true, @@ -120,7 +122,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }, }, events: { - file: true, + file: false, network: true, process: true, }, @@ -144,7 +146,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }, }, events: { - file: true, + file: false, network: true, process: true, }, @@ -172,8 +174,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }, events: { dll_and_driver_load: true, - dns: false, - file: true, + dns: true, + file: false, network: true, process: true, registry: true, @@ -196,19 +198,19 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { namespace: 'default', package: { name: 'endpoint', - version: '0.2.0', + version: policyInfo.packageInfo.version, }, use_output: 'default', }, ], - id: 'e59252f0-a9b8-11ea-8cdc-f3228a168e40', + id: policyInfo.agentConfig.id, outputs: { default: { hosts: ['http://localhost:9200'], type: 'elasticsearch', }, }, - revision: 5, + revision: 3, settings: { monitoring: { enabled: false, diff --git a/x-pack/test/functional_endpoint/page_objects/page_utils.ts b/x-pack/test/functional_endpoint/page_objects/page_utils.ts index 0b310a7cdd84b..daf66464f7e1e 100644 --- a/x-pack/test/functional_endpoint/page_objects/page_utils.ts +++ b/x-pack/test/functional_endpoint/page_objects/page_utils.ts @@ -4,12 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { WebElementWrapper } from '../../../../test/functional/services/lib/web_element_wrapper'; import { FtrProviderContext } from '../ftr_provider_context'; export function EndpointPageUtils({ getService }: FtrProviderContext) { const find = getService('find'); - const log = getService('log'); return { /** @@ -18,34 +16,15 @@ export function EndpointPageUtils({ getService }: FtrProviderContext) { * @param euiCheckBoxTestId */ async clickOnEuiCheckbox(euiCheckBoxTestId: string) { - // FIXME: this method is extreemly slow - fix it - const checkboxes = await find.allByCssSelector('.euiCheckbox'); - const silentCatch = () => {}; + // 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 `