diff --git a/docs/tool-reference.md b/docs/tool-reference.md index f2d37c56..2e468bb2 100644 --- a/docs/tool-reference.md +++ b/docs/tool-reference.md @@ -172,7 +172,8 @@ **Parameters:** -- **pageIdx** (number) **(required)**: The index of the page to select. Call [`list_pages`](#list_pages) to list pages. +- **bringToFront** (boolean) _(optional)_: Whether to focus the page and bring it to the top. +- **pageIdx** (number) **(required)**: The index of the page to select. Call [`list_pages`](#list_pages) to get available pages. --- diff --git a/src/McpContext.ts b/src/McpContext.ts index b76c8d1e..11bb3d97 100644 --- a/src/McpContext.ts +++ b/src/McpContext.ts @@ -348,10 +348,16 @@ export class McpContext implements Context { const oldPage = this.#selectedPage; if (oldPage) { oldPage.off('dialog', this.#dialogHandler); + void oldPage.emulateFocusedPage(false).catch(error => { + this.logger('Error turning off focused page emulation', error); + }); } this.#selectedPage = newPage; newPage.on('dialog', this.#dialogHandler); this.#updateSelectedPageTimeouts(); + void newPage.emulateFocusedPage(true).catch(error => { + this.logger('Error turning on focused page emulation', error); + }); } #updateSelectedPageTimeouts() { diff --git a/src/tools/pages.ts b/src/tools/pages.ts index f4638860..96ab2cc0 100644 --- a/src/tools/pages.ts +++ b/src/tools/pages.ts @@ -34,14 +34,20 @@ export const selectPage = defineTool({ pageIdx: zod .number() .describe( - 'The index of the page to select. Call list_pages to list pages.', + `The index of the page to select. Call ${listPages.name} to get available pages.`, ), + bringToFront: zod + .boolean() + .optional() + .describe('Whether to focus the page and bring it to the top.'), }, handler: async (request, response, context) => { const page = context.getPageByIdx(request.params.pageIdx); - await page.bringToFront(); context.selectPage(page); response.setIncludePages(true); + if (request.params.bringToFront) { + await page.bringToFront(); + } }, }); diff --git a/tests/tools/pages.test.ts b/tests/tools/pages.test.ts index 76b99cb1..b10c1d9b 100644 --- a/tests/tools/pages.test.ts +++ b/tests/tools/pages.test.ts @@ -77,6 +77,23 @@ describe('pages', () => { assert.ok(response.includePages); }); }); + it('selects a page and keeps it focused in the background', async () => { + await withMcpContext(async (response, context) => { + await context.newPage(); + assert.strictEqual(context.getPageByIdx(1), context.getSelectedPage()); + assert.strictEqual( + await context.getPageByIdx(0).evaluate(() => document.hasFocus()), + false, + ); + await selectPage.handler({params: {pageIdx: 0}}, response, context); + assert.strictEqual(context.getPageByIdx(0), context.getSelectedPage()); + assert.strictEqual( + await context.getPageByIdx(0).evaluate(() => document.hasFocus()), + true, + ); + assert.ok(response.includePages); + }); + }); }); describe('navigate_page', () => { it('navigates to correct page', async () => {