33 * Copyright 2025 Google LLC
44 * SPDX-License-Identifier: Apache-2.0
55 */
6- import type { JSHandle } from 'puppeteer-core' ;
6+ import type { Frame , JSHandle , Page } from 'puppeteer-core' ;
77
88import { zod } from '../third_party/modelcontextprotocol-sdk/index.js' ;
99
@@ -45,15 +45,29 @@ Example with arguments: \`(el) => {
4545 . describe ( `An optional list of arguments to pass to the function.` ) ,
4646 } ,
4747 handler : async ( request , response , context ) => {
48- const page = context . getSelectedPage ( ) ;
49- const fn = await page . evaluateHandle ( `(${ request . params . function } )` ) ;
50- const args : Array < JSHandle < unknown > > = [ fn ] ;
48+ const args : Array < JSHandle < unknown > > = [ ] ;
5149 try {
50+ const frames = new Set < Frame > ( ) ;
5251 for ( const el of request . params . args ?? [ ] ) {
53- args . push ( await context . getElementByUid ( el . uid ) ) ;
52+ const handle = await context . getElementByUid ( el . uid ) ;
53+ frames . add ( handle . frame ) ;
54+ args . push ( handle ) ;
5455 }
56+ let pageOrFrame : Page | Frame ;
57+ // We can't evaluate the element handle across frames
58+ if ( frames . size > 1 ) {
59+ throw new Error (
60+ "Elements from different frames can't be evaluated together." ,
61+ ) ;
62+ } else {
63+ pageOrFrame = [ ...frames . values ( ) ] [ 0 ] ?? context . getSelectedPage ( ) ;
64+ }
65+ const fn = await pageOrFrame . evaluateHandle (
66+ `(${ request . params . function } )` ,
67+ ) ;
68+ args . unshift ( fn ) ;
5569 await context . waitForEventsAfterAction ( async ( ) => {
56- const result = await page . evaluate (
70+ const result = await pageOrFrame . evaluate (
5771 async ( fn , ...args ) => {
5872 // @ts -expect-error no types.
5973 return JSON . stringify ( await fn ( ...args ) ) ;
@@ -66,9 +80,7 @@ Example with arguments: \`(el) => {
6680 response . appendResponseLine ( '```' ) ;
6781 } ) ;
6882 } finally {
69- Promise . allSettled ( args . map ( arg => arg . dispose ( ) ) ) . catch ( ( ) => {
70- // Ignore errors
71- } ) ;
83+ void Promise . allSettled ( args . map ( arg => arg . dispose ( ) ) ) ;
7284 }
7385 } ,
7486} ) ;
0 commit comments