diff --git a/x-pack/plugins/lens/public/drag_drop/providers.tsx b/x-pack/plugins/lens/public/drag_drop/providers.tsx index 46247fd981134..5e0fc648454ad 100644 --- a/x-pack/plugins/lens/public/drag_drop/providers.tsx +++ b/x-pack/plugins/lens/public/drag_drop/providers.tsx @@ -171,7 +171,7 @@ export function ReorderProvider({
-

+

{state.keyboardReorderMessage}

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 831dfce2efadd..999f75686b1cb 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 @@ -193,7 +193,7 @@ export function LayerPanel( - {groups.map((group, groupIndex) => { + {groups.map((group) => { const newId = generateId(); const isMissing = !isEmptyLayer && group.required && group.accessors.length === 0; @@ -207,7 +207,7 @@ export function LayerPanel( fullWidth label={

{group.groupLabel}
} labelType="legend" - key={groupIndex} + key={group.groupId} isInvalid={isMissing} error={ isMissing ? ( @@ -222,7 +222,10 @@ export function LayerPanel( } > <> - + {group.accessors.map((accessorConfig) => { const accessor = accessorConfig.columnId; const { dragging } = dragDropContext; diff --git a/x-pack/plugins/lens/public/editor_frame_service/service.tsx b/x-pack/plugins/lens/public/editor_frame_service/service.tsx index d4e9522f3bed1..249d678f56af9 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/service.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/service.tsx @@ -125,6 +125,12 @@ export class EditorFrameService { collectAsyncDefinitions(this.visualizations), ]); + const unmount = () => { + if (domElement) { + unmountComponentAtNode(domElement); + } + }; + return { mount: async ( element, @@ -141,6 +147,9 @@ export class EditorFrameService { searchSessionId, } ) => { + if (domElement !== element) { + unmount(); + } domElement = element; const firstDatasourceId = Object.keys(resolvedDatasources)[0]; const firstVisualizationId = Object.keys(resolvedVisualizations)[0]; @@ -179,11 +188,7 @@ export class EditorFrameService { domElement ); }, - unmount() { - if (domElement) { - unmountComponentAtNode(domElement); - } - }, + unmount, }; }; diff --git a/x-pack/test/accessibility/apps/lens.ts b/x-pack/test/accessibility/apps/lens.ts new file mode 100644 index 0000000000000..bfd79f070d284 --- /dev/null +++ b/x-pack/test/accessibility/apps/lens.ts @@ -0,0 +1,138 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { FtrProviderContext } from '../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const PageObjects = getPageObjects(['common', 'visualize', 'header', 'home', 'settings', 'lens']); + const a11y = getService('a11y'); + const testSubjects = getService('testSubjects'); + const listingTable = getService('listingTable'); + + describe('Lens', () => { + const lensChartName = 'MyLensChart'; + before(async () => { + await PageObjects.common.navigateToUrl('home', '/tutorial_directory/sampleData', { + useActualUrl: true, + }); + await PageObjects.home.addSampleDataSet('flights'); + }); + + after(async () => { + await PageObjects.common.navigateToApp('visualize'); + await listingTable.searchForItemWithName(lensChartName); + await listingTable.checkListingSelectAllCheckbox(); + await listingTable.clickDeleteSelected(); + await PageObjects.common.clickConfirmOnModal(); + }); + + it('lens', async () => { + await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.clickVisType('lens'); + await a11y.testAppSnapshot(); + }); + + it('lens XY chart', async () => { + await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.clickVisType('lens'); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension', + operation: 'date_histogram', + field: 'timestamp', + }); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension', + operation: 'avg', + field: 'AvgTicketPrice', + }); + + await a11y.testAppSnapshot(); + }); + + it('lens pie chart', async () => { + await PageObjects.lens.switchToVisualization('pie'); + await a11y.testAppSnapshot(); + }); + + it('lens datatable', async () => { + await PageObjects.lens.switchToVisualization('lnsDatatable'); + await a11y.testAppSnapshot(); + }); + + it('lens metric chart', async () => { + await PageObjects.lens.switchToVisualization('lnsMetric'); + await a11y.testAppSnapshot(); + }); + + it('dimension configuration panel', async () => { + await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.clickVisType('lens'); + + await PageObjects.lens.openDimensionEditor('lnsXY_xDimensionPanel > lns-empty-dimension'); + await a11y.testAppSnapshot(); + + await PageObjects.lens.closeDimensionEditor(); + await PageObjects.lens.openDimensionEditor('lnsXY_yDimensionPanel > lns-empty-dimension'); + await a11y.testAppSnapshot(); + + await PageObjects.lens.closeDimensionEditor(); + }); + + it('change chart type', async () => { + await PageObjects.lens.switchToVisualization('line'); + await a11y.testAppSnapshot(); + }); + + it('change chart type via suggestions', async () => { + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension', + operation: 'date_histogram', + field: 'timestamp', + }); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension', + operation: 'avg', + field: 'AvgTicketPrice', + }); + + await testSubjects.click('lnsSuggestion-barChart > lnsSuggestion'); + await a11y.testAppSnapshot(); + }); + + // Skip until https://github.com/elastic/kibana/issues/88661 gets closed + it.skip('lens XY chart with multiple layers', async () => { + await PageObjects.lens.createLayer(); + + await PageObjects.lens.switchToVisualization('area'); + await PageObjects.lens.configureDimension( + { + dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension', + operation: 'terms', + field: 'DestCityName', + }, + 1 + ); + + await PageObjects.lens.configureDimension( + { + dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension', + operation: 'median', + field: 'FlightTimeMin', + }, + 1 + ); + await a11y.testAppSnapshot(); + }); + + it('saves lens chart', async () => { + await PageObjects.lens.save(lensChartName); + await a11y.testAppSnapshot(); + }); + }); +} diff --git a/x-pack/test/accessibility/config.ts b/x-pack/test/accessibility/config.ts index 070e2c3a61f2b..cf13a009c2821 100644 --- a/x-pack/test/accessibility/config.ts +++ b/x-pack/test/accessibility/config.ts @@ -28,6 +28,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { require.resolve('./apps/kibana_overview'), require.resolve('./apps/ingest_node_pipelines'), require.resolve('./apps/ml'), + require.resolve('./apps/lens'), ], pageObjects,