From 10196b5a97a0be1612680f44fd559cf680b6ea8d Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Mon, 3 Aug 2020 15:47:36 +0200 Subject: [PATCH 1/8] lens functional tests --- .../pie_visualization/pie_visualization.tsx | 4 + .../xy_visualization/xy_config_panel.test.tsx | 2 + .../xy_visualization/xy_config_panel.tsx | 2 +- .../test/functional/apps/lens/smokescreen.ts | 83 ++++++++++++++---- .../es_archives/lens/basic/data.json.gz | Bin 4183 -> 4623 bytes .../test/functional/page_objects/lens_page.ts | 28 ++++++ 6 files changed, 102 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/lens/public/pie_visualization/pie_visualization.tsx b/x-pack/plugins/lens/public/pie_visualization/pie_visualization.tsx index 369ab28293fbc8..5a68516db6aa3f 100644 --- a/x-pack/plugins/lens/public/pie_visualization/pie_visualization.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/pie_visualization.tsx @@ -122,6 +122,7 @@ export const pieVisualization: Visualization { /> ); + // TODO: fix const options = component .find('[data-test-subj="lnsXY_seriesType"]') .first() @@ -78,6 +79,7 @@ describe('XY Config panels', () => { /> ); + // TODO: fix const options = component .find('[data-test-subj="lnsXY_seriesType"]') .first() diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 59c4b393df467a..64c61f23996e03 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -95,13 +95,13 @@ export function LayerContextMenu(props: VisualizationLayerWidgetProps) { })} name="chartType" className="eui-displayInlineBlock" - data-test-subj="lnsXY_seriesType" options={visualizationTypes .filter((t) => isHorizontalSeries(t.id as SeriesType) === horizontalOnly) .map((t) => ({ id: t.id, label: t.label, iconType: t.icon || 'empty', + 'data-test-subj': `lnsXY_seriesType-${t.id}`, }))} idSelected={layer.seriesType} onChange={(seriesType) => { diff --git a/x-pack/test/functional/apps/lens/smokescreen.ts b/x-pack/test/functional/apps/lens/smokescreen.ts index 23d4cc972675bb..5b7f609efa886f 100644 --- a/x-pack/test/functional/apps/lens/smokescreen.ts +++ b/x-pack/test/functional/apps/lens/smokescreen.ts @@ -46,13 +46,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); } - async function assertExpectedChart() { + async function assertExpectedChartTitleInEmbeddable(title: string) { await PageObjects.lens.assertExactText( - '[data-test-subj="embeddablePanelHeading-lnsXYvis"]', - 'lnsXYvis' + `[data-test-subj="embeddablePanelHeading-${title}"]`, + title ); } + async function assertExpectedChartTitle(title: string) { + await PageObjects.lens.assertExactText(`[data-test-subj="lns_ChartTitle"]`, title); + } + async function assertExpectedTimerange() { const time = await PageObjects.timePicker.getTimeConfig(); expect(time.start).to.equal('Sep 21, 2015 @ 09:00:00.000'); @@ -99,24 +103,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await testSubjects.missingOrFail('applyFiltersPopoverButton'); }); - await assertExpectedChart(); + await assertExpectedChartTitleInEmbeddable('lnsXYvis'); await assertExpectedTimerange(); const hasIpFilter = await filterBar.hasFilter('ip', '97.220.3.248'); expect(hasIpFilter).to.be(true); }); - it('should allow seamless transition to and from table view', async () => { - await PageObjects.visualize.gotoVisualizationLandingPage(); - await listingTable.searchForItemWithName('Artistpreviouslyknownaslens'); - await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens'); - await PageObjects.lens.goToTimeRange(); - await assertExpectedMetric(); - await PageObjects.lens.switchToVisualization('lnsDatatable'); - await assertExpectedTable(); - await PageObjects.lens.switchToVisualization('lnsMetric'); - await assertExpectedMetric(); - }); - it('should allow creation of lens visualizations', async () => { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickVisType('lens'); @@ -166,6 +158,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(await find.allByCssSelector('.echLegendItem')).to.have.length(3); }); + it('should allow seamless transition to and from table view', async () => { + await PageObjects.visualize.gotoVisualizationLandingPage(); + await listingTable.searchForItemWithName('Artistpreviouslyknownaslens'); + await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens'); + await PageObjects.lens.goToTimeRange(); + await assertExpectedMetric(); + await PageObjects.lens.switchToVisualization('lnsDatatable'); + await assertExpectedTable(); + await PageObjects.lens.switchToVisualization('lnsMetric'); + await assertExpectedMetric(); + }); + it('should switch from a multi-layer stacked bar to a multi-layer line chart', async () => { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickVisType('lens'); @@ -191,5 +195,52 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(await PageObjects.lens.getLayerCount()).to.eql(2); }); + + it('should allow transition from line chart to donut chart and to bar chart', async () => { + await PageObjects.visualize.gotoVisualizationLandingPage(); + await listingTable.searchForItemWithName('lnsXYvis'); + await PageObjects.lens.clickVisualizeListItemTitle('lnsXYvis'); + await PageObjects.lens.goToTimeRange(); + await PageObjects.lens.switchToVisualization('donut'); + await assertExpectedChartTitle('lnsXYvis'); + // TODO: to check if chart is valid, we check dimension panel + // - once we have access to check if chart renders properly, we should make assertions based on chart + expect( + await PageObjects.lens.getVisibleTextOfDimensionTrigger('lnsPie_sliceByDimensionPanel') + ).to.eql('Top values of ip'); + expect( + await PageObjects.lens.getVisibleTextOfDimensionTrigger('lnsPie_sizeByDimensionPanel') + ).to.eql('Average of bytes'); + + await PageObjects.lens.switchToVisualization('bar'); + await assertExpectedChartTitle('lnsXYvis'); + }); + + it('should allow seamless transition from bar chart to line chart using layer chart switch', async () => { + await PageObjects.visualize.gotoVisualizationLandingPage(); + await listingTable.searchForItemWithName('lnsXYvis'); + await PageObjects.lens.clickVisualizeListItemTitle('lnsXYvis'); + await PageObjects.lens.goToTimeRange(); + await PageObjects.lens.switchLayerSeriesType('line'); + await assertExpectedChartTitle('lnsXYvis'); + }); + + it('should allow seamless transition from pie chart to treemap chart', async () => { + await PageObjects.visualize.gotoVisualizationLandingPage(); + await listingTable.searchForItemWithName('lnsPieVis'); + await PageObjects.lens.clickVisualizeListItemTitle('lnsPieVis'); + await PageObjects.lens.goToTimeRange(); + expect(await PageObjects.lens.hasChartSwitchWarning('treemap')).to.eql(false); + await PageObjects.lens.switchToVisualization('treemap'); + expect( + await PageObjects.lens.getVisibleTextOfDimensionTrigger('lnsPie_groupByDimensionPanel', 0) + ).to.eql('Top values of geo.dest'); + expect( + await PageObjects.lens.getVisibleTextOfDimensionTrigger('lnsPie_groupByDimensionPanel', 1) + ).to.eql('Top values of geo.src'); + expect( + await PageObjects.lens.getVisibleTextOfDimensionTrigger('lnsPie_sizeByDimensionPanel') + ).to.eql('Average of bytes'); + }); }); } diff --git a/x-pack/test/functional/es_archives/lens/basic/data.json.gz b/x-pack/test/functional/es_archives/lens/basic/data.json.gz index 4ed7c29f7391e4b01ea2737a318cb533d72bf63a..ddf4a27289dffdaf1c605b0db01cfa9554a2b209 100644 GIT binary patch literal 4623 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 diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts index 79548db0e26301..2b50cd7502409f 100644 --- a/x-pack/test/functional/page_objects/lens_page.ts +++ b/x-pack/test/functional/page_objects/lens_page.ts @@ -181,6 +181,20 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont return await testSubjects.descendantExists('euiKeyPadMenuItem__betaBadgeWrapper', element); }, + /** + * Uses the Lens layer switcher to switch seriesType for xy charts. + * + * @param subVisualizationId - the ID of the sub-visualization to switch to, such as + * line, + */ + async switchLayerSeriesType(seriesType: string) { + await retry.try(async () => { + await testSubjects.click('lns_layer_settings'); + }); + + return await testSubjects.click(`lnsXY_seriesType-${seriesType}`); + }, + /** * Returns the number of layers visible in the chart configuration */ @@ -205,5 +219,19 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont await PageObjects.header.waitUntilLoadingHasFinished(); await testSubjects.missingOrFail('lnsApp_saveAndReturnButton'); }, + /** + * Gets label of dimension trigger in dimension panel + * + * @param dimension - the selector of the dimension + */ + async getVisibleTextOfDimensionTrigger(dimension: string, index = 0) { + const dimensionElements = await testSubjects.findAll(dimension); + const trigger = await testSubjects.findDescendant( + 'lns-dimensionTrigger', + dimensionElements[index] + ); + const text = await trigger.getVisibleText(); + return text; + }, }); } From dc44b7b9eede24e0b7037800bdc483d2a7ad06b0 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Mon, 3 Aug 2020 15:53:05 +0200 Subject: [PATCH 2/8] fix unit tests --- .../lens/public/xy_visualization/xy_config_panel.test.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.test.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.test.tsx index 418d555e45f1c9..375eaf736cc958 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.test.tsx @@ -6,7 +6,7 @@ import React from 'react'; import { mountWithIntl as mount, shallowWithIntl as shallow } from 'test_utils/enzyme_helpers'; -import { EuiButtonGroupProps, EuiSuperSelect } from '@elastic/eui'; +import { EuiButtonGroupProps, EuiSuperSelect, EuiButtonGroup } from '@elastic/eui'; import { LayerContextMenu, XyToolbar } from './xy_config_panel'; import { FramePublicAPI } from '../types'; import { State } from './types'; @@ -51,9 +51,8 @@ describe('XY Config panels', () => { /> ); - // TODO: fix const options = component - .find('[data-test-subj="lnsXY_seriesType"]') + .find(EuiButtonGroup) .first() .prop('options') as EuiButtonGroupProps['options']; @@ -79,9 +78,8 @@ describe('XY Config panels', () => { /> ); - // TODO: fix const options = component - .find('[data-test-subj="lnsXY_seriesType"]') + .find(EuiButtonGroup) .first() .prop('options') as EuiButtonGroupProps['options']; From 97bfa1f3399e4dcb23f9e124a1e9795fb1528cfc Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Tue, 4 Aug 2020 09:05:57 +0200 Subject: [PATCH 3/8] test: add pie tests, divide into dashboard and smokescreen --- .../api_integration/apis/lens/telemetry.ts | 1 + x-pack/test/functional/apps/lens/dashboard.ts | 74 ++++++++++ x-pack/test/functional/apps/lens/index.ts | 1 + .../test/functional/apps/lens/smokescreen.ts | 127 ++++++------------ 4 files changed, 120 insertions(+), 83 deletions(-) create mode 100644 x-pack/test/functional/apps/lens/dashboard.ts diff --git a/x-pack/test/api_integration/apis/lens/telemetry.ts b/x-pack/test/api_integration/apis/lens/telemetry.ts index bd6144a2690b02..03a1cfc5c2a723 100644 --- a/x-pack/test/api_integration/apis/lens/telemetry.ts +++ b/x-pack/test/api_integration/apis/lens/telemetry.ts @@ -192,6 +192,7 @@ export default ({ getService }: FtrProviderContext) => { expect(results.saved_overall).to.eql({ lnsMetric: 1, bar_stacked: 1, + lnsPie: 1, }); expect(results.saved_overall_total).to.eql(2); diff --git a/x-pack/test/functional/apps/lens/dashboard.ts b/x-pack/test/functional/apps/lens/dashboard.ts new file mode 100644 index 00000000000000..b1e294b784b077 --- /dev/null +++ b/x-pack/test/functional/apps/lens/dashboard.ts @@ -0,0 +1,74 @@ +/* + * 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 expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +// eslint-disable-next-line import/no-default-export +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const PageObjects = getPageObjects(['header', 'common', 'dashboard', 'timePicker', 'lens']); + + const find = getService('find'); + const dashboardAddPanel = getService('dashboardAddPanel'); + const elasticChart = getService('elasticChart'); + const browser = getService('browser'); + const retry = getService('retry'); + const testSubjects = getService('testSubjects'); + const filterBar = getService('filterBar'); + + async function assertExpectedMetric(title: string, metric: string) { + await PageObjects.lens.assertExactText('[data-test-subj="lns_metric_title"]', title); + await PageObjects.lens.assertExactText('[data-test-subj="lns_metric_value"]', metric); + } + + async function assertExpectedChartTitleInEmbeddable(title: string) { + await PageObjects.lens.assertExactText( + `[data-test-subj="embeddablePanelHeading-${title}"]`, + title + ); + } + + async function clickInChart(x: number, y: number) { + const el = await elasticChart.getCanvas(); + await browser.getActions().move({ x, y, origin: el._webElement }).click().perform(); + } + + describe('lens dashboard tests', () => { + it('metric should be embeddable in dashboards', async () => { + await PageObjects.common.navigateToApp('dashboard'); + await PageObjects.dashboard.clickNewDashboard(); + await dashboardAddPanel.clickOpenAddPanel(); + await dashboardAddPanel.filterEmbeddableNames('Artistpreviouslyknownaslens'); + await find.clickByButtonText('Artistpreviouslyknownaslens'); + await dashboardAddPanel.closeAddPanel(); + await PageObjects.lens.goToTimeRange(); + await assertExpectedMetric('Maximum of bytes', '19,986'); + }); + + it('click on the bar in XYChart adds proper filters/timerange in dashboard', async () => { + await PageObjects.common.navigateToApp('dashboard'); + await PageObjects.dashboard.clickNewDashboard(); + await dashboardAddPanel.clickOpenAddPanel(); + await dashboardAddPanel.filterEmbeddableNames('lnsXYvis'); + await find.clickByButtonText('lnsXYvis'); + await dashboardAddPanel.closeAddPanel(); + await PageObjects.lens.goToTimeRange(); + await clickInChart(5, 5); // hardcoded position of bar + + await retry.try(async () => { + await testSubjects.click('applyFiltersPopoverButton'); + await testSubjects.missingOrFail('applyFiltersPopoverButton'); + }); + + await assertExpectedChartTitleInEmbeddable('lnsXYvis'); + const time = await PageObjects.timePicker.getTimeConfig(); + expect(time.start).to.equal('Sep 21, 2015 @ 09:00:00.000'); + expect(time.end).to.equal('Sep 21, 2015 @ 12:00:00.000'); + const hasIpFilter = await filterBar.hasFilter('ip', '97.220.3.248'); + expect(hasIpFilter).to.be(true); + }); + }); +} diff --git a/x-pack/test/functional/apps/lens/index.ts b/x-pack/test/functional/apps/lens/index.ts index 9e04f6e9df22b5..47fa19b0aa9fa3 100644 --- a/x-pack/test/functional/apps/lens/index.ts +++ b/x-pack/test/functional/apps/lens/index.ts @@ -31,6 +31,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./smokescreen')); loadTestFile(require.resolve('./persistent_context')); loadTestFile(require.resolve('./lens_reporting')); + loadTestFile(require.resolve('./dashboard')); }); }); } diff --git a/x-pack/test/functional/apps/lens/smokescreen.ts b/x-pack/test/functional/apps/lens/smokescreen.ts index 5b7f609efa886f..f375d02763685d 100644 --- a/x-pack/test/functional/apps/lens/smokescreen.ts +++ b/x-pack/test/functional/apps/lens/smokescreen.ts @@ -9,63 +9,31 @@ import { FtrProviderContext } from '../../ftr_provider_context'; // eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: FtrProviderContext) { - const PageObjects = getPageObjects([ - 'header', - 'common', - 'visualize', - 'dashboard', - 'header', - 'timePicker', - 'lens', - ]); + const PageObjects = getPageObjects(['visualize', 'lens']); const find = getService('find'); - const dashboardAddPanel = getService('dashboardAddPanel'); - const elasticChart = getService('elasticChart'); - const browser = getService('browser'); - const retry = getService('retry'); - const testSubjects = getService('testSubjects'); - const filterBar = getService('filterBar'); const listingTable = getService('listingTable'); - async function assertExpectedMetric(metricCount: string = '19,986') { - await PageObjects.lens.assertExactText( - '[data-test-subj="lns_metric_title"]', - 'Maximum of bytes' - ); - await PageObjects.lens.assertExactText('[data-test-subj="lns_metric_value"]', metricCount); - } - - async function assertExpectedTable() { - await PageObjects.lens.assertExactText( - '[data-test-subj="lnsDataTable"] thead .euiTableCellContent__text', - 'Maximum of bytes' - ); - await PageObjects.lens.assertExactText( - '[data-test-subj="lnsDataTable"] [data-test-subj="lnsDataTableCellValue"]', - '19,986' - ); - } - - async function assertExpectedChartTitleInEmbeddable(title: string) { - await PageObjects.lens.assertExactText( - `[data-test-subj="embeddablePanelHeading-${title}"]`, - title - ); + async function assertExpectedMetric(title: string, metric: string) { + await PageObjects.lens.assertExactText('[data-test-subj="lns_metric_title"]', title); + await PageObjects.lens.assertExactText('[data-test-subj="lns_metric_value"]', metric); } async function assertExpectedChartTitle(title: string) { await PageObjects.lens.assertExactText(`[data-test-subj="lns_ChartTitle"]`, title); } - async function assertExpectedTimerange() { - const time = await PageObjects.timePicker.getTimeConfig(); - expect(time.start).to.equal('Sep 21, 2015 @ 09:00:00.000'); - expect(time.end).to.equal('Sep 21, 2015 @ 12:00:00.000'); + async function assertDatatableThText(text: string, index = 0) { + return PageObjects.lens.assertExactText( + `[data-test-subj="lnsDataTable"] thead th:nth-child(${index + 1}) .euiTableCellContent__text`, + text + ); } - async function clickOnBarHistogram() { - const el = await elasticChart.getCanvas(); - await browser.getActions().move({ x: 5, y: 5, origin: el._webElement }).click().perform(); + async function assertDatatableCellText(text: string, rowIndex = 0, colIndex = 0) { + return PageObjects.lens.assertExactText( + `[data-test-subj="lnsDataTable"] tr:nth-child(${rowIndex + 1}) td:nth-child(${colIndex + 1})`, + text + ); } describe('lens smokescreen tests', () => { @@ -74,42 +42,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await listingTable.searchForItemWithName('Artistpreviouslyknownaslens'); await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens'); await PageObjects.lens.goToTimeRange(); - await assertExpectedMetric(); + await assertExpectedMetric('Maximum of bytes', '19,986'); }); - it('metric should be embeddable in dashboards', async () => { - await PageObjects.common.navigateToApp('dashboard'); - await PageObjects.dashboard.clickNewDashboard(); - await dashboardAddPanel.clickOpenAddPanel(); - await dashboardAddPanel.filterEmbeddableNames('Artistpreviouslyknownaslens'); - await find.clickByButtonText('Artistpreviouslyknownaslens'); - await dashboardAddPanel.closeAddPanel(); - await PageObjects.lens.goToTimeRange(); - await assertExpectedMetric(); - }); - - it('click on the bar in XYChart adds proper filters/timerange in dashboard', async () => { - await PageObjects.common.navigateToApp('dashboard'); - await PageObjects.dashboard.clickNewDashboard(); - await dashboardAddPanel.clickOpenAddPanel(); - await dashboardAddPanel.filterEmbeddableNames('lnsXYvis'); - await find.clickByButtonText('lnsXYvis'); - await dashboardAddPanel.closeAddPanel(); - await PageObjects.lens.goToTimeRange(); - await clickOnBarHistogram(); - - await retry.try(async () => { - await testSubjects.click('applyFiltersPopoverButton'); - await testSubjects.missingOrFail('applyFiltersPopoverButton'); - }); - - await assertExpectedChartTitleInEmbeddable('lnsXYvis'); - await assertExpectedTimerange(); - const hasIpFilter = await filterBar.hasFilter('ip', '97.220.3.248'); - expect(hasIpFilter).to.be(true); - }); - - it('should allow creation of lens visualizations', async () => { + it('should allow creation of lens xy chart', async () => { await PageObjects.visualize.navigateToNewVisualization(); await PageObjects.visualize.clickVisType('lens'); await PageObjects.lens.goToTimeRange(); @@ -163,11 +99,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await listingTable.searchForItemWithName('Artistpreviouslyknownaslens'); await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens'); await PageObjects.lens.goToTimeRange(); - await assertExpectedMetric(); + await assertExpectedMetric('Maximum of bytes', '19,986'); await PageObjects.lens.switchToVisualization('lnsDatatable'); - await assertExpectedTable(); + await assertDatatableThText('Maximum of bytes'); + await assertDatatableCellText('19,986', 0, 0); await PageObjects.lens.switchToVisualization('lnsMetric'); - await assertExpectedMetric(); + await assertExpectedMetric('Maximum of bytes', '19,986'); }); it('should switch from a multi-layer stacked bar to a multi-layer line chart', async () => { @@ -242,5 +179,29 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.lens.getVisibleTextOfDimensionTrigger('lnsPie_sizeByDimensionPanel') ).to.eql('Average of bytes'); }); + + it('should allow creating a pie chart and switching to datatable', async () => { + await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.clickVisType('lens'); + await PageObjects.lens.goToTimeRange(); + await PageObjects.lens.switchToVisualization('pie'); + await PageObjects.lens.configureDimension({ + dimension: 'lnsPie_sliceByDimensionPanel > lns-empty-dimension', + operation: 'date_histogram', + field: '@timestamp', + }); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsPie_sizeByDimensionPanel > lns-empty-dimension', + operation: 'avg', + field: 'bytes', + }); + + await PageObjects.lens.switchToVisualization('lnsDatatable'); + await assertDatatableThText('@timestamp per 3 hours', 0); + await assertDatatableThText('Average of bytes', 1); + await assertDatatableCellText('2015-09-20 00:00', 0, 0); + await assertDatatableCellText('6,011.351', 0, 1); + }); }); } From a766affe41f504a585a49031573cb90e8af39832 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Tue, 4 Aug 2020 09:38:03 +0200 Subject: [PATCH 4/8] move assertion lens specific functions to page object --- x-pack/test/functional/apps/lens/dashboard.ts | 20 ++---- .../test/functional/apps/lens/smokescreen.ts | 69 +++++++------------ .../test/functional/page_objects/lens_page.ts | 53 +++++++++++++- 3 files changed, 79 insertions(+), 63 deletions(-) diff --git a/x-pack/test/functional/apps/lens/dashboard.ts b/x-pack/test/functional/apps/lens/dashboard.ts index b1e294b784b077..827659ba733bef 100644 --- a/x-pack/test/functional/apps/lens/dashboard.ts +++ b/x-pack/test/functional/apps/lens/dashboard.ts @@ -19,25 +19,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const filterBar = getService('filterBar'); - async function assertExpectedMetric(title: string, metric: string) { - await PageObjects.lens.assertExactText('[data-test-subj="lns_metric_title"]', title); - await PageObjects.lens.assertExactText('[data-test-subj="lns_metric_value"]', metric); - } - - async function assertExpectedChartTitleInEmbeddable(title: string) { - await PageObjects.lens.assertExactText( - `[data-test-subj="embeddablePanelHeading-${title}"]`, - title - ); - } - async function clickInChart(x: number, y: number) { const el = await elasticChart.getCanvas(); await browser.getActions().move({ x, y, origin: el._webElement }).click().perform(); } describe('lens dashboard tests', () => { - it('metric should be embeddable in dashboards', async () => { + it('metric should be embeddable', async () => { await PageObjects.common.navigateToApp('dashboard'); await PageObjects.dashboard.clickNewDashboard(); await dashboardAddPanel.clickOpenAddPanel(); @@ -45,10 +33,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await find.clickByButtonText('Artistpreviouslyknownaslens'); await dashboardAddPanel.closeAddPanel(); await PageObjects.lens.goToTimeRange(); - await assertExpectedMetric('Maximum of bytes', '19,986'); + await PageObjects.lens.assertMetric('Maximum of bytes', '19,986'); }); - it('click on the bar in XYChart adds proper filters/timerange in dashboard', async () => { + it('should be able to add filters/timerange by clicking in XYChart', async () => { await PageObjects.common.navigateToApp('dashboard'); await PageObjects.dashboard.clickNewDashboard(); await dashboardAddPanel.clickOpenAddPanel(); @@ -63,7 +51,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await testSubjects.missingOrFail('applyFiltersPopoverButton'); }); - await assertExpectedChartTitleInEmbeddable('lnsXYvis'); + await PageObjects.lens.assertChartTitle('lnsXYvis'); const time = await PageObjects.timePicker.getTimeConfig(); expect(time.start).to.equal('Sep 21, 2015 @ 09:00:00.000'); expect(time.end).to.equal('Sep 21, 2015 @ 12:00:00.000'); diff --git a/x-pack/test/functional/apps/lens/smokescreen.ts b/x-pack/test/functional/apps/lens/smokescreen.ts index f375d02763685d..fdb210ce9c01aa 100644 --- a/x-pack/test/functional/apps/lens/smokescreen.ts +++ b/x-pack/test/functional/apps/lens/smokescreen.ts @@ -13,36 +13,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const find = getService('find'); const listingTable = getService('listingTable'); - async function assertExpectedMetric(title: string, metric: string) { - await PageObjects.lens.assertExactText('[data-test-subj="lns_metric_title"]', title); - await PageObjects.lens.assertExactText('[data-test-subj="lns_metric_value"]', metric); - } - - async function assertExpectedChartTitle(title: string) { - await PageObjects.lens.assertExactText(`[data-test-subj="lns_ChartTitle"]`, title); - } - - async function assertDatatableThText(text: string, index = 0) { - return PageObjects.lens.assertExactText( - `[data-test-subj="lnsDataTable"] thead th:nth-child(${index + 1}) .euiTableCellContent__text`, - text - ); - } - - async function assertDatatableCellText(text: string, rowIndex = 0, colIndex = 0) { - return PageObjects.lens.assertExactText( - `[data-test-subj="lnsDataTable"] tr:nth-child(${rowIndex + 1}) td:nth-child(${colIndex + 1})`, - text - ); - } - describe('lens smokescreen tests', () => { it('should allow editing saved visualizations', async () => { await PageObjects.visualize.gotoVisualizationLandingPage(); await listingTable.searchForItemWithName('Artistpreviouslyknownaslens'); await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens'); await PageObjects.lens.goToTimeRange(); - await assertExpectedMetric('Maximum of bytes', '19,986'); + await PageObjects.lens.assertMetric('Maximum of bytes', '19,986'); }); it('should allow creation of lens xy chart', async () => { @@ -99,12 +76,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await listingTable.searchForItemWithName('Artistpreviouslyknownaslens'); await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens'); await PageObjects.lens.goToTimeRange(); - await assertExpectedMetric('Maximum of bytes', '19,986'); + await PageObjects.lens.assertMetric('Maximum of bytes', '19,986'); await PageObjects.lens.switchToVisualization('lnsDatatable'); - await assertDatatableThText('Maximum of bytes'); - await assertDatatableCellText('19,986', 0, 0); + await PageObjects.lens.assertDatatableThText('Maximum of bytes'); + await PageObjects.lens.assertDatatableCellText('19,986', 0, 0); await PageObjects.lens.switchToVisualization('lnsMetric'); - await assertExpectedMetric('Maximum of bytes', '19,986'); + await PageObjects.lens.assertMetric('Maximum of bytes', '19,986'); }); it('should switch from a multi-layer stacked bar to a multi-layer line chart', async () => { @@ -139,18 +116,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.lens.clickVisualizeListItemTitle('lnsXYvis'); await PageObjects.lens.goToTimeRange(); await PageObjects.lens.switchToVisualization('donut'); - await assertExpectedChartTitle('lnsXYvis'); + await PageObjects.lens.assertChartTitle('lnsXYvis'); // TODO: to check if chart is valid, we check dimension panel // - once we have access to check if chart renders properly, we should make assertions based on chart - expect( - await PageObjects.lens.getVisibleTextOfDimensionTrigger('lnsPie_sliceByDimensionPanel') - ).to.eql('Top values of ip'); - expect( - await PageObjects.lens.getVisibleTextOfDimensionTrigger('lnsPie_sizeByDimensionPanel') - ).to.eql('Average of bytes'); + expect(await PageObjects.lens.getDimensionTriggerText('lnsPie_sliceByDimensionPanel')).to.eql( + 'Top values of ip' + ); + expect(await PageObjects.lens.getDimensionTriggerText('lnsPie_sizeByDimensionPanel')).to.eql( + 'Average of bytes' + ); await PageObjects.lens.switchToVisualization('bar'); - await assertExpectedChartTitle('lnsXYvis'); + await PageObjects.lens.assertChartTitle('lnsXYvis'); }); it('should allow seamless transition from bar chart to line chart using layer chart switch', async () => { @@ -159,7 +136,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.lens.clickVisualizeListItemTitle('lnsXYvis'); await PageObjects.lens.goToTimeRange(); await PageObjects.lens.switchLayerSeriesType('line'); - await assertExpectedChartTitle('lnsXYvis'); + await PageObjects.lens.assertChartTitle('lnsXYvis'); }); it('should allow seamless transition from pie chart to treemap chart', async () => { @@ -170,14 +147,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(await PageObjects.lens.hasChartSwitchWarning('treemap')).to.eql(false); await PageObjects.lens.switchToVisualization('treemap'); expect( - await PageObjects.lens.getVisibleTextOfDimensionTrigger('lnsPie_groupByDimensionPanel', 0) + await PageObjects.lens.getDimensionTriggerText('lnsPie_groupByDimensionPanel', 0) ).to.eql('Top values of geo.dest'); expect( - await PageObjects.lens.getVisibleTextOfDimensionTrigger('lnsPie_groupByDimensionPanel', 1) + await PageObjects.lens.getDimensionTriggerText('lnsPie_groupByDimensionPanel', 1) ).to.eql('Top values of geo.src'); - expect( - await PageObjects.lens.getVisibleTextOfDimensionTrigger('lnsPie_sizeByDimensionPanel') - ).to.eql('Average of bytes'); + expect(await PageObjects.lens.getDimensionTriggerText('lnsPie_sizeByDimensionPanel')).to.eql( + 'Average of bytes' + ); }); it('should allow creating a pie chart and switching to datatable', async () => { @@ -198,10 +175,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); await PageObjects.lens.switchToVisualization('lnsDatatable'); - await assertDatatableThText('@timestamp per 3 hours', 0); - await assertDatatableThText('Average of bytes', 1); - await assertDatatableCellText('2015-09-20 00:00', 0, 0); - await assertDatatableCellText('6,011.351', 0, 1); + await PageObjects.lens.assertDatatableThText('@timestamp per 3 hours', 0); + await PageObjects.lens.assertDatatableThText('Average of bytes', 1); + await PageObjects.lens.assertDatatableCellText('2015-09-20 00:00', 0, 0); + await PageObjects.lens.assertDatatableCellText('6,011.351', 0, 1); }); }); } diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts index 2b50cd7502409f..c1c0ae2adf4589 100644 --- a/x-pack/test/functional/page_objects/lens_page.ts +++ b/x-pack/test/functional/page_objects/lens_page.ts @@ -224,7 +224,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont * * @param dimension - the selector of the dimension */ - async getVisibleTextOfDimensionTrigger(dimension: string, index = 0) { + async getDimensionTriggerText(dimension: string, index = 0) { const dimensionElements = await testSubjects.findAll(dimension); const trigger = await testSubjects.findDescendant( 'lns-dimensionTrigger', @@ -233,5 +233,56 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont const text = await trigger.getVisibleText(); return text; }, + + /** + * Asserts that metric has expected title and count + * + * @param title - expected title + * @param count - expected count of metric + */ + async assertMetric(title: string, count: string) { + await this.assertExactText('[data-test-subj="lns_metric_title"]', title); + await this.assertExactText('[data-test-subj="lns_metric_value"]', count); + }, + + /** + * Asserts expected chart title + * + * @param title - expected title + */ + async assertChartTitle(title: string) { + await this.assertExactText(`[data-test-subj="lns_ChartTitle"]`, title); + }, + + /** + * Asserts that datatable th element has expected text + * + * @param text - the expected text + * @param index - index of th element in datatable + */ + async assertDatatableThText(text: string, index = 0) { + return this.assertExactText( + `[data-test-subj="lnsDataTable"] thead th:nth-child(${ + index + 1 + }) .euiTableCellContent__text`, + text + ); + }, + + /** + * Asserts that the specified datatable cell has expected text + * + * @param text - the expected text + * @param rowIndex - index of row of the cell + * @param colIndex - index of column of the cell + */ + async assertDatatableCellText(text: string, rowIndex = 0, colIndex = 0) { + return this.assertExactText( + `[data-test-subj="lnsDataTable"] tr:nth-child(${rowIndex + 1}) td:nth-child(${ + colIndex + 1 + })`, + text + ); + }, }); } From 5031e492b06c6efaf079726c0323c2fde3174e1c Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Tue, 4 Aug 2020 09:46:22 +0200 Subject: [PATCH 5/8] prepare for flaky-test-runner --- x-pack/test/functional/apps/lens/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/lens/index.ts b/x-pack/test/functional/apps/lens/index.ts index 47fa19b0aa9fa3..8b8f204fcf6393 100644 --- a/x-pack/test/functional/apps/lens/index.ts +++ b/x-pack/test/functional/apps/lens/index.ts @@ -12,7 +12,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { const log = getService('log'); const esArchiver = getService('esArchiver'); - describe('lens app', () => { + describe.only('lens app', () => { before(async () => { log.debug('Starting lens before method'); await browser.setWindowSize(1280, 800); From a9b52befc22d1c09a9a9e234e83ce31e34d155d8 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Tue, 4 Aug 2020 14:09:53 +0200 Subject: [PATCH 6/8] fixes --- .../change_indexpattern.tsx | 2 +- .../api_integration/apis/lens/telemetry.ts | 2 +- x-pack/test/functional/apps/lens/dashboard.ts | 5 +- x-pack/test/functional/apps/lens/index.ts | 2 +- .../test/functional/apps/lens/smokescreen.ts | 22 +++---- .../test/functional/page_objects/lens_page.ts | 62 +++++++++---------- 6 files changed, 46 insertions(+), 49 deletions(-) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/change_indexpattern.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/change_indexpattern.tsx index 5e2fe9d7bbc14b..a62db353e2bafa 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/change_indexpattern.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/change_indexpattern.tsx @@ -57,7 +57,7 @@ export function ChangeIndexPattern({ panelPaddingSize="s" ownFocus > -
+
{i18n.translate('xpack.lens.indexPattern.changeIndexPatternTitle', { defaultMessage: 'Change index pattern', diff --git a/x-pack/test/api_integration/apis/lens/telemetry.ts b/x-pack/test/api_integration/apis/lens/telemetry.ts index 03a1cfc5c2a723..fd63a34c8a9b29 100644 --- a/x-pack/test/api_integration/apis/lens/telemetry.ts +++ b/x-pack/test/api_integration/apis/lens/telemetry.ts @@ -194,7 +194,7 @@ export default ({ getService }: FtrProviderContext) => { bar_stacked: 1, lnsPie: 1, }); - expect(results.saved_overall_total).to.eql(2); + expect(results.saved_overall_total).to.eql(3); await esArchiver.unload('lens/basic'); }); diff --git a/x-pack/test/functional/apps/lens/dashboard.ts b/x-pack/test/functional/apps/lens/dashboard.ts index 827659ba733bef..046ff298f67e19 100644 --- a/x-pack/test/functional/apps/lens/dashboard.ts +++ b/x-pack/test/functional/apps/lens/dashboard.ts @@ -51,7 +51,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await testSubjects.missingOrFail('applyFiltersPopoverButton'); }); - await PageObjects.lens.assertChartTitle('lnsXYvis'); + await PageObjects.lens.assertExactText( + '[data-test-subj="embeddablePanelHeading-lnsXYvis"]', + 'lnsXYvis' + ); const time = await PageObjects.timePicker.getTimeConfig(); expect(time.start).to.equal('Sep 21, 2015 @ 09:00:00.000'); expect(time.end).to.equal('Sep 21, 2015 @ 12:00:00.000'); diff --git a/x-pack/test/functional/apps/lens/index.ts b/x-pack/test/functional/apps/lens/index.ts index 8b8f204fcf6393..c9e2ae0586ac04 100644 --- a/x-pack/test/functional/apps/lens/index.ts +++ b/x-pack/test/functional/apps/lens/index.ts @@ -29,9 +29,9 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { this.tags(['ciGroup4', 'skipFirefox']); loadTestFile(require.resolve('./smokescreen')); + loadTestFile(require.resolve('./dashboard')); loadTestFile(require.resolve('./persistent_context')); loadTestFile(require.resolve('./lens_reporting')); - loadTestFile(require.resolve('./dashboard')); }); }); } diff --git a/x-pack/test/functional/apps/lens/smokescreen.ts b/x-pack/test/functional/apps/lens/smokescreen.ts index fdb210ce9c01aa..80060d5d5c9ea8 100644 --- a/x-pack/test/functional/apps/lens/smokescreen.ts +++ b/x-pack/test/functional/apps/lens/smokescreen.ts @@ -78,8 +78,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.lens.goToTimeRange(); await PageObjects.lens.assertMetric('Maximum of bytes', '19,986'); await PageObjects.lens.switchToVisualization('lnsDatatable'); - await PageObjects.lens.assertDatatableThText('Maximum of bytes'); - await PageObjects.lens.assertDatatableCellText('19,986', 0, 0); + expect(await PageObjects.lens.getDatatableThText()).to.eql('Maximum of bytes'); + expect(await PageObjects.lens.getDatatableCellText(0, 0)).to.eql('19,986'); await PageObjects.lens.switchToVisualization('lnsMetric'); await PageObjects.lens.assertMetric('Maximum of bytes', '19,986'); }); @@ -116,9 +116,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.lens.clickVisualizeListItemTitle('lnsXYvis'); await PageObjects.lens.goToTimeRange(); await PageObjects.lens.switchToVisualization('donut'); - await PageObjects.lens.assertChartTitle('lnsXYvis'); - // TODO: to check if chart is valid, we check dimension panel - // - once we have access to check if chart renders properly, we should make assertions based on chart + + expect(await PageObjects.lens.getTitle()).to.eql('lnsXYvis'); expect(await PageObjects.lens.getDimensionTriggerText('lnsPie_sliceByDimensionPanel')).to.eql( 'Top values of ip' ); @@ -127,7 +126,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); await PageObjects.lens.switchToVisualization('bar'); - await PageObjects.lens.assertChartTitle('lnsXYvis'); + expect(await PageObjects.lens.getTitle()).to.eql('lnsXYvis'); }); it('should allow seamless transition from bar chart to line chart using layer chart switch', async () => { @@ -136,7 +135,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.lens.clickVisualizeListItemTitle('lnsXYvis'); await PageObjects.lens.goToTimeRange(); await PageObjects.lens.switchLayerSeriesType('line'); - await PageObjects.lens.assertChartTitle('lnsXYvis'); + expect(await PageObjects.lens.getTitle()).to.eql('lnsXYvis'); }); it('should allow seamless transition from pie chart to treemap chart', async () => { @@ -175,10 +174,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); await PageObjects.lens.switchToVisualization('lnsDatatable'); - await PageObjects.lens.assertDatatableThText('@timestamp per 3 hours', 0); - await PageObjects.lens.assertDatatableThText('Average of bytes', 1); - await PageObjects.lens.assertDatatableCellText('2015-09-20 00:00', 0, 0); - await PageObjects.lens.assertDatatableCellText('6,011.351', 0, 1); + + expect(await PageObjects.lens.getDatatableThText()).to.eql('@timestamp per 3 hours'); + expect(await PageObjects.lens.getDatatableCellText(0, 0)).to.eql('2015-09-20 00:00'); + expect(await PageObjects.lens.getDatatableThText(1)).to.eql('Average of bytes'); + expect(await PageObjects.lens.getDatatableCellText(0, 1)).to.eql('6,011.351'); }); }); } diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts index c1c0ae2adf4589..4866ba4235cea7 100644 --- a/x-pack/test/functional/page_objects/lens_page.ts +++ b/x-pack/test/functional/page_objects/lens_page.ts @@ -190,6 +190,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont async switchLayerSeriesType(seriesType: string) { await retry.try(async () => { await testSubjects.click('lns_layer_settings'); + await testSubjects.exists(`lnsXY_seriesType-${seriesType}`); }); return await testSubjects.click(`lnsXY_seriesType-${seriesType}`); @@ -235,54 +236,47 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont }, /** - * Asserts that metric has expected title and count + * Gets text of the specified datatable header cell * - * @param title - expected title - * @param count - expected count of metric + * @param index - index of th element in datatable */ - async assertMetric(title: string, count: string) { - await this.assertExactText('[data-test-subj="lns_metric_title"]', title); - await this.assertExactText('[data-test-subj="lns_metric_value"]', count); + async getDatatableThText(index = 0) { + return find + .byCssSelector( + `[data-test-subj="lnsDataTable"] thead th:nth-child(${ + index + 1 + }) .euiTableCellContent__text` + ) + .then((el) => el.getVisibleText()); }, /** - * Asserts expected chart title + * Gets text of the specified datatable cell * - * @param title - expected title + * @param rowIndex - index of row of the cell + * @param colIndex - index of column of the cell */ - async assertChartTitle(title: string) { - await this.assertExactText(`[data-test-subj="lns_ChartTitle"]`, title); + async getDatatableCellText(rowIndex = 0, colIndex = 0) { + return find + .byCssSelector( + `[data-test-subj="lnsDataTable"] tr:nth-child(${rowIndex + 1}) td:nth-child(${ + colIndex + 1 + })` + ) + .then((el) => el.getVisibleText()); }, /** - * Asserts that datatable th element has expected text + * Asserts that metric has expected title and count * - * @param text - the expected text - * @param index - index of th element in datatable + * @param title - expected title + * @param count - expected count of metric */ - async assertDatatableThText(text: string, index = 0) { - return this.assertExactText( - `[data-test-subj="lnsDataTable"] thead th:nth-child(${ - index + 1 - }) .euiTableCellContent__text`, - text - ); + async assertMetric(title: string, count: string) { + await this.assertExactText('[data-test-subj="lns_metric_title"]', title); + await this.assertExactText('[data-test-subj="lns_metric_value"]', count); }, - /** - * Asserts that the specified datatable cell has expected text - * - * @param text - the expected text - * @param rowIndex - index of row of the cell - * @param colIndex - index of column of the cell - */ - async assertDatatableCellText(text: string, rowIndex = 0, colIndex = 0) { - return this.assertExactText( - `[data-test-subj="lnsDataTable"] tr:nth-child(${rowIndex + 1}) td:nth-child(${ - colIndex + 1 - })`, - text - ); }, }); } From 78cf61a58af7759471e73b6ee5f36ef8816bfe92 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Tue, 4 Aug 2020 15:08:25 +0200 Subject: [PATCH 7/8] typo --- x-pack/test/functional/page_objects/lens_page.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts index 4866ba4235cea7..f09aed59f69e84 100644 --- a/x-pack/test/functional/page_objects/lens_page.ts +++ b/x-pack/test/functional/page_objects/lens_page.ts @@ -276,7 +276,5 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont await this.assertExactText('[data-test-subj="lns_metric_title"]', title); await this.assertExactText('[data-test-subj="lns_metric_value"]', count); }, - - }, }); } From 67f8497a6789e0a70564f6a024b61fbb0c17da5c Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Thu, 6 Aug 2020 11:38:07 +0200 Subject: [PATCH 8/8] fixing hasChartSwitchWarning function, CR corrections & eslint conflicts --- x-pack/test/functional/apps/lens/dashboard.ts | 1 - x-pack/test/functional/apps/lens/index.ts | 2 +- .../test/functional/apps/lens/smokescreen.ts | 24 ++++++++++++++++--- .../test/functional/page_objects/lens_page.ts | 11 +++++---- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/x-pack/test/functional/apps/lens/dashboard.ts b/x-pack/test/functional/apps/lens/dashboard.ts index 046ff298f67e19..ccf2f88a9d0ed1 100644 --- a/x-pack/test/functional/apps/lens/dashboard.ts +++ b/x-pack/test/functional/apps/lens/dashboard.ts @@ -7,7 +7,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default function ({ getService, getPageObjects }: FtrProviderContext) { const PageObjects = getPageObjects(['header', 'common', 'dashboard', 'timePicker', 'lens']); diff --git a/x-pack/test/functional/apps/lens/index.ts b/x-pack/test/functional/apps/lens/index.ts index 6fa2dbbe4a76cb..f2dcf28c017433 100644 --- a/x-pack/test/functional/apps/lens/index.ts +++ b/x-pack/test/functional/apps/lens/index.ts @@ -11,7 +11,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { const log = getService('log'); const esArchiver = getService('esArchiver'); - describe.only('lens app', () => { + describe('lens app', () => { before(async () => { log.debug('Starting lens before method'); await browser.setWindowSize(1280, 800); diff --git a/x-pack/test/functional/apps/lens/smokescreen.ts b/x-pack/test/functional/apps/lens/smokescreen.ts index 00aac8fd9d69fb..77b9aa1e25edd8 100644 --- a/x-pack/test/functional/apps/lens/smokescreen.ts +++ b/x-pack/test/functional/apps/lens/smokescreen.ts @@ -77,7 +77,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.lens.goToTimeRange(); await PageObjects.lens.assertMetric('Maximum of bytes', '19,986'); await PageObjects.lens.switchToVisualization('lnsDatatable'); - expect(await PageObjects.lens.getDatatableThText()).to.eql('Maximum of bytes'); + expect(await PageObjects.lens.getDatatableHeaderText()).to.eql('Maximum of bytes'); expect(await PageObjects.lens.getDatatableCellText(0, 0)).to.eql('19,986'); await PageObjects.lens.switchToVisualization('lnsMetric'); await PageObjects.lens.assertMetric('Maximum of bytes', '19,986'); @@ -114,6 +114,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await listingTable.searchForItemWithName('lnsXYvis'); await PageObjects.lens.clickVisualizeListItemTitle('lnsXYvis'); await PageObjects.lens.goToTimeRange(); + expect(await PageObjects.lens.hasChartSwitchWarning('donut')).to.eql(true); await PageObjects.lens.switchToVisualization('donut'); expect(await PageObjects.lens.getTitle()).to.eql('lnsXYvis'); @@ -124,8 +125,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'Average of bytes' ); + expect(await PageObjects.lens.hasChartSwitchWarning('bar')).to.eql(false); await PageObjects.lens.switchToVisualization('bar'); expect(await PageObjects.lens.getTitle()).to.eql('lnsXYvis'); + expect(await PageObjects.lens.getDimensionTriggerText('lnsXY_xDimensionPanel')).to.eql( + 'Top values of ip' + ); + expect(await PageObjects.lens.getDimensionTriggerText('lnsXY_yDimensionPanel')).to.eql( + 'Average of bytes' + ); }); it('should allow seamless transition from bar chart to line chart using layer chart switch', async () => { @@ -135,6 +143,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.lens.goToTimeRange(); await PageObjects.lens.switchLayerSeriesType('line'); expect(await PageObjects.lens.getTitle()).to.eql('lnsXYvis'); + expect(await PageObjects.lens.getDimensionTriggerText('lnsXY_xDimensionPanel')).to.eql( + '@timestamp' + ); + expect(await PageObjects.lens.getDimensionTriggerText('lnsXY_yDimensionPanel')).to.eql( + 'Average of bytes' + ); + expect(await PageObjects.lens.getDimensionTriggerText('lnsXY_splitDimensionPanel')).to.eql( + 'Top values of ip' + ); }); it('should allow seamless transition from pie chart to treemap chart', async () => { @@ -172,11 +189,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { field: 'bytes', }); + expect(await PageObjects.lens.hasChartSwitchWarning('lnsDatatable')).to.eql(false); await PageObjects.lens.switchToVisualization('lnsDatatable'); - expect(await PageObjects.lens.getDatatableThText()).to.eql('@timestamp per 3 hours'); + expect(await PageObjects.lens.getDatatableHeaderText()).to.eql('@timestamp per 3 hours'); expect(await PageObjects.lens.getDatatableCellText(0, 0)).to.eql('2015-09-20 00:00'); - expect(await PageObjects.lens.getDatatableThText(1)).to.eql('Average of bytes'); + expect(await PageObjects.lens.getDatatableHeaderText(1)).to.eql('Average of bytes'); expect(await PageObjects.lens.getDatatableCellText(0, 1)).to.eql('6,011.351'); }); }); diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts index f09aed59f69e84..bed0e3a159e23f 100644 --- a/x-pack/test/functional/page_objects/lens_page.ts +++ b/x-pack/test/functional/page_objects/lens_page.ts @@ -176,9 +176,11 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont */ async hasChartSwitchWarning(subVisualizationId: string) { await this.openChartSwitchPopover(); - const element = await testSubjects.find(`lnsChartSwitchPopover_${subVisualizationId}`); - return await testSubjects.descendantExists('euiKeyPadMenuItem__betaBadgeWrapper', element); + return await find.descendantExistsByCssSelector( + '.euiKeyPadMenuItem__betaBadgeWrapper', + element + ); }, /** @@ -231,8 +233,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont 'lns-dimensionTrigger', dimensionElements[index] ); - const text = await trigger.getVisibleText(); - return text; + return await trigger.getVisibleText(); }, /** @@ -240,7 +241,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont * * @param index - index of th element in datatable */ - async getDatatableThText(index = 0) { + async getDatatableHeaderText(index = 0) { return find .byCssSelector( `[data-test-subj="lnsDataTable"] thead th:nth-child(${