Visitar URL original
feat: report pages opened by input actions by lisa0314 · Pull Request #2679 · ChromeDevTools/chrome-devtools-mcp · GitHub
Skip to content

feat: report pages opened by input actions - #2679

Merged
OrKoN merged 1 commit into
ChromeDevTools:mainfrom
lisa0314:fix/367-report-new-pages
Oct 14, 2026
Merged

OrKoN merged 1 commit into
ChromeDevTools:mainfrom
lisa0314:fix/367-report-new-pages

Conversation

@lisa0314

@lisa0314 lisa0314 commented Sep 7, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #367

Report pages opened by input actions using the source page popup events. The response lists only opened pages under ## Opened pages with their MCP page ID, title, and URL, and exposes them as structuredContent.openedPages. Already-open pages are excluded; a full page list is not implicitly enabled.

The popup set uses a WeakSet. Before formatting a response, the page snapshot is refreshed so opened pages have MCP IDs. The response follows the context page order rather than promising event order. Shared page formatting also covers the regular and extension page lists.

Tests cover a popup alongside an unrelated page, multiple popups without depending on order, and listener cleanup.

Testing

  • npm run format and npm run build passed.
  • npm run test tests/utils/WaitForHelper.test.ts and npm run test tests/tools/input.test.ts passed with system Chrome.
  • The full npm run test run encounters Page.captureScreenshot: Page is too large in the large full-page screenshot test; the same failure reproduces on an unchanged main checkout with the same Chrome.

@lisa0314

lisa0314 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

PTAL. Thanks!

Comment thread src/utils/WaitForHelper.ts Resolved
Comment thread src/utils/WaitForHelper.ts Resolved
Comment thread src/McpResponse.ts Resolved
Comment thread src/McpResponse.ts Resolved
Comment thread tests/tools/input.test.ts Resolved
Comment thread src/McpResponse.ts Resolved
@Lightning00Blade

Copy link
Copy Markdown
Collaborator

@lisa0314 Please rebase, and verify no changes are needed after #2812

@OrKoN OrKoN left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, let's make following changes after rebasing:

  • In src/utils/WaitForHelper.ts (WaitForHelper.waitForEventsAfterAction) and src/McpResponse.ts (McpResponse.format, formatPage), track opened popups by page.target() (mcpPage.target) instead of mcpPage.pptrPage, and use await mcpPage.getTitle() and mcpPage.url() inside formatPage. After PR #2812, unselected McpPage instances in context.getPages() (including newly opened popups) are lazily initialized from Target and throw McpPage is not initialized when mcpPage.pptrPage is accessed, and fetchPageTitle has been replaced by mcpPage.getTitle().
  • In tests/utils/WaitForHelper.test.ts and tests/tools/input.test.ts, replace the withMcpContext real-browser popup tests with mock-based unit tests using createMockPuppeteerPage() (emitting 'popup') and mock-based McpResponse tests in tests/McpResponse.test.ts. AGENTS.md requires preferring mock-based unit tests over launching a real browser via withMcpContext when testing event listener wiring and response formatting.

@OrKoN
OrKoN self-requested a review September 30, 2026 08:56

@OrKoN OrKoN left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

marking as needing changes

@lisa0314
lisa0314 force-pushed the fix/367-report-new-pages branch from 2647b63 to 3a9c5bf Compare September 30, 2026 10:59

@OrKoN OrKoN left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's check the following:

  1. In src/McpResponse.ts (formatPage), use await mcpPage.getTitle() and mcpPage.url() instead of calling fetchPageTitle(mcpPage.pptrPage) and mcpPage.pptrPage.url(). Unselected pages (such as other open pages formatted under ## Pages or ## Extension Pages) do not have an initialized pptrPage, causing formatPage to throw McpPage is not initialized. I am actually working on removing the fetches for titles, let's wait for that.

  2. In src/utils/WaitForHelper.ts and src/McpResponse.ts, record popup.target() in a Set<Target> rather than storing page: object in a WeakSet<object>. This avoids the loose object typing and #hasOpenedPages flag, and allows synchronous matching via openedTargets.has(mcpPage.target) without awaiting mcpPage.target.page() or eagerly calling await mcpPage.init().

  3. In tests/utils/WaitForHelper.test.ts, update the popup test to emit 'popup' from createMockPuppeteerPage() rather than launching a full browser via withMcpContext. Unit tests in WaitForHelper.test.ts should verify event wiring and listener cleanup using mocks rather than real browser integration tests.

@lisa0314
lisa0314 force-pushed the fix/367-report-new-pages branch from 9242de5 to a539adb Compare September 30, 2026 12:47
@lisa0314

lisa0314 commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor Author

Addressed the latest review feedback and pushed a539adb:

  • Popup tracking now uses Set<Target> with page.target() / mcpPage.target.
  • formatPage uses getTitle() and url().
  • Popup and response coverage is mock-based.

PTAL, Thanks.

Comment thread src/utils/WaitForHelper.ts Resolved
@OrKoN

OrKoN commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

@lisa0314 there seem to be another merge conflict, could you please rebase?

@OrKoN OrKoN left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

marking as needing changes

@lisa0314
lisa0314 force-pushed the fix/367-report-new-pages branch 2 times, most recently from 62161ff to 397556a Compare October 8, 2026 05:55
@lisa0314

lisa0314 commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

@OrKoN Sorry for the late reply. The rebase work has been completed. Please take another look. Thanks!

@Lightning00Blade

Copy link
Copy Markdown
Collaborator

@lisa0314 It looks like there is till a rebase issue after more changes landed, could you take care of the new ones as well?

@lisa0314
lisa0314 force-pushed the fix/367-report-new-pages branch from 397556a to 673214d Compare October 13, 2026 01:30
@lisa0314

Copy link
Copy Markdown
Contributor Author

@Lightning00Blade Rebased onto the latest main and resolved the new conflict. I also added explicit return types to comply with the new ESLint rules. Please take another look. Thanks!

@OrKoN OrKoN left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PTAL:

  1. In src/utils/WaitForHelper.ts, import the internal Page type through src/third_party/index.ts (e.g. add export type {Page as InternalPage} from 'puppeteer-core/internal/api/Page.js' there) instead of importing puppeteer-core/internal/api/Page.js directly. All other Puppeteer internals go through src/third_party/index.ts, which is the bundling boundary for third-party code.

  2. In tests/utils/WaitForHelper.test.ts (captures popup targets opened by the action), also check that the 'popup' listener is removed after waitForEventsAfterAction resolves (e.g. pptrPage.listenerCount('popup') === 0). The previous review asked for coverage of both event wiring and listener cleanup, and a leaked listener would add targets from later actions to a stale helper.

  3. In tests/McpResponse.test.ts (reports only pages opened by the attached action), add sinon.assert.calledOnceWithExactly(context.createPagesSnapshot). The new openedPages && !includePages snapshot refresh in McpResponse.format is currently untested, and without it newly opened popups have no McpPage entry and are silently left out.

  4. Revert the unrelated blank-line change in tests/tools/input.test.ts. It is the only change left in that file after the real-browser popup test was removed, so it is just diff noise.

@lisa0314
lisa0314 force-pushed the fix/367-report-new-pages branch from 673214d to 1b86018 Compare October 14, 2026 01:27
@lisa0314

Copy link
Copy Markdown
Contributor Author

Thanks for the review! All four points are addressed:

  • Routed the internal Page type through src/third_party/index.ts as InternalPage.

  • Added assertions that the popup listener is registered during the action and removed afterward, with listener-count support in the shared mock.

  • Added sinon.assert.calledOnceWithExactly(context.createPagesSnapshot). The refresh currently lives in handle(), so the test now calls that entry point.

  • Reverted the unrelated blank-line change in tests/tools/input.test.ts.

PTAL. Thanks!

@OrKoN
OrKoN self-requested a review October 14, 2026 05:58

@OrKoN OrKoN left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! The last item: I think the InternalPage usage can be dropped:

  1. In src/utils/WaitForHelper.ts (waitForEventsAfterAction), register the 'popup' listener on the public Page passed to the constructor so the handler gets a public Page | null and page.target() can go into #openedPages directly, then remove the runtime instanceof Target check and the InternalPage export from src/third_party/index.ts. Right now the instanceof check exists only to convert the internal Target type to the public one, which goes against the AGENTS.md rule against redundant type checks, and if it ever fails the popup is silently dropped.

@lisa0314
lisa0314 force-pushed the fix/367-report-new-pages branch from 1b86018 to 187cc32 Compare October 14, 2026 07:56
@OrKoN
OrKoN self-requested a review October 14, 2026 07:56
@OrKoN

OrKoN commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator

@lisa0314 could you please rebase as well?

@lisa0314
lisa0314 force-pushed the fix/367-report-new-pages branch from 187cc32 to b4e6e59 Compare October 14, 2026 08:18
@lisa0314

Copy link
Copy Markdown
Contributor Author

@OrKoN Rebased onto the latest main, resolved the McpResponse conflict while preserving fresh page titles and popup reporting.

@OrKoN
OrKoN enabled auto-merge October 14, 2026 08:55
auto-merge was automatically disabled October 14, 2026 09:40

Head branch was pushed to by a user without write access

@lisa0314
lisa0314 force-pushed the fix/367-report-new-pages branch from b4e6e59 to b6f597c Compare October 14, 2026 09:40
@OrKoN
OrKoN enabled auto-merge October 14, 2026 09:44
@lisa0314

Copy link
Copy Markdown
Contributor Author

Rebased onto the latest main and resolved the helper-function insertion conflict introduced by the Lighthouse update. Auto-merge was automatically disabled. Please help to approve to merge again. Thanks! @OrKoN

@OrKoN
OrKoN added this pull request to the merge queue Oct 14, 2026
Merged via the queue into ChromeDevTools:main with commit 28fb230 Oct 14, 2026
20 checks passed
OrKoN added a commit that referenced this pull request Oct 15, 2026
🤖 I have created a release *beep* *boop*
---


##
[1.11.0](chrome-devtools-mcp-v1.10.1...chrome-devtools-mcp-v1.11.0)
(2026-10-15)


### 🎉 Features

* add --file-navigations flag to reject file: URL navigations
([#2853](#2853))
([54cae57](54cae57))
* Add analyze_heapsnapshot_contexts MCP tool
([#2791](#2791))
([190aeee](190aeee))
* add ignoreCache option to performance_start_trace
([#2931](#2931))
([3467d40](3467d40))
* add maxNameLength truncation option to compare_heapsnapshots
([#3098](#3098))
([1e1c53e](1e1c53e))
* Add pagination to compare_heapsnapshots
([#3140](#3140))
([daebfd1](daebfd1))
* **config:** add ConfigWatcher to watch config file changes
([#3139](#3139))
([9171f77](9171f77))
* discover the config file in predefined locations
([#2876](#2876))
([02c0112](02c0112))
* implement ffmpeg-free screencast tools enabled by default
([#3123](#3123))
([8953ea5](8953ea5))
* reduce StaticText noise in text snapshots
([#2895](#2895))
([4441325](4441325))
* report pages opened by input actions
([#2679](#2679))
([28fb230](28fb230))
* resolve config defaults after merging CLI and config file
([#2849](#2849))
([bdeb70d](bdeb70d))
* return failing audits and DOM nodes inline from lighthouse_audit
([#2930](#2930))
([241fba5](241fba5))
* skip more redundant data in text snapshots
([#2896](#2896))
([b2f522c](b2f522c))
* support debugging WebMCP tools in third-party developer tools
([#2900](#2900))
([0db519f](0db519f))
* support emulating additional CSS media features
([#2929](#2929))
([69524f0](69524f0))
* support evaluating scripts from local files
([#2606](#2606))
([9cf47a4](9cf47a4))
* Support truncation in get_heapsnapshot_details
([#3137](#3137))
([f827e06](f827e06))
* Truncate long names by default to 100 characters
([#2893](#2893))
([5ddb0a3](5ddb0a3))


### 🛠️ Fixes

* account for scroll offsets in downscaled screenshots
([#2685](#2685))
([830c693](830c693))
* allow --categoryExtensions when connecting to an existing browser
([#3041](#3041))
([d250bc5](d250bc5))
* allow stopping the CLI if command fails
([#3088](#3088))
([77e238e](77e238e)),
closes
[#2982](#2982)
* avoid runtime title fetches
([#2883](#2883))
([04195d1](04195d1))
* better config support for chrome-devtools CLI
([#2819](#2819))
([9624e64](9624e64))
* clamp async stack trace separator repeat count
([#3035](#3035))
([93e06ab](93e06ab)),
closes
[#3031](#3031)
* **cli:** pass positional values starting with `-` through to tools
([#3084](#3084))
([9de05ae](9de05ae)),
closes
[#2984](#2984)
* **collectors:** ignore transient target errors when subscribing to
service workers
([#2888](#2888))
([551dd6c](551dd6c))
* **daemon:** bound browser shutdown and avoid watchFile timeout on stop
([#2887](#2887))
([f3db5e7](f3db5e7))
* **daemon:** keep fallback socket in private runtime dir
([#2766](#2766))
([871a37e](871a37e))
* **daemon:** verify process identity before treating PID file as active
([#3109](#3109))
([b608bed](b608bed))
* do not close a healthy browser when a tool call outlasts 60s
([#3149](#3149))
([39c7db1](39c7db1))
* ensure aggregate IDs in heap snapshots are deterministic
([#2923](#2923))
([e918c47](e918c47))
* escape client-supplied values in McpContext logs and errors
([#2832](#2832))
([efb0d02](efb0d02)),
closes
[#2831](#2831)
* fail fast on tool calls stuck after a dead browser connection
([#2699](#2699))
([2a7ef50](2a7ef50))
* harden third-party tool result serialization
([#2892](#2892))
([4418a7b](4418a7b))
* honor explicit --allowUnrestrictedPaths=false in CLI mode
([#3040](#3040))
([61fc362](61fc362))
* include errors in slim responses
([#3085](#3085))
([ee38097](ee38097))
* **input:** reject multiple file paths on single-file input in
upload_file
([#2995](#2995))
([#3135](#3135))
([e650843](e650843))
* list fresh page titles
([#3103](#3103))
([e717082](e717082))
* **memory:** reject contradictory pagination options in
take_heapsnapshot
([#3002](#3002))
([#3131](#3131))
([508126c](508126c))
* **network:** enforce URL policy across redirects
([#2767](#2767))
([274cd4c](274cd4c))
* pass categoryExtensions to the target filter when connecting
([#3047](#3047))
([4e90238](4e90238))
* **performance:** report an error when performance_stop_trace is called
with no active trace
([#3001](#3001))
([#3126](#3126))
([e170384](e170384))
* preserve HeapSnapshotManager across browser reconnects
([#3025](#3025))
([64388c6](64388c6))
* propagate failed responseFilePath write error instead of reporting
body unavailable
([#2957](#2957))
([#3119](#3119))
([3cee3bd](3cee3bd))
* **pwa:** wait for initial navigation on launch and retry transient
install error
([#2889](#2889))
([63010cb](63010cb))
* record screencast at the page's device pixel size
([#3155](#3155))
([62e2aa4](62e2aa4))
* reject --blockedUrlPattern/--allowedUrlPattern hostname regexp groups
([#2796](#2796))
([ae0aaef](ae0aaef))
* reject JSON arrays as 3p and WebMCP tool params
([#2785](#2785))
([c14e616](c14e616))
* reject named groups in URL patterns
([#2857](#2857))
([5b2c6f9](5b2c6f9))
* reject non-positive --viewport dimensions
([#2781](#2781))
([0ef528a](0ef528a))
* reject non-positive resize_page dimensions
([#2784](#2784))
([6ab6d35](6ab6d35))
* reject unrestricted paths with an explicit workspace
([#2858](#2858))
([45c1c6c](45c1c6c))
* report unknown page id before last-page guard in close_page
([#3042](#3042))
([bdc7e24](bdc7e24))
* round lighthouse category scores and show unscored categories as n/a
([#2924](#2924))
([7007680](7007680)),
closes
[#2915](#2915)
[#2916](#2916)
* set empty filePath to undefined instead of empty string
([#2836](#2836))
([adfc1ff](adfc1ff)),
closes
[#2825](#2825)
* surface WebMCP tool exceptions in execute_webmcp_tool
([#3107](#3107))
([d80d22e](d80d22e)),
closes
[#2975](#2975)
* url pattern partial ipv4
([#2859](#2859))
([c87d190](c87d190))


### 📄 Documentation

* clarify Antigravity MCP setup for VS Code extension
([#2855](#2855))
([12e13ca](12e13ca))
* clarify scope of --no-javascript-evaluation
([#3100](#3100))
([0c67cd5](0c67cd5))
* correct link to configuration
([#3086](#3086))
([bbb1e36](bbb1e36))
* document trusted host environment in SECURITY.md
([#3125](#3125))
([1352207](1352207))
* fix inaccurate examples in skills and CLI docs
([#2922](#2922))
([ec372b0](ec372b0)),
closes
[#2906](#2906)
[#2907](#2907)
[#2908](#2908)
[#2910](#2910)
[#2912](#2912)
[#2913](#2913)
[#2918](#2918)
[#2919](#2919)
[#2920](#2920)
[#2921](#2921)
* fix some reported issues
([#3099](#3099))
([d5d2f08](d5d2f08))
* include serviceWorkerId parameter for evaluate_script
([#3015](#3015))
([#3129](#3129))
([0623434](0623434))
* mention heapsnapshot being cached between runs
([#3045](#3045))
([f08dbe1](f08dbe1)),
closes
[#2976](#2976)
* **skills:** remove invalid outputDir flag from lighthouse_audit calls
([#3013](#3013))
([#3130](#3130))
([7754226](7754226))
* update documentation and SKILL for get_css_styles tool
([#2824](#2824))
([3c12a91](3c12a91))


### ⚡ Performance

* **cli:** re-use MCPServer.from helpers for daemon
([#2804](#2804))
([89eb3d5](89eb3d5))
* Load heap snapshots in parallel in compare_heapsnapshots
([#3023](#3023))
([20c1391](20c1391))


### 🏗️ Refactor

* centralize config defaults and conflict checks
([#2753](#2753))
([a739ba8](a739ba8))
* create all tools and register per slim mode
([#2874](#2874))
([99847a7](99847a7))
* enable categories by default
([#2811](#2811))
([e33ee48](e33ee48))
* extract CLI examples and conflict list in mcp-options
([#2848](#2848))
([45000d9](45000d9))
* extract config parsing logic in a class
([#2861](#2861))
([e4168d0](e4168d0))
* extract worker logic into McpWorker
([#2800](#2800))
([77165c6](77165c6))
* group Puppeteer and tool options
([#2875](#2875))
([699c4d5](699c4d5))
* lazily initialize McpPage from Target and enumerate targets in
McpContext
([#2812](#2812))
([545cbe3](545cbe3))
* use default Error for toolSchema
([#2822](#2822))
([8b2768d](8b2768d))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: Alex Rudenko <OrKoN@users.noreply.github.com>
zjdCander pushed a commit to zjdCander/chrome-devtools-mcp that referenced this pull request Oct 19, 2026
## Summary

Add a **Pre-submit checklist** section to `AGENTS.md`. Each item comes
from a recent review finding or a landed bug fix in this repository.

The checklist has five groups:

- **Scope and PR description**: one change per PR, title and commit type
match, description lists every behavior change and matches the diff,
`npm run gen` and `npm run format` ran.
- **Design**: fix in the lowest layer that owns the data, fix upstream
(Puppeteer, devtools-frontend) first, one helper for repeated code,
options objects instead of positional `undefined` arguments, validation
in Zod schemas.
- **Correctness and edge cases**: no stale state after a failed call,
artifacts written before a throw, abandoned async continuations, mutex
guards, file removal races, `dispose()` releases every resource, secrets
never reach logs, path parameters validated even when they parse as
URLs.
- **Tests**: every new function has a test, no vacuous assertions,
`notCalled` targets the first call after validation, exact-argument
assertions, reusable stubs in `tests/mocks.ts`, bounded timeouts, no
second CDP session for event waits.
- **Documentation and output**: tool descriptions state when a parameter
is ignored, skills stay generic, one-sentence inline comments.

Sources: review comments on ChromeDevTools#2679, ChromeDevTools#2797, ChromeDevTools#2859, ChromeDevTools#2881, ChromeDevTools#2901, ChromeDevTools#3048,
ChromeDevTools#3082, ChromeDevTools#3109, ChromeDevTools#3120, ChromeDevTools#3132, ChromeDevTools#3134, ChromeDevTools#3139, ChromeDevTools#3148, ChromeDevTools#3156, ChromeDevTools#3158, ChromeDevTools#3161,
ChromeDevTools#3182, ChromeDevTools#3183, ChromeDevTools#3186, ChromeDevTools#3187, ChromeDevTools#3188, ChromeDevTools#3189, ChromeDevTools#3192, ChromeDevTools#3196, ChromeDevTools#3197, ChromeDevTools#3198,
ChromeDevTools#3203, ChromeDevTools#3204, and fixes ChromeDevTools#3150, ChromeDevTools#3160, ChromeDevTools#3185, ChromeDevTools#3202, ChromeDevTools#3207, ChromeDevTools#3208.

Existing content in `AGENTS.md` is unchanged.

Closes ChromeDevTools#3222
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

return all pages when click web element

3 participants