Skip to content
16 changes: 16 additions & 0 deletions src/tools/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,22 @@ export const resizePage = defineTool({
handler: async (request, response, context) => {
const page = context.getSelectedPage();

try {
const browser = page.browser();
const windowId = await page.windowId();

const bounds = await browser.getWindowBounds(windowId);

if (bounds.windowState === 'fullscreen') {
// 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') {
await browser.setWindowBounds(windowId, {windowState: 'normal'});
}
} catch {
// Window APIs are not supported on all platforms
}
await page.resize({
contentWidth: request.params.width,
contentHeight: request.params.height,
Expand Down
129 changes: 128 additions & 1 deletion tests/tools/pages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,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(() => {
Expand All @@ -228,12 +228,139 @@ describe('pages', () => {
context,
);
await resizePromise;
await page.waitForFunction(
() => window.innerWidth === 700 && window.innerHeight === 500,
);
const dimensions = await page.evaluate(() => {
return [window.innerWidth, window.innerHeight];
});
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;
await page.waitForFunction(
() => window.innerWidth === 650 && window.innerHeight === 450,
);
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;
await page.waitForFunction(
() => window.innerWidth === 750 && window.innerHeight === 550,
);
const dimensions = await page.evaluate(() => {
return [window.innerWidth, window.innerHeight];
});
assert.deepStrictEqual(dimensions, [750, 550]);
});
});

it('resize when window state is maximized', async () => {
Comment thread
0xlakshan marked this conversation as resolved.
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: 725, height: 525}},
response,
context,
);
await resizePromise;
await page.waitForFunction(
() => window.innerWidth === 725 && window.innerHeight === 525,
);
const dimensions = await page.evaluate(() => {
return [window.innerWidth, window.innerHeight];
});
assert.deepStrictEqual(dimensions, [725, 525]);
});
});

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;
await page.waitForFunction(
() => window.innerWidth === 850 && window.innerHeight === 650,
);
const dimensions = await page.evaluate(() => {
return [window.innerWidth, window.innerHeight];
});
assert.deepStrictEqual(dimensions, [850, 650]);
});
});
});

describe('dialogs', () => {
Expand Down
1 change: 1 addition & 0 deletions tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down