[Lens] Add more chart editor tests based on the debug state (#86750) (#87069)

This commit is contained in:
Marco Liberati 2021-01-05 09:42:18 +01:00 committed by GitHub
parent d41cfa0259
commit c0ef9d531c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 232 additions and 0 deletions

View file

@ -38,6 +38,15 @@ import {
} from '../../../../../src/plugins/charts/public';
import { LensIconChartDonut } from '../assets/chart_donut';
declare global {
interface Window {
/**
* Flag used to enable debugState on elastic charts
*/
_echDebugStateFlag?: boolean;
}
}
const EMPTY_SLICE = Symbol('empty_slice');
export function PieComponent(
@ -251,6 +260,7 @@ export function PieComponent(
>
<Chart>
<Settings
debugState={window._echDebugStateFlag ?? false}
// Legend is hidden in many scenarios
// - Tiny preview
// - Treemap does not need a legend because it uses category labels

View file

@ -6,6 +6,7 @@ exports[`xy_expression XYChart component it renders area 1`] = `
>
<Connect(SpecInstance)
baseTheme={Object {}}
debugState={false}
legendPosition="top"
onBrushEnd={[Function]}
onElementClick={[Function]}
@ -201,6 +202,7 @@ exports[`xy_expression XYChart component it renders bar 1`] = `
>
<Connect(SpecInstance)
baseTheme={Object {}}
debugState={false}
legendPosition="top"
onBrushEnd={[Function]}
onElementClick={[Function]}
@ -404,6 +406,7 @@ exports[`xy_expression XYChart component it renders horizontal bar 1`] = `
>
<Connect(SpecInstance)
baseTheme={Object {}}
debugState={false}
legendPosition="top"
onBrushEnd={[Function]}
onElementClick={[Function]}
@ -607,6 +610,7 @@ exports[`xy_expression XYChart component it renders line 1`] = `
>
<Connect(SpecInstance)
baseTheme={Object {}}
debugState={false}
legendPosition="top"
onBrushEnd={[Function]}
onElementClick={[Function]}
@ -802,6 +806,7 @@ exports[`xy_expression XYChart component it renders stacked area 1`] = `
>
<Connect(SpecInstance)
baseTheme={Object {}}
debugState={false}
legendPosition="top"
onBrushEnd={[Function]}
onElementClick={[Function]}
@ -1005,6 +1010,7 @@ exports[`xy_expression XYChart component it renders stacked bar 1`] = `
>
<Connect(SpecInstance)
baseTheme={Object {}}
debugState={false}
legendPosition="top"
onBrushEnd={[Function]}
onElementClick={[Function]}
@ -1216,6 +1222,7 @@ exports[`xy_expression XYChart component it renders stacked horizontal bar 1`] =
>
<Connect(SpecInstance)
baseTheme={Object {}}
debugState={false}
legendPosition="top"
onBrushEnd={[Function]}
onElementClick={[Function]}

View file

@ -60,6 +60,15 @@ import { fittingFunctionDefinitions, getFitOptions } from './fitting_functions';
import { getAxesConfiguration } from './axes_configuration';
import { getColorAssignments } from './color_assignment';
declare global {
interface Window {
/**
* Flag used to enable debugState on elastic charts
*/
_echDebugStateFlag?: boolean;
}
}
type InferPropType<T> = T extends React.FunctionComponent<infer P> ? P : T;
type SeriesSpec = InferPropType<typeof LineSeries> &
InferPropType<typeof BarSeries> &
@ -508,6 +517,7 @@ export function XYChart({
return (
<Chart>
<Settings
debugState={window._echDebugStateFlag ?? false}
showLegend={
legend.isVisible && !legend.showSingleSeries
? chartHasMoreThanOneSeries

View file

@ -94,6 +94,7 @@ const valueLabelsOptions: Array<{
id: string;
value: 'hide' | 'inside' | 'outside';
label: string;
'data-test-subj': string;
}> = [
{
id: `value_labels_hide`,
@ -101,6 +102,7 @@ const valueLabelsOptions: Array<{
label: i18n.translate('xpack.lens.xyChart.valueLabelsVisibility.auto', {
defaultMessage: 'Hide',
}),
'data-test-subj': 'lnsXY_valueLabels_hide',
},
{
id: `value_labels_inside`,
@ -108,6 +110,7 @@ const valueLabelsOptions: Array<{
label: i18n.translate('xpack.lens.xyChart.valueLabelsVisibility.inside', {
defaultMessage: 'Show',
}),
'data-test-subj': 'lnsXY_valueLabels_inside',
},
];
@ -513,6 +516,7 @@ export function DimensionEditor(
legend={i18n.translate('xpack.lens.xyChart.axisSide.label', {
defaultMessage: 'Axis side',
})}
data-test-subj="lnsXY_axisSide_groups"
name="axisSide"
buttonSize="compressed"
options={[
@ -521,6 +525,7 @@ export function DimensionEditor(
label: i18n.translate('xpack.lens.xyChart.axisSide.auto', {
defaultMessage: 'Auto',
}),
'data-test-subj': 'lnsXY_axisSide_groups_auto',
},
{
id: `${idPrefix}left`,
@ -531,6 +536,7 @@ export function DimensionEditor(
: i18n.translate('xpack.lens.xyChart.axisSide.left', {
defaultMessage: 'Left',
}),
'data-test-subj': 'lnsXY_axisSide_groups_left',
},
{
id: `${idPrefix}right`,
@ -541,6 +547,7 @@ export function DimensionEditor(
: i18n.translate('xpack.lens.xyChart.axisSide.right', {
defaultMessage: 'Right',
}),
'data-test-subj': 'lnsXY_axisSide_groups_right',
},
]}
idSelected={`${idPrefix}${axisMode}`}

View file

@ -0,0 +1,107 @@
/*
* 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 { DebugState } from '@elastic/charts';
import expect from '@kbn/expect';
import { range } from 'lodash';
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['visualize', 'lens', 'common', 'header']);
const elasticChart = getService('elasticChart');
describe('lens chart data', () => {
before(async () => {
await PageObjects.visualize.navigateToNewVisualization();
await PageObjects.visualize.clickVisType('lens');
await elasticChart.setNewChartUiDebugFlag(true);
await PageObjects.lens.goToTimeRange();
await PageObjects.lens.configureDimension({
dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension',
operation: 'terms',
field: 'ip',
});
await PageObjects.lens.configureDimension({
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
operation: 'avg',
field: 'bytes',
});
await PageObjects.header.waitUntilLoadingHasFinished();
});
const expectedData = [
{ x: '0.53.251.53', y: 4624.75 },
{ x: '0.108.3.2', y: 7359.41 },
{ x: '0.209.80.244', y: 6169.9 },
{ x: '0.228.1.71', y: 7092.8 },
{ x: '0.254.91.215', y: 3835.58 },
{ x: '__other__', y: 5727.24 },
];
function assertMatchesExpectedData(state: DebugState) {
expect(
state.bars![0].bars.map((bar) => ({
x: bar.x,
y: Math.round(bar.y * 100) / 100,
}))
).to.eql(expectedData);
}
it('should render xy chart', async () => {
const data = await PageObjects.lens.getCurrentChartDebugState();
assertMatchesExpectedData(data!);
});
// Partition chart tests have to be skipped until
// https://github.com/elastic/elastic-charts/issues/917 gets fixed
it.skip('should render pie chart', async () => {
await PageObjects.lens.switchToVisualization('pie');
await PageObjects.header.waitUntilLoadingHasFinished();
const data = await PageObjects.lens.getCurrentChartDebugState();
assertMatchesExpectedData(data!);
});
it.skip('should render donut chart', async () => {
await PageObjects.lens.switchToVisualization('donut');
await PageObjects.header.waitUntilLoadingHasFinished();
const data = await PageObjects.lens.getCurrentChartDebugState();
assertMatchesExpectedData(data!);
});
it.skip('should render treemap chart', async () => {
await PageObjects.lens.switchToVisualization('treemap');
await PageObjects.header.waitUntilLoadingHasFinished();
const data = await PageObjects.lens.getCurrentChartDebugState();
assertMatchesExpectedData(data!);
});
it('should render datatable', async () => {
await PageObjects.lens.switchToVisualization('lnsDatatable');
await PageObjects.header.waitUntilLoadingHasFinished();
const terms = await Promise.all(
range(0, 6).map((index) => PageObjects.lens.getDatatableCellText(index, 0))
);
const values = await Promise.all(
range(0, 6).map((index) => PageObjects.lens.getDatatableCellText(index, 1))
);
expect(terms.map((term) => (term === 'Other' ? '__other__' : term))).to.eql(
expectedData.map(({ x }) => x)
);
expect(values.map((value) => Math.round(100 * Number(value.replace(',', ''))) / 100)).to.eql(
expectedData.map(({ y }) => y)
);
});
it('should render metric', async () => {
await PageObjects.lens.switchToVisualization('lnsMetric');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
});
});
}

View file

@ -31,6 +31,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./dashboard'));
loadTestFile(require.resolve('./persistent_context'));
loadTestFile(require.resolve('./colors'));
loadTestFile(require.resolve('./chart_data'));
loadTestFile(require.resolve('./drag_and_drop'));
loadTestFile(require.resolve('./lens_reporting'));

View file

@ -12,6 +12,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const find = getService('find');
const listingTable = getService('listingTable');
const testSubjects = getService('testSubjects');
const elasticChart = getService('elasticChart');
describe('lens smokescreen tests', () => {
it('should allow creation of lens xy chart', async () => {
@ -191,6 +192,82 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await testSubjects.missingOrFail('lnsXY_yDimensionPanel > lns-dimensionTrigger');
});
it('should allow creation of a multi-axis chart', async () => {
await PageObjects.visualize.navigateToNewVisualization();
await PageObjects.visualize.clickVisType('lens');
await elasticChart.setNewChartUiDebugFlag(true);
await PageObjects.lens.goToTimeRange();
await PageObjects.lens.switchToVisualization('bar');
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.configureDimension({
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
operation: 'cardinality',
field: 'bytes',
keepOpen: true,
});
await PageObjects.lens.changeAxisSide('right');
await PageObjects.lens.closeDimensionEditor();
await PageObjects.header.waitUntilLoadingHasFinished();
const data = await PageObjects.lens.getCurrentChartDebugState();
expect(data?.axes?.y.length).to.eql(2);
expect(data?.axes?.y.some(({ position }) => position === 'right')).to.eql(true);
});
it('should show value labels on bar charts when enabled', async () => {
// enable value labels
await PageObjects.lens.toggleToolbarPopover('lnsValuesButton');
await testSubjects.click('lnsXY_valueLabels_inside');
await PageObjects.header.waitUntilLoadingHasFinished();
// check for value labels
let data = await PageObjects.lens.getCurrentChartDebugState();
expect(data?.bars?.[0].labels).not.to.eql(0);
// switch to stacked bar chart
await PageObjects.lens.switchToVisualization('bar_stacked');
await PageObjects.header.waitUntilLoadingHasFinished();
// check for value labels
data = await PageObjects.lens.getCurrentChartDebugState();
expect(data?.bars?.[0].labels.length).to.eql(0);
});
it('should override axis title', async () => {
const axisTitle = 'overridden axis';
await PageObjects.lens.toggleToolbarPopover('lnsLeftAxisButton');
await testSubjects.setValue('lnsyLeftAxisTitle', axisTitle, {
clearWithKeyboard: true,
});
await PageObjects.header.waitUntilLoadingHasFinished();
let data = await PageObjects.lens.getCurrentChartDebugState();
expect(data?.axes?.y?.[0].title).to.eql(axisTitle);
// hide the gridlines
await testSubjects.click('lnsshowyLeftAxisGridlines');
await PageObjects.header.waitUntilLoadingHasFinished();
data = await PageObjects.lens.getCurrentChartDebugState();
expect(data?.axes?.y?.[0].gridlines.length).to.eql(0);
});
it('should transition from a multi-layer stacked bar to donut chart using suggestions', async () => {
await PageObjects.visualize.navigateToNewVisualization();
await PageObjects.visualize.clickVisType('lens');

View file

@ -12,6 +12,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
const log = getService('log');
const testSubjects = getService('testSubjects');
const retry = getService('retry');
const elasticChart = getService('elasticChart');
const find = getService('find');
const comboBox = getService('comboBox');
const browser = getService('browser');
@ -216,6 +217,10 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
});
},
async toggleToolbarPopover(buttonTestSub: string) {
await testSubjects.click(buttonTestSub);
},
/**
* Open the specified dimension.
*
@ -353,6 +358,10 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
});
},
async changeAxisSide(newSide: string) {
await testSubjects.click(`lnsXY_axisSide_groups_${newSide}`);
},
/** Counts the visible warnings in the config panel */
async getErrorCount() {
const moreButton = await testSubjects.exists('configuration-failure-more-errors');
@ -484,6 +493,10 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
);
},
async getCurrentChartDebugState() {
return await elasticChart.getChartDebugData('lnsWorkspace');
},
/**
* Gets text of the specified datatable header cell
*