diff --git a/packages/playwright-core/src/server/chromium/chromium.ts b/packages/playwright-core/src/server/chromium/chromium.ts index bb7203a368..f4a7b0d12d 100644 --- a/packages/playwright-core/src/server/chromium/chromium.ts +++ b/packages/playwright-core/src/server/chromium/chromium.ts @@ -45,6 +45,7 @@ import http from 'http'; import https from 'https'; import { registry } from '../registry'; import { ManualPromise } from '../../utils/manualPromise'; +import { validateBrowserContextOptions } from '../browserContext'; const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-'); @@ -93,12 +94,13 @@ export class Chromium extends BrowserType { await cleanedUp; }; const browserProcess: BrowserProcess = { close: doClose, kill: doClose }; + const persistent: types.BrowserContextOptions = { noDefaultViewport: true }; const browserOptions: BrowserOptions = { ...this._playwrightOptions, slowMo: options.slowMo, name: 'chromium', isChromium: true, - persistent: { noDefaultViewport: true }, + persistent, browserProcess, protocolLogger: helper.debugProtocolLogger(), browserLogsCollector: new RecentLogsCollector(), @@ -112,6 +114,7 @@ export class Chromium extends BrowserType { // does not work at all with proxies on Windows. proxy: { server: 'per-context' }, }; + validateBrowserContextOptions(persistent, browserOptions); progress.throwIfAborted(); const browser = await CRBrowser.connect(chromeTransport, browserOptions); browser.on(Browser.Events.Disconnected, doCleanup); diff --git a/tests/library/chromium/chromium.spec.ts b/tests/library/chromium/chromium.spec.ts index bb6f08bfe0..fd0900c130 100644 --- a/tests/library/chromium/chromium.spec.ts +++ b/tests/library/chromium/chromium.spec.ts @@ -133,6 +133,44 @@ playwrightTest('should cleanup artifacts dir after connectOverCDP disconnects du expect(exists2).toBe(false); }); +playwrightTest('should connectOverCDP and manage downloads in default context', async ({ browserType, toImpl, mode, server }, testInfo) => { + playwrightTest.skip(mode !== 'default'); + + server.setRoute('/downloadWithFilename', (req, res) => { + res.setHeader('Content-Type', 'application/octet-stream'); + res.setHeader('Content-Disposition', 'attachment; filename=file.txt'); + res.end(`Hello world`); + }); + + const port = 9339 + testInfo.workerIndex; + const browserServer = await browserType.launch({ + args: ['--remote-debugging-port=' + port] + }); + + try { + const browser = await browserType.connectOverCDP({ + endpointURL: `http://127.0.0.1:${port}/`, + }); + const page = await browser.contexts()[0].newPage(); + await page.setContent(`download`); + + const [ download ] = await Promise.all([ + page.waitForEvent('download'), + page.click('a') + ]); + expect(download.page()).toBe(page); + expect(download.url()).toBe(`${server.PREFIX}/downloadWithFilename`); + expect(download.suggestedFilename()).toBe(`file.txt`); + + const userPath = testInfo.outputPath('download.txt'); + await download.saveAs(userPath); + expect(fs.existsSync(userPath)).toBeTruthy(); + expect(fs.readFileSync(userPath).toString()).toBe('Hello world'); + } finally { + await browserServer.close(); + } +}); + playwrightTest('should connect to an existing cdp session twice', async ({ browserType, server }, testInfo) => { const port = 9339 + testInfo.workerIndex; const browserServer = await browserType.launch({