Skip to content

Commit 462fe08

Browse files
authored
stabilize waiting for visualization (#93469)
1 parent fe1ae92 commit 462fe08

File tree

9 files changed

+66
-31
lines changed

9 files changed

+66
-31
lines changed

x-pack/plugins/lens/public/visualization_container.test.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ describe('VisualizationContainer', () => {
2828
expect(reportingEl.prop('data-shared-item')).toBeTruthy();
2929
});
3030

31+
test('increments counter in data attribute for each render', () => {
32+
const component = mount(<VisualizationContainer isReady={true}>Hello!</VisualizationContainer>);
33+
34+
let reportingEl = component.find('[data-shared-item]').first();
35+
expect(reportingEl.prop('data-rendering-count')).toEqual(1);
36+
37+
component.setProps({ children: 'Hello2!' });
38+
39+
reportingEl = component.find('[data-shared-item]').first();
40+
expect(reportingEl.prop('data-rendering-count')).toEqual(2);
41+
});
42+
3143
test('renders child content', () => {
3244
const component = mount(
3345
<VisualizationContainer isReady={false}>Hello!</VisualizationContainer>

x-pack/plugins/lens/public/visualization_container.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import './visualization_container.scss';
99

10-
import React from 'react';
10+
import React, { useRef } from 'react';
1111
import classNames from 'classnames';
1212

1313
interface Props extends React.HTMLAttributes<HTMLDivElement> {
@@ -28,6 +28,8 @@ export function VisualizationContainer({
2828
className,
2929
...rest
3030
}: Props) {
31+
const counterRef = useRef(0);
32+
counterRef.current++;
3133
const attributes: Partial<{ 'data-title': string; 'data-description': string }> = {};
3234
if (reportTitle) {
3335
attributes['data-title'] = reportTitle;
@@ -39,6 +41,8 @@ export function VisualizationContainer({
3941
<div
4042
data-shared-item
4143
data-render-complete={isReady}
44+
data-rendering-count={counterRef.current}
45+
data-test-subj="lnsVisualizationContainer"
4246
className={classNames(className, 'lnsVisualizationContainer')}
4347
{...attributes}
4448
{...rest}

x-pack/test/functional/apps/lens/add_to_dashboard.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
3737

3838
await PageObjects.lens.switchToVisualization('lnsMetric');
3939

40-
await PageObjects.header.waitUntilLoadingHasFinished();
40+
await PageObjects.lens.waitForVisualization();
4141
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
4242

4343
await PageObjects.lens.save('New Lens from Modal', false, false, 'new');
@@ -96,7 +96,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
9696

9797
await PageObjects.lens.switchToVisualization('lnsMetric');
9898

99-
await PageObjects.header.waitUntilLoadingHasFinished();
99+
await PageObjects.lens.waitForVisualization();
100100
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
101101

102102
await PageObjects.lens.save(
@@ -183,10 +183,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
183183

184184
await PageObjects.lens.switchToVisualization('lnsMetric');
185185

186-
await PageObjects.header.waitUntilLoadingHasFinished();
186+
await PageObjects.lens.waitForVisualization();
187187
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
188188

189-
await PageObjects.header.waitUntilLoadingHasFinished();
189+
await PageObjects.lens.waitForVisualization();
190190
await testSubjects.click('lnsApp_saveButton');
191191

192192
const hasOptions = await testSubjects.exists('add-to-dashboard-options');
@@ -228,10 +228,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
228228

229229
await PageObjects.lens.switchToVisualization('lnsMetric');
230230

231-
await PageObjects.header.waitUntilLoadingHasFinished();
231+
await PageObjects.lens.waitForVisualization();
232232
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
233233

234-
await PageObjects.header.waitUntilLoadingHasFinished();
234+
await PageObjects.lens.waitForVisualization();
235235
await testSubjects.click('lnsApp_saveButton');
236236

237237
const hasOptions = await testSubjects.exists('add-to-dashboard-options');

x-pack/test/functional/apps/lens/chart_data.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
3333
field: 'bytes',
3434
});
3535

36-
await PageObjects.header.waitUntilLoadingHasFinished();
36+
await PageObjects.lens.waitForVisualization();
3737
});
3838

3939
const expectedData = [
@@ -63,28 +63,28 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
6363
// https://github.com/elastic/elastic-charts/issues/917 gets fixed
6464
it.skip('should render pie chart', async () => {
6565
await PageObjects.lens.switchToVisualization('pie');
66-
await PageObjects.header.waitUntilLoadingHasFinished();
66+
await PageObjects.lens.waitForVisualization();
6767
const data = await PageObjects.lens.getCurrentChartDebugState();
6868
assertMatchesExpectedData(data!);
6969
});
7070

7171
it.skip('should render donut chart', async () => {
7272
await PageObjects.lens.switchToVisualization('donut');
73-
await PageObjects.header.waitUntilLoadingHasFinished();
73+
await PageObjects.lens.waitForVisualization();
7474
const data = await PageObjects.lens.getCurrentChartDebugState();
7575
assertMatchesExpectedData(data!);
7676
});
7777

7878
it.skip('should render treemap chart', async () => {
7979
await PageObjects.lens.switchToVisualization('treemap');
80-
await PageObjects.header.waitUntilLoadingHasFinished();
80+
await PageObjects.lens.waitForVisualization();
8181
const data = await PageObjects.lens.getCurrentChartDebugState();
8282
assertMatchesExpectedData(data!);
8383
});
8484

8585
it('should render datatable', async () => {
8686
await PageObjects.lens.switchToVisualization('lnsDatatable');
87-
await PageObjects.header.waitUntilLoadingHasFinished();
87+
await PageObjects.lens.waitForVisualization();
8888
const terms = await Promise.all(
8989
range(0, 6).map((index) => PageObjects.lens.getDatatableCellText(index, 0))
9090
);
@@ -101,7 +101,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
101101

102102
it('should render metric', async () => {
103103
await PageObjects.lens.switchToVisualization('lnsMetric');
104-
await PageObjects.header.waitUntilLoadingHasFinished();
104+
await PageObjects.lens.waitForVisualization();
105105
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
106106
});
107107
});

x-pack/test/functional/apps/lens/drag_and_drop.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export default function ({ getPageObjects }: FtrProviderContext) {
5454

5555
it('should reorder the elements for the table', async () => {
5656
await PageObjects.lens.reorderDimensions('lnsDatatable_column', 3, 1);
57-
await PageObjects.header.waitUntilLoadingHasFinished();
57+
await PageObjects.lens.waitForVisualization();
5858
expect(await PageObjects.lens.getDimensionTriggersTexts('lnsDatatable_column')).to.eql([
5959
'Top values of @message.raw',
6060
'Top values of clientip',
@@ -224,9 +224,9 @@ export default function ({ getPageObjects }: FtrProviderContext) {
224224
await PageObjects.lens.goToTimeRange();
225225
await PageObjects.header.waitUntilLoadingHasFinished();
226226
await PageObjects.lens.dragFieldToWorkspace('@timestamp');
227-
await PageObjects.header.waitUntilLoadingHasFinished();
227+
await PageObjects.lens.waitForVisualization();
228228
await PageObjects.lens.dragFieldToWorkspace('clientip');
229-
await PageObjects.header.waitUntilLoadingHasFinished();
229+
await PageObjects.lens.waitForVisualization();
230230
expect(
231231
await PageObjects.lens.getDimensionTriggersTexts('lnsXY_splitDimensionPanel')
232232
).to.eql(['Top values of clientip']);
@@ -239,9 +239,9 @@ export default function ({ getPageObjects }: FtrProviderContext) {
239239

240240
it('overwrite existing time dimension if one exists already', async () => {
241241
await PageObjects.lens.dragFieldToWorkspace('utc_time');
242-
await PageObjects.header.waitUntilLoadingHasFinished();
242+
await PageObjects.lens.waitForVisualization();
243243
await PageObjects.lens.dragFieldToWorkspace('clientip');
244-
await PageObjects.header.waitUntilLoadingHasFinished();
244+
await PageObjects.lens.waitForVisualization();
245245
expect(await PageObjects.lens.getDimensionTriggersTexts('lnsXY_xDimensionPanel')).to.eql([
246246
'utc_time',
247247
]);

x-pack/test/functional/apps/lens/rollup.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
8484
operation: 'sum',
8585
field: 'bytes',
8686
});
87-
await PageObjects.header.waitUntilLoadingHasFinished();
87+
await PageObjects.lens.waitForVisualization();
8888

8989
await PageObjects.lens.assertMetric('Sum of bytes', '16,788');
9090

9191
await PageObjects.lens.switchFirstLayerIndexPattern('lens_rolled_up_data');
92-
await PageObjects.header.waitUntilLoadingHasFinished();
92+
await PageObjects.lens.waitForVisualization();
9393

9494
await PageObjects.lens.assertMetric('Sum of bytes', '16,788');
9595
});

x-pack/test/functional/apps/lens/smokescreen.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
180180
const longLabel =
181181
'Veryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryvery long label wrapping multiple lines';
182182
await PageObjects.lens.editDimensionLabel(longLabel);
183-
await PageObjects.header.waitUntilLoadingHasFinished();
183+
await PageObjects.lens.waitForVisualization();
184184
await PageObjects.lens.closeDimensionEditor();
185185

186186
expect(await PageObjects.lens.getDimensionTriggerText('lnsXY_yDimensionPanel')).to.eql(
@@ -223,7 +223,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
223223

224224
await PageObjects.lens.closeDimensionEditor();
225225

226-
await PageObjects.header.waitUntilLoadingHasFinished();
226+
await PageObjects.lens.waitForVisualization();
227227

228228
const data = await PageObjects.lens.getCurrentChartDebugState();
229229
expect(data?.axes?.y.length).to.eql(2);
@@ -235,15 +235,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
235235
await PageObjects.lens.toggleToolbarPopover('lnsValuesButton');
236236
await testSubjects.click('lnsXY_valueLabels_inside');
237237

238-
await PageObjects.header.waitUntilLoadingHasFinished();
238+
await PageObjects.lens.waitForVisualization();
239239

240240
// check for value labels
241241
let data = await PageObjects.lens.getCurrentChartDebugState();
242242
expect(data?.bars?.[0].labels).not.to.eql(0);
243243

244244
// switch to stacked bar chart
245245
await PageObjects.lens.switchToVisualization('bar_stacked');
246-
await PageObjects.header.waitUntilLoadingHasFinished();
246+
await PageObjects.lens.waitForVisualization();
247247

248248
// check for value labels
249249
data = await PageObjects.lens.getCurrentChartDebugState();
@@ -256,14 +256,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
256256
await testSubjects.setValue('lnsyLeftAxisTitle', axisTitle, {
257257
clearWithKeyboard: true,
258258
});
259-
await PageObjects.header.waitUntilLoadingHasFinished();
259+
await PageObjects.lens.waitForVisualization();
260260

261261
let data = await PageObjects.lens.getCurrentChartDebugState();
262262
expect(data?.axes?.y?.[0].title).to.eql(axisTitle);
263263

264264
// hide the gridlines
265265
await testSubjects.click('lnsshowyLeftAxisGridlines');
266-
await PageObjects.header.waitUntilLoadingHasFinished();
266+
await PageObjects.lens.waitForVisualization();
267267

268268
data = await PageObjects.lens.getCurrentChartDebugState();
269269
expect(data?.axes?.y?.[0].gridlines.length).to.eql(0);

x-pack/test/functional/apps/lens/table.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,20 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
2323
await PageObjects.lens.switchToVisualization('lnsDatatable');
2424
// Sort by number
2525
await PageObjects.lens.changeTableSortingBy(2, 'ascending');
26-
await PageObjects.header.waitUntilLoadingHasFinished();
26+
await PageObjects.lens.waitForVisualization();
2727
expect(await PageObjects.lens.getDatatableCellText(0, 2)).to.eql('17,246');
2828
// Now sort by IP
2929
await PageObjects.lens.changeTableSortingBy(0, 'ascending');
30-
await PageObjects.header.waitUntilLoadingHasFinished();
30+
await PageObjects.lens.waitForVisualization();
3131
expect(await PageObjects.lens.getDatatableCellText(0, 0)).to.eql('78.83.247.30');
3232
// Change the sorting
3333
await PageObjects.lens.changeTableSortingBy(0, 'descending');
34-
await PageObjects.header.waitUntilLoadingHasFinished();
34+
await PageObjects.lens.waitForVisualization();
3535
expect(await PageObjects.lens.getDatatableCellText(0, 0)).to.eql('169.228.188.120');
3636
// Remove the sorting
3737
await retry.try(async () => {
3838
await PageObjects.lens.changeTableSortingBy(0, 'none');
39-
await PageObjects.header.waitUntilLoadingHasFinished();
39+
await PageObjects.lens.waitForVisualization();
4040
expect(await PageObjects.lens.isDatatableHeaderSorted(0)).to.eql(false);
4141
});
4242
});
@@ -45,7 +45,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
4545
const firstCellContent = await PageObjects.lens.getDatatableCellText(0, 0);
4646
await retry.try(async () => {
4747
await PageObjects.lens.clickTableCellAction(0, 0, 'lensDatatableFilterOut');
48-
await PageObjects.header.waitUntilLoadingHasFinished();
48+
await PageObjects.lens.waitForVisualization();
4949
expect(
5050
await find.existsByCssSelector(
5151
`[data-test-subj*="filter-value-${firstCellContent}"][data-test-subj*="filter-negated"]`

x-pack/test/functional/page_objects/lens_page.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
1919
const browser = getService('browser');
2020

2121
const PageObjects = getPageObjects([
22+
'common',
2223
'header',
2324
'timePicker',
2425
'common',
@@ -753,5 +754,23 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
753754
const focusedElementText = await fieldAncestor.getVisibleText();
754755
expect(focusedElementText).to.eql(name);
755756
},
757+
758+
async waitForVisualization() {
759+
async function getRenderingCount() {
760+
const visualizationContainer = await testSubjects.find('lnsVisualizationContainer');
761+
const renderingCount = await visualizationContainer.getAttribute('data-rendering-count');
762+
return Number(renderingCount);
763+
}
764+
await PageObjects.header.waitUntilLoadingHasFinished();
765+
await retry.waitFor('rendering count to stabilize', async () => {
766+
const firstCount = await getRenderingCount();
767+
768+
await PageObjects.common.sleep(1000);
769+
770+
const secondCount = await getRenderingCount();
771+
772+
return firstCount === secondCount;
773+
});
774+
},
756775
});
757776
}

0 commit comments

Comments
 (0)