From 0ba242c4063926340c944d75675e7662a79c8bf1 Mon Sep 17 00:00:00 2001 From: 0xluckycoder Date: Fri, 9 Jan 2026 23:57:20 +0530 Subject: [PATCH 01/10] window state --- src/tools/pages.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tools/pages.ts b/src/tools/pages.ts index cfdf99db0..bd6dbe28f 100644 --- a/src/tools/pages.ts +++ b/src/tools/pages.ts @@ -211,6 +211,12 @@ export const resizePage = defineTool({ handler: async (request, response, context) => { const page = context.getSelectedPage(); + const client = await page.createCDPSession(); + const {windowId} = await client.send('Browser.getWindowForTarget'); + const {bounds} = await client.send('Browser.getWindowBounds', { + windowId, + }); + await page.resize({ contentWidth: request.params.width, contentHeight: request.params.height, From ece0df98c37433c787a86bf9b68a462b0dd09beb Mon Sep 17 00:00:00 2001 From: 0xluckycoder Date: Sat, 10 Jan 2026 23:54:30 +0530 Subject: [PATCH 02/10] fixed --- src/tools/pages.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/tools/pages.ts b/src/tools/pages.ts index bd6dbe28f..0f27704eb 100644 --- a/src/tools/pages.ts +++ b/src/tools/pages.ts @@ -4,6 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +// import fs from 'node:fs'; +// import path from 'node:path'; + import {logger} from '../logger.js'; import {zod} from '../third_party/index.js'; @@ -217,6 +220,22 @@ export const resizePage = defineTool({ windowId, }); + if (bounds.windowState === 'fullscreen') { + // have to call this twice when window is in fullscreen mode + await client.send('Browser.setWindowBounds', { + windowId, + bounds: {windowState: 'normal'}, + }); + await client.send('Browser.setWindowBounds', { + windowId, + bounds: {windowState: 'normal'}, + }); + } else if (bounds.windowState !== 'normal') { + await client.send('Browser.setWindowBounds', { + windowId, + bounds: {windowState: 'normal'}, + }); + } await page.resize({ contentWidth: request.params.width, contentHeight: request.params.height, From 4716f7e53eb7a3d49f3460e0684edbcd23f9236f Mon Sep 17 00:00:00 2001 From: 0xluckycoder Date: Sun, 11 Jan 2026 00:10:44 +0530 Subject: [PATCH 03/10] remove trailing logs --- src/tools/pages.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/tools/pages.ts b/src/tools/pages.ts index 0f27704eb..26835360d 100644 --- a/src/tools/pages.ts +++ b/src/tools/pages.ts @@ -4,9 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -// import fs from 'node:fs'; -// import path from 'node:path'; - import {logger} from '../logger.js'; import {zod} from '../third_party/index.js'; From 01c7b803ed8fa0177ab414579aef560746cf71ec Mon Sep 17 00:00:00 2001 From: 0xluckycoder Date: Mon, 12 Jan 2026 03:52:56 +0530 Subject: [PATCH 04/10] remove CDP calls in favor of browser helpers --- src/tools/pages.ts | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/tools/pages.ts b/src/tools/pages.ts index 26835360d..6abaabe4b 100644 --- a/src/tools/pages.ts +++ b/src/tools/pages.ts @@ -211,27 +211,17 @@ export const resizePage = defineTool({ handler: async (request, response, context) => { const page = context.getSelectedPage(); - const client = await page.createCDPSession(); - const {windowId} = await client.send('Browser.getWindowForTarget'); - const {bounds} = await client.send('Browser.getWindowBounds', { - windowId, - }); + const browser = page.browser(); + const windowId = await page.windowId(); + + const bounds = await browser.getWindowBounds(windowId); if (bounds.windowState === 'fullscreen') { // have to call this twice when window is in fullscreen mode - await client.send('Browser.setWindowBounds', { - windowId, - bounds: {windowState: 'normal'}, - }); - await client.send('Browser.setWindowBounds', { - windowId, - bounds: {windowState: 'normal'}, - }); + await browser.setWindowBounds(windowId, {windowState: 'normal'}); + await browser.setWindowBounds(windowId, {windowState: 'normal'}); } else if (bounds.windowState !== 'normal') { - await client.send('Browser.setWindowBounds', { - windowId, - bounds: {windowState: 'normal'}, - }); + await browser.setWindowBounds(windowId, {windowState: 'normal'}); } await page.resize({ contentWidth: request.params.width, From bc2a1c0460cc075e55f96e717ea4052b8c370471 Mon Sep 17 00:00:00 2001 From: 0xluckycoder Date: Mon, 12 Jan 2026 03:54:19 +0530 Subject: [PATCH 05/10] test coverage for window resizing --- tests/tools/pages.test.ts | 114 +++++++++++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/tests/tools/pages.test.ts b/tests/tools/pages.test.ts index 46cbc2ad0..7709b4ff0 100644 --- a/tests/tools/pages.test.ts +++ b/tests/tools/pages.test.ts @@ -213,7 +213,7 @@ describe('pages', () => { }); }); describe('resize', () => { - it('create a page', async () => { + it('resize the page', async () => { await withMcpContext(async (response, context) => { const page = context.getSelectedPage(); const resizePromise = page.evaluate(() => { @@ -233,6 +233,118 @@ describe('pages', () => { assert.deepStrictEqual(dimensions, [700, 500]); }); }); + + it('resize when window state is normal', async () => { + await withMcpContext(async (response, context) => { + const page = context.getSelectedPage(); + const browser = page.browser(); + const windowId = await page.windowId(); + await browser.setWindowBounds(windowId, {windowState: 'normal'}); + + const {windowState} = await browser.getWindowBounds(windowId); + assert.strictEqual(windowState, 'normal'); + + const resizePromise = page.evaluate(() => { + return new Promise(resolve => { + window.addEventListener('resize', resolve, {once: true}); + }); + }); + await resizePage.handler( + {params: {width: 650, height: 450}}, + response, + context, + ); + await resizePromise; + const dimensions = await page.evaluate(() => { + return [window.innerWidth, window.innerHeight]; + }); + assert.deepStrictEqual(dimensions, [650, 450]); + }); + }); + + it('resize when window state is minimized', async () => { + await withMcpContext(async (response, context) => { + const page = context.getSelectedPage(); + const browser = page.browser(); + const windowId = await page.windowId(); + await browser.setWindowBounds(windowId, {windowState: 'minimized'}); + + const {windowState} = await browser.getWindowBounds(windowId); + assert.strictEqual(windowState, 'minimized'); + + const resizePromise = page.evaluate(() => { + return new Promise(resolve => { + window.addEventListener('resize', resolve, {once: true}); + }); + }); + await resizePage.handler( + {params: {width: 750, height: 550}}, + response, + context, + ); + await resizePromise; + const dimensions = await page.evaluate(() => { + return [window.innerWidth, window.innerHeight]; + }); + assert.deepStrictEqual(dimensions, [750, 550]); + }); + }); + + it('resize when window state is maximized', async () => { + await withMcpContext(async (response, context) => { + const page = context.getSelectedPage(); + const browser = page.browser(); + const windowId = await page.windowId(); + await browser.setWindowBounds(windowId, {windowState: 'maximized'}); + + const {windowState} = await browser.getWindowBounds(windowId); + assert.strictEqual(windowState, 'maximized'); + + const resizePromise = page.evaluate(() => { + return new Promise(resolve => { + window.addEventListener('resize', resolve, {once: true}); + }); + }); + await resizePage.handler( + {params: {width: 800, height: 600}}, + response, + context, + ); + await resizePromise; + const dimensions = await page.evaluate(() => { + return [window.innerWidth, window.innerHeight]; + }); + assert.deepStrictEqual(dimensions, [800, 600]); + }); + }); + + it('resize when window state is fullscreen', async () => { + await withMcpContext(async (response, context) => { + const page = context.getSelectedPage(); + const browser = page.browser(); + const windowId = await page.windowId(); + await browser.setWindowBounds(windowId, {windowState: 'fullscreen'}); + + const {windowState} = await browser.getWindowBounds(windowId); + assert.strictEqual(windowState, 'fullscreen'); + + const resizePromise = page.evaluate(() => { + return new Promise(resolve => { + window.addEventListener('resize', resolve, {once: true}); + }); + }); + await resizePage.handler( + {params: {width: 850, height: 650}}, + response, + context, + ); + await resizePromise; + const dimensions = await page.evaluate(() => { + return [window.innerWidth, window.innerHeight]; + }); + assert.deepStrictEqual(dimensions, [850, 650]); + }); + }); }); describe('dialogs', () => { From 69af2165dd71370f0bbcd97bf1ebd5ee8e2b9f3e Mon Sep 17 00:00:00 2001 From: 0xluckycoder Date: Mon, 12 Jan 2026 16:50:32 +0530 Subject: [PATCH 06/10] handle unsupported window APIs --- src/tools/pages.ts | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/tools/pages.ts b/src/tools/pages.ts index 6abaabe4b..92f3eb8f9 100644 --- a/src/tools/pages.ts +++ b/src/tools/pages.ts @@ -211,17 +211,21 @@ export const resizePage = defineTool({ handler: async (request, response, context) => { const page = context.getSelectedPage(); - const browser = page.browser(); - const windowId = await page.windowId(); + try { + const browser = page.browser(); + const windowId = await page.windowId(); - const bounds = await browser.getWindowBounds(windowId); + const bounds = await browser.getWindowBounds(windowId); - if (bounds.windowState === 'fullscreen') { - // have to call this twice when window is in fullscreen mode - await browser.setWindowBounds(windowId, {windowState: 'normal'}); - await browser.setWindowBounds(windowId, {windowState: 'normal'}); - } else if (bounds.windowState !== 'normal') { - await browser.setWindowBounds(windowId, {windowState: 'normal'}); + if (bounds.windowState === 'fullscreen') { + // have to call this twice when window is in fullscreen mode + await browser.setWindowBounds(windowId, {windowState: 'normal'}); + await browser.setWindowBounds(windowId, {windowState: 'normal'}); + } else if (bounds.windowState !== 'normal') { + await browser.setWindowBounds(windowId, {windowState: 'normal'}); + } + } catch { + // Window APIs are not supported on all platforms } await page.resize({ contentWidth: request.params.width, From f486e01884d68735a0f989ce44cce7bb7cbab822 Mon Sep 17 00:00:00 2001 From: Lakshan Perera <39025880+0xlakshan@users.noreply.github.com> Date: Mon, 12 Jan 2026 17:05:16 +0530 Subject: [PATCH 07/10] update comment Co-authored-by: Alex Rudenko --- src/tools/pages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pages.ts b/src/tools/pages.ts index 92f3eb8f9..df37254be 100644 --- a/src/tools/pages.ts +++ b/src/tools/pages.ts @@ -218,7 +218,7 @@ export const resizePage = defineTool({ const bounds = await browser.getWindowBounds(windowId); if (bounds.windowState === 'fullscreen') { - // have to call this twice when window is in fullscreen mode + // Have to call this twice on Ubuntu when the window is in fullscreen mode. await browser.setWindowBounds(windowId, {windowState: 'normal'}); await browser.setWindowBounds(windowId, {windowState: 'normal'}); } else if (bounds.windowState !== 'normal') { From 900be6326c30ff3a43984c465686be4993eb07a0 Mon Sep 17 00:00:00 2001 From: 0xluckycoder Date: Mon, 12 Jan 2026 23:33:06 +0530 Subject: [PATCH 08/10] keep dimensions below clamp threshold --- tests/tools/pages.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tools/pages.test.ts b/tests/tools/pages.test.ts index ad5a63a99..f92002c52 100644 --- a/tests/tools/pages.test.ts +++ b/tests/tools/pages.test.ts @@ -307,7 +307,7 @@ describe('pages', () => { }); }); await resizePage.handler( - {params: {width: 800, height: 600}}, + {params: {width: 725, height: 525}}, response, context, ); @@ -315,7 +315,7 @@ describe('pages', () => { const dimensions = await page.evaluate(() => { return [window.innerWidth, window.innerHeight]; }); - assert.deepStrictEqual(dimensions, [800, 600]); + assert.deepStrictEqual(dimensions, [725, 525]); }); }); From e3fce117c06fe2d9f6e8c22f7e04ce6ce906b39d Mon Sep 17 00:00:00 2001 From: 0xluckycoder Date: Tue, 13 Jan 2026 01:15:07 +0530 Subject: [PATCH 09/10] add --screen-info arg for test browser --- tests/utils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/utils.ts b/tests/utils.ts index 6e480ffbb..1c73fc5be 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -55,6 +55,7 @@ export async function withBrowser( devtools: options.autoOpenDevTools ?? false, pipe: true, handleDevToolsAsPage: true, + args: ['--screen-info={3840x2160}'], }; const key = JSON.stringify(launchOptions); From 263c26072d407b6088710acf3ae4e3a7243df945 Mon Sep 17 00:00:00 2001 From: 0xluckycoder Date: Tue, 13 Jan 2026 21:33:10 +0530 Subject: [PATCH 10/10] wait until window size is set --- tests/tools/pages.test.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/tools/pages.test.ts b/tests/tools/pages.test.ts index f92002c52..7bf7e747d 100644 --- a/tests/tools/pages.test.ts +++ b/tests/tools/pages.test.ts @@ -228,6 +228,9 @@ describe('pages', () => { context, ); await resizePromise; + await page.waitForFunction( + () => window.innerWidth === 700 && window.innerHeight === 500, + ); const dimensions = await page.evaluate(() => { return [window.innerWidth, window.innerHeight]; }); @@ -256,6 +259,9 @@ describe('pages', () => { context, ); await resizePromise; + await page.waitForFunction( + () => window.innerWidth === 650 && window.innerHeight === 450, + ); const dimensions = await page.evaluate(() => { return [window.innerWidth, window.innerHeight]; }); @@ -284,6 +290,9 @@ describe('pages', () => { context, ); await resizePromise; + await page.waitForFunction( + () => window.innerWidth === 750 && window.innerHeight === 550, + ); const dimensions = await page.evaluate(() => { return [window.innerWidth, window.innerHeight]; }); @@ -312,6 +321,9 @@ describe('pages', () => { context, ); await resizePromise; + await page.waitForFunction( + () => window.innerWidth === 725 && window.innerHeight === 525, + ); const dimensions = await page.evaluate(() => { return [window.innerWidth, window.innerHeight]; }); @@ -340,6 +352,9 @@ describe('pages', () => { context, ); await resizePromise; + await page.waitForFunction( + () => window.innerWidth === 850 && window.innerHeight === 650, + ); const dimensions = await page.evaluate(() => { return [window.innerWidth, window.innerHeight]; });