Skip to content

Commit c6d15bb

Browse files
authored
Merge branch 'main' into mcp-dialog-pt1
2 parents 64adcb8 + 66dacb8 commit c6d15bb

9 files changed

Lines changed: 197 additions & 868 deletions
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* @license
3+
* Copyright 2026 Google LLC
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
import assert from 'node:assert';
8+
9+
import type {TestScenario} from '../eval_gemini.ts';
10+
11+
export const scenario: TestScenario = {
12+
prompt:
13+
'Go to <TEST_URL>, fill the form with size = 2 CPUs and components = [docker, nginx].',
14+
maxTurns: 3,
15+
htmlRoute: {
16+
path: '/input_test.html',
17+
htmlContent: `
18+
<form action="/post" method="POST">
19+
<div>
20+
<label for="size">CPU/Memory size:</label>
21+
<select id="size" name="size" required>
22+
<option value="small">1 vCPU, 2GB RAM</option>
23+
<option value="medium">2 vCPU, 4GB RAM</option>
24+
<option value="large">4 vCPU, 8GB RAM</option>
25+
</select>
26+
</div>
27+
<br>
28+
<div>
29+
<p>Pre-installed components:</p>
30+
<input type="checkbox" id="docker" name="components" value="docker">
31+
<label for="docker">Docker</label><br>
32+
<input type="checkbox" id="nodejs" name="components" value="nodejs">
33+
<label for="nodejs">Node.js</label><br>
34+
<input type="checkbox" id="python" name="components" value="python">
35+
<label for="python">Python</label><br>
36+
<input type="checkbox" id="nginx" name="components" value="nginx">
37+
<label for="nginx">Nginx</label>
38+
</div>
39+
<button type="submit">Spawn Server</button>
40+
</form>
41+
`,
42+
},
43+
expectations: calls => {
44+
assert.strictEqual(calls.length, 3);
45+
assert.ok(
46+
calls[0].name === 'navigate_page' || calls[0].name === 'new_page',
47+
);
48+
assert.strictEqual(calls[1].name, 'take_snapshot');
49+
assert.strictEqual(calls[2].name, 'fill_form');
50+
51+
const elements = calls[2].args.elements as Array<{
52+
uid: string;
53+
value: string;
54+
}>;
55+
assert.strictEqual(elements.length, 3);
56+
57+
const uids = new Set(elements.map(e => e.uid));
58+
assert.strictEqual(
59+
uids.size,
60+
3,
61+
'fill_form should target three distinct elements',
62+
);
63+
64+
const values = elements.map(e => e.value).sort();
65+
assert.deepStrictEqual(values, ['2 vCPU, 4GB RAM', 'true', 'true']);
66+
},
67+
};

scripts/generate-cli.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {createTools} from '../build/src/tools/tools.js';
1616

1717
const OUTPUT_PATH = path.join(
1818
import.meta.dirname,
19-
'../src/bin/cliDefinitions.ts',
19+
'../src/bin/chrome-devtools-cli-options.ts',
2020
);
2121

2222
async function fetchTools() {

src/McpResponse.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type {WebMCPTool} from 'puppeteer-core';
99
import type {ParsedArguments} from './bin/chrome-devtools-mcp-cli-options.js';
1010
import {ConsoleFormatter} from './formatters/ConsoleFormatter.js';
1111
import {HeapSnapshotFormatter} from './formatters/HeapSnapshotFormatter.js';
12+
import {isNodeLike} from './formatters/HeapSnapshotFormatter.js';
1213
import {IssueFormatter} from './formatters/IssueFormatter.js';
1314
import {NetworkFormatter} from './formatters/NetworkFormatter.js';
1415
import {SnapshotFormatter} from './formatters/SnapshotFormatter.js';
@@ -957,8 +958,12 @@ Call ${handleDialog.name} to handle it before continuing.`);
957958
}
958959
const nodes = this.#heapSnapshotOptions.nodes;
959960
if (nodes) {
961+
const sortedItems = nodes.items
962+
.filter(isNodeLike)
963+
.sort((a, b) => b.retainedSize - a.retainedSize);
964+
960965
const paginationData = this.#dataWithPagination(
961-
nodes.items,
966+
sortedItems,
962967
this.#heapSnapshotOptions.pagination,
963968
);
964969

src/bin/chrome-devtools-cli-options.ts

Lines changed: 16 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ export const commands: Commands = {
110110
name: 'geolocation',
111111
type: 'string',
112112
description:
113-
'Geolocation (`<latitude>x<longitude>`) to emulate. Latitude between -90 and 90. Longitude between -180 and 180. Omit clear the geolocation override.',
113+
'Geolocation (`<latitude>x<longitude>`) to emulate. Latitude between -90 and 90. Longitude between -180 and 180. Omit to clear the geolocation override.',
114114
required: false,
115115
},
116116
userAgent: {
@@ -155,11 +155,18 @@ export const commands: Commands = {
155155
description: 'An optional list of arguments to pass to the function.',
156156
required: false,
157157
},
158+
dialogAction: {
159+
name: 'dialogAction',
160+
type: 'string',
161+
description:
162+
'Handle dialogs while execution. "accept", "dismiss", or string for response of window.prompt. Defaults to accept.',
163+
required: false,
164+
},
158165
},
159166
},
160167
fill: {
161168
description:
162-
'Type text into a input, text area or select an option from a <select> element.',
169+
'Type text into an input, text area or select an option from a <select> element.',
163170
category: 'Input automation',
164171
args: {
165172
uid: {
@@ -184,25 +191,6 @@ export const commands: Commands = {
184191
},
185192
},
186193
},
187-
fill_form: {
188-
description: 'Fill out multiple form elements at once',
189-
category: 'Input automation',
190-
args: {
191-
elements: {
192-
name: 'elements',
193-
type: 'array',
194-
description: 'Elements from snapshot to fill out.',
195-
required: true,
196-
},
197-
includeSnapshot: {
198-
name: 'includeSnapshot',
199-
type: 'boolean',
200-
description:
201-
'Whether to include a snapshot in the response. Default is false.',
202-
required: false,
203-
},
204-
},
205-
},
206194
get_console_message: {
207195
description:
208196
'Gets a console message by its ID. You can get all messages by calling list_console_messages.',
@@ -233,14 +221,14 @@ export const commands: Commands = {
233221
name: 'requestFilePath',
234222
type: 'string',
235223
description:
236-
'The absolute or relative path to save the request body to. If omitted, the body is returned inline.',
224+
'The absolute or relative path to a .network-request file to save the request body to. If omitted, the body is returned inline.',
237225
required: false,
238226
},
239227
responseFilePath: {
240228
name: 'responseFilePath',
241229
type: 'string',
242230
description:
243-
'The absolute or relative path to save the response body to. If omitted, the body is returned inline.',
231+
'The absolute or relative path to a .network-response file to save the response body to. If omitted, the body is returned inline.',
244232
required: false,
245233
},
246234
},
@@ -324,7 +312,7 @@ export const commands: Commands = {
324312
name: 'pageSize',
325313
type: 'integer',
326314
description:
327-
'Maximum number of messages to return. When omitted, returns all requests.',
315+
'Maximum number of messages to return. When omitted, returns all messages.',
328316
required: false,
329317
},
330318
pageIdx: {
@@ -388,7 +376,7 @@ export const commands: Commands = {
388376
},
389377
},
390378
list_pages: {
391-
description: 'Get a list of pages open in the browser.',
379+
description: 'Get a list of pages open in the browser.',
392380
category: 'Navigation automation',
393381
args: {},
394382
},
@@ -601,8 +589,8 @@ export const commands: Commands = {
601589
},
602590
take_memory_snapshot: {
603591
description:
604-
'Capture a memory heapsnapshot of the currently selected page to memory leak debugging',
605-
category: 'Performance',
592+
'Capture a heap snapshot of the currently selected page. Use to analyze the memory distribution of JavaScript objects and debug memory leaks.',
593+
category: 'Memory',
606594
args: {
607595
filePath: {
608596
name: 'filePath',
@@ -637,7 +625,7 @@ export const commands: Commands = {
637625
name: 'uid',
638626
type: 'string',
639627
description:
640-
'The uid of an element on the page from the page content snapshot. If omitted takes a pages screenshot.',
628+
'The uid of an element on the page from the page content snapshot. If omitted, takes a page screenshot.',
641629
required: false,
642630
},
643631
fullPage: {
@@ -722,24 +710,4 @@ export const commands: Commands = {
722710
},
723711
},
724712
},
725-
wait_for: {
726-
description: 'Wait for the specified text to appear on the selected page.',
727-
category: 'Navigation automation',
728-
args: {
729-
text: {
730-
name: 'text',
731-
type: 'array',
732-
description:
733-
'Non-empty list of texts. Resolves when any value appears on the page.',
734-
required: true,
735-
},
736-
timeout: {
737-
name: 'timeout',
738-
type: 'integer',
739-
description:
740-
'Maximum wait time in milliseconds. If set to 0, the default timeout will be used.',
741-
required: false,
742-
},
743-
},
744-
},
745713
} as const;

0 commit comments

Comments
 (0)