Skip to content

Commit 9824f31

Browse files
jackfranklinDevtools-frontend LUCI CQ
authored andcommitted
Lighthouse: change auditing message when AI is running
This CL updates the Lighthouse status view so that we can show a custom string when AI is running LH vs the user is, so the dialog is less confusing. It also adds some tests to the status view for the header; the tests aren't perfect because the StatusView is not a proper UI Eng widget, but they are better than none and cover the new header text changes. Bug: 489620101 Change-Id: I93b603607718b4ca17807fba60a9b3d88b36e032 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/7673381 Auto-Submit: Jack Franklin <[email protected]> Reviewed-by: Kim-Anh Tran <[email protected]> Commit-Queue: Kim-Anh Tran <[email protected]>
1 parent d143aab commit 9824f31

File tree

7 files changed

+102
-9
lines changed

7 files changed

+102
-9
lines changed

front_end/models/lighthouse/RunTypes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@ export interface Flags {
3838

3939
export interface RunOverrides {
4040
categoryIds: CategoryId[];
41+
isAIControlled?: boolean;
4142
}

front_end/panels/lighthouse/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ devtools_ui_module("unittests") {
9595
"LighthouseProtocolService.test.ts",
9696
"LighthouseReportRenderer.test.ts",
9797
"LighthouseStartView.test.ts",
98+
"LighthouseStatusView.test.ts",
9899
"LighthouseTimespanView.test.ts",
99100
"RadioSetting.test.ts",
100101
]

front_end/panels/lighthouse/LighthouseController.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ class LighthouseRun {
191191
formFactor: (string|undefined),
192192
mode: string,
193193
};
194+
readonly isAIControlled: boolean;
194195
private emulationStateBefore?: {
195196
emulation: {
196197
type: EmulationModel.DeviceModeModel.Type,
@@ -209,12 +210,13 @@ class LighthouseRun {
209210

210211
constructor(
211212
controller: LighthouseController, protocolService: ProtocolService, inspectedURL: Platform.DevToolsPath.UrlString,
212-
categoryIDs: string[], flags: {formFactor: (string|undefined), mode: string}) {
213+
categoryIDs: string[], flags: {formFactor: (string|undefined), mode: string}, isAIControlled: boolean) {
213214
this.controller = controller;
214215
this.protocolService = protocolService;
215216
this.inspectedURL = inspectedURL;
216217
this.categoryIDs = categoryIDs;
217218
this.flags = flags;
219+
this.isAIControlled = isAIControlled;
218220
this.#isRunning = false;
219221
}
220222

@@ -550,6 +552,7 @@ export class LighthouseController extends Common.ObjectWrapper.ObjectWrapper<Eve
550552
inspectedURL: this.currentLighthouseRun.inspectedURL,
551553
categoryIDs: this.currentLighthouseRun.categoryIDs,
552554
flags: this.currentLighthouseRun.flags,
555+
isAIControlled: this.currentLighthouseRun.isAIControlled,
553556
};
554557
}
555558

@@ -661,7 +664,8 @@ export class LighthouseController extends Common.ObjectWrapper.ObjectWrapper<Eve
661664

662665
this.recordMetrics(flags, categoryIDs);
663666

664-
this.currentLighthouseRun = new LighthouseRun(this, this.protocolService, inspectedURL, categoryIDs, flags);
667+
this.currentLighthouseRun = new LighthouseRun(
668+
this, this.protocolService, inspectedURL, categoryIDs, flags, Boolean(overrides?.isAIControlled));
665669
await this.currentLighthouseRun.start();
666670
resolve();
667671
});

front_end/panels/lighthouse/LighthousePanel.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,9 +289,10 @@ export class LighthousePanel extends UI.Panel.Panel {
289289
}
290290

291291
private renderStatusView(): void {
292-
const inspectedURL = this.controller.getCurrentRun()?.inspectedURL;
292+
const currentRun = this.controller.getCurrentRun();
293293
this.contentElement.classList.toggle('in-progress', true);
294-
this.statusView.setInspectedURL(inspectedURL);
294+
this.statusView.setInspectedURL(currentRun?.inspectedURL);
295+
this.statusView.setAIControlled(Boolean(currentRun?.isAIControlled));
295296
this.statusView.show(this.contentElement);
296297
}
297298

front_end/panels/lighthouse/LighthouseProtocolService.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export interface LighthouseRun {
5555
formFactor: (string|undefined),
5656
mode: string,
5757
};
58+
isAIControlled?: boolean;
5859
}
5960

6061
/**
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright 2026 The Chromium Authors
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import {getCleanTextContentFromSingleElement, renderElementIntoDOM} from '../../testing/DOMHelpers.js';
6+
import {describeWithEnvironment} from '../../testing/EnvironmentHelpers.js';
7+
8+
import * as LighthouseModule from './lighthouse.js';
9+
10+
describeWithEnvironment('LighthouseStatusView', () => {
11+
let statusView: LighthouseModule.LighthouseStatusView.StatusView;
12+
let container: HTMLElement;
13+
14+
beforeEach(() => {
15+
const protocolService = new LighthouseModule.LighthouseProtocolService.ProtocolService();
16+
const controller = new LighthouseModule.LighthouseController.LighthouseController(protocolService);
17+
const panel =
18+
LighthouseModule.LighthousePanel.LighthousePanel.instance({forceNew: true, protocolService, controller});
19+
statusView = new LighthouseModule.LighthouseStatusView.StatusView(panel);
20+
container = document.createElement('div');
21+
renderElementIntoDOM(container);
22+
});
23+
24+
function getHeaderText(statusView: LighthouseModule.LighthouseStatusView.StatusView): string {
25+
assert.isOk(statusView.dialog.contentElement.shadowRoot);
26+
const headerText = getCleanTextContentFromSingleElement(statusView.dialog.contentElement.shadowRoot, '.header');
27+
return headerText;
28+
}
29+
30+
it('shows the correct header for non-AI controlled runs', () => {
31+
statusView.setAIControlled(false);
32+
statusView.setInspectedURL('http://example.com');
33+
statusView.show(container);
34+
35+
assert.strictEqual(getHeaderText(statusView), 'Auditing example.com…');
36+
});
37+
38+
it('shows the correct header for AI controlled runs', () => {
39+
statusView.setAIControlled(true);
40+
statusView.setInspectedURL('http://example.com');
41+
statusView.show(container);
42+
43+
assert.strictEqual(getHeaderText(statusView), 'AI assistance is auditing example.com…');
44+
});
45+
46+
it('shows the correct header when no URL is set', () => {
47+
statusView.setAIControlled(false);
48+
statusView.setInspectedURL('');
49+
statusView.show(container);
50+
51+
assert.strictEqual(getHeaderText(statusView), 'Auditing your web page…');
52+
});
53+
54+
it('shows the correct header for AI controlled runs when no URL is set', () => {
55+
statusView.setAIControlled(true);
56+
statusView.setInspectedURL('');
57+
statusView.show(container);
58+
59+
assert.strictEqual(getHeaderText(statusView), 'AI assistance is auditing your web page…');
60+
});
61+
});

front_end/panels/lighthouse/LighthouseStatusView.ts

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ const UIStrings = {
3333
* @description Status text in Lighthouse splash screen while an audit is being performed
3434
*/
3535
auditingYourWebPage: 'Auditing your web page',
36+
/**
37+
* @description Status text in Lighthouse splash screen while an AI assistant is performing an audit
38+
* @example {github.com} PH1
39+
*/
40+
aiAuditingS: 'AI assistance is auditing {PH1}',
41+
/**
42+
* @description Status text in Lighthouse splash screen while an AI assistant is performing an audit
43+
*/
44+
aiAuditingYourWebPage: 'AI assistance is auditing your web page',
3645
/**
3746
* @description Status text in Lighthouse splash screen while an audit is being performed, and cancellation to take effect
3847
*/
@@ -245,13 +254,14 @@ export class StatusView {
245254
private currentPhase: StatusPhase|null;
246255
private scheduledFastFactTimeout: number|null;
247256
private dialogRoot: ShadowRoot|null = null;
248-
private readonly dialog: UI.Dialog.Dialog;
257+
readonly dialog: UI.Dialog.Dialog;
249258

250259
private statusHeader: string;
251260
private statusText: string;
252261
private progressBarClass: string;
253262
private progressBarValue: number;
254263
private cancelButtonVisible: boolean;
264+
private isAIControlled: boolean;
255265
private bugReport: {error: Error, auditURL: string, knownBugPattern?: boolean}|null;
256266

257267
constructor(panel: LighthousePanel) {
@@ -273,6 +283,7 @@ export class StatusView {
273283
this.progressBarClass = '';
274284
this.progressBarValue = 0;
275285
this.cancelButtonVisible = true;
286+
this.isAIControlled = false;
276287
this.bugReport = null;
277288

278289
this.render();
@@ -317,15 +328,24 @@ export class StatusView {
317328
this.reset();
318329
this.updateStatus(i18nString(UIStrings.loading));
319330

320-
const parsedURL = Common.ParsedURL.ParsedURL.fromString(this.inspectedURL);
321-
const pageHost = parsedURL?.host;
322-
const statusHeader =
323-
pageHost ? i18nString(UIStrings.auditingS, {PH1: pageHost}) : i18nString(UIStrings.auditingYourWebPage);
331+
const statusHeader = this.getStatusHeader();
324332
this.renderStatusHeader(statusHeader);
325333
this.dialog.show(dialogRenderElement);
326334
this.render();
327335
}
328336

337+
private getStatusHeader(): string {
338+
const parsedURL = Common.ParsedURL.ParsedURL.fromString(this.inspectedURL);
339+
const pageHost = parsedURL?.host;
340+
341+
if (this.isAIControlled) {
342+
return pageHost ? i18nString(UIStrings.aiAuditingS, {PH1: pageHost}) :
343+
i18nString(UIStrings.aiAuditingYourWebPage);
344+
}
345+
346+
return pageHost ? i18nString(UIStrings.auditingS, {PH1: pageHost}) : i18nString(UIStrings.auditingYourWebPage);
347+
}
348+
329349
private renderStatusHeader(statusHeader?: string): void {
330350
this.statusHeader = `${statusHeader}…`;
331351
this.render();
@@ -337,6 +357,10 @@ export class StatusView {
337357
}
338358
}
339359

360+
setAIControlled(isAIControlled: boolean): void {
361+
this.isAIControlled = isAIControlled;
362+
}
363+
340364
setInspectedURL(url = ''): void {
341365
this.inspectedURL = url;
342366
}

0 commit comments

Comments
 (0)