[Lens] Corrects incorrect copy for line chart & fix flaky test (#192734)

## Summary
Corrects incorrect copy for line chart. 

Rewrites some of the tests to rtl.
Unskips flaky or failing tests.
Fixes https://github.com/elastic/kibana/issues/192476
Removes some errors from the console that appear during unit test
running.

---------

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Marta Bondyra 2024-09-18 20:39:25 +02:00 committed by GitHub
parent 4d4afa55b3
commit e1db296963
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 499 additions and 965 deletions

View file

@ -125,11 +125,11 @@ const datasourceMap = mockDatasourceMap();
const visualizationMap = mockVisualizationMap();
describe('LensEditConfigurationFlyout', () => {
function renderConfigFlyout(
async function renderConfigFlyout(
propsOverrides: Partial<EditConfigPanelProps> = {},
query?: Query | AggregateQuery
) {
return renderWithReduxStore(
const { container, ...rest } = renderWithReduxStore(
<LensEditConfigurationFlyout
attributes={lensAttributes}
updatePanelState={jest.fn()}
@ -155,12 +155,13 @@ describe('LensEditConfigurationFlyout', () => {
},
}
);
await waitFor(() => container.querySelector('lnsEditFlyoutBody'));
return { container, ...rest };
}
it('should display the header and the link to editor if necessary props are given', async () => {
const navigateToLensEditorSpy = jest.fn();
renderConfigFlyout({
await renderConfigFlyout({
displayFlyoutHeader: true,
navigateToLensEditor: navigateToLensEditorSpy,
});
@ -170,7 +171,7 @@ describe('LensEditConfigurationFlyout', () => {
});
it('should display the header title correctly for a newly created panel', async () => {
renderConfigFlyout({
await renderConfigFlyout({
displayFlyoutHeader: true,
isNewPanel: true,
});
@ -182,7 +183,7 @@ describe('LensEditConfigurationFlyout', () => {
it('should call the closeFlyout callback if cancel button is clicked', async () => {
const closeFlyoutSpy = jest.fn();
renderConfigFlyout({
await renderConfigFlyout({
closeFlyout: closeFlyoutSpy,
});
expect(screen.getByTestId('lns-layerPanel-0')).toBeInTheDocument();
@ -192,7 +193,7 @@ describe('LensEditConfigurationFlyout', () => {
it('should call the updatePanelState callback if cancel button is clicked', async () => {
const updatePanelStateSpy = jest.fn();
renderConfigFlyout({
await renderConfigFlyout({
updatePanelState: updatePanelStateSpy,
});
expect(screen.getByTestId('lns-layerPanel-0')).toBeInTheDocument();
@ -203,7 +204,7 @@ describe('LensEditConfigurationFlyout', () => {
it('should call the updateByRefInput callback if cancel button is clicked and savedObjectId exists', async () => {
const updateByRefInputSpy = jest.fn();
renderConfigFlyout({
await renderConfigFlyout({
closeFlyout: jest.fn(),
updateByRefInput: updateByRefInputSpy,
savedObjectId: 'id',
@ -216,7 +217,7 @@ describe('LensEditConfigurationFlyout', () => {
const updateByRefInputSpy = jest.fn();
const saveByRefSpy = jest.fn();
renderConfigFlyout({
await renderConfigFlyout({
closeFlyout: jest.fn(),
updateByRefInput: updateByRefInputSpy,
savedObjectId: 'id',
@ -230,7 +231,7 @@ describe('LensEditConfigurationFlyout', () => {
it('should call the onApplyCb callback if apply button is clicked', async () => {
const onApplyCbSpy = jest.fn();
renderConfigFlyout(
await renderConfigFlyout(
{
closeFlyout: jest.fn(),
onApplyCb: onApplyCbSpy,
@ -254,14 +255,14 @@ describe('LensEditConfigurationFlyout', () => {
});
it('should not display the editor if canEditTextBasedQuery prop is false', async () => {
renderConfigFlyout({
await renderConfigFlyout({
canEditTextBasedQuery: false,
});
expect(screen.queryByTestId('TextBasedLangEditor')).toBeNull();
});
it('should not display the editor if canEditTextBasedQuery prop is true but the query is not text based', async () => {
renderConfigFlyout({
await renderConfigFlyout({
canEditTextBasedQuery: true,
attributes: {
...lensAttributes,
@ -278,14 +279,14 @@ describe('LensEditConfigurationFlyout', () => {
});
it('should not display the suggestions if hidesSuggestions prop is true', async () => {
renderConfigFlyout({
await renderConfigFlyout({
hidesSuggestions: true,
});
expect(screen.queryByTestId('InlineEditingSuggestions')).toBeNull();
});
it('should display the suggestions if canEditTextBasedQuery prop is true', async () => {
renderConfigFlyout(
await renderConfigFlyout(
{
canEditTextBasedQuery: true,
},
@ -298,7 +299,7 @@ describe('LensEditConfigurationFlyout', () => {
});
it('should display the ES|QL results table if canEditTextBasedQuery prop is true', async () => {
renderConfigFlyout({
await renderConfigFlyout({
canEditTextBasedQuery: true,
});
await waitFor(() => expect(screen.getByTestId('ESQLQueryResults')).toBeInTheDocument());
@ -317,7 +318,7 @@ describe('LensEditConfigurationFlyout', () => {
// todo: replace testDatasource with formBased or textBased as it's the only ones accepted
// @ts-ignore
newProps.attributes.state.datasourceStates.testDatasource = 'state';
renderConfigFlyout(newProps);
await renderConfigFlyout(newProps);
expect(screen.getByRole('button', { name: /apply changes/i })).toBeDisabled();
});
it('save button should be disabled if expression cannot be generated', async () => {
@ -337,7 +338,7 @@ describe('LensEditConfigurationFlyout', () => {
},
};
renderConfigFlyout(newProps);
await renderConfigFlyout(newProps);
expect(screen.getByRole('button', { name: /apply changes/i })).toBeDisabled();
});
});

View file

@ -41,7 +41,7 @@ import type { FormBasedPrivateState } from './types';
import { IndexPatternServiceAPI } from '../../data_views_service/service';
import { FieldItem } from '../common/field_item';
export type Props = Omit<
export type FormBasedDataPanelProps = Omit<
DatasourceDataPanelProps<FormBasedPrivateState>,
'core' | 'onChangeIndexPattern'
> & {
@ -97,7 +97,7 @@ export function FormBasedDataPanel({
onIndexPatternRefresh,
usedIndexPatterns,
layerFields,
}: Props) {
}: FormBasedDataPanelProps) {
const { indexPatterns, indexPatternRefs } = frame.dataViews;
const { currentIndexPatternId } = state;

View file

@ -187,8 +187,7 @@ function mountWithServices(component: React.ReactElement): ReactWrapper {
* - Dimension trigger: Not tested here
* - Dimension editor component: First half of the tests
*/
// Failing: See https://github.com/elastic/kibana/issues/192476
describe.skip('FormBasedDimensionEditor', () => {
describe('FormBasedDimensionEditor', () => {
let state: FormBasedPrivateState;
let setState: jest.Mock;
let defaultProps: FormBasedDimensionEditorProps;
@ -353,8 +352,7 @@ describe.skip('FormBasedDimensionEditor', () => {
await userEvent.click(screen.getByRole('button', { name: /open list of options/i }));
expect(screen.getByText(/There aren't any options available/)).toBeInTheDocument();
});
it('should list all field names and document as a whole in prioritized order', async () => {
test('should list all field names and document as a whole in prioritized order', async () => {
const { getVisibleFieldSelectOptions } = renderDimensionPanel();
const comboBoxButton = screen.getAllByRole('button', { name: /open list of options/i })[0];
@ -372,14 +370,9 @@ describe.skip('FormBasedDimensionEditor', () => {
];
expect(allOptions.slice(0, 7)).toEqual(getVisibleFieldSelectOptions());
// keep hitting arrow down to scroll to the next options (react-window only renders visible options)
await userEvent.type(comboBoxInput, '{ArrowDown}'.repeat(12));
expect(getVisibleFieldSelectOptions()).toEqual(allOptions.slice(5, 16));
// press again to go back to the beginning
await userEvent.type(comboBoxInput, '{ArrowDown}');
expect(getVisibleFieldSelectOptions()).toEqual(allOptions.slice(0, 9));
// // press arrow up to go back to the beginning
await userEvent.type(comboBoxInput, '{ArrowUp}{ArrowUp}');
expect(getVisibleFieldSelectOptions()).toEqual(allOptions.slice(8));
});
it('should hide fields that have no data', () => {

View file

@ -7,9 +7,10 @@
import React from 'react';
import { mount } from 'enzyme';
import { fireEvent, render, screen } from '@testing-library/react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { act } from 'react-dom/test-utils';
import { EuiComboBox } from '@elastic/eui';
import userEvent from '@testing-library/user-event';
import { GenericOperationDefinition } from '../operations';
import {
averageOperation,
@ -28,38 +29,8 @@ import { GenericIndexPatternColumn, FormBasedLayer, FormBasedPrivateState } from
import { ReferenceBasedIndexPatternColumn } from '../operations/definitions/column_types';
import { FieldSelect } from './field_select';
import { IndexPattern, VisualizationDimensionGroupConfig } from '../../../types';
import userEvent from '@testing-library/user-event';
jest.mock('../operations/layer_helpers', () => {
const original = jest.requireActual('../operations/layer_helpers');
return {
...original,
insertOrReplaceColumn: () => {
return {} as FormBasedLayer;
},
};
});
const defaultProps = {
indexPattern: createMockedIndexPattern(),
currentFieldIsInvalid: false,
incompleteField: null,
incompleteOperation: undefined,
incompleteParams: {},
dimensionGroups: [] as VisualizationDimensionGroupConfig[],
groupId: 'any',
operationDefinitionMap: {
terms: termsOperation,
average: averageOperation,
count: countOperation,
differences: derivativeOperation,
staticValue: staticValueOperation,
min: minOperation,
} as unknown as Record<string, GenericOperationDefinition>,
};
function getStringBasedOperationColumn(field = 'source'): FieldBasedIndexPatternColumn {
function getStringBasedOperationColumn(field = 'source') {
return {
label: `Top value of ${field}`,
dataType: 'string',
@ -109,12 +80,32 @@ function getCountOperationColumn(): GenericIndexPatternColumn {
operationType: 'count',
};
}
function getLayer(
col1: GenericIndexPatternColumn = getStringBasedOperationColumn(),
indexPattern?: IndexPattern
) {
const defaultDataView = createMockedIndexPattern();
const defaultProps = {
columnId: 'col1',
layer: getLayer(),
operationSupportMatrix: getDefaultOperationSupportMatrix(getLayer(), 'col1'),
indexPattern: defaultDataView,
currentFieldIsInvalid: false,
incompleteField: null,
incompleteOperation: undefined,
incompleteParams: {},
dimensionGroups: [] as VisualizationDimensionGroupConfig[],
groupId: 'any',
updateLayer: jest.fn(),
operationDefinitionMap: {
terms: termsOperation,
average: averageOperation,
count: countOperation,
differences: derivativeOperation,
staticValue: staticValueOperation,
min: minOperation,
} as unknown as Record<string, GenericOperationDefinition>,
};
function getLayer(col1: GenericIndexPatternColumn = getStringBasedOperationColumn()) {
return {
indexPatternId: defaultProps.indexPattern.id,
indexPatternId: defaultDataView.id,
columnOrder: ['col1', 'col2'],
columns: {
col1,
@ -135,53 +126,28 @@ function getDefaultOperationSupportMatrix(
filterOperations: () => true,
columnId,
indexPatterns: {
[defaultProps.indexPattern.id]: indexPattern ?? defaultProps.indexPattern,
[defaultDataView.id]: indexPattern ?? defaultDataView,
},
});
}
const mockedReader = {
hasFieldData: (dataViewId: string, fieldName: string) => {
if (defaultProps.indexPattern.id !== dataViewId) {
return false;
}
const map: Record<string, boolean> = {};
for (const field of defaultProps.indexPattern.fields) {
map[field.name] = true;
}
return map[fieldName];
},
};
jest.mock('@kbn/unified-field-list/src/hooks/use_existing_fields', () => ({
useExistingFieldsReader: jest.fn(() => mockedReader),
}));
const renderFieldInput = (
overrideProps?: Partial<FieldInputProps<FieldBasedIndexPatternColumn>>
) => {
const updateLayerSpy = jest.fn();
const layer = getLayer();
const operationSupportMatrix = getDefaultOperationSupportMatrix(layer, 'col1');
return render(
<FieldInput
{...defaultProps}
layer={layer}
columnId={'col1'}
updateLayer={updateLayerSpy}
operationSupportMatrix={operationSupportMatrix}
{...overrideProps}
/>
);
return render(<FieldInput {...defaultProps} {...overrideProps} />);
};
const waitForComboboxToClose = async () =>
await waitFor(() => expect(screen.queryByRole('listbox')).toBeNull());
const getErrorElement = (container: HTMLElement) => container.querySelector('.euiFormErrorText');
const getLabelElement = () =>
screen.getByTestId('indexPattern-field-selection-row').querySelector('label');
describe('FieldInput', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('should render a field select box', () => {
renderFieldInput();
expect(screen.getByTestId('indexPattern-dimension-field')).toBeInTheDocument();
@ -248,6 +214,14 @@ describe('FieldInput', () => {
);
});
it('should update the layer on field selection', async () => {
renderFieldInput({ selectedColumn: getStringBasedOperationColumn() });
await userEvent.click(screen.getByRole('combobox'));
fireEvent.click(screen.getByTestId('lns-fieldOption-bytes'));
expect(defaultProps.updateLayer).toHaveBeenCalled();
await waitForComboboxToClose();
});
it('should prioritize errors over help messages', () => {
const helpMessage = 'My help message';
renderFieldInput({ helpMessage, currentFieldIsInvalid: true });
@ -256,32 +230,16 @@ describe('FieldInput', () => {
);
});
it('should update the layer on field selection', async () => {
const updateLayerSpy = jest.fn();
renderFieldInput({
selectedColumn: getStringBasedOperationColumn(),
updateLayer: updateLayerSpy,
});
await userEvent.click(screen.getByRole('combobox'));
fireEvent.click(screen.getByTestId('lns-fieldOption-bytes'));
expect(updateLayerSpy).toHaveBeenCalled();
});
it('should not trigger when the same selected field is selected again', async () => {
const updateLayerSpy = jest.fn();
renderFieldInput({
selectedColumn: getStringBasedOperationColumn(),
updateLayer: updateLayerSpy,
});
renderFieldInput({ selectedColumn: getStringBasedOperationColumn() });
await userEvent.click(screen.getByRole('combobox'));
fireEvent.click(screen.getByTestId('lns-fieldOption-source'));
expect(updateLayerSpy).not.toHaveBeenCalled();
await waitForComboboxToClose();
expect(defaultProps.updateLayer).not.toHaveBeenCalled();
});
it('should prioritize incomplete fields over selected column field to display', () => {
const updateLayerSpy = jest.fn();
const layer = getLayer();
const operationSupportMatrix = getDefaultOperationSupportMatrix(layer, 'col1');
const instance = mount(
@ -289,7 +247,7 @@ describe('FieldInput', () => {
{...defaultProps}
layer={layer}
columnId={'col1'}
updateLayer={updateLayerSpy}
updateLayer={defaultProps.updateLayer}
operationSupportMatrix={operationSupportMatrix}
incompleteField={'dest'}
selectedColumn={getStringBasedOperationColumn()}
@ -305,7 +263,6 @@ describe('FieldInput', () => {
});
it('should forward the onDeleteColumn function', () => {
const updateLayerSpy = jest.fn();
const onDeleteColumn = jest.fn();
const layer = getLayer();
const operationSupportMatrix = getDefaultOperationSupportMatrix(layer, 'col1');
@ -314,7 +271,7 @@ describe('FieldInput', () => {
{...defaultProps}
layer={layer}
columnId={'col1'}
updateLayer={updateLayerSpy}
updateLayer={defaultProps.updateLayer}
operationSupportMatrix={operationSupportMatrix}
onDeleteColumn={onDeleteColumn}
/>
@ -325,7 +282,7 @@ describe('FieldInput', () => {
});
expect(onDeleteColumn).toHaveBeenCalled();
expect(updateLayerSpy).not.toHaveBeenCalled();
expect(defaultProps.updateLayer).not.toHaveBeenCalled();
});
describe('time series group', () => {
@ -341,7 +298,6 @@ describe('FieldInput', () => {
return layer;
}
it('should not render the time dimension category if it has tsdb metric column but the group is not a breakdown', () => {
const updateLayerSpy = jest.fn();
const layer = getLayerWithTSDBMetric();
const operationSupportMatrix = getDefaultOperationSupportMatrix(layer, 'col1');
const instance = mount(
@ -359,7 +315,7 @@ describe('FieldInput', () => {
])}
layer={layer}
columnId={'col1'}
updateLayer={updateLayerSpy}
updateLayer={defaultProps.updateLayer}
operationSupportMatrix={operationSupportMatrix}
/>
);
@ -368,7 +324,6 @@ describe('FieldInput', () => {
});
it('should render the time dimension category if it has tsdb metric column and the group is a breakdown one', () => {
const updateLayerSpy = jest.fn();
const layer = getLayerWithTSDBMetric();
const operationSupportMatrix = getDefaultOperationSupportMatrix(layer, 'col1');
const instance = mount(
@ -393,7 +348,7 @@ describe('FieldInput', () => {
groupId="breakdown"
layer={layer}
columnId={'col1'}
updateLayer={updateLayerSpy}
updateLayer={defaultProps.updateLayer}
operationSupportMatrix={operationSupportMatrix}
/>
);

View file

@ -63,7 +63,7 @@ const renderFormatSelector = (propsOverrides?: Partial<FormatSelectorProps>) =>
// see for example the first two tests, they run the same code but expect
// different results. With the updated userEvent code the tests no longer work
// with this setup and should be refactored.
describe.skip('FormatSelector', () => {
describe('FormatSelector', () => {
let user: UserEvent;
beforeEach(() => {
@ -83,7 +83,7 @@ describe.skip('FormatSelector', () => {
});
it('updates the format decimals to upper range when input exceeds the range', async () => {
renderFormatSelector();
await user.type(screen.getByLabelText('Decimals'), '{backspace}10');
await user.type(screen.getByLabelText('Decimals'), '{backspace}20');
expect(props.onChange).toBeCalledWith({ id: 'bytes', params: { decimals: 15 } });
});
it('updates the format decimals to lower range when input is smaller than range', async () => {

View file

@ -13,6 +13,9 @@ import { getFieldByNameFactory } from './pure_helpers';
import { TermsIndexPatternColumn } from './operations';
import userEvent from '@testing-library/user-event';
Object.defineProperty(HTMLElement.prototype, 'scrollWidth', { value: 400 });
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', { value: 200 });
jest.mock('@kbn/unified-search-plugin/public', () => {
const actual = jest.requireActual('@kbn/unified-search-plugin/public');
return {
@ -219,9 +222,7 @@ describe('Layer Data Panel', () => {
};
});
const renderLayerPanel = () => {
return render(<LayerPanel {...defaultProps} />);
};
const renderLayerPanel = () => render(<LayerPanel {...defaultProps} />);
it('should list all index patterns', async () => {
renderLayerPanel();

View file

@ -264,8 +264,8 @@ describe('chart_switch', () => {
fireEvent.click(getMenuItem(subType));
};
const waitForChartSwitchClosed = () => {
waitFor(() => {
const waitForChartSwitchClosed = async () => {
await waitFor(() => {
expect(screen.queryByTestId('lnsChartSwitchList')).not.toBeInTheDocument();
});
};
@ -448,14 +448,13 @@ describe('chart_switch', () => {
await openChartSwitch();
switchToVis('testVis2');
// expect(datasourceMap.testDatasource.publicAPIMock.getTableSpec).toHaveBeenCalled();
expect(visualizationMap.testVis2.getSuggestions).toHaveBeenCalled();
expect(visualizationMap.testVis2.initialize).toHaveBeenCalledWith(
expect.any(Function), // generated layerId
undefined,
undefined
);
waitForChartSwitchClosed();
await waitForChartSwitchClosed();
});
it('should use initial state if there is no suggestion from the target visualization', async () => {

View file

@ -444,52 +444,6 @@ describe('editor_frame', () => {
instance.unmount();
});
// this test doesn't test anything, it's buggy and should be rewritten when we find a way to user test drag and drop
it.skip('should switch to best suggested visualization on field drop', async () => {
const suggestionVisState = {};
visualizationMap = {
testVis: {
...mockVisualization,
getSuggestions: () => [
{
score: 0.2,
state: {},
title: 'Suggestion1',
previewIcon: 'empty',
},
{
score: 0.8,
state: suggestionVisState,
title: 'Suggestion2',
previewIcon: 'empty',
},
],
},
testVis2: mockVisualization2,
};
datasourceMap = {
testDatasource: {
...mockDatasource,
getDatasourceSuggestionsForField: () => [generateSuggestion()],
getDatasourceSuggestionsFromCurrentState: () => [generateSuggestion()],
getDatasourceSuggestionsForVisualizeField: () => [generateSuggestion()],
},
};
renderEditorFrame();
mockVisualization.getConfiguration.mockClear();
act(() => {
instance.find('[data-test-subj="lnsWorkspace"]').last().simulate('drop');
});
expect(mockVisualization.getConfiguration).toHaveBeenCalledWith(
expect.objectContaining({
state: {},
})
);
});
it('should use the currently selected visualization if possible on field drop', async () => {
mockDatasource.getLayers.mockReturnValue(['first', 'second', 'third']);
const suggestionVisState = {};

View file

@ -14,6 +14,9 @@ import { css } from '@emotion/react';
import { type IndexPatternRef } from '../../types';
import { type ChangeIndexPatternTriggerProps, TriggerButton } from './trigger';
const MAX_WIDTH = 600;
const MIN_WIDTH = 320;
export function ChangeIndexPattern({
indexPatternRefs,
isMissingCurrent,
@ -52,8 +55,8 @@ export function ChangeIndexPattern({
<div
css={css`
width: ${calculateWidthFromEntries(indexPatternRefs, ['name', 'id'], {
minWidth: 320,
maxWidth: 600,
minWidth: MIN_WIDTH,
maxWidth: MAX_WIDTH,
})}px;
`}
>

View file

@ -142,12 +142,14 @@ describe('Legend Settings', () => {
toolTipContent: 'Shows the average value',
},
],
legendStats: [LegendValue.Average],
onLegendStatsChange,
});
expect(screen.queryByRole('button', { name: 'Layout' })).toBeNull();
fireEvent.click(screen.getByRole('combobox', { name: 'Statistics' }));
fireEvent.click(screen.getByRole('option', { name: 'Current and last value' }));
// expect(screen.getByRole('group', { name: 'Layout' })).toBeInTheDocument();
expect(onLegendStatsChange).toBeCalledWith([LegendValue.CurrentAndLastValue], false);
expect(onLegendStatsChange).toBeCalledWith(
[LegendValue.Average, LegendValue.CurrentAndLastValue],
false
);
});
});

View file

@ -6,31 +6,25 @@
*/
import React from 'react';
import { mount } from 'enzyme';
import { VisualizationContainer } from './visualization_container';
import { render, screen } from '@testing-library/react';
describe('VisualizationContainer', () => {
const renderVisContainer = (props?: React.HTMLAttributes<HTMLDivElement>) => {
return render(<VisualizationContainer {...props}>Hello!</VisualizationContainer>);
};
test('renders child content', () => {
const component = mount(<VisualizationContainer>Hello!</VisualizationContainer>);
expect(component.text()).toEqual('Hello!');
renderVisContainer();
expect(screen.getByText('Hello!')).toBeInTheDocument();
});
test('renders style', () => {
const component = mount(
<VisualizationContainer style={{ color: 'blue' }}>Hello!</VisualizationContainer>
);
const el = component.find('.lnsVisualizationContainer').first();
expect(el.prop('style')).toEqual({ color: 'blue' });
renderVisContainer({ style: { color: 'blue' } });
expect(screen.getByText('Hello!')).toHaveStyle({ color: 'blue' });
});
test('combines class names with container class', () => {
const component = mount(
<VisualizationContainer className="myClass">Hello!</VisualizationContainer>
);
const el = component.find('.lnsVisualizationContainer').first();
expect(el.prop('className')).toEqual('myClass lnsVisualizationContainer');
renderVisContainer({ className: 'myClass' });
expect(screen.getByText('Hello!')).toHaveClass('myClass lnsVisualizationContainer');
});
});

View file

@ -24,6 +24,7 @@ import { createMockDatasource, createMockFramePublicAPI } from '../../../mocks';
import { TableDimensionEditor } from './dimension_editor';
import { ColumnState } from '../../../../common/expressions';
import { capitalize } from 'lodash';
import { I18nProvider } from '@kbn/i18n-react';
describe('data table dimension editor', () => {
let user: UserEvent;
@ -60,7 +61,6 @@ describe('data table dimension editor', () => {
});
beforeEach(() => {
// Workaround for timeout via https://github.com/testing-library/user-event/issues/833#issuecomment-1171452841
user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
btnGroups = {
colorMode: new EuiButtonGroupTestHarness('lnsDatatable_dynamicColoring_groups'),
@ -123,10 +123,10 @@ describe('data table dimension editor', () => {
) => {
return render(<TableDimensionEditor {...props} {...overrideProps} />, {
wrapper: ({ children }) => (
<>
<I18nProvider>
<div ref={props.panelRef} />
{children}
</>
</I18nProvider>
),
});
};
@ -243,6 +243,7 @@ describe('data table dimension editor', () => {
renderTableDimensionEditor();
await user.click(screen.getByLabelText('Edit colors'));
act(() => jest.advanceTimersByTime(256));
expect(screen.getByTestId(`lns-palettePanel-${flyout}`)).toBeInTheDocument();
}

View file

@ -193,6 +193,18 @@ const areaShared = {
}),
};
const lineShared = {
id: 'line',
icon: IconChartLine,
label: i18n.translate('xpack.lens.xyVisualization.lineLabel', {
defaultMessage: 'Line',
}),
sortPriority: 2,
description: i18n.translate('xpack.lens.line.visualizationDescription', {
defaultMessage: 'Reveal variations in data over time.',
}),
};
export const visualizationSubtypes: VisualizationType[] = [
{
id: 'bar',
@ -278,17 +290,7 @@ export const visualizationSubtypes: VisualizationType[] = [
}),
...areaShared,
},
{
id: 'line',
icon: IconChartLine,
label: i18n.translate('xpack.lens.xyVisualization.lineLabel', {
defaultMessage: 'Line',
}),
sortPriority: 2,
description: i18n.translate('xpack.lens.line.visualizationDescription', {
defaultMessage: 'Reveal variations in data over time.',
}),
},
lineShared,
];
export const visualizationTypes: VisualizationType[] = [
@ -306,10 +308,7 @@ export const visualizationTypes: VisualizationType[] = [
label: i18n.translate('xpack.lens.xyVisualization.barLabel', {
defaultMessage: 'Bar',
}),
sortPriority: 1,
description: i18n.translate('xpack.lens.bar.visualizationDescription', {
defaultMessage: 'Compare categories or groups of data via bars.',
}),
...barShared,
getCompatibleSubtype: (seriesType?: string) => {
if (seriesType === 'area') {
return 'bar';
@ -342,15 +341,7 @@ export const visualizationTypes: VisualizationType[] = [
},
},
{
id: 'line',
icon: IconChartLine,
label: i18n.translate('xpack.lens.xyVisualization.lineLabel', {
defaultMessage: 'Line',
}),
sortPriority: 2,
description: i18n.translate('xpack.lens.line.visualizationDescription', {
defaultMessage: 'Reveal variations in data over time or categorically.',
}),
...lineShared,
subtypes: ['line'],
},
];