diff --git a/docs/api.md b/docs/api.md index 0d8f3a3ec3b4d..27f757a5bab9b 100644 --- a/docs/api.md +++ b/docs/api.md @@ -3215,7 +3215,7 @@ Returns download error if any. Returns path to the downloaded file in case of successful download. #### download.saveAs(path) -- `path` <[string]> Path where the download should be saved. The directory structure MUST exist as `saveAs` will not create it. +- `path` <[string]> Path where the download should be saved. - returns: <[Promise]> Saves the download to a user-specified path. diff --git a/src/download.ts b/src/download.ts index 60969e379e238..cc1c450ff81be 100644 --- a/src/download.ts +++ b/src/download.ts @@ -92,6 +92,8 @@ export class Download { async _saveAs(downloadPath: string) { const fileName = path.join(this._downloadsPath, this._uuid); + // This will harmlessly throw on windows if the dirname is the root directory. + await util.promisify(fs.mkdir)(path.dirname(downloadPath), {recursive: true}).catch(() => {}); await util.promisify(fs.copyFile)(fileName, downloadPath); } diff --git a/test/download.jest.js b/test/download.jest.js index 6934fbc3ff910..7d69f7b97e3a8 100644 --- a/test/download.jest.js +++ b/test/download.jest.js @@ -134,19 +134,17 @@ describe('Download', function() { expect(fs.readFileSync(userPath).toString()).toBe('Hello world'); await page.close(); }); - it('should error when saving to non-existent user-specified path', async({persistentDirectory, browser, server}) => { + it('should create subdirectories when saving to non-existent user-specified path', async({persistentDirectory, browser, server}) => { const page = await browser.newPage({ acceptDownloads: true }); await page.setContent(`download`); const [ download ] = await Promise.all([ page.waitForEvent('download'), page.click('a') ]); - const nonExistentUserPath = path.join(persistentDirectory, "does-not-exist","download.txt"); - const { message } = await download.saveAs(nonExistentUserPath).catch(e => e); - expect(message).toContain('ENOENT'); - expect(message).toContain('copyfile'); - expect(message).toContain('no such file or directory'); - expect(message).toContain('does-not-exist'); + const nestedPath = path.join(persistentDirectory, "these", "are", "directories", "download.txt"); + await download.saveAs(nestedPath) + expect(fs.existsSync(nestedPath)).toBeTruthy(); + expect(fs.readFileSync(nestedPath).toString()).toBe('Hello world'); await page.close(); }); it('should error when saving with downloads disabled', async({persistentDirectory, browser, server}) => {