diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/get_processes_action.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/get_processes_action.tsx index fee7a2b73e815..095710e50466a 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/get_processes_action.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/command_render_components/get_processes_action.tsx @@ -22,16 +22,20 @@ const StyledEuiBasicTable = styled(EuiBasicTable)` table { background-color: transparent; } + .euiTableHeaderCell { border-bottom: ${(props) => props.theme.eui.euiBorderThin}; + .euiTableCellContent__text { font-weight: ${(props) => props.theme.eui.euiFontWeightRegular}; } } + .euiTableRow { &:hover { background-color: ${({ theme: { eui } }) => eui.euiColorEmptyShade} !important; } + .euiTableRowCell { border-top: none !important; border-bottom: none !important; @@ -71,6 +75,7 @@ export const GetProcessesActionResult = memo( () => [ { field: 'user', + 'data-test-subj': 'process_list_user', name: i18n.translate( 'xpack.securitySolution.endpointResponseActions.getProcesses.table.header.user', { defaultMessage: 'USER' } @@ -79,6 +84,7 @@ export const GetProcessesActionResult = memo( }, { field: 'pid', + 'data-test-subj': 'process_list_pid', name: i18n.translate( 'xpack.securitySolution.endpointResponseActions.getProcesses.table.header.pid', { defaultMessage: 'PID' } @@ -87,6 +93,7 @@ export const GetProcessesActionResult = memo( }, { field: 'entity_id', + 'data-test-subj': 'process_list_entity_id', name: i18n.translate( 'xpack.securitySolution.endpointResponseActions.getProcesses.table.header.enityId', { defaultMessage: 'ENTITY ID' } @@ -96,6 +103,7 @@ export const GetProcessesActionResult = memo( { field: 'command', + 'data-test-subj': 'process_list_command', name: i18n.translate( 'xpack.securitySolution.endpointResponseActions.getProcesses.table.header.command', { defaultMessage: 'COMMAND' } @@ -120,7 +128,11 @@ export const GetProcessesActionResult = memo( // Show results return ( - + ); } diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/process_operations.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/process_operations.cy.ts index a50bdf394a9a1..c7120ded692b9 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/process_operations.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/process_operations.cy.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { getRunningProcesses } from '../../../tasks/response_actions'; import type { PolicyData } from '../../../../../../common/endpoint/types'; import type { CreateAndEnrollEndpointHostResponse } from '../../../../../../scripts/endpoint/common/endpoint_host_services'; import { @@ -23,16 +24,12 @@ import { enableAllPolicyProtections } from '../../../tasks/endpoint_policy'; import { createEndpointHost } from '../../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../../tasks/delete_all_endpoint_data'; -// FLAKY: https://github.com/elastic/kibana/issues/170563 -describe.skip('Response console', { tags: ['@ess', '@serverless'] }, () => { +describe('Response console', { tags: ['@ess', '@serverless'] }, () => { beforeEach(() => { login(); }); describe('Processes operations:', () => { - let cronPID: string; - let newCronPID: string; - let indexedPolicy: IndexedFleetEndpointPolicyResponse; let policy: PolicyData; let createdHost: CreateAndEnrollEndpointHostResponse; @@ -70,58 +67,47 @@ describe.skip('Response console', { tags: ['@ess', '@serverless'] }, () => { it('"processes" - should obtain a list of processes', () => { waitForEndpointListPageToBeLoaded(createdHost.hostname); openResponseConsoleFromEndpointList(); + + // get running processes performCommandInputChecks('processes'); submitCommand(); cy.contains('Action pending.').should('exist'); - cy.getByTestSubj('getProcessesSuccessCallout', { timeout: 120000 }).within(() => { + + // on success + cy.getByTestSubj('getProcessListTable', { timeout: 120000 }).within(() => { ['USER', 'PID', 'ENTITY ID', 'COMMAND'].forEach((header) => { cy.contains(header); }); cy.get('tbody > tr').should('have.length.greaterThan', 0); - cy.get('tbody > tr > td').should('contain', '/usr/sbin/cron'); - cy.get('tbody > tr > td') - .contains('/usr/sbin/cron') - .parents('td') - .siblings('td') - .eq(1) - .find('span') - .then((span) => { - cronPID = span.text(); - }); + cy.get('tbody > tr > td').should('contain', '/components/filebeat'); }); }); it('"kill-process --pid" - should kill a process', () => { waitForEndpointListPageToBeLoaded(createdHost.hostname); openResponseConsoleFromEndpointList(); - inputConsoleCommand(`kill-process --pid ${cronPID}`); - submitCommand(); - waitForCommandToBeExecuted('kill-process'); - - performCommandInputChecks('processes'); - submitCommand(); - cy.getByTestSubj('getProcessesSuccessCallout', { timeout: 120000 }).within(() => { - cy.get('tbody > tr > td') - .contains('/usr/sbin/cron') - .parents('td') - .siblings('td') - .eq(1) - .find('span') - .then((span) => { - newCronPID = span.text(); - }); + // get running processes + getRunningProcesses('/components/filebeat').then((pid) => { + // kill the process using PID + inputConsoleCommand(`kill-process --pid ${pid}`); + submitCommand(); + waitForCommandToBeExecuted('kill-process'); }); - expect(newCronPID).to.not.equal(cronPID); }); it('"suspend-process --pid" - should suspend a process', () => { waitForEndpointListPageToBeLoaded(createdHost.hostname); openResponseConsoleFromEndpointList(); - inputConsoleCommand(`suspend-process --pid ${newCronPID}`); - submitCommand(); - waitForCommandToBeExecuted('suspend-process'); + + // get running processes + getRunningProcesses('/components/filebeat').then((pid) => { + // suspend the process using PID + inputConsoleCommand(`suspend-process --pid ${pid}`); + submitCommand(); + waitForCommandToBeExecuted('suspend-process'); + }); }); }); }); diff --git a/x-pack/plugins/security_solution/public/management/cypress/tasks/response_actions.ts b/x-pack/plugins/security_solution/public/management/cypress/tasks/response_actions.ts index 80f1aaba567a0..387f86c0dd160 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/tasks/response_actions.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/tasks/response_actions.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { inputConsoleCommand, submitCommand } from './response_console'; import type { UserAuthzAccessLevel } from '../screens'; import { loadPage, request } from './common'; import { resolvePathVariables } from '../../../common/utils/resolve_path_variables'; @@ -66,6 +67,28 @@ export const visitRuleActions = (ruleId: string) => { cy.getByTestSubj('stepPanelProgress').should('not.exist'); }; +export const getRunningProcesses = (command: string): Cypress.Chainable => { + inputConsoleCommand('processes'); + submitCommand(); + cy.contains('Action pending.').should('exist'); + + // on success + // find pid of process + // traverse back from last column to the second column that has pid + return cy + .getByTestSubj('getProcessListTable', { timeout: 120000 }) + .findByTestSubj('process_list_command') + .contains(command) + .parents('td') + .siblings('td') + .eq(1) + .find('span') + .then((span) => { + // get pid + return Number(span.text()); + }); +}; + export const tryAddingDisabledResponseAction = (itemNumber = 0) => { cy.getByTestSubj('response-actions-wrapper').within(() => { cy.getByTestSubj('Endpoint Security-response-action-type-selection-option').should(