From dca6e6b4555e2ff5091c70d026d194d59ef690ff Mon Sep 17 00:00:00 2001 From: alinavarkki Date: Tue, 30 Sep 2025 06:30:37 +0200 Subject: [PATCH 1/4] fix: snapshot does not capture Iframe content --- src/McpContext.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/McpContext.ts b/src/McpContext.ts index 713086760..57fab7941 100644 --- a/src/McpContext.ts +++ b/src/McpContext.ts @@ -302,7 +302,9 @@ export class McpContext implements Context { */ async createTextSnapshot(): Promise { const page = this.getSelectedPage(); - const rootNode = await page.accessibility.snapshot(); + const rootNode = await page.accessibility.snapshot({ + includeIframes: true, + }); if (!rootNode) { return; } From 7ae38f835efbbb5719fbc3fb4136bf64e3e6eb93 Mon Sep 17 00:00:00 2001 From: alinavarkki Date: Tue, 30 Sep 2025 07:37:38 +0200 Subject: [PATCH 2/4] add test --- src/tools/snapshot.ts | 11 +++++++---- tests/tools/snapshot.test.ts | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/tools/snapshot.ts b/src/tools/snapshot.ts index f84d6d44e..4aee4a56a 100644 --- a/src/tools/snapshot.ts +++ b/src/tools/snapshot.ts @@ -36,11 +36,14 @@ export const waitFor = defineTool({ }, handler: async (request, response, context) => { const page = context.getSelectedPage(); + const frames = page.frames(); - await Locator.race([ - page.locator(`aria/${request.params.text}`), - page.locator(`text/${request.params.text}`), - ]).wait(); + const locators = frames.flatMap(frame => [ + frame.locator(`aria/${request.params.text}`), + frame.locator(`text/${request.params.text}`), + ]); + + await Locator.race(locators).wait(); response.appendResponseLine( `Element with text "${request.params.text}" found.`, diff --git a/tests/tools/snapshot.test.ts b/tests/tools/snapshot.test.ts index a44a0bf29..085b11142 100644 --- a/tests/tools/snapshot.test.ts +++ b/tests/tools/snapshot.test.ts @@ -95,5 +95,33 @@ describe('snapshot', () => { assert.ok(response.includeSnapshot); }); }); + + + it('should work with iframe content', async () => { + await withBrowser(async (response, context) => { + const page = await context.getSelectedPage(); + + await page.setContent( + html`

Top level

+ `, + ); + + await waitFor.handler( + { + params: { + text: 'Hello iframe', + }, + }, + response, + context, + ); + + assert.equal( + response.responseLines[0], + 'Element with text "Hello iframe" found.', + ); + assert.ok(response.includeSnapshot); + }); + }); }); }); From c23e3c784162bad07f9eb41739edf585bb6bcc3e Mon Sep 17 00:00:00 2001 From: alinavarkki Date: Tue, 30 Sep 2025 07:51:44 +0200 Subject: [PATCH 3/4] format --- docs/tool-reference.md | 5 +++-- tests/tools/snapshot.test.ts | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tool-reference.md b/docs/tool-reference.md index 1b39e869a..d005e0af2 100644 --- a/docs/tool-reference.md +++ b/docs/tool-reference.md @@ -281,15 +281,16 @@ so returned values have to JSON-serializable. - **args** (array) _(optional)_: An optional list of arguments to pass to the function. - **function** (string) **(required)**: A JavaScript function to run in the currently selected page. - Example without arguments: `() => { +Example without arguments: `() => { return document.title }` or `async () => { return await fetch("example.com") }`. - Example with arguments: `(el) => { +Example with arguments: `(el) => { return el.innerText; }` + --- ### `list_console_messages` diff --git a/tests/tools/snapshot.test.ts b/tests/tools/snapshot.test.ts index 085b11142..31857ff5a 100644 --- a/tests/tools/snapshot.test.ts +++ b/tests/tools/snapshot.test.ts @@ -96,7 +96,6 @@ describe('snapshot', () => { }); }); - it('should work with iframe content', async () => { await withBrowser(async (response, context) => { const page = await context.getSelectedPage(); From 8f02bc0a3b735dd683ebebfe7a2fbe72016a5963 Mon Sep 17 00:00:00 2001 From: alinavarkki Date: Tue, 30 Sep 2025 08:52:08 +0200 Subject: [PATCH 4/4] format --- docs/tool-reference.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/tool-reference.md b/docs/tool-reference.md index d005e0af2..1b39e869a 100644 --- a/docs/tool-reference.md +++ b/docs/tool-reference.md @@ -281,16 +281,15 @@ so returned values have to JSON-serializable. - **args** (array) _(optional)_: An optional list of arguments to pass to the function. - **function** (string) **(required)**: A JavaScript function to run in the currently selected page. -Example without arguments: `() => { + Example without arguments: `() => { return document.title }` or `async () => { return await fetch("example.com") }`. -Example with arguments: `(el) => { + Example with arguments: `(el) => { return el.innerText; }` - --- ### `list_console_messages`