brave-mcp 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +51 -25
  2. package/build/src/McpContext.js +12 -2
  3. package/build/src/McpPage.js +9 -4
  4. package/build/src/McpResponse.js +35 -17
  5. package/build/src/TextSnapshot.js +2 -2
  6. package/build/src/WaitForHelper.js +5 -0
  7. package/build/src/bin/brave-devtools-cli-options.js +228 -46
  8. package/build/src/bin/brave-devtools-mcp-cli-options.js +9 -5
  9. package/build/src/bin/brave-devtools-mcp-main.js +0 -5
  10. package/build/src/bin/brave-devtools.js +26 -18
  11. package/build/src/browser.js +16 -3
  12. package/build/src/formatters/HeapSnapshotFormatter.js +3 -3
  13. package/build/src/index.js +93 -50
  14. package/build/src/telemetry/ClearcutLogger.js +12 -1
  15. package/build/src/third_party/index.js +2 -1
  16. package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolDescription.md +5 -0
  17. package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolName.md +5 -0
  18. package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingName.md +5 -0
  19. package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingTitleAndDescription.md +5 -0
  20. package/build/src/third_party/issue-descriptions/genericFormModelContextRequiredParameterMissingName.md +5 -0
  21. package/build/src/third_party/lighthouse-devtools-mcp-bundle.js +21716 -20261
  22. package/build/src/tools/categories.js +9 -3
  23. package/build/src/tools/console.js +2 -0
  24. package/build/src/tools/emulation.js +1 -0
  25. package/build/src/tools/extensions.js +5 -0
  26. package/build/src/tools/input.js +54 -1
  27. package/build/src/tools/lighthouse.js +15 -9
  28. package/build/src/tools/memory.js +4 -0
  29. package/build/src/tools/network.js +2 -0
  30. package/build/src/tools/pages.js +13 -5
  31. package/build/src/tools/performance.js +3 -0
  32. package/build/src/tools/screencast.js +4 -2
  33. package/build/src/tools/screenshot.js +1 -0
  34. package/build/src/tools/script.js +1 -0
  35. package/build/src/tools/slim/tools.js +3 -0
  36. package/build/src/tools/snapshot.js +2 -0
  37. package/build/src/tools/{inPage.js → thirdPartyDeveloper.js} +17 -17
  38. package/build/src/tools/tools.js +2 -2
  39. package/build/src/tools/webmcp.js +4 -4
  40. package/build/src/version.js +1 -1
  41. package/package.json +6 -7
  42. package/build/src/bin/cliDefinitions.js +0 -622
  43. package/build/src/third_party/THIRD_PARTY_NOTICES +0 -4297
  44. package/build/src/third_party/bundled-packages.json +0 -9
  45. package/build/src/utils/ExtensionRegistry.js +0 -35
package/README.md CHANGED
@@ -96,7 +96,9 @@ If Brave is not detected automatically, set `BRAVE_PATH`:
96
96
  "mcpServers": {
97
97
  "brave-devtools": {
98
98
  "command": "node",
99
- "args": ["/absolute/path/to/brave-devtools-mcp/build/src/bin/brave-devtools-mcp.js"],
99
+ "args": [
100
+ "/absolute/path/to/brave-devtools-mcp/build/src/bin/brave-devtools-mcp.js"
101
+ ],
100
102
  "env": {
101
103
  "BRAVE_PATH": "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"
102
104
  }
@@ -139,7 +141,12 @@ brave-browser --remote-debugging-port=9222
139
141
  "mcpServers": {
140
142
  "brave-devtools": {
141
143
  "command": "npx",
142
- "args": ["-y", "brave-mcp@latest", "--browserUrl", "http://localhost:9222"]
144
+ "args": [
145
+ "-y",
146
+ "brave-mcp@latest",
147
+ "--browserUrl",
148
+ "http://localhost:9222"
149
+ ]
143
150
  }
144
151
  }
145
152
  }
@@ -154,7 +161,8 @@ Or if running from source:
154
161
  "command": "node",
155
162
  "args": [
156
163
  "/absolute/path/to/brave-devtools-mcp/build/src/bin/brave-devtools-mcp.js",
157
- "--browserUrl", "http://localhost:9222"
164
+ "--browserUrl",
165
+ "http://localhost:9222"
158
166
  ]
159
167
  }
160
168
  }
@@ -198,7 +206,8 @@ If you are interested in only basic browser tasks, use `--slim` mode:
198
206
  "command": "node",
199
207
  "args": [
200
208
  "/absolute/path/to/brave-devtools-mcp/build/src/bin/brave-devtools-mcp.js",
201
- "--slim", "--headless"
209
+ "--slim",
210
+ "--headless"
202
211
  ]
203
212
  }
204
213
  }
@@ -586,7 +595,7 @@ If you run into any issues, checkout our [troubleshooting guide](./docs/troubles
586
595
 
587
596
  <!-- BEGIN AUTO GENERATED TOOLS -->
588
597
 
589
- - **Input automation** (9 tools)
598
+ - **Input automation** (10 tools)
590
599
  - [`click`](docs/tool-reference.md#click)
591
600
  - [`drag`](docs/tool-reference.md#drag)
592
601
  - [`fill`](docs/tool-reference.md#fill)
@@ -596,6 +605,7 @@ If you run into any issues, checkout our [troubleshooting guide](./docs/troubles
596
605
  - [`press_key`](docs/tool-reference.md#press_key)
597
606
  - [`type_text`](docs/tool-reference.md#type_text)
598
607
  - [`upload_file`](docs/tool-reference.md#upload_file)
608
+ - [`click_at`](docs/tool-reference.md#click_at)
599
609
  - **Navigation automation** (6 tools)
600
610
  - [`close_page`](docs/tool-reference.md#close_page)
601
611
  - [`list_pages`](docs/tool-reference.md#list_pages)
@@ -613,21 +623,32 @@ If you run into any issues, checkout our [troubleshooting guide](./docs/troubles
613
623
  - **Network** (2 tools)
614
624
  - [`get_network_request`](docs/tool-reference.md#get_network_request)
615
625
  - [`list_network_requests`](docs/tool-reference.md#list_network_requests)
616
- - **Debugging** (6 tools)
626
+ - **Debugging** (8 tools)
617
627
  - [`evaluate_script`](docs/tool-reference.md#evaluate_script)
618
628
  - [`get_console_message`](docs/tool-reference.md#get_console_message)
619
629
  - [`lighthouse_audit`](docs/tool-reference.md#lighthouse_audit)
620
630
  - [`list_console_messages`](docs/tool-reference.md#list_console_messages)
621
631
  - [`take_screenshot`](docs/tool-reference.md#take_screenshot)
622
632
  - [`take_snapshot`](docs/tool-reference.md#take_snapshot)
633
+ - [`screencast_start`](docs/tool-reference.md#screencast_start)
634
+ - [`screencast_stop`](docs/tool-reference.md#screencast_stop)
635
+ - **Memory** (4 tools)
636
+ - [`take_memory_snapshot`](docs/tool-reference.md#take_memory_snapshot)
637
+ - [`get_memory_snapshot_details`](docs/tool-reference.md#get_memory_snapshot_details)
638
+ - [`get_nodes_by_class`](docs/tool-reference.md#get_nodes_by_class)
639
+ - [`load_memory_snapshot`](docs/tool-reference.md#load_memory_snapshot)
623
640
  - **Extensions** (5 tools)
624
641
  - [`install_extension`](docs/tool-reference.md#install_extension)
625
642
  - [`list_extensions`](docs/tool-reference.md#list_extensions)
626
643
  - [`reload_extension`](docs/tool-reference.md#reload_extension)
627
644
  - [`trigger_extension_action`](docs/tool-reference.md#trigger_extension_action)
628
645
  - [`uninstall_extension`](docs/tool-reference.md#uninstall_extension)
629
- - **Memory** (1 tools)
630
- - [`take_memory_snapshot`](docs/tool-reference.md#take_memory_snapshot)
646
+ - **Third-party** (2 tools)
647
+ - [`execute_3p_developer_tool`](docs/tool-reference.md#execute_3p_developer_tool)
648
+ - [`list_3p_developer_tools`](docs/tool-reference.md#list_3p_developer_tools)
649
+ - **WebMCP** (2 tools)
650
+ - [`execute_webmcp_tool`](docs/tool-reference.md#execute_webmcp_tool)
651
+ - [`list_webmcp_tools`](docs/tool-reference.md#list_webmcp_tools)
631
652
 
632
653
  <!-- END AUTO GENERATED TOOLS -->
633
654
 
@@ -638,16 +659,16 @@ The Brave DevTools MCP server supports the following configuration options:
638
659
  <!-- BEGIN AUTO GENERATED OPTIONS -->
639
660
 
640
661
  - **`--autoConnect`/ `--auto-connect`**
641
- If specified, automatically connects to a browser (Chrome 144+) running locally from the user data directory identified by the channel param (default channel is stable). Requires the remote debugging server to be started in the Chrome instance via chrome://inspect/#remote-debugging.
662
+ If specified, automatically connects to a Brave instance running locally from the user data directory identified by the channel param (default channel is release). Requires the remote debugging server to be started in the Brave instance via brave://inspect/#remote-debugging.
642
663
  - **Type:** boolean
643
664
  - **Default:** `false`
644
665
 
645
666
  - **`--browserUrl`/ `--browser-url`, `-u`**
646
- Connect to a running, debuggable Chrome instance (e.g. `http://127.0.0.1:9222`). For more details see: https://github.com/ChromeDevTools/chrome-devtools-mcp#connecting-to-a-running-chrome-instance.
667
+ Connect to a running, debuggable Brave instance (e.g. `http://127.0.0.1:9222`).
647
668
  - **Type:** string
648
669
 
649
670
  - **`--wsEndpoint`/ `--ws-endpoint`, `-w`**
650
- WebSocket endpoint to connect to a running Chrome instance (e.g., ws://127.0.0.1:9222/devtools/browser/<id>). Alternative to --browserUrl.
671
+ WebSocket endpoint to connect to a running Brave instance (e.g., ws://127.0.0.1:9222/devtools/browser/<id>). Alternative to --browserUrl.
651
672
  - **Type:** string
652
673
 
653
674
  - **`--wsHeaders`/ `--ws-headers`**
@@ -660,7 +681,7 @@ The Brave DevTools MCP server supports the following configuration options:
660
681
  - **Default:** `false`
661
682
 
662
683
  - **`--executablePath`/ `--executable-path`, `-e`**
663
- Path to custom Chrome executable.
684
+ Path to custom Brave executable. Can also be set via BRAVE_PATH environment variable.
664
685
  - **Type:** string
665
686
 
666
687
  - **`--isolated`**
@@ -668,24 +689,24 @@ The Brave DevTools MCP server supports the following configuration options:
668
689
  - **Type:** boolean
669
690
 
670
691
  - **`--userDataDir`/ `--user-data-dir`**
671
- Path to the user data directory for Chrome. Default is $HOME/.cache/chrome-devtools-mcp/chrome-profile$CHANNEL_SUFFIX_IF_NON_STABLE
692
+ Path to the user data directory for Brave. Default is $HOME/.cache/brave-devtools-mcp/brave-profile$CHANNEL_SUFFIX_IF_NON_RELEASE
672
693
  - **Type:** string
673
694
 
674
695
  - **`--channel`**
675
- Specify a different Chrome channel that should be used. The default is the stable channel version.
696
+ Specify a different Brave channel that should be used. The default is the release channel.
676
697
  - **Type:** string
677
- - **Choices:** `canary`, `dev`, `beta`, `stable`
698
+ - **Choices:** `release`, `beta`, `nightly`, `dev`
678
699
 
679
700
  - **`--logFile`/ `--log-file`**
680
701
  Path to a file to write debug logs to. Set the env variable `DEBUG` to `*` to enable verbose logs. Useful for submitting bug reports.
681
702
  - **Type:** string
682
703
 
683
704
  - **`--viewport`**
684
- Initial viewport size for the Chrome instances started by the server. For example, `1280x720`. In headless mode, max size is 3840x2160px.
705
+ Initial viewport size for the Brave instances started by the server. For example, `1280x720`. In headless mode, max size is 3840x2160px.
685
706
  - **Type:** string
686
707
 
687
708
  - **`--proxyServer`/ `--proxy-server`**
688
- Proxy server configuration for Chrome passed as --proxy-server when launching the browser. See https://www.chromium.org/developers/design-documents/network-settings/ for details.
709
+ Proxy server configuration for Brave passed as --proxy-server when launching the browser. See https://www.chromium.org/developers/design-documents/network-settings/ for details.
689
710
  - **Type:** string
690
711
 
691
712
  - **`--acceptInsecureCerts`/ `--accept-insecure-certs`**
@@ -704,16 +725,16 @@ The Brave DevTools MCP server supports the following configuration options:
704
725
  Path to ffmpeg executable for screencast recording.
705
726
  - **Type:** string
706
727
 
707
- - **`--experimentalWebmcp`/ `--experimental-webmcp`**
708
- Set to true to enable debugging WebMCP tools. Requires Chrome 149+ with the following flags: `--enable-features=WebMCPTesting,DevToolsWebMCPSupport`
728
+ - **`--categoryExperimentalWebmcp`/ `--category-experimental-webmcp`**
729
+ Set to true to enable debugging WebMCP tools. Requires Brave with the following flags: `--enable-features=WebMCPTesting,DevToolsWebMCPSupport`
709
730
  - **Type:** boolean
710
731
 
711
- - **`--chromeArg`/ `--chrome-arg`**
712
- Additional arguments for Chrome. Only applies when Chrome is launched by chrome-devtools-mcp.
732
+ - **`--braveArg`/ `--brave-arg`**
733
+ Additional arguments for Brave. Only applies when Brave is launched by brave-devtools-mcp.
713
734
  - **Type:** array
714
735
 
715
- - **`--ignoreDefaultChromeArg`/ `--ignore-default-chrome-arg`**
716
- Explicitly disable default arguments for Chrome. Only applies when Chrome is launched by chrome-devtools-mcp.
736
+ - **`--ignoreDefaultBraveArg`/ `--ignore-default-brave-arg`**
737
+ Explicitly disable default arguments for Brave. Only applies when Brave is launched by brave-devtools-mcp.
717
738
  - **Type:** array
718
739
 
719
740
  - **`--categoryEmulation`/ `--category-emulation`**
@@ -736,15 +757,20 @@ The Brave DevTools MCP server supports the following configuration options:
736
757
  - **Type:** boolean
737
758
  - **Default:** `false`
738
759
 
760
+ - **`--categoryExperimentalThirdParty`/ `--category-experimental-third-party`**
761
+ Set to true to enable third-party developer tools exposed by the inspected page itself
762
+ - **Type:** boolean
763
+ - **Default:** `false`
764
+
739
765
  - **`--performanceCrux`/ `--performance-crux`**
740
766
  Set to false to disable sending URLs from performance traces to CrUX API to get field performance data.
741
767
  - **Type:** boolean
742
768
  - **Default:** `true`
743
769
 
744
770
  - **`--usageStatistics`/ `--usage-statistics`**
745
- Set to false to opt-out of usage statistics collection. Google collects usage data to improve the tool, handled under the Google Privacy Policy (https://policies.google.com/privacy). This is independent from Chrome browser metrics. Disabled if `CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS` or `CI` env variables are set.
771
+ Usage statistics collection (disabled by default in this fork).
746
772
  - **Type:** boolean
747
- - **Default:** `true`
773
+ - **Default:** `false`
748
774
 
749
775
  - **`--slim`**
750
776
  Exposes a "slim" set of 3 tools covering navigation, script execution and screenshots only. Useful for basic browser tasks.
@@ -4,8 +4,9 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import fs from 'node:fs/promises';
7
+ import os from 'node:os';
7
8
  import path from 'node:path';
8
- import { fileURLToPath } from 'node:url';
9
+ import { fileURLToPath, pathToFileURL } from 'node:url';
9
10
  import { UniverseManager } from './DevtoolsUtils.js';
10
11
  import { HeapSnapshotManager } from './HeapSnapshotManager.js';
11
12
  import { McpPage } from './McpPage.js';
@@ -91,7 +92,16 @@ export class McpContext {
91
92
  return context;
92
93
  }
93
94
  roots() {
94
- return this.#roots;
95
+ if (this.#roots === undefined) {
96
+ return undefined;
97
+ }
98
+ return [
99
+ ...this.#roots,
100
+ {
101
+ uri: pathToFileURL(os.tmpdir()).href,
102
+ name: 'temp',
103
+ },
104
+ ];
95
105
  }
96
106
  setRoots(roots) {
97
107
  this.#roots = roots;
@@ -30,7 +30,7 @@ export class McpPage {
30
30
  // Dialog
31
31
  #dialog;
32
32
  #dialogHandler;
33
- inPageTools;
33
+ thirdPartyDeveloperTools;
34
34
  constructor(page, id) {
35
35
  this.pptrPage = page;
36
36
  this.id = id;
@@ -48,8 +48,13 @@ export class McpPage {
48
48
  clearDialog() {
49
49
  this.#dialog = undefined;
50
50
  }
51
- getInPageTools() {
52
- return this.inPageTools;
51
+ throwIfDialogOpen() {
52
+ if (this.#dialog) {
53
+ throw new Error(`A dialog is open (${this.#dialog.type()}: ${this.#dialog.message()}).`);
54
+ }
55
+ }
56
+ getThirdPartyDeveloperTools() {
57
+ return this.thirdPartyDeveloperTools;
53
58
  }
54
59
  getWebMcpTools() {
55
60
  return this.pptrPage.webmcp.tools();
@@ -83,7 +88,7 @@ export class McpPage {
83
88
  dispose() {
84
89
  this.pptrPage.off('dialog', this.#dialogHandler);
85
90
  }
86
- async executeInPageTool(toolName, params, response) {
91
+ async executeThirdPartyDeveloperTool(toolName, params, response) {
87
92
  // Creates array of ElementHandles from the UIDs in the params.
88
93
  // We do not replace the uids with the ElementsHandles yet, because
89
94
  // the `evaluate` function only turns them into DOM elements if they
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import { ConsoleFormatter } from './formatters/ConsoleFormatter.js';
7
7
  import { HeapSnapshotFormatter } from './formatters/HeapSnapshotFormatter.js';
8
+ import { isNodeLike } from './formatters/HeapSnapshotFormatter.js';
8
9
  import { IssueFormatter } from './formatters/IssueFormatter.js';
9
10
  import { NetworkFormatter } from './formatters/NetworkFormatter.js';
10
11
  import { SnapshotFormatter } from './formatters/SnapshotFormatter.js';
@@ -124,13 +125,14 @@ export class McpResponse {
124
125
  #networkRequestsOptions;
125
126
  #consoleDataOptions;
126
127
  #listExtensions;
127
- #listInPageTools;
128
+ #listThirdPartyDeveloperTools;
128
129
  #listWebMcpTools;
129
130
  #devToolsData;
130
131
  #tabId;
131
132
  #args;
132
133
  #page;
133
134
  #redactNetworkHeaders = true;
135
+ #error;
134
136
  constructor(args) {
135
137
  this.#args = args;
136
138
  }
@@ -161,9 +163,9 @@ export class McpResponse {
161
163
  setListExtensions() {
162
164
  this.#listExtensions = true;
163
165
  }
164
- setListInPageTools() {
165
- if (this.#args.categoryInPageTools) {
166
- this.#listInPageTools = true;
166
+ setListThirdPartyDeveloperTools() {
167
+ if (this.#args.categoryExperimentalThirdParty) {
168
+ this.#listThirdPartyDeveloperTools = true;
167
169
  }
168
170
  }
169
171
  setListWebMcpTools() {
@@ -204,6 +206,9 @@ export class McpResponse {
204
206
  includePreservedMessages: options?.includePreservedMessages,
205
207
  };
206
208
  }
209
+ setError(error) {
210
+ this.#error = error;
211
+ }
207
212
  attachNetworkRequest(reqId, options) {
208
213
  this.#attachedNetworkRequestId = reqId;
209
214
  this.#attachedNetworkRequestOptions = options;
@@ -254,6 +259,9 @@ export class McpResponse {
254
259
  get consoleMessagesTypes() {
255
260
  return this.#consoleDataOptions?.types;
256
261
  }
262
+ get error() {
263
+ return this.#error;
264
+ }
257
265
  appendResponseLine(value) {
258
266
  this.#textResponseLines.push(value);
259
267
  }
@@ -373,14 +381,14 @@ export class McpResponse {
373
381
  if (this.#listExtensions) {
374
382
  extensions = await context.listExtensions();
375
383
  }
376
- let inPageTools;
377
- if (this.#listInPageTools) {
384
+ let thirdPartyDeveloperTools;
385
+ if (this.#listThirdPartyDeveloperTools) {
378
386
  const page = this.#page ?? context.getSelectedMcpPage();
379
- inPageTools = await getToolGroup(page);
380
- page.inPageTools = inPageTools;
387
+ thirdPartyDeveloperTools = await getToolGroup(page);
388
+ page.thirdPartyDeveloperTools = thirdPartyDeveloperTools;
381
389
  }
382
390
  let webmcpTools;
383
- if (this.#listWebMcpTools && this.#args.experimentalWebmcp) {
391
+ if (this.#listWebMcpTools && this.#args.categoryExperimentalWebmcp) {
384
392
  const page = this.#page ?? context.getSelectedMcpPage();
385
393
  webmcpTools = page.getWebMcpTools();
386
394
  }
@@ -461,8 +469,9 @@ export class McpResponse {
461
469
  traceSummary: this.#attachedTraceSummary,
462
470
  extensions,
463
471
  lighthouseResult: this.#attachedLighthouseResult,
464
- inPageTools,
472
+ thirdPartyDeveloperTools,
465
473
  webmcpTools,
474
+ errorMessage: this.#error?.message,
466
475
  });
467
476
  }
468
477
  format(toolName, context, data) {
@@ -655,7 +664,10 @@ Call ${handleDialog.name} to handle it before continuing.`);
655
664
  }
656
665
  const nodes = this.#heapSnapshotOptions.nodes;
657
666
  if (nodes) {
658
- const paginationData = this.#dataWithPagination(nodes.items, this.#heapSnapshotOptions.pagination);
667
+ const sortedItems = nodes.items
668
+ .filter(isNodeLike)
669
+ .sort((a, b) => b.retainedSize - a.retainedSize);
670
+ const paginationData = this.#dataWithPagination(sortedItems, this.#heapSnapshotOptions.pagination);
659
671
  response.push(HeapSnapshotFormatter.formatNodes(paginationData.items));
660
672
  structuredContent.pagination = paginationData.pagination;
661
673
  response.push(...paginationData.info);
@@ -688,14 +700,16 @@ Call ${handleDialog.name} to handle it before continuing.`);
688
700
  response.push(extensionsMessage);
689
701
  }
690
702
  }
691
- if (this.#listInPageTools) {
692
- structuredContent.inPageTools = data.inPageTools ?? undefined;
693
- response.push('## In-page tools');
694
- if (!data.inPageTools || !data.inPageTools.tools) {
695
- response.push('No in-page tools available.');
703
+ if (this.#listThirdPartyDeveloperTools) {
704
+ structuredContent.thirdPartyDeveloperTools =
705
+ data.thirdPartyDeveloperTools ?? undefined;
706
+ response.push('## Third-party developer tools');
707
+ if (!data.thirdPartyDeveloperTools ||
708
+ !data.thirdPartyDeveloperTools.tools) {
709
+ response.push('No third-party developer tools available.');
696
710
  }
697
711
  else {
698
- const toolGroup = data.inPageTools;
712
+ const toolGroup = data.thirdPartyDeveloperTools;
699
713
  response.push(`${toolGroup.name}: ${toolGroup.description}`);
700
714
  response.push('Available tools:');
701
715
  const toolDefinitionsMessage = toolGroup.tools
@@ -760,6 +774,10 @@ Call ${handleDialog.name} to handle it before continuing.`);
760
774
  response.push('<no console messages found>');
761
775
  }
762
776
  }
777
+ if (data.errorMessage) {
778
+ response.push(`Error: ${data.errorMessage}`);
779
+ structuredContent.errorMessage = data.errorMessage;
780
+ }
763
781
  const text = {
764
782
  type: 'text',
765
783
  text: response.join('\n'),
@@ -99,8 +99,8 @@ export class TextSnapshot {
99
99
  return snapshot;
100
100
  }
101
101
  // ExtraHandles represent DOM nodes which might not be part of the accessibility tree, e.g. DOM nodes
102
- // returned by in-page tools. We insert them into the tree by finding the closest ancestor in the
103
- // tree and inserting the node as a child. The ancestor's child nodes are re-parented if necessary.
102
+ // returned by third-party developer tools. We insert them into the tree by finding the closest ancestor
103
+ // in the tree and inserting the node as a child. The ancestor's child nodes are re-parented if necessary.
104
104
  static async insertExtraNodes(page, idToNode, seenUniqueIds, snapshotId, idCounter, rootNodeWithId, seenBackendNodeIds, extraHandles) {
105
105
  const { uniqueBackendNodeIdToMcpId } = page;
106
106
  const createExtraNode = async (handle) => {
@@ -104,8 +104,10 @@ export class WaitForHelper {
104
104
  });
105
105
  }
106
106
  async waitForEventsAfterAction(action, options) {
107
+ let dialogOpened = false;
107
108
  if (options?.handleDialog) {
108
109
  const dialogHandler = (dialog) => {
110
+ dialogOpened = true;
109
111
  if (options.handleDialog === 'dismiss') {
110
112
  void dialog.dismiss();
111
113
  }
@@ -142,6 +144,9 @@ export class WaitForHelper {
142
144
  }
143
145
  try {
144
146
  await navigationFinished;
147
+ if (dialogOpened) {
148
+ return;
149
+ }
145
150
  // Wait for stable dom after navigation so we execute in
146
151
  // the correct context
147
152
  await this.waitForStableDom();