-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Defend Workflows][E2E]Endpoint e2e response console (#155605)
Depends on #155519 E2E coverage of `isolate`, `processes`, `kill-process` and `suspend-process` commands on mocked endpoint. E2E coverage of the above but on real endpoint is [here](#155519). Because these tests are run against mocked data I've decided not to mock `kill-process` and `suspend-process` outcome (whether process is actually killed/suspended) because it would mean testing mocks themselves. What is tested is the outcome the user sees ('Action completed'). --------- Co-authored-by: Patryk Kopycinski <[email protected]> (cherry picked from commit fd5309f)
- Loading branch information
1 parent
82c4eac
commit e195e3e
Showing
8 changed files
with
606 additions
and
331 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
230 changes: 230 additions & 0 deletions
230
...lugins/security_solution/public/management/cypress/e2e/mocked_data/response_console.cy.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import type { ActionDetails } from '../../../../../common/endpoint/types'; | ||
import type { ReturnTypeFromChainable } from '../../types'; | ||
import { indexEndpointHosts } from '../../tasks/index_endpoint_hosts'; | ||
import { | ||
checkReturnedProcessesTable, | ||
inputConsoleCommand, | ||
openResponseConsoleFromEndpointList, | ||
performCommandInputChecks, | ||
submitCommand, | ||
waitForEndpointListPageToBeLoaded, | ||
} from '../../tasks/response_console'; | ||
import { | ||
checkEndpointIsIsolated, | ||
checkEndpointIsNotIsolated, | ||
interceptActionRequests, | ||
sendActionResponse, | ||
} from '../../tasks/isolate'; | ||
import { login } from '../../tasks/login'; | ||
|
||
describe('Response console', () => { | ||
beforeEach(() => { | ||
login(); | ||
}); | ||
|
||
describe('Isolate command', () => { | ||
let endpointData: ReturnTypeFromChainable<typeof indexEndpointHosts>; | ||
let endpointHostname: string; | ||
let isolateRequestResponse: ActionDetails; | ||
|
||
before(() => { | ||
indexEndpointHosts({ withResponseActions: false, isolation: false }).then( | ||
(indexEndpoints) => { | ||
endpointData = indexEndpoints; | ||
endpointHostname = endpointData.data.hosts[0].host.name; | ||
} | ||
); | ||
}); | ||
|
||
after(() => { | ||
if (endpointData) { | ||
endpointData.cleanup(); | ||
// @ts-expect-error ignore setting to undefined | ||
endpointData = undefined; | ||
} | ||
}); | ||
|
||
it('should isolate host from response console', () => { | ||
waitForEndpointListPageToBeLoaded(endpointHostname); | ||
checkEndpointIsNotIsolated(endpointHostname); | ||
openResponseConsoleFromEndpointList(); | ||
performCommandInputChecks('isolate'); | ||
interceptActionRequests((responseBody) => { | ||
isolateRequestResponse = responseBody; | ||
}, 'isolate'); | ||
|
||
submitCommand(); | ||
cy.contains('Action pending.').should('exist'); | ||
cy.wait('@isolate').then(() => { | ||
sendActionResponse(isolateRequestResponse); | ||
}); | ||
cy.contains('Action completed.', { timeout: 120000 }).should('exist'); | ||
waitForEndpointListPageToBeLoaded(endpointHostname); | ||
checkEndpointIsIsolated(endpointHostname); | ||
}); | ||
}); | ||
|
||
describe('Release command', () => { | ||
let endpointData: ReturnTypeFromChainable<typeof indexEndpointHosts>; | ||
let endpointHostname: string; | ||
let releaseRequestResponse: ActionDetails; | ||
|
||
before(() => { | ||
indexEndpointHosts({ withResponseActions: false, isolation: true }).then((indexEndpoints) => { | ||
endpointData = indexEndpoints; | ||
endpointHostname = endpointData.data.hosts[0].host.name; | ||
}); | ||
}); | ||
|
||
after(() => { | ||
if (endpointData) { | ||
endpointData.cleanup(); | ||
// @ts-expect-error ignore setting to undefined | ||
endpointData = undefined; | ||
} | ||
}); | ||
|
||
it('should release host from response console', () => { | ||
waitForEndpointListPageToBeLoaded(endpointHostname); | ||
checkEndpointIsIsolated(endpointHostname); | ||
openResponseConsoleFromEndpointList(); | ||
performCommandInputChecks('release'); | ||
interceptActionRequests((responseBody) => { | ||
releaseRequestResponse = responseBody; | ||
}, 'release'); | ||
submitCommand(); | ||
cy.contains('Action pending.').should('exist'); | ||
cy.wait('@release').then(() => { | ||
sendActionResponse(releaseRequestResponse); | ||
}); | ||
cy.contains('Action completed.', { timeout: 120000 }).should('exist'); | ||
waitForEndpointListPageToBeLoaded(endpointHostname); | ||
checkEndpointIsNotIsolated(endpointHostname); | ||
}); | ||
}); | ||
|
||
describe('Processes command', () => { | ||
let endpointData: ReturnTypeFromChainable<typeof indexEndpointHosts>; | ||
let endpointHostname: string; | ||
let processesRequestResponse: ActionDetails; | ||
|
||
before(() => { | ||
indexEndpointHosts({ withResponseActions: false, isolation: false }).then( | ||
(indexEndpoints) => { | ||
endpointData = indexEndpoints; | ||
endpointHostname = endpointData.data.hosts[0].host.name; | ||
} | ||
); | ||
}); | ||
|
||
after(() => { | ||
if (endpointData) { | ||
endpointData.cleanup(); | ||
// @ts-expect-error ignore setting to undefined | ||
endpointData = undefined; | ||
} | ||
}); | ||
|
||
it('should return processes from response console', () => { | ||
waitForEndpointListPageToBeLoaded(endpointHostname); | ||
openResponseConsoleFromEndpointList(); | ||
performCommandInputChecks('processes'); | ||
interceptActionRequests((responseBody) => { | ||
processesRequestResponse = responseBody; | ||
}, 'processes'); | ||
submitCommand(); | ||
cy.contains('Action pending.').should('exist'); | ||
cy.wait('@processes').then(() => { | ||
sendActionResponse(processesRequestResponse); | ||
}); | ||
cy.getByTestSubj('getProcessesSuccessCallout', { timeout: 120000 }).within(() => { | ||
checkReturnedProcessesTable(); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('Kill process command', () => { | ||
let endpointData: ReturnTypeFromChainable<typeof indexEndpointHosts>; | ||
let endpointHostname: string; | ||
let killProcessRequestResponse: ActionDetails; | ||
|
||
before(() => { | ||
indexEndpointHosts({ withResponseActions: false, isolation: false }).then( | ||
(indexEndpoints) => { | ||
endpointData = indexEndpoints; | ||
endpointHostname = endpointData.data.hosts[0].host.name; | ||
} | ||
); | ||
}); | ||
|
||
after(() => { | ||
if (endpointData) { | ||
endpointData.cleanup(); | ||
// @ts-expect-error ignore setting to undefined | ||
endpointData = undefined; | ||
} | ||
}); | ||
|
||
it('should kill process from response console', () => { | ||
waitForEndpointListPageToBeLoaded(endpointHostname); | ||
openResponseConsoleFromEndpointList(); | ||
inputConsoleCommand(`kill-process --pid 1`); | ||
|
||
interceptActionRequests((responseBody) => { | ||
killProcessRequestResponse = responseBody; | ||
}, 'kill-process'); | ||
submitCommand(); | ||
cy.contains('Action pending.').should('exist'); | ||
cy.wait('@kill-process').then(() => { | ||
sendActionResponse(killProcessRequestResponse); | ||
}); | ||
cy.contains('Action completed.', { timeout: 120000 }).should('exist'); | ||
}); | ||
}); | ||
|
||
describe('Suspend process command', () => { | ||
let endpointData: ReturnTypeFromChainable<typeof indexEndpointHosts>; | ||
let endpointHostname: string; | ||
let suspendProcessRequestResponse: ActionDetails; | ||
|
||
before(() => { | ||
indexEndpointHosts({ withResponseActions: false, isolation: false }).then( | ||
(indexEndpoints) => { | ||
endpointData = indexEndpoints; | ||
endpointHostname = endpointData.data.hosts[0].host.name; | ||
} | ||
); | ||
}); | ||
|
||
after(() => { | ||
if (endpointData) { | ||
endpointData.cleanup(); | ||
// @ts-expect-error ignore setting to undefined | ||
endpointData = undefined; | ||
} | ||
}); | ||
|
||
it('should suspend process from response console', () => { | ||
waitForEndpointListPageToBeLoaded(endpointHostname); | ||
openResponseConsoleFromEndpointList(); | ||
inputConsoleCommand(`suspend-process --pid 1`); | ||
|
||
interceptActionRequests((responseBody) => { | ||
suspendProcessRequestResponse = responseBody; | ||
}, 'suspend-process'); | ||
submitCommand(); | ||
cy.contains('Action pending.').should('exist'); | ||
cy.wait('@suspend-process').then(() => { | ||
sendActionResponse(suspendProcessRequestResponse); | ||
}); | ||
cy.contains('Action completed.', { timeout: 120000 }).should('exist'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.