Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/playwright-core/src/tools/backend/tab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export class Tab extends EventEmitter<TabEventsInterface> {
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);
this._downloadStarted(download).catch(e => debug('pw:tools:error')(e));
}),
];
// eslint-disable-next-line no-restricted-syntax
Expand Down
43 changes: 43 additions & 0 deletions tests/mcp/files.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,49 @@ 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'), browser: { isolated: true } },
});

server.setContent('/', `<a href="/download" download="test.txt">Download</a>`, '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 });
Expand Down
25 changes: 25 additions & 0 deletions tests/page/page-screenshot.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(`<body style="margin:0"><div style="width:100px;height:100px;background:rgb(0,255,0)"></div></body>`);
const expected = await page.screenshot();

await page.setContent(`<body style="margin:0"><canvas style="width:100px;height:100px"></canvas><script>
const gl = document.querySelector('canvas').getContext('webgl');
window.draw = size => {
gl.canvas.width = size;
gl.canvas.height = size;
gl.viewport(0, 0, size, size);
gl.clearColor(0, 1, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
};
draw(100);
</script></body>`);
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');
Expand Down
Loading