Skip to content

Commit 7187d61

Browse files
danilsomsikovDevtools-frontend LUCI CQ
authored andcommitted
Add more tests for PerformanceMonitor.
This change adds tests for: - `PerformanceMonitorImpl` to verify polling starts/stops on show/hide and chart height updates. - `ControlPane` to check indicator rendering, chart toggling, and metric value updates. Bug: 407751888 Change-Id: I7211fa18d087c5aac9d689dd8b95eacefc002369 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6870371 Auto-Submit: Danil Somsikov <[email protected]> Reviewed-by: Benedikt Meurer <[email protected]> Commit-Queue: Danil Somsikov <[email protected]> Reviewed-by: Changhao Han <[email protected]>
1 parent 122abcd commit 7187d61

File tree

1 file changed

+115
-1
lines changed

1 file changed

+115
-1
lines changed

front_end/panels/performance_monitor/PerformanceMonitor.test.ts

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import type * as Common from '../../core/common/common.js';
56
import * as SDK from '../../core/sdk/sdk.js';
67
import {renderElementIntoDOM} from '../../testing/DOMHelpers.js';
7-
import {createTarget} from '../../testing/EnvironmentHelpers.js';
8+
import {createTarget, stubNoopSettings} from '../../testing/EnvironmentHelpers.js';
89
import {expectCall} from '../../testing/ExpectStubCall.js';
910
import {describeWithMockConnection} from '../../testing/MockConnection.js';
1011
import {createViewFunctionStub} from '../../testing/ViewFunctionHelpers.js';
@@ -35,4 +36,117 @@ describeWithMockConnection('PerformanceMonitor', () => {
3536
await expectCall(getMetrics, {fakeFn: () => Promise.resolve({metrics: [{name: 'LayoutCount', value: 84}]})});
3637
assert.isNotEmpty((await view.nextInput).metrics);
3738
});
39+
40+
it('starts polling when shown and stops when hidden', async () => {
41+
const getMetrics = sinon.stub(target.performanceAgent(), 'invoke_getMetrics');
42+
const view = createViewFunctionStub(PerformanceMonitor.PerformanceMonitor.PerformanceMonitorImpl);
43+
performanceMonitor = new PerformanceMonitor.PerformanceMonitor.PerformanceMonitorImpl(10, view);
44+
const model = target.model(SDK.PerformanceMetricsModel.PerformanceMetricsModel);
45+
assert.exists(model);
46+
const modelEnableSpy = sinon.spy(model, 'enable');
47+
const modelDisableSpy = sinon.spy(model, 'disable');
48+
49+
performanceMonitor.markAsRoot();
50+
renderElementIntoDOM(performanceMonitor);
51+
52+
// Starts polling when shown.
53+
await expectCall(getMetrics, {fakeFn: () => Promise.resolve({metrics: [], getError: () => undefined})});
54+
sinon.assert.calledOnce(modelEnableSpy);
55+
56+
performanceMonitor.detach();
57+
58+
// Stops polling when hidden.
59+
getMetrics.resetHistory();
60+
await new Promise(resolve => setTimeout(resolve, 20));
61+
sinon.assert.notCalled(getMetrics);
62+
sinon.assert.calledOnce(modelDisableSpy);
63+
64+
renderElementIntoDOM(performanceMonitor);
65+
66+
// Resumes polling when shown again.
67+
await expectCall(getMetrics, {fakeFn: () => Promise.resolve({metrics: [], getError: () => undefined})});
68+
sinon.assert.calledTwice(modelEnableSpy);
69+
});
70+
71+
it('updates chart visibility and height', async () => {
72+
const view = createViewFunctionStub(PerformanceMonitor.PerformanceMonitor.PerformanceMonitorImpl);
73+
performanceMonitor = new PerformanceMonitor.PerformanceMonitor.PerformanceMonitorImpl(0, view);
74+
renderElementIntoDOM(performanceMonitor);
75+
76+
const {onMetricChanged, chartsInfo, height: initialHeight} = await view.nextInput;
77+
// From recalcChartHeight(): height = this.scaleHeight when no active charts.
78+
// scaleHeight is 16.
79+
assert.strictEqual(initialHeight, Math.ceil(16 * window.devicePixelRatio));
80+
81+
const chartToActivate = chartsInfo[0].metrics[0].name;
82+
onMetricChanged(chartToActivate, true);
83+
84+
const {height: heightAfterActivation} = await view.nextInput;
85+
// graphHeight is 90.
86+
assert.strictEqual(heightAfterActivation, Math.ceil((16 + 90) * window.devicePixelRatio));
87+
88+
onMetricChanged(chartToActivate, false);
89+
const {height: heightAfterDeactivation} = await view.nextInput;
90+
assert.strictEqual(heightAfterDeactivation, initialHeight);
91+
});
92+
});
93+
94+
describe('ControlPane', () => {
95+
const chartsInfo: PerformanceMonitor.PerformanceMonitor.ChartInfo[] = [
96+
{
97+
title: 'Chart1' as unknown as Common.UIString.LocalizedString,
98+
metrics: [{name: 'Metric1', color: 'red'}],
99+
},
100+
{
101+
title: 'Chart2' as unknown as Common.UIString.LocalizedString,
102+
metrics: [{name: 'Metric2', color: 'blue'}],
103+
},
104+
];
105+
106+
beforeEach(() => {
107+
stubNoopSettings();
108+
});
109+
110+
it('renders indicators', async () => {
111+
const view = createViewFunctionStub(PerformanceMonitor.PerformanceMonitor.ControlPane);
112+
const controlPane = new PerformanceMonitor.PerformanceMonitor.ControlPane(document.createElement('div'), view);
113+
renderElementIntoDOM(controlPane);
114+
controlPane.chartsInfo = chartsInfo;
115+
const {chartsInfo: renderedChartsInfo} = await view.nextInput;
116+
assert.deepEqual(renderedChartsInfo.map(c => c.title), ['Chart1', 'Chart2']);
117+
});
118+
119+
it('toggles charts', async () => {
120+
const view = createViewFunctionStub(PerformanceMonitor.PerformanceMonitor.ControlPane);
121+
const controlPane = new PerformanceMonitor.PerformanceMonitor.ControlPane(document.createElement('div'), view);
122+
renderElementIntoDOM(controlPane);
123+
124+
const onMetricChanged = sinon.spy();
125+
controlPane.onMetricChanged = onMetricChanged;
126+
127+
controlPane.chartsInfo = chartsInfo;
128+
const {onCheckboxChange} = await view.nextInput;
129+
130+
const event = {target: {checked: true}} as unknown as Event;
131+
onCheckboxChange('Metric1', event);
132+
133+
assert.isTrue(onMetricChanged.calledOnceWith('Metric1', true));
134+
135+
const event2 = {target: {checked: false}} as unknown as Event;
136+
onCheckboxChange('Metric1', event2);
137+
sinon.assert.calledTwice(onMetricChanged);
138+
sinon.assert.calledWith(onMetricChanged.secondCall, 'Metric1', false);
139+
});
140+
141+
it('updates metric values', async () => {
142+
const view = createViewFunctionStub(PerformanceMonitor.PerformanceMonitor.ControlPane);
143+
const controlPane = new PerformanceMonitor.PerformanceMonitor.ControlPane(document.createElement('div'), view);
144+
renderElementIntoDOM(controlPane);
145+
controlPane.chartsInfo = chartsInfo;
146+
await view.nextInput;
147+
148+
controlPane.metrics = new Map([['Metric1', 42]]);
149+
const {metricValues} = await view.nextInput;
150+
assert.strictEqual(metricValues.get('Metric1'), 42);
151+
});
38152
});

0 commit comments

Comments
 (0)