From a0aa6541e39d4ac6890085b3a608a4aa05ccb21e Mon Sep 17 00:00:00 2001 From: Michael Olorunnisola Date: Mon, 10 Aug 2020 10:37:11 -0400 Subject: [PATCH 1/9] initialized graph control tests --- .../test_utilities/simulator/index.tsx | 30 +++++- .../simulator/mock_resolver.tsx | 15 +-- .../resolver/view/graph_controls.test.tsx | 101 ++++++++++++++++++ .../public/resolver/view/graph_controls.tsx | 1 + 4 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx diff --git a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx index cae6a18576ebd..6e64e5a957e3c 100644 --- a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx +++ b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx @@ -14,8 +14,9 @@ import { spyMiddlewareFactory } from '../spy_middleware_factory'; import { resolverMiddlewareFactory } from '../../store/middleware'; import { resolverReducer } from '../../store/reducer'; import { MockResolver } from './mock_resolver'; -import { ResolverState, DataAccessLayer, SpyMiddleware } from '../../types'; +import { ResolverState, DataAccessLayer, SpyMiddleware, SideEffectSimulator } from '../../types'; import { ResolverAction } from '../../store/actions'; +import { sideEffectSimulatorFactory } from '../../view/side_effect_simulator_factory'; /** * Test a Resolver instance using jest, enzyme, and a mock data layer. @@ -43,6 +44,11 @@ export class Simulator { * This is used by `debugActions`. */ private readonly spyMiddleware: SpyMiddleware; + /** + * A fake simulator that allows you to explicitly simulate resize events and run animation frames + */ + public readonly sideEffectSimulator: SideEffectSimulator; + constructor({ dataAccessLayer, resolverComponentInstanceID, @@ -87,11 +93,14 @@ export class Simulator { // Used for `KibanaContextProvider` const coreStart: CoreStart = coreMock.createStart(); + this.sideEffectSimulator = sideEffectSimulatorFactory(); + // Render Resolver via the `MockResolver` component, using `enzyme`. this.wrapper = mount( ['history']; /** Pass a resolver store. See `storeFactory` and `mockDataAccessLayer` */ store: Store; + /** + * Pass the side effect simulator which handles animations and resizing. See `sideEffectSimulatorFactory` + */ + sideEffectSimulator: SideEffectSimulator; /** * All the props from `ResolverWithoutStore` can be passed. These aren't defaulted to anything (you might want to test what happens when they aren't present.) */ @@ -66,8 +69,6 @@ export const MockResolver = React.memo((props: MockResolverProps) => { setResolverElement(element); }, []); - const simulator: SideEffectSimulator = useMemo(() => sideEffectSimulatorFactory(), []); - // Resize the Resolver element to match the passed in props. Resolver is size dependent. useEffect(() => { if (resolverElement) { @@ -84,15 +85,15 @@ export const MockResolver = React.memo((props: MockResolverProps) => { return this; }, }; - simulator.controls.simulateElementResize(resolverElement, size); + props.sideEffectSimulator.controls.simulateElementResize(resolverElement, size); } - }, [props.rasterWidth, props.rasterHeight, simulator.controls, resolverElement]); + }, [props.rasterWidth, props.rasterHeight, props.sideEffectSimulator.controls, resolverElement]); return ( - + { + let simulator: Simulator; + let originEntityID: string; + const resolverComponentInstanceID = 'graph-controls-test'; + + beforeEach(async () => { + const { + metadata: { databaseDocumentID, entityIDs }, + dataAccessLayer, + } = oneAncestorTwoChildren(); + + simulator = new Simulator({ + dataAccessLayer, + databaseDocumentID, + resolverComponentInstanceID, + }); + originEntityID = entityIDs.origin; + }); + + it('should load graph controls', () => { + expect(simulator.graphControlElement().length).toBe(1); + }); + + describe('panning', () => { + const originalPositionStyle = { left: '746.93132px', top: '535.5792px' }; + it('should pan west', async () => { + const originNode = simulator.processNodeElements({ entityID: originEntityID }); + expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); + + const westPanButton = simulator.graphControlElement().find('[data-test-subj="west-button"]'); + westPanButton.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + + expect(originNode.getDOMNode()).toHaveStyle({ left: '796.93132px', top: '535.5792px' }); + }); + + it('should pan south', async () => { + const originNode = simulator.processNodeElements({ entityID: originEntityID }); + expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); + + const southPanButton = simulator + .graphControlElement() + .find('[data-test-subj="south-button"]'); + southPanButton.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + + expect(originNode.getDOMNode()).toHaveStyle({ left: '746.93132px', top: '485.5792px' }); + }); + + it('should pan east', async () => { + const originNode = simulator.processNodeElements({ entityID: originEntityID }); + expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); + + const eastPanButton = simulator.graphControlElement().find('[data-test-subj="east-button"]'); + eastPanButton.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + + expect(originNode.getDOMNode()).toHaveStyle({ left: '696.93132px', top: '535.5792px' }); + }); + + it('should pan north', async () => { + const originNode = simulator.processNodeElements({ entityID: originEntityID }); + expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); + + const northButton = simulator.graphControlElement().find('[data-test-subj="north-button"]'); + northButton.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + + expect(originNode.getDOMNode()).toHaveStyle({ left: '746.93132px', top: '585.5792px' }); + }); + + it('should recenter', async () => { + const originNode = simulator.processNodeElements({ entityID: originEntityID }); + const northButton = simulator.graphControlElement().find('[data-test-subj="north-button"]'); + const centerButton = simulator.graphControlElement().find('[data-test-subj="center-button"]'); + + expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); + + northButton.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + + expect(originNode.getDOMNode()).toHaveStyle({ left: '746.93132px', top: '585.5792px' }); + + centerButton.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + + expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/resolver/view/graph_controls.tsx b/x-pack/plugins/security_solution/public/resolver/view/graph_controls.tsx index c2a7bbaacbf1d..b2632996f9937 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/graph_controls.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/graph_controls.tsx @@ -125,6 +125,7 @@ const GraphControlsComponent = React.memo( className={className} graphControlsBackground={colorMap.graphControlsBackground} graphControlsIconColor={colorMap.graphControls} + data-test-subj="resolver:graph-controls" >
From 72ad3d424c1a21b1395ac85137d8baf221abaa05 Mon Sep 17 00:00:00 2001 From: Michael Olorunnisola Date: Mon, 10 Aug 2020 12:38:20 -0400 Subject: [PATCH 2/9] added zoom tests --- .../test_utilities/simulator/index.tsx | 2 +- .../resolver/view/graph_controls.test.tsx | 71 ++++++++++++++++++- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx index 6e64e5a957e3c..8ebe153b2f776 100644 --- a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx +++ b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx @@ -271,7 +271,7 @@ export class Simulator { * Wrapper for the panning and zooming controls */ public graphControlElement(): ReactWrapper { - return this.findInDOM('[data-test-subj="resolver:graph-controls"]'); + return this.domNodes('[data-test-subj="resolver:graph-controls"]'); } /** diff --git a/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx b/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx index 4bbffd1fb4735..ee2e5d6aed698 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx @@ -5,7 +5,7 @@ */ import { Simulator } from '../test_utilities/simulator'; -import { oneAncestorTwoChildren } from '../data_access_layer/mocks/one_ancestor_two_children'; +import { noAncestorsTwoChildren } from '../data_access_layer/mocks/no_ancestors_two_children'; import { nudgeAnimationDuration } from '../store/camera/scaling_constants'; import '../test_utilities/extend_jest'; @@ -18,7 +18,7 @@ describe('graph controls', () => { const { metadata: { databaseDocumentID, entityIDs }, dataAccessLayer, - } = oneAncestorTwoChildren(); + } = noAncestorsTwoChildren(); simulator = new Simulator({ dataAccessLayer, @@ -98,4 +98,71 @@ describe('graph controls', () => { expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); }); }); + + describe('zoom', () => { + const originalSizeStyle = { width: '360px', height: '120px' }; + describe('buttons', () => { + it('should zoom in', () => { + const originNode = simulator.processNodeElements({ entityID: originEntityID }); + expect(originNode.getDOMNode()).toHaveStyle(originalSizeStyle); + + const zoomInButton = simulator.graphControlElement().find('[data-test-subj="zoom-in"]'); + zoomInButton.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + + expect(originNode.getDOMNode()).toHaveStyle({ + width: '427.7538290724795px', + height: '142.5846096908265px', + }); + }); + it('should zoom out', () => { + const originNode = simulator.processNodeElements({ entityID: originEntityID }); + expect(originNode.getDOMNode()).toHaveStyle(originalSizeStyle); + + const zoomInButton = simulator.graphControlElement().find('[data-test-subj="zoom-out"]'); + zoomInButton.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + + expect(originNode.getDOMNode()).toHaveStyle({ + width: '303.0461709275204px', + height: '101.01539030917347px', + }); + }); + }); + + describe('slider', () => { + it('should zoom in', () => { + const originNode = simulator.processNodeElements({ entityID: originEntityID }); + expect(originNode.getDOMNode()).toHaveStyle(originalSizeStyle); + + const zoomSlider = simulator + .graphControlElement() + .find('[data-test-subj="zoom-slider"]') + .last(); + zoomSlider.simulate('change', { target: { value: 0.8 } }); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + + expect(originNode.getDOMNode()).toHaveStyle({ + width: '525.6000000000001px', + height: '175.20000000000005px', + }); + }); + it('should zoom out', () => { + const originNode = simulator.processNodeElements({ entityID: originEntityID }); + expect(originNode.getDOMNode()).toHaveStyle(originalSizeStyle); + + const zoomSlider = simulator + .graphControlElement() + .find('[data-test-subj="zoom-slider"]') + .last(); + zoomSlider.simulate('change', { target: { value: 0.2 } }); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + + expect(originNode.getDOMNode()).toHaveStyle({ + width: '201.60000000000002px', + height: '67.2px', + }); + }); + }); + }); }); From 57eac4b5f3439f1d358f1b10edf713bbc6419b81 Mon Sep 17 00:00:00 2001 From: Michael Olorunnisola Date: Mon, 10 Aug 2020 12:45:16 -0400 Subject: [PATCH 3/9] fix comments --- .../public/resolver/test_utilities/simulator/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx index 8ebe153b2f776..cca5dc212c651 100644 --- a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx +++ b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx @@ -45,7 +45,7 @@ export class Simulator { */ private readonly spyMiddleware: SpyMiddleware; /** - * A fake simulator that allows you to explicitly simulate resize events and run animation frames + * Simulator which allows you to explicitly simulate resize events and trigger animation frames */ public readonly sideEffectSimulator: SideEffectSimulator; @@ -193,7 +193,7 @@ export class Simulator { /** * Return an Enzyme ReactWrapper that includes the Related Events host button for a given process node * - * @param entityID The entity ID of åthe proocess node to select in + * @param entityID The entity ID of the proocess node to select in */ public processNodeRelatedEventButton(entityID: string): ReactWrapper { return this.domNodes( From 9a84f5ac045afa10b5162f186d0f9464ee361242 Mon Sep 17 00:00:00 2001 From: Michael Olorunnisola Date: Mon, 10 Aug 2020 16:43:51 -0400 Subject: [PATCH 4/9] make graph control tests more explicit --- .../test_utilities/simulator/index.tsx | 4 +- .../resolver/view/graph_controls.test.tsx | 221 ++++++++++++------ .../public/resolver/view/graph_controls.tsx | 24 +- 3 files changed, 172 insertions(+), 77 deletions(-) diff --git a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx index cca5dc212c651..68a380387ba54 100644 --- a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx +++ b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx @@ -47,7 +47,7 @@ export class Simulator { /** * Simulator which allows you to explicitly simulate resize events and trigger animation frames */ - public readonly sideEffectSimulator: SideEffectSimulator; + private readonly sideEffectSimulator: SideEffectSimulator; constructor({ dataAccessLayer, @@ -186,7 +186,7 @@ export class Simulator { * This manually runs the animation frames tied to a configurable timestamp in the future */ public runAnimationFramesTimeFromNow(time: number = 0) { - this.sideEffectSimulator.controls.time = new Date().getTime() + time; + this.sideEffectSimulator.controls.time = time; this.sideEffectSimulator.controls.provideAnimationFrame(); } diff --git a/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx b/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx index ee2e5d6aed698..043845c8f45a5 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx @@ -8,10 +8,12 @@ import { Simulator } from '../test_utilities/simulator'; import { noAncestorsTwoChildren } from '../data_access_layer/mocks/no_ancestors_two_children'; import { nudgeAnimationDuration } from '../store/camera/scaling_constants'; import '../test_utilities/extend_jest'; +import { ReactWrapper } from 'enzyme'; describe('graph controls', () => { let simulator: Simulator; let originEntityID: string; + let originNode: ReactWrapper; const resolverComponentInstanceID = 'graph-controls-test'; beforeEach(async () => { @@ -28,101 +30,183 @@ describe('graph controls', () => { originEntityID = entityIDs.origin; }); - it('should load graph controls', () => { - expect(simulator.graphControlElement().length).toBe(1); + describe('when the graph controls load', () => { + it('should display all cardinal panning buttons and the center button', () => { + const westPanButton = simulator + .graphControlElement() + .find('[data-test-subj="resolver:graph-controls:west-button"]'); + const southPanButton = simulator + .graphControlElement() + .find('[data-test-subj="resolver:graph-controls:west-button"]'); + const eastPanButton = simulator + .graphControlElement() + .find('[data-test-subj="resolver:graph-controls:west-button"]'); + const northPanButton = simulator + .graphControlElement() + .find('[data-test-subj="resolver:graph-controls:west-button"]'); + const centerButton = simulator + .graphControlElement() + .find('[data-test-subj="resolver:graph-controls:center-button"]'); + + expect(westPanButton.length).toBe(1); + expect(southPanButton.length).toBe(1); + expect(eastPanButton.length).toBe(1); + expect(northPanButton.length).toBe(1); + expect(centerButton.length).toBe(1); + }); + + it('should display the zoom buttons and slider', () => { + const zoomInButton = simulator + .graphControlElement() + .find('[data-test-subj="resolver:graph-controls:zoom-in"]'); + const zoomOutButton = simulator + .graphControlElement() + .find('[data-test-subj="resolver:graph-controls:zoom-out"]'); + const zoomSlider = simulator + .graphControlElement() + .find('[data-test-subj="resolver:graph-controls:zoom-slider"]'); + + expect(zoomInButton.length).toBe(1); + expect(zoomOutButton.length).toBe(1); + // Zoom slider is an EUI component that enzyme renders as EUIRangeTrack, EUIRangeSlider, input element + expect(zoomSlider.length).toBeGreaterThan(0); + }); }); describe('panning', () => { const originalPositionStyle = { left: '746.93132px', top: '535.5792px' }; - it('should pan west', async () => { - const originNode = simulator.processNodeElements({ entityID: originEntityID }); - expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); - - const westPanButton = simulator.graphControlElement().find('[data-test-subj="west-button"]'); - westPanButton.simulate('click'); - simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); - - expect(originNode.getDOMNode()).toHaveStyle({ left: '796.93132px', top: '535.5792px' }); + beforeEach(() => { + originNode = simulator.processNodeElements({ entityID: originEntityID }); }); - it('should pan south', async () => { - const originNode = simulator.processNodeElements({ entityID: originEntityID }); - expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); + describe('when the user has not interacted with panning yet', () => { + it("should show the origin node in it's original position", () => { + expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); + }); + }); - const southPanButton = simulator - .graphControlElement() - .find('[data-test-subj="south-button"]'); - southPanButton.simulate('click'); - simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + describe('when the user clicks the west panning button', () => { + let westPanButton: ReactWrapper; + beforeEach(() => { + westPanButton = simulator + .graphControlElement() + .find('[data-test-subj="resolver:graph-controls:west-button"]'); + westPanButton.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + }); - expect(originNode.getDOMNode()).toHaveStyle({ left: '746.93132px', top: '485.5792px' }); + it('should show the origin node further left on the screen', async () => { + expect(originNode.getDOMNode()).toHaveStyle({ left: '796.93132px', top: '535.5792px' }); + }); }); - it('should pan east', async () => { - const originNode = simulator.processNodeElements({ entityID: originEntityID }); - expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); - - const eastPanButton = simulator.graphControlElement().find('[data-test-subj="east-button"]'); - eastPanButton.simulate('click'); - simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + describe('when the user clicks the south panning button', () => { + let southPanButton: ReactWrapper; + beforeEach(() => { + southPanButton = simulator + .graphControlElement() + .find('[data-test-subj="resolver:graph-controls:south-button"]'); + southPanButton.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + }); - expect(originNode.getDOMNode()).toHaveStyle({ left: '696.93132px', top: '535.5792px' }); + it('should show the origin node lower on the screen', async () => { + expect(originNode.getDOMNode()).toHaveStyle({ left: '746.93132px', top: '485.5792px' }); + }); }); - it('should pan north', async () => { - const originNode = simulator.processNodeElements({ entityID: originEntityID }); - expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); - - const northButton = simulator.graphControlElement().find('[data-test-subj="north-button"]'); - northButton.simulate('click'); - simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + describe('when the user clicks the east panning button', () => { + let eastPanButton: ReactWrapper; + beforeEach(() => { + eastPanButton = simulator + .graphControlElement() + .find('[data-test-subj="resolver:graph-controls:east-button"]'); + eastPanButton.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + }); - expect(originNode.getDOMNode()).toHaveStyle({ left: '746.93132px', top: '585.5792px' }); + it('should show the origin node further right on the screen', async () => { + expect(originNode.getDOMNode()).toHaveStyle({ left: '696.93132px', top: '535.5792px' }); + }); }); - it('should recenter', async () => { - const originNode = simulator.processNodeElements({ entityID: originEntityID }); - const northButton = simulator.graphControlElement().find('[data-test-subj="north-button"]'); - const centerButton = simulator.graphControlElement().find('[data-test-subj="center-button"]'); - - expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); + describe('when the user clicks the north panning button', () => { + let northPanButton: ReactWrapper; + beforeEach(() => { + northPanButton = simulator + .graphControlElement() + .find('[data-test-subj="resolver:graph-controls:north-button"]'); + northPanButton.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + }); - northButton.simulate('click'); - simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + it('should show the origin node higher on the screen', async () => { + expect(originNode.getDOMNode()).toHaveStyle({ left: '746.93132px', top: '585.5792px' }); + }); + }); - expect(originNode.getDOMNode()).toHaveStyle({ left: '746.93132px', top: '585.5792px' }); + describe('when the user clicks the center panning button', () => { + let northPanButton: ReactWrapper; + let centerButton: ReactWrapper; + beforeEach(() => { + northPanButton = simulator + .graphControlElement() + .find('[data-test-subj="resolver:graph-controls:north-button"]'); + centerButton = simulator + .graphControlElement() + .find('[data-test-subj="resolver:graph-controls:center-button"]'); - centerButton.simulate('click'); - simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + northPanButton.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + centerButton.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + }); - expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); + it("should return the origin node to it's original position", async () => { + expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); + }); }); }); - describe('zoom', () => { + describe('zooming', () => { const originalSizeStyle = { width: '360px', height: '120px' }; - describe('buttons', () => { - it('should zoom in', () => { - const originNode = simulator.processNodeElements({ entityID: originEntityID }); + beforeEach(() => { + originNode = simulator.processNodeElements({ entityID: originEntityID }); + }); + + describe('when the user has not interacted with the zoom buttons or slider yet', () => { + it('should show the origin node as larger on the screen', () => { expect(originNode.getDOMNode()).toHaveStyle(originalSizeStyle); + }); + }); - const zoomInButton = simulator.graphControlElement().find('[data-test-subj="zoom-in"]'); + describe('when the zoom in button is clicked', () => { + beforeEach(() => { + const zoomInButton = simulator + .graphControlElement() + .find('[data-test-subj="resolver:graph-controls:zoom-in"]'); zoomInButton.simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + }); + it('should show the origin node as larger on the screen', () => { expect(originNode.getDOMNode()).toHaveStyle({ width: '427.7538290724795px', height: '142.5846096908265px', }); }); - it('should zoom out', () => { - const originNode = simulator.processNodeElements({ entityID: originEntityID }); - expect(originNode.getDOMNode()).toHaveStyle(originalSizeStyle); + }); - const zoomInButton = simulator.graphControlElement().find('[data-test-subj="zoom-out"]'); - zoomInButton.simulate('click'); + describe('when the zoom out button is clicked', () => { + beforeEach(() => { + const zoomOutButton = simulator + .graphControlElement() + .find('[data-test-subj="resolver:graph-controls:zoom-out"]'); + zoomOutButton.simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + }); + it('should show the origin node as smaller on the screen', () => { expect(originNode.getDOMNode()).toHaveStyle({ width: '303.0461709275204px', height: '101.01539030917347px', @@ -130,34 +214,37 @@ describe('graph controls', () => { }); }); - describe('slider', () => { - it('should zoom in', () => { - const originNode = simulator.processNodeElements({ entityID: originEntityID }); + describe('when the slider is moved upwards', () => { + beforeEach(() => { expect(originNode.getDOMNode()).toHaveStyle(originalSizeStyle); const zoomSlider = simulator .graphControlElement() - .find('[data-test-subj="zoom-slider"]') + .find('[data-test-subj="resolver:graph-controls:zoom-slider"]') .last(); zoomSlider.simulate('change', { target: { value: 0.8 } }); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + }); + it('should show the origin node as large on the screen', () => { expect(originNode.getDOMNode()).toHaveStyle({ width: '525.6000000000001px', height: '175.20000000000005px', }); }); - it('should zoom out', () => { - const originNode = simulator.processNodeElements({ entityID: originEntityID }); - expect(originNode.getDOMNode()).toHaveStyle(originalSizeStyle); + }); + describe('when the slider is moved downwards', () => { + beforeEach(() => { const zoomSlider = simulator .graphControlElement() - .find('[data-test-subj="zoom-slider"]') - .last(); + .find('[data-test-subj="resolver:graph-controls:zoom-slider"]') + .last(); // The last element rendered is the actual slider input element zoomSlider.simulate('change', { target: { value: 0.2 } }); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + }); + it('should show the origin node as smaller on the screen', () => { expect(originNode.getDOMNode()).toHaveStyle({ width: '201.60000000000002px', height: '67.2px', diff --git a/x-pack/plugins/security_solution/public/resolver/view/graph_controls.tsx b/x-pack/plugins/security_solution/public/resolver/view/graph_controls.tsx index b2632996f9937..610deef07775b 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/graph_controls.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/graph_controls.tsx @@ -131,7 +131,7 @@ const GraphControlsComponent = React.memo(
- - From 96be89e48e3611d1afe0f66d6cf368e048e4bb14 Mon Sep 17 00:00:00 2001 From: Michael Olorunnisola Date: Tue, 11 Aug 2020 14:55:12 -0400 Subject: [PATCH 5/9] refactor to use domNodes and map --- .../test_utilities/simulator/index.tsx | 55 +++++++- .../resolver/view/graph_controls.test.tsx | 128 ++++++------------ 2 files changed, 92 insertions(+), 91 deletions(-) diff --git a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx index 68a380387ba54..d195a80da3832 100644 --- a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx +++ b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx @@ -268,10 +268,59 @@ export class Simulator { } /** - * Wrapper for the panning and zooming controls + * Wrapper for the west panning button */ - public graphControlElement(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:graph-controls"]'); + public westPanElement(): ReactWrapper { + return this.domNodes('[data-test-subj="resolver:graph-controls:west-button"]'); + } + + /** + * Wrapper for the south panning button + */ + public southPanElement(): ReactWrapper { + return this.domNodes('[data-test-subj="resolver:graph-controls:south-button"]'); + } + + /** + * Wrapper for the east panning button + */ + public eastPanElement(): ReactWrapper { + return this.domNodes('[data-test-subj="resolver:graph-controls:east-button"]'); + } + + /** + * Wrapper for the north panning button + */ + public northPanElement(): ReactWrapper { + return this.domNodes('[data-test-subj="resolver:graph-controls:north-button"]'); + } + + /** + * Wrapper for the center panning button + */ + public centerPanElement(): ReactWrapper { + return this.domNodes('[data-test-subj="resolver:graph-controls:center-button"]'); + } + + /** + * Wrapper for the zoom in button + */ + public zoomInElement(): ReactWrapper { + return this.domNodes('[data-test-subj="resolver:graph-controls:zoom-in"]'); + } + + /** + * Wrapper for the zoom out button + */ + public zoomOutElement(): ReactWrapper { + return this.domNodes('[data-test-subj="resolver:graph-controls:zoom-out"]'); + } + + /** + * Wrapper for the zoom slider button + */ + public zoomSliderElement(): ReactWrapper { + return this.domNodes('[data-test-subj="resolver:graph-controls:zoom-slider"]'); } /** diff --git a/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx b/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx index 043845c8f45a5..9c484d936f58c 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx @@ -31,45 +31,36 @@ describe('graph controls', () => { }); describe('when the graph controls load', () => { - it('should display all cardinal panning buttons and the center button', () => { - const westPanButton = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:west-button"]'); - const southPanButton = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:west-button"]'); - const eastPanButton = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:west-button"]'); - const northPanButton = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:west-button"]'); - const centerButton = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:center-button"]'); - - expect(westPanButton.length).toBe(1); - expect(southPanButton.length).toBe(1); - expect(eastPanButton.length).toBe(1); - expect(northPanButton.length).toBe(1); - expect(centerButton.length).toBe(1); - }); - - it('should display the zoom buttons and slider', () => { - const zoomInButton = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:zoom-in"]'); - const zoomOutButton = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:zoom-out"]'); - const zoomSlider = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:zoom-slider"]'); - - expect(zoomInButton.length).toBe(1); - expect(zoomOutButton.length).toBe(1); - // Zoom slider is an EUI component that enzyme renders as EUIRangeTrack, EUIRangeSlider, input element - expect(zoomSlider.length).toBeGreaterThan(0); + it('should display all cardinal panning buttons and the center button', async () => { + await expect( + simulator.map(() => ({ + westPanButton: simulator.westPanElement().length, + southPanButton: simulator.southPanElement().length, + eastPanButton: simulator.eastPanElement().length, + northPanButton: simulator.northPanElement().length, + centerButton: simulator.centerPanElement().length, + })) + ).toYieldEqualTo({ + westPanButton: 1, + southPanButton: 1, + eastPanButton: 1, + northPanButton: 1, + centerButton: 1, + }); + }); + + it('should display the zoom buttons and slider', async () => { + await expect( + simulator.map(() => ({ + zoomInButton: simulator.zoomInElement().length, + zoomOutButton: simulator.zoomOutElement().length, + zoomSlider: simulator.zoomSliderElement().length, + })) + ).toYieldEqualTo({ + zoomInButton: 1, + zoomOutButton: 1, + zoomSlider: 1, + }); }); }); @@ -86,12 +77,8 @@ describe('graph controls', () => { }); describe('when the user clicks the west panning button', () => { - let westPanButton: ReactWrapper; beforeEach(() => { - westPanButton = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:west-button"]'); - westPanButton.simulate('click'); + simulator.westPanElement().simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); @@ -101,12 +88,8 @@ describe('graph controls', () => { }); describe('when the user clicks the south panning button', () => { - let southPanButton: ReactWrapper; beforeEach(() => { - southPanButton = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:south-button"]'); - southPanButton.simulate('click'); + simulator.southPanElement().simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); @@ -116,12 +99,8 @@ describe('graph controls', () => { }); describe('when the user clicks the east panning button', () => { - let eastPanButton: ReactWrapper; beforeEach(() => { - eastPanButton = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:east-button"]'); - eastPanButton.simulate('click'); + simulator.eastPanElement().simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); @@ -131,12 +110,8 @@ describe('graph controls', () => { }); describe('when the user clicks the north panning button', () => { - let northPanButton: ReactWrapper; beforeEach(() => { - northPanButton = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:north-button"]'); - northPanButton.simulate('click'); + simulator.northPanElement().simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); @@ -146,19 +121,10 @@ describe('graph controls', () => { }); describe('when the user clicks the center panning button', () => { - let northPanButton: ReactWrapper; - let centerButton: ReactWrapper; beforeEach(() => { - northPanButton = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:north-button"]'); - centerButton = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:center-button"]'); - - northPanButton.simulate('click'); + simulator.northPanElement().simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); - centerButton.simulate('click'); + simulator.centerPanElement().simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); @@ -182,10 +148,7 @@ describe('graph controls', () => { describe('when the zoom in button is clicked', () => { beforeEach(() => { - const zoomInButton = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:zoom-in"]'); - zoomInButton.simulate('click'); + simulator.zoomInElement().simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); @@ -199,10 +162,7 @@ describe('graph controls', () => { describe('when the zoom out button is clicked', () => { beforeEach(() => { - const zoomOutButton = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:zoom-out"]'); - zoomOutButton.simulate('click'); + simulator.zoomOutElement().simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); @@ -218,11 +178,7 @@ describe('graph controls', () => { beforeEach(() => { expect(originNode.getDOMNode()).toHaveStyle(originalSizeStyle); - const zoomSlider = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:zoom-slider"]') - .last(); - zoomSlider.simulate('change', { target: { value: 0.8 } }); + simulator.zoomSliderElement().simulate('change', { target: { value: 0.8 } }); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); @@ -236,11 +192,7 @@ describe('graph controls', () => { describe('when the slider is moved downwards', () => { beforeEach(() => { - const zoomSlider = simulator - .graphControlElement() - .find('[data-test-subj="resolver:graph-controls:zoom-slider"]') - .last(); // The last element rendered is the actual slider input element - zoomSlider.simulate('change', { target: { value: 0.2 } }); + simulator.zoomSliderElement().simulate('change', { target: { value: 0.2 } }); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); From e1b95230d8589544f89aeb6904ddc0d59b91f217 Mon Sep 17 00:00:00 2001 From: Michael Olorunnisola Date: Tue, 11 Aug 2020 14:58:44 -0400 Subject: [PATCH 6/9] slider, not button --- .../public/resolver/test_utilities/simulator/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx index d195a80da3832..85b283a76cfa9 100644 --- a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx +++ b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx @@ -317,7 +317,7 @@ export class Simulator { } /** - * Wrapper for the zoom slider button + * Wrapper for the zoom slider */ public zoomSliderElement(): ReactWrapper { return this.domNodes('[data-test-subj="resolver:graph-controls:zoom-slider"]'); From f3376f8e07968dd2f6fac5732a82e2c090d12444 Mon Sep 17 00:00:00 2001 From: oatkiller Date: Wed, 12 Aug 2020 12:44:20 -0400 Subject: [PATCH 7/9] Add .toYieldObjectEqualTo matcher. resolve graph control test wrappers before use. use yield-equal-to pattern in graph control tests. change graph control spec language --- .../resolver/test_utilities/extend_jest.ts | 65 +++++ .../test_utilities/simulator/index.tsx | 2 +- .../resolver/view/graph_controls.test.tsx | 272 +++++++++--------- 3 files changed, 209 insertions(+), 130 deletions(-) diff --git a/x-pack/plugins/security_solution/public/resolver/test_utilities/extend_jest.ts b/x-pack/plugins/security_solution/public/resolver/test_utilities/extend_jest.ts index 9fc7af38beb42..df8f32d15a7ab 100644 --- a/x-pack/plugins/security_solution/public/resolver/test_utilities/extend_jest.ts +++ b/x-pack/plugins/security_solution/public/resolver/test_utilities/extend_jest.ts @@ -17,6 +17,7 @@ declare global { namespace jest { interface Matchers { toYieldEqualTo(expectedYield: T extends AsyncIterable ? E : never): Promise; + toYieldObjectEqualTo(expectedYield: unknown): Promise; } } } @@ -57,6 +58,70 @@ expect.extend({ } } + // Use `pass` as set in the above loop (or initialized to `false`) + // See https://jestjs.io/docs/en/expect#custom-matchers-api and https://jestjs.io/docs/en/expect#thisutils + const message = pass + ? () => + `${this.utils.matcherHint(matcherName, undefined, undefined, options)}\n\n` + + `Expected: not ${this.utils.printExpected(expected)}\n${ + this.utils.stringify(expected) !== this.utils.stringify(received[received.length - 1]!) + ? `Received: ${this.utils.printReceived(received[received.length - 1])}` + : '' + }` + : () => + `${this.utils.matcherHint(matcherName, undefined, undefined, options)}\n\nCompared ${ + received.length + } yields.\n\n${received + .map( + (next, index) => + `yield ${index + 1}:\n\n${this.utils.printDiffOrStringify( + expected, + next, + 'Expected', + 'Received', + this.expand + )}` + ) + .join(`\n\n`)}`; + + return { message, pass }; + }, + /** + * A custom matcher that takes an async generator and compares each value it yields to an expected value. + * This uses the same equality logic as `toMatchObject`. + * If any yielded value equals the expected value, the matcher will pass. + * If the generator ends with none of the yielded values matching, it will fail. + */ + async toYieldObjectEqualTo( + this: jest.MatcherContext, + receivedIterable: AsyncIterable, + expected: T + ): Promise<{ pass: boolean; message: () => string }> { + // Used in printing out the pass or fail message + const matcherName = 'toSometimesYieldEqualTo'; + const options: jest.MatcherHintOptions = { + comment: 'deep equality with any yielded value', + isNot: this.isNot, + promise: this.promise, + }; + // The last value received: Used in printing the message + const received: T[] = []; + + // Set to true if the test passes. + let pass: boolean = false; + + // Async iterate over the iterable + for await (const next of receivedIterable) { + // keep track of all received values. Used in pass and fail messages + received.push(next); + // Use deep equals to compare the value to the expected value + if ((this.equals(next, expected), [this.utils.iterableEquality, this.utils.subsetEquality])) { + // If the value is equal, break + pass = true; + break; + } + } + // Use `pass` as set in the above loop (or initialized to `false`) // See https://jestjs.io/docs/en/expect#custom-matchers-api and https://jestjs.io/docs/en/expect#thisutils const message = pass diff --git a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx index 85b283a76cfa9..6607056b2a4bc 100644 --- a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx +++ b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx @@ -370,7 +370,7 @@ export class Simulator { public async resolveWrapper( wrapperFactory: () => ReactWrapper, predicate: (wrapper: ReactWrapper) => boolean = (wrapper) => wrapper.length > 0 - ): Promise { + ): Promise { for await (const wrapper of this.map(wrapperFactory)) { if (predicate(wrapper)) { return wrapper; diff --git a/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx b/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx index 9c484d936f58c..3b66f6af87cb4 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx @@ -8,14 +8,22 @@ import { Simulator } from '../test_utilities/simulator'; import { noAncestorsTwoChildren } from '../data_access_layer/mocks/no_ancestors_two_children'; import { nudgeAnimationDuration } from '../store/camera/scaling_constants'; import '../test_utilities/extend_jest'; -import { ReactWrapper } from 'enzyme'; -describe('graph controls', () => { +describe('graph controls: when relsover is loaded with an origin node', () => { let simulator: Simulator; let originEntityID: string; - let originNode: ReactWrapper; + let originNodeStyle: () => AsyncIterable; const resolverComponentInstanceID = 'graph-controls-test'; + const originalPositionStyle: Readonly<{ left: string; top: string }> = { + left: '746.93132px', + top: '535.5792px', + }; + const originalSizeStyle: Readonly<{ width: string; height: string }> = { + width: '360px', + height: '120px', + }; + beforeEach(async () => { const { metadata: { databaseDocumentID, entityIDs }, @@ -28,179 +36,185 @@ describe('graph controls', () => { resolverComponentInstanceID, }); originEntityID = entityIDs.origin; - }); - - describe('when the graph controls load', () => { - it('should display all cardinal panning buttons and the center button', async () => { - await expect( - simulator.map(() => ({ - westPanButton: simulator.westPanElement().length, - southPanButton: simulator.southPanElement().length, - eastPanButton: simulator.eastPanElement().length, - northPanButton: simulator.northPanElement().length, - centerButton: simulator.centerPanElement().length, - })) - ).toYieldEqualTo({ - westPanButton: 1, - southPanButton: 1, - eastPanButton: 1, - northPanButton: 1, - centerButton: 1, - }); - }); - it('should display the zoom buttons and slider', async () => { - await expect( - simulator.map(() => ({ - zoomInButton: simulator.zoomInElement().length, - zoomOutButton: simulator.zoomOutElement().length, - zoomSlider: simulator.zoomSliderElement().length, - })) - ).toYieldEqualTo({ - zoomInButton: 1, - zoomOutButton: 1, - zoomSlider: 1, + originNodeStyle = () => + simulator.map(() => { + const wrapper = simulator.processNodeElements({ entityID: originEntityID }); + // `getDOMNode` can only be called on a wrapper of a single node: https://enzymejs.github.io/enzyme/docs/api/ReactWrapper/getDOMNode.html + if (wrapper.length === 1) { + return wrapper.getDOMNode().style; + } + return null; }); - }); }); - describe('panning', () => { - const originalPositionStyle = { left: '746.93132px', top: '535.5792px' }; - beforeEach(() => { - originNode = simulator.processNodeElements({ entityID: originEntityID }); + it('should display all cardinal panning buttons and the center button', async () => { + await expect( + simulator.map(() => ({ + westPanButton: simulator.westPanElement().length, + southPanButton: simulator.southPanElement().length, + eastPanButton: simulator.eastPanElement().length, + northPanButton: simulator.northPanElement().length, + centerButton: simulator.centerPanElement().length, + })) + ).toYieldEqualTo({ + westPanButton: 1, + southPanButton: 1, + eastPanButton: 1, + northPanButton: 1, + centerButton: 1, }); + }); - describe('when the user has not interacted with panning yet', () => { - it("should show the origin node in it's original position", () => { - expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); - }); + it('should display the zoom buttons and slider', async () => { + await expect( + simulator.map(() => ({ + zoomInButton: simulator.zoomInElement().length, + zoomOutButton: simulator.zoomOutElement().length, + zoomSlider: simulator.zoomSliderElement().length, + })) + ).toYieldEqualTo({ + zoomInButton: 1, + zoomOutButton: 1, + zoomSlider: 1, }); + }); - describe('when the user clicks the west panning button', () => { - beforeEach(() => { - simulator.westPanElement().simulate('click'); - simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); - }); + it("should show the origin node in it's original position", async () => { + await expect(originNodeStyle()).toYieldObjectEqualTo(originalPositionStyle); + }); - it('should show the origin node further left on the screen', async () => { - expect(originNode.getDOMNode()).toHaveStyle({ left: '796.93132px', top: '535.5792px' }); - }); + describe('when the user clicks the west panning button', () => { + beforeEach(async () => { + (await simulator.resolveWrapper(() => simulator.westPanElement()))!.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); - describe('when the user clicks the south panning button', () => { - beforeEach(() => { - simulator.southPanElement().simulate('click'); - simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); - }); - - it('should show the origin node lower on the screen', async () => { - expect(originNode.getDOMNode()).toHaveStyle({ left: '746.93132px', top: '485.5792px' }); + it('should show the origin node further left on the screen', async () => { + await expect(originNodeStyle()).toYieldObjectEqualTo({ + left: '796.93132px', + top: '535.5792px', }); }); + }); - describe('when the user clicks the east panning button', () => { - beforeEach(() => { - simulator.eastPanElement().simulate('click'); - simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); - }); + describe('when the user clicks the south panning button', () => { + beforeEach(async () => { + (await simulator.resolveWrapper(() => simulator.southPanElement()))!.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + }); - it('should show the origin node further right on the screen', async () => { - expect(originNode.getDOMNode()).toHaveStyle({ left: '696.93132px', top: '535.5792px' }); + it('should show the origin node lower on the screen', async () => { + await expect(originNodeStyle()).toYieldObjectEqualTo({ + left: '746.93132px', + top: '485.5792px', }); }); + }); - describe('when the user clicks the north panning button', () => { - beforeEach(() => { - simulator.northPanElement().simulate('click'); - simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); - }); + describe('when the user clicks the east panning button', () => { + beforeEach(async () => { + (await simulator.resolveWrapper(() => simulator.eastPanElement()))!.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + }); - it('should show the origin node higher on the screen', async () => { - expect(originNode.getDOMNode()).toHaveStyle({ left: '746.93132px', top: '585.5792px' }); + it('should show the origin node further right on the screen', async () => { + await expect(originNodeStyle()).toYieldObjectEqualTo({ + left: '696.93132px', + top: '535.5792px', }); }); + }); - describe('when the user clicks the center panning button', () => { - beforeEach(() => { - simulator.northPanElement().simulate('click'); - simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); - simulator.centerPanElement().simulate('click'); - simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); - }); + describe('when the user clicks the north panning button', () => { + beforeEach(async () => { + (await simulator.resolveWrapper(() => simulator.northPanElement()))!.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + }); - it("should return the origin node to it's original position", async () => { - expect(originNode.getDOMNode()).toHaveStyle(originalPositionStyle); + it('should show the origin node higher on the screen', async () => { + await expect(originNodeStyle()).toYieldObjectEqualTo({ + left: '746.93132px', + top: '585.5792px', }); }); }); - describe('zooming', () => { - const originalSizeStyle = { width: '360px', height: '120px' }; - beforeEach(() => { - originNode = simulator.processNodeElements({ entityID: originEntityID }); + describe('when the user clicks the center panning button', () => { + beforeEach(async () => { + (await simulator.resolveWrapper(() => simulator.northPanElement()))!.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + (await simulator.resolveWrapper(() => simulator.centerPanElement()))!.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); - describe('when the user has not interacted with the zoom buttons or slider yet', () => { - it('should show the origin node as larger on the screen', () => { - expect(originNode.getDOMNode()).toHaveStyle(originalSizeStyle); - }); + it("should return the origin node to it's original position", async () => { + await expect(originNodeStyle()).toYieldObjectEqualTo(originalPositionStyle); }); + }); - describe('when the zoom in button is clicked', () => { - beforeEach(() => { - simulator.zoomInElement().simulate('click'); - simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); - }); + it('should show the origin node as larger on the screen', async () => { + await expect(originNodeStyle()).toYieldObjectEqualTo(originalSizeStyle); + }); - it('should show the origin node as larger on the screen', () => { - expect(originNode.getDOMNode()).toHaveStyle({ - width: '427.7538290724795px', - height: '142.5846096908265px', - }); - }); + describe('when the zoom in button is clicked', () => { + beforeEach(async () => { + (await simulator.resolveWrapper(() => simulator.zoomInElement()))!.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); - describe('when the zoom out button is clicked', () => { - beforeEach(() => { - simulator.zoomOutElement().simulate('click'); - simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + it('should show the origin node as larger on the screen', async () => { + await expect(originNodeStyle()).toYieldObjectEqualTo({ + width: '427.7538290724795px', + height: '142.5846096908265px', }); + }); + }); + + describe('when the zoom out button is clicked', () => { + beforeEach(async () => { + (await simulator.resolveWrapper(() => simulator.zoomOutElement()))!.simulate('click'); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + }); - it('should show the origin node as smaller on the screen', () => { - expect(originNode.getDOMNode()).toHaveStyle({ - width: '303.0461709275204px', - height: '101.01539030917347px', - }); + it('should show the origin node as smaller on the screen', async () => { + await expect(originNodeStyle()).toYieldObjectEqualTo({ + width: '303.0461709275204px', + height: '101.01539030917347px', }); }); + }); - describe('when the slider is moved upwards', () => { - beforeEach(() => { - expect(originNode.getDOMNode()).toHaveStyle(originalSizeStyle); + describe('when the slider is moved upwards', () => { + beforeEach(async () => { + await expect(originNodeStyle()).toYieldObjectEqualTo(originalSizeStyle); - simulator.zoomSliderElement().simulate('change', { target: { value: 0.8 } }); - simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + (await simulator.resolveWrapper(() => simulator.zoomSliderElement()))!.simulate('change', { + target: { value: 0.8 }, }); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + }); - it('should show the origin node as large on the screen', () => { - expect(originNode.getDOMNode()).toHaveStyle({ - width: '525.6000000000001px', - height: '175.20000000000005px', - }); + it('should show the origin node as large on the screen', async () => { + await expect(originNodeStyle()).toYieldObjectEqualTo({ + width: '525.6000000000001px', + height: '175.20000000000005px', }); }); + }); - describe('when the slider is moved downwards', () => { - beforeEach(() => { - simulator.zoomSliderElement().simulate('change', { target: { value: 0.2 } }); - simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + describe('when the slider is moved downwards', () => { + beforeEach(async () => { + (await simulator.resolveWrapper(() => simulator.zoomSliderElement()))!.simulate('change', { + target: { value: 0.2 }, }); + simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); + }); - it('should show the origin node as smaller on the screen', () => { - expect(originNode.getDOMNode()).toHaveStyle({ - width: '201.60000000000002px', - height: '67.2px', - }); + it('should show the origin node as smaller on the screen', async () => { + await expect(originNodeStyle()).toYieldObjectEqualTo({ + width: '201.60000000000002px', + height: '67.2px', }); }); }); From df4ca517924594997dca4854c727c2b0c9bbbb44 Mon Sep 17 00:00:00 2001 From: Michael Olorunnisola Date: Wed, 12 Aug 2020 16:26:32 -0400 Subject: [PATCH 8/9] simplify selector logic --- .../test_utilities/simulator/index.tsx | 140 +++--------------- .../resolver/view/clickthrough.test.tsx | 31 ++-- .../resolver/view/graph_controls.test.tsx | 36 ++--- .../public/resolver/view/panel.test.tsx | 24 +-- 4 files changed, 68 insertions(+), 163 deletions(-) diff --git a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx index 6607056b2a4bc..355b53e374092 100644 --- a/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx +++ b/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx @@ -158,6 +158,18 @@ export class Simulator { return this.domNodes(processNodeElementSelector(options)); } + /** + * Return an Enzyme ReactWrapper for any child elements of a specific processNodeElement + * + * @param entityID The entity ID of the proocess node to select in + * @param selector The selector for the child element of the process node + */ + public processNodeChildElements(entityID: string, selector: string): ReactWrapper { + return this.domNodes( + `${processNodeElementSelector({ entityID })} [data-test-subj="${selector}"]` + ); + } + /** * Return the node element with the given `entityID`. */ @@ -190,24 +202,6 @@ export class Simulator { this.sideEffectSimulator.controls.provideAnimationFrame(); } - /** - * Return an Enzyme ReactWrapper that includes the Related Events host button for a given process node - * - * @param entityID The entity ID of the proocess node to select in - */ - public processNodeRelatedEventButton(entityID: string): ReactWrapper { - return this.domNodes( - `${processNodeElementSelector({ entityID })} [data-test-subj="resolver:submenu:button"]` - ); - } - - /** - * The items in the submenu that is opened by expanding a node in the map. - */ - public processNodeSubmenuItems(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:map:node-submenu-item"]'); - } - /** * Return the selected node query string values. */ @@ -219,115 +213,17 @@ export class Simulator { } /** - * The element that shows when Resolver is waiting for the graph data. - */ - public graphLoadingElement(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:graph:loading"]'); - } - - /** - * The element that shows if Resolver couldn't draw the graph. - */ - public graphErrorElement(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:graph:error"]'); - } - - /** - * The element where nodes get drawn. - */ - public graphElement(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:graph"]'); - } - - /** - * The titles of the links that select a node in the node list view. - */ - public nodeListNodeLinkText(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:node-list:node-link:title"]'); - } - - /** - * The icons in the links that select a node in the node list view. - */ - public nodeListNodeLinkIcons(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:node-list:node-link:icon"]'); - } - - /** - * Link rendered in the breadcrumbs of the node detail view. Takes the user to the node list. - */ - public nodeDetailBreadcrumbNodeListLink(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:node-detail:breadcrumbs:node-list-link"]'); - } - - /** - * The title element for the node detail view. - */ - public nodeDetailViewTitle(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:node-detail:title"]'); - } - - /** - * Wrapper for the west panning button - */ - public westPanElement(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:graph-controls:west-button"]'); - } - - /** - * Wrapper for the south panning button - */ - public southPanElement(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:graph-controls:south-button"]'); - } - - /** - * Wrapper for the east panning button - */ - public eastPanElement(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:graph-controls:east-button"]'); - } - - /** - * Wrapper for the north panning button - */ - public northPanElement(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:graph-controls:north-button"]'); - } - - /** - * Wrapper for the center panning button - */ - public centerPanElement(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:graph-controls:center-button"]'); - } - - /** - * Wrapper for the zoom in button - */ - public zoomInElement(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:graph-controls:zoom-in"]'); - } - - /** - * Wrapper for the zoom out button - */ - public zoomOutElement(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:graph-controls:zoom-out"]'); - } - - /** - * Wrapper for the zoom slider + * Given a 'data-test-subj' value, it will resolve the react wrapper or undefined if not found */ - public zoomSliderElement(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:graph-controls:zoom-slider"]'); + public async resolve(selector: string): Promise { + return this.resolveWrapper(() => this.domNodes(`[data-test-subj="${selector}"]`)); } /** - * The details of the selected node are shown in a description list. This returns the description elements of the description list. + * Given a 'data-test-subj' selector, it will return the domNode */ - public nodeDetailViewTitleIcon(): ReactWrapper { - return this.domNodes('[data-test-subj="resolver:node-detail:title-icon"]'); + public testSubject(selector: string): ReactWrapper { + return this.domNodes(`[data-test-subj="${selector}"]`); } /** diff --git a/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx b/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx index 60122f2e450c7..1f291e8b7478d 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx @@ -42,9 +42,9 @@ describe('Resolver, when analyzing a tree that has no ancestors and 2 children', * For example, there might be no loading element at one point, and 1 graph element at one point, but never a single time when there is both 1 graph element and 0 loading elements. */ simulator.map(() => ({ - graphElements: simulator.graphElement().length, - graphLoadingElements: simulator.graphLoadingElement().length, - graphErrorElements: simulator.graphErrorElement().length, + graphElements: simulator.testSubject('resolver:graph').length, + graphLoadingElements: simulator.testSubject('resolver:graph:loading').length, + graphErrorElements: simulator.testSubject('resolver:graph:error').length, })) ).toYieldEqualTo({ // it should have 1 graph element, an no error or loading elements. @@ -72,8 +72,12 @@ describe('Resolver, when analyzing a tree that has no ancestors and 2 children', }); it(`should show links to the 3 nodes (with icons) in the node list.`, async () => { - await expect(simulator.map(() => simulator.nodeListNodeLinkText().length)).toYieldEqualTo(3); - await expect(simulator.map(() => simulator.nodeListNodeLinkIcons().length)).toYieldEqualTo(3); + await expect( + simulator.map(() => simulator.testSubject('resolver:node-list:node-link:title').length) + ).toYieldEqualTo(3); + await expect( + simulator.map(() => simulator.testSubject('resolver:node-list:node-link:title').length) + ).toYieldEqualTo(3); }); describe("when the second child node's first button has been clicked", () => { @@ -131,9 +135,9 @@ describe('Resolver, when analyzing a tree that has two related events for the or beforeEach(async () => { await expect( simulator.map(() => ({ - graphElements: simulator.graphElement().length, - graphLoadingElements: simulator.graphLoadingElement().length, - graphErrorElements: simulator.graphErrorElement().length, + graphElements: simulator.testSubject('resolver:graph').length, + graphLoadingElements: simulator.testSubject('resolver:graph:loading').length, + graphErrorElements: simulator.testSubject('resolver:graph:error').length, originNode: simulator.processNodeElements({ entityID: entityIDs.origin }).length, })) ).toYieldEqualTo({ @@ -147,7 +151,10 @@ describe('Resolver, when analyzing a tree that has two related events for the or it('should render a related events button', async () => { await expect( simulator.map(() => ({ - relatedEventButtons: simulator.processNodeRelatedEventButton(entityIDs.origin).length, + relatedEventButtons: simulator.processNodeChildElements( + entityIDs.origin, + 'resolver:submenu:button' + ).length, })) ).toYieldEqualTo({ relatedEventButtons: 1, @@ -156,7 +163,7 @@ describe('Resolver, when analyzing a tree that has two related events for the or describe('when the related events button is clicked', () => { beforeEach(async () => { const button = await simulator.resolveWrapper(() => - simulator.processNodeRelatedEventButton(entityIDs.origin) + simulator.processNodeChildElements(entityIDs.origin, 'resolver:submenu:button') ); if (button) { button.simulate('click'); @@ -164,7 +171,9 @@ describe('Resolver, when analyzing a tree that has two related events for the or }); it('should open the submenu and display exactly one option with the correct count', async () => { await expect( - simulator.map(() => simulator.processNodeSubmenuItems().map((node) => node.text())) + simulator.map(() => + simulator.testSubject('resolver:map:node-submenu-item').map((node) => node.text()) + ) ).toYieldEqualTo(['2 registry']); await expect( simulator.map(() => simulator.processNodeSubmenuItems().length) diff --git a/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx b/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx index 3b66f6af87cb4..6497cc2971980 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/graph_controls.test.tsx @@ -51,11 +51,11 @@ describe('graph controls: when relsover is loaded with an origin node', () => { it('should display all cardinal panning buttons and the center button', async () => { await expect( simulator.map(() => ({ - westPanButton: simulator.westPanElement().length, - southPanButton: simulator.southPanElement().length, - eastPanButton: simulator.eastPanElement().length, - northPanButton: simulator.northPanElement().length, - centerButton: simulator.centerPanElement().length, + westPanButton: simulator.testSubject('resolver:graph-controls:west-button').length, + southPanButton: simulator.testSubject('resolver:graph-controls:south-button').length, + eastPanButton: simulator.testSubject('resolver:graph-controls:east-button').length, + northPanButton: simulator.testSubject('resolver:graph-controls:north-button').length, + centerButton: simulator.testSubject('resolver:graph-controls:center-button').length, })) ).toYieldEqualTo({ westPanButton: 1, @@ -69,9 +69,9 @@ describe('graph controls: when relsover is loaded with an origin node', () => { it('should display the zoom buttons and slider', async () => { await expect( simulator.map(() => ({ - zoomInButton: simulator.zoomInElement().length, - zoomOutButton: simulator.zoomOutElement().length, - zoomSlider: simulator.zoomSliderElement().length, + zoomInButton: simulator.testSubject('resolver:graph-controls:zoom-in').length, + zoomOutButton: simulator.testSubject('resolver:graph-controls:zoom-out').length, + zoomSlider: simulator.testSubject('resolver:graph-controls:zoom-slider').length, })) ).toYieldEqualTo({ zoomInButton: 1, @@ -86,7 +86,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => { describe('when the user clicks the west panning button', () => { beforeEach(async () => { - (await simulator.resolveWrapper(() => simulator.westPanElement()))!.simulate('click'); + (await simulator.resolve('resolver:graph-controls:west-button'))!.simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); @@ -100,7 +100,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => { describe('when the user clicks the south panning button', () => { beforeEach(async () => { - (await simulator.resolveWrapper(() => simulator.southPanElement()))!.simulate('click'); + (await simulator.resolve('resolver:graph-controls:south-button'))!.simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); @@ -114,7 +114,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => { describe('when the user clicks the east panning button', () => { beforeEach(async () => { - (await simulator.resolveWrapper(() => simulator.eastPanElement()))!.simulate('click'); + (await simulator.resolve('resolver:graph-controls:east-button'))!.simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); @@ -128,7 +128,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => { describe('when the user clicks the north panning button', () => { beforeEach(async () => { - (await simulator.resolveWrapper(() => simulator.northPanElement()))!.simulate('click'); + (await simulator.resolve('resolver:graph-controls:north-button'))!.simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); @@ -142,9 +142,9 @@ describe('graph controls: when relsover is loaded with an origin node', () => { describe('when the user clicks the center panning button', () => { beforeEach(async () => { - (await simulator.resolveWrapper(() => simulator.northPanElement()))!.simulate('click'); + (await simulator.resolve('resolver:graph-controls:north-button'))!.simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); - (await simulator.resolveWrapper(() => simulator.centerPanElement()))!.simulate('click'); + (await simulator.resolve('resolver:graph-controls:center-button'))!.simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); @@ -159,7 +159,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => { describe('when the zoom in button is clicked', () => { beforeEach(async () => { - (await simulator.resolveWrapper(() => simulator.zoomInElement()))!.simulate('click'); + (await simulator.resolve('resolver:graph-controls:zoom-in'))!.simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); @@ -173,7 +173,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => { describe('when the zoom out button is clicked', () => { beforeEach(async () => { - (await simulator.resolveWrapper(() => simulator.zoomOutElement()))!.simulate('click'); + (await simulator.resolve('resolver:graph-controls:zoom-out'))!.simulate('click'); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); }); @@ -189,7 +189,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => { beforeEach(async () => { await expect(originNodeStyle()).toYieldObjectEqualTo(originalSizeStyle); - (await simulator.resolveWrapper(() => simulator.zoomSliderElement()))!.simulate('change', { + (await simulator.resolve('resolver:graph-controls:zoom-slider'))!.simulate('change', { target: { value: 0.8 }, }); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); @@ -205,7 +205,7 @@ describe('graph controls: when relsover is loaded with an origin node', () => { describe('when the slider is moved downwards', () => { beforeEach(async () => { - (await simulator.resolveWrapper(() => simulator.zoomSliderElement()))!.simulate('change', { + (await simulator.resolve('resolver:graph-controls:zoom-slider'))!.simulate('change', { target: { value: 0.2 }, }); simulator.runAnimationFramesTimeFromNow(nudgeAnimationDuration); diff --git a/x-pack/plugins/security_solution/public/resolver/view/panel.test.tsx b/x-pack/plugins/security_solution/public/resolver/view/panel.test.tsx index 4d391a6c9ce59..21b5a30ee9890 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/panel.test.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/panel.test.tsx @@ -72,8 +72,8 @@ describe(`Resolver: when analyzing a tree with no ancestors and two children, an it('should show the node details for the origin', async () => { await expect( simulator().map(() => { - const titleWrapper = simulator().nodeDetailViewTitle(); - const titleIconWrapper = simulator().nodeDetailViewTitleIcon(); + const titleWrapper = simulator().testSubject('resolver:node-detail:title'); + const titleIconWrapper = simulator().testSubject('resolver:node-detail:title-icon'); return { title: titleWrapper.exists() ? titleWrapper.text() : null, titleIcon: titleIconWrapper.exists() ? titleIconWrapper.text() : null, @@ -122,17 +122,17 @@ describe(`Resolver: when analyzing a tree with no ancestors and two children, an }); it('should have 3 nodes (with icons) in the node list', async () => { - await expect(simulator().map(() => simulator().nodeListNodeLinkText().length)).toYieldEqualTo( - 3 - ); - await expect(simulator().map(() => simulator().nodeListNodeLinkIcons().length)).toYieldEqualTo( - 3 - ); + await expect( + simulator().map(() => simulator().testSubject('resolver:node-list:node-link:title').length) + ).toYieldEqualTo(3); + await expect( + simulator().map(() => simulator().testSubject('resolver:node-list:node-link:icon').length) + ).toYieldEqualTo(3); }); describe('when there is an item in the node list and its text has been clicked', () => { beforeEach(async () => { - const nodeLinks = await simulator().resolveWrapper(() => simulator().nodeListNodeLinkText()); + const nodeLinks = await simulator().resolve('resolver:node-list:node-link:title'); expect(nodeLinks).toBeTruthy(); if (nodeLinks) { nodeLinks.first().simulate('click'); @@ -158,8 +158,8 @@ describe(`Resolver: when analyzing a tree with no ancestors and two children, an }); describe('and when the node list link has been clicked', () => { beforeEach(async () => { - const nodeListLink = await simulator().resolveWrapper(() => - simulator().nodeDetailBreadcrumbNodeListLink() + const nodeListLink = await simulator().resolve( + 'resolver:node-detail:breadcrumbs:node-list-link' ); if (nodeListLink) { nodeListLink.simulate('click'); @@ -169,7 +169,7 @@ describe(`Resolver: when analyzing a tree with no ancestors and two children, an await expect( simulator().map(() => { return simulator() - .nodeListNodeLinkText() + .testSubject('resolver:node-list:node-link:title') .map((node) => node.text()); }) ).toYieldEqualTo(['c', 'd', 'e']); From 505a348d89097b12baf3784e1d726c381f2f11d8 Mon Sep 17 00:00:00 2001 From: Michael Olorunnisola Date: Thu, 13 Aug 2020 11:55:59 -0400 Subject: [PATCH 9/9] replaced old method references --- .../public/resolver/view/clickthrough.test.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx b/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx index 1f291e8b7478d..23b36e818b7a8 100644 --- a/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx +++ b/x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx @@ -176,14 +176,14 @@ describe('Resolver, when analyzing a tree that has two related events for the or ) ).toYieldEqualTo(['2 registry']); await expect( - simulator.map(() => simulator.processNodeSubmenuItems().length) + simulator.map(() => simulator.testSubject('resolver:map:node-submenu-item').length) ).toYieldEqualTo(1); }); }); describe('and when the related events button is clicked again', () => { beforeEach(async () => { const button = await simulator.resolveWrapper(() => - simulator.processNodeRelatedEventButton(entityIDs.origin) + simulator.processNodeChildElements(entityIDs.origin, 'resolver:submenu:button') ); if (button) { button.simulate('click'); @@ -191,7 +191,7 @@ describe('Resolver, when analyzing a tree that has two related events for the or }); it('should close the submenu', async () => { await expect( - simulator.map(() => simulator.processNodeSubmenuItems().length) + simulator.map(() => simulator.testSubject('resolver:map:node-submenu-item').length) ).toYieldEqualTo(0); }); });