diff --git a/packages/playwright-core/src/server/browserContext.ts b/packages/playwright-core/src/server/browserContext.ts index 404f94fe4f..c5a5c9a142 100644 --- a/packages/playwright-core/src/server/browserContext.ts +++ b/packages/playwright-core/src/server/browserContext.ts @@ -654,8 +654,13 @@ export function validateBrowserContextOptions(options: channels.BrowserNewContex throw new Error(`"deviceScaleFactor" option is not supported with null "viewport"`); if (options.noDefaultViewport && !!options.isMobile) throw new Error(`"isMobile" option is not supported with null "viewport"`); - if (options.acceptDownloads === undefined) + if (options.acceptDownloads === undefined && browserOptions.name !== 'electron') options.acceptDownloads = 'accept'; + // Electron requires explicit acceptDownloads: true since we wait for + // https://github.com/electron/electron/pull/41718 to be widely shipped. + // In 6-12 months, we can remove this check. + else if (options.acceptDownloads === undefined && browserOptions.name === 'electron') + options.acceptDownloads = 'internal-browser-default'; if (!options.viewport && !options.noDefaultViewport) options.viewport = { width: 1280, height: 720 }; if (options.recordVideo) { diff --git a/packages/playwright-core/src/server/chromium/crBrowser.ts b/packages/playwright-core/src/server/chromium/crBrowser.ts index 09a24c1d1b..254a86c164 100644 --- a/packages/playwright-core/src/server/chromium/crBrowser.ts +++ b/packages/playwright-core/src/server/chromium/crBrowser.ts @@ -348,7 +348,7 @@ export class CRBrowserContext extends BrowserContext { override async _initialize() { assert(!Array.from(this._browser._crPages.values()).some(page => page._browserContext === this)); const promises: Promise[] = [super._initialize()]; - if (this._browser.options.name !== 'electron' && this._browser.options.name !== 'clank' && this._options.acceptDownloads !== 'internal-browser-default') { + if (this._browser.options.name !== 'clank' && this._options.acceptDownloads !== 'internal-browser-default') { promises.push(this._browser._session.send('Browser.setDownloadBehavior', { behavior: this._options.acceptDownloads === 'accept' ? 'allowAndName' : 'deny', browserContextId: this._browserContextId, diff --git a/tests/electron/electron-app.spec.ts b/tests/electron/electron-app.spec.ts index 37bb69ea9e..caf7251261 100644 --- a/tests/electron/electron-app.spec.ts +++ b/tests/electron/electron-app.spec.ts @@ -314,3 +314,27 @@ test('should return app name / version from manifest', async ({ launchElectronAp version: '1.0.0' }); }); + +test('should report downloads', async ({ launchElectronApp, server }) => { + test.skip(parseInt(require('electron/package.json').version.split('.')[0], 10) < 30, 'Depends on https://github.com/electron/electron/pull/41718'); + + server.setRoute('/download', (req, res) => { + res.setHeader('Content-Type', 'application/octet-stream'); + res.setHeader('Content-Disposition', 'attachment'); + res.end(`Hello world`); + }); + + const app = await launchElectronApp('electron-window-app.js', [], { + acceptDownloads: true, + }); + const window = await app.firstWindow(); + await window.setContent(`download`); + const [download] = await Promise.all([ + window.waitForEvent('download'), + window.click('a') + ]); + const path = await download.path(); + expect(fs.existsSync(path)).toBeTruthy(); + expect(fs.readFileSync(path).toString()).toBe('Hello world'); + await app.close(); +});