From 19c348d15b78d5288eedba621111935f9e952aac Mon Sep 17 00:00:00 2001 From: "Yury Semikhatskii (from Dev Box)" Date: Thu, 24 Sep 2026 15:40:39 -0700 Subject: [PATCH 1/4] fix(mcp): do not crash when download fails after browser close Fixes: https://github.com/microsoft/playwright/issues/42831 --- .../playwright-core/src/tools/backend/tab.ts | 3 +- tests/mcp/files.spec.ts | 42 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/packages/playwright-core/src/tools/backend/tab.ts b/packages/playwright-core/src/tools/backend/tab.ts index de61c443c4ed0..59e21d20fc365 100644 --- a/packages/playwright-core/src/tools/backend/tab.ts +++ b/packages/playwright-core/src/tools/backend/tab.ts @@ -137,7 +137,8 @@ export class Tab extends EventEmitter { eventsHelper.addEventListener(p, 'dialog', dialog => this._dialogShown(dialog)), eventsHelper.addEventListener(p, 'dialogclosed', dialog => this._dialogClosed(dialog)), eventsHelper.addEventListener(p, 'download', download => { - void this._downloadStarted(download); + // Download may fail or be interrupted by the browser closing, possibly after the context has been disposed. + this._downloadStarted(download).catch(e => debug('pw:tools:error')(e)); }), ]; // eslint-disable-next-line no-restricted-syntax diff --git a/tests/mcp/files.spec.ts b/tests/mcp/files.spec.ts index 8cc7ddaf9028e..5002cd85f86c0 100644 --- a/tests/mcp/files.spec.ts +++ b/tests/mcp/files.spec.ts @@ -198,6 +198,48 @@ test('navigating to download link emits download', async ({ startClient, server, }); }); +test('closing browser during download does not crash the server', async ({ startClient, server }, testInfo) => { + const { client } = await startClient({ + config: { outputDir: testInfo.outputPath('output') }, + }); + + server.setContent('/', `Download`, 'text/html'); + server.setRoute('/download', (req, res) => { + res.writeHead(200, { + 'Content-Type': 'application/octet-stream', + 'Content-Disposition': 'attachment; filename=test.txt', + }); + // Never finish the response so that the download stays in progress. + res.write('a'.repeat(4096)); + }); + + await client.callTool({ + name: 'browser_navigate', + arguments: { url: server.PREFIX }, + }); + let events = parseResponse(await client.callTool({ + name: 'browser_click', + arguments: { element: 'Download link', target: 'e2' }, + })).events ?? ''; + await expect.poll(async () => { + events += parseResponse(await client.callTool({ name: 'browser_snapshot' })).events ?? ''; + return events; + }).toContain('- Downloading file test.txt ...'); + + expect(await client.callTool({ name: 'browser_close' })).toHaveResponse({ + result: expect.stringContaining('No open tabs'), + }); + // Give the pending download a chance to fail after the browser is gone. + await new Promise(f => setTimeout(f, 1000)); + + expect(await client.callTool({ + name: 'browser_navigate', + arguments: { url: server.PREFIX }, + })).toHaveResponse({ + snapshot: expect.stringContaining(`- link "Download" [ref=e2]`), + }); +}); + test('file upload restricted to roots by default', async ({ startClient, server }, testInfo) => { const rootDir = testInfo.outputPath('workspace'); await fs.mkdir(rootDir, { recursive: true }); From 19c9e7263d84e57fbc7687cd75509ea521d2d9fb Mon Sep 17 00:00:00 2001 From: "Yury Semikhatskii (from Dev Box)" Date: Thu, 24 Sep 2026 15:49:42 -0700 Subject: [PATCH 2/4] chore: remove comment --- packages/playwright-core/src/tools/backend/tab.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/playwright-core/src/tools/backend/tab.ts b/packages/playwright-core/src/tools/backend/tab.ts index 59e21d20fc365..da326c2721a56 100644 --- a/packages/playwright-core/src/tools/backend/tab.ts +++ b/packages/playwright-core/src/tools/backend/tab.ts @@ -137,7 +137,6 @@ export class Tab extends EventEmitter { eventsHelper.addEventListener(p, 'dialog', dialog => this._dialogShown(dialog)), eventsHelper.addEventListener(p, 'dialogclosed', dialog => this._dialogClosed(dialog)), eventsHelper.addEventListener(p, 'download', download => { - // Download may fail or be interrupted by the browser closing, possibly after the context has been disposed. this._downloadStarted(download).catch(e => debug('pw:tools:error')(e)); }), ]; From 0a05fc1a269384cbf004a75ee43dcdc1d58d1755 Mon Sep 17 00:00:00 2001 From: "Yury Semikhatskii (from Dev Box)" Date: Thu, 24 Sep 2026 16:44:57 -0700 Subject: [PATCH 3/4] test(mcp): use isolated browser in download close test --- tests/mcp/files.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/mcp/files.spec.ts b/tests/mcp/files.spec.ts index 5002cd85f86c0..d08e3c89042e2 100644 --- a/tests/mcp/files.spec.ts +++ b/tests/mcp/files.spec.ts @@ -199,8 +199,9 @@ test('navigating to download link emits download', async ({ startClient, server, }); test('closing browser during download does not crash the server', async ({ startClient, server }, testInfo) => { + // Persistent Chromium on macOS does not quit while a download is in progress. const { client } = await startClient({ - config: { outputDir: testInfo.outputPath('output') }, + config: { outputDir: testInfo.outputPath('output'), browser: { isolated: true } }, }); server.setContent('/', `Download`, 'text/html'); From e927358c41ace2fbfc7869e24b88eb63860f26fd Mon Sep 17 00:00:00 2001 From: "Yury Semikhatskii (from Dev Box)" Date: Fri, 2 Oct 2026 15:59:57 -0700 Subject: [PATCH 4/4] test(webkit): screenshot webgl canvas after drawing buffer resize Fixes: https://github.com/microsoft/playwright/issues/42885 --- tests/page/page-screenshot.spec.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/page/page-screenshot.spec.ts b/tests/page/page-screenshot.spec.ts index 6daca69121e88..d22ebf4bc123e 100644 --- a/tests/page/page-screenshot.spec.ts +++ b/tests/page/page-screenshot.spec.ts @@ -401,6 +401,31 @@ it.describe('page screenshot', () => { expect(screenshot).toMatchSnapshot('screenshot-webgl.png'); }); + it('should capture webgl canvas after its drawing buffer is resized', async ({ page, browserName, platform }) => { + it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/42885' }); + it.skip(browserName === 'webkit' && platform === 'darwin' && os.arch() === 'x64', 'WebGL is not available on Intel macOS - https://bugs.webkit.org/show_bug.cgi?id=278277'); + + await page.setViewportSize({ width: 200, height: 200 }); + await page.setContent(`
`); + const expected = await page.screenshot(); + + await page.setContent(``); + await rafraf(page); + await page.evaluate(() => (window as any).draw(50)); + await rafraf(page); + expect(comparePNGs(await page.screenshot(), expected)).toBe(null); + }); + it('should work for translateZ', async ({ page, server }) => { await page.setViewportSize({ width: 500, height: 500 }); await page.goto(server.PREFIX + '/screenshots/translateZ.html');