From e04e05aa562d5be949a2121b72c6f58530d4557a Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Tue, 18 Aug 2020 14:27:43 +0200 Subject: [PATCH] [Lens] Fix crash when two layers xychart switches to pie (#75267) * [Lens] fix crash on two layers and add a functional test with two layers switching to pie chart --- .../config_panel/config_panel.tsx | 3 +- .../config_panel/layer_panel.test.tsx | 1 + .../editor_frame/config_panel/layer_panel.tsx | 5 +- .../editor_frame/suggestion_panel.tsx | 54 ++++++++++--------- .../test/functional/apps/lens/smokescreen.ts | 49 +++++++++++++++++ .../test/functional/page_objects/lens_page.ts | 8 ++- 6 files changed, 89 insertions(+), 31 deletions(-) diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx index 5f041a8d8562f1..446f5b44c2e509 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx @@ -89,11 +89,12 @@ function LayerPanels( return ( - {layerIds.map((layerId) => ( + {layerIds.map((layerId, index) => ( { onRemoveLayer: jest.fn(), dispatch: jest.fn(), core: coreMock.createStart(), + dataTestSubj: 'lns_layerPanel-0', }; } diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx index a384e339e8fbdb..38224bf962a3f9 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx @@ -36,6 +36,7 @@ const initialPopoverState = { export function LayerPanel( props: Exclude & { layerId: string; + dataTestSubj: string; isOnlyLayer: boolean; updateVisualization: StateSetter; updateDatasource: (datasourceId: string, newState: unknown) => void; @@ -50,7 +51,7 @@ export function LayerPanel( const dragDropContext = useContext(DragContext); const [popoverState, setPopoverState] = useState(initialPopoverState); - const { framePublicAPI, layerId, isOnlyLayer, onRemoveLayer } = props; + const { framePublicAPI, layerId, isOnlyLayer, onRemoveLayer, dataTestSubj } = props; const datasourcePublicAPI = framePublicAPI.datasourceLayers[layerId]; useEffect(() => { @@ -96,7 +97,7 @@ export function LayerPanel( return ( - + { return ( - - {preview.expression ? ( - - ) : ( - - - - )} - {showTitleAsLabel && ( - {preview.title} - )} - +
+ + {preview.expression ? ( + + ) : ( + + + + )} + {showTitleAsLabel && ( + {preview.title} + )} + +
); }; @@ -204,8 +206,8 @@ export function SuggestionPanel({ : undefined; return { suggestions: newSuggestions, currentStateExpression: newStateExpression }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [ - frame, currentDatasourceStates, currentVisualizationState, currentVisualizationId, diff --git a/x-pack/test/functional/apps/lens/smokescreen.ts b/x-pack/test/functional/apps/lens/smokescreen.ts index 77b9aa1e25edd8..8c4321d77acf46 100644 --- a/x-pack/test/functional/apps/lens/smokescreen.ts +++ b/x-pack/test/functional/apps/lens/smokescreen.ts @@ -11,6 +11,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const PageObjects = getPageObjects(['visualize', 'lens']); const find = getService('find'); const listingTable = getService('listingTable'); + const testSubjects = getService('testSubjects'); describe('lens smokescreen tests', () => { it('should allow editing saved visualizations', async () => { @@ -109,6 +110,54 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(await PageObjects.lens.getLayerCount()).to.eql(2); }); + it('should switch from a multi-layer stacked bar to donut chart using suggestions', async () => { + await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.clickVisType('lens'); + await PageObjects.lens.goToTimeRange(); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension', + operation: 'terms', + field: 'geo.dest', + }); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension', + operation: 'avg', + field: 'bytes', + }); + + await PageObjects.lens.createLayer(); + + await PageObjects.lens.configureDimension( + { + dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension', + operation: 'terms', + field: 'geo.src', + }, + 1 + ); + + await PageObjects.lens.configureDimension( + { + dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension', + operation: 'avg', + field: 'bytes', + }, + 1 + ); + await PageObjects.lens.save('twolayerchart'); + await testSubjects.click('lnsSuggestion-asDonut > lnsSuggestion'); + + expect(await PageObjects.lens.getLayerCount()).to.eql(1); + expect(await PageObjects.lens.getDimensionTriggerText('lnsPie_sliceByDimensionPanel')).to.eql( + 'Top values of geo.dest' + ); + expect(await PageObjects.lens.getDimensionTriggerText('lnsPie_sizeByDimensionPanel')).to.eql( + 'Average of bytes' + ); + }); + it('should allow transition from line chart to donut chart and to bar chart', async () => { await PageObjects.visualize.gotoVisualizationLandingPage(); await listingTable.searchForItemWithName('lnsXYvis'); diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts index bed0e3a159e23f..acba3fa472b1a6 100644 --- a/x-pack/test/functional/page_objects/lens_page.ts +++ b/x-pack/test/functional/page_objects/lens_page.ts @@ -89,10 +89,14 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont * @param opts.dimension - the selector of the dimension being changed * @param opts.operation - the desired operation ID for the dimension * @param opts.field - the desired field for the dimension + * @param layerIndex - the index of the layer */ - async configureDimension(opts: { dimension: string; operation: string; field: string }) { + async configureDimension( + opts: { dimension: string; operation: string; field: string }, + layerIndex = 0 + ) { await retry.try(async () => { - await testSubjects.click(opts.dimension); + await testSubjects.click(`lns-layerPanel-${layerIndex} > ${opts.dimension}`); await testSubjects.exists(`lns-indexPatternDimension-${opts.operation}`); });