From d26e2399f267164b45746c92f26a0e6ad05e7c4a Mon Sep 17 00:00:00 2001 From: Andrey Lushnikov Date: Fri, 28 Jul 2017 00:06:57 -0700 Subject: [PATCH] Resolve paths against CWD in page.uploadFile() method This patch: - teaches page.uploadFile() to resolve given file paths against current working directory. This aligns paths handling with all the other methods - moves page.uploadFile() under Frame - changes test to use relative path for file upload --- docs/api.md | 8 +++++++- lib/FrameManager.js | 16 ++++++++++++++++ lib/Page.js | 7 +------ test/test.js | 3 ++- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/docs/api.md b/docs/api.md index 3381ac12..abac963b 100644 --- a/docs/api.md +++ b/docs/api.md @@ -90,6 +90,7 @@ + [frame.name()](#framename) + [frame.parentFrame()](#frameparentframe) + [frame.title()](#frametitle) + + [frame.uploadFile(selector, ...filePaths)](#frameuploadfileselector-filepaths) + [frame.url()](#frameurl) + [frame.waitFor(selectorOrFunctionOrTimeout[, options])](#framewaitforselectororfunctionortimeout-options) + [frame.waitForFunction(pageFunction[, options, ...args])](#framewaitforfunctionpagefunction-options-args) @@ -630,7 +631,7 @@ To press a special key, use [`page.press`](#pagepresskey-options). #### page.uploadFile(selector, ...filePaths) - `selector` <[string]> A query [selector] to a file input -- `...filePaths` <[string]> Sets the value of the file input these paths +- `...filePaths` <[string]> Sets the value of the file input these paths. If some of the `filePaths` are relative paths, then they are resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). - returns: <[Promise]> Promise which resolves when the value is set. #### page.url() @@ -900,6 +901,11 @@ Note: This value is calculated once when the frame is created, and will not upda #### frame.title() - returns: <[Promise]<[string]>> Returns page's title. +#### frame.uploadFile(selector, ...filePaths) +- `selector` <[string]> A query [selector] to a file input +- `...filePaths` <[string]> Sets the value of the file input these paths. If some of the `filePaths` are relative paths, then they are resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). +- returns: <[Promise]> Promise which resolves when the value is set. + #### frame.url() - returns: <[string]> diff --git a/lib/FrameManager.js b/lib/FrameManager.js index fcd8264c..9ef74a23 100644 --- a/lib/FrameManager.js +++ b/lib/FrameManager.js @@ -15,6 +15,7 @@ */ let fs = require('fs'); +let path = require('path'); let EventEmitter = require('events'); let helper = require('./helper'); @@ -323,6 +324,21 @@ class Frame { return new WaitTask(this, predicateCode, polling, timeout).promise; } + /** + * @param {string} selector + * @param {!Array} filePaths + * @return {!Promise} + */ + async uploadFile(selector, ...filePaths) { + let expression = helper.evaluationString(selector => document.querySelector(selector), selector); + const {result} = await this._client.send('Runtime.evaluate', { expression }); + if (!result) + return; + const objectId = result.objectId; + filePaths = filePaths.map(filePath => path.resolve(filePath)); + return this._client.send('DOM.setFileInputFiles', { objectId, files: filePaths }); + } + /** * @template T * @param {string} selector diff --git a/lib/Page.js b/lib/Page.js index 50c5fc19..6cabff24 100644 --- a/lib/Page.js +++ b/lib/Page.js @@ -590,12 +590,7 @@ class Page extends EventEmitter { * @return {!Promise} */ async uploadFile(selector, ...filePaths) { - let expression = helper.evaluationString(selector => document.querySelector(selector), selector); - const {result} = await this._client.send('Runtime.evaluate', { expression }); - if (!result) - return; - const objectId = result.objectId; - return this._client.send('DOM.setFileInputFiles', { objectId, files: filePaths }); + return this.mainFrame().uploadFile(selector, ...filePaths); } /** diff --git a/test/test.js b/test/test.js index b78bc7bd..e7041e80 100644 --- a/test/test.js +++ b/test/test.js @@ -875,7 +875,8 @@ describe('Puppeteer', function() { })); it('should upload the file', SX(async function(){ await page.navigate(PREFIX + '/input/fileupload.html'); - await page.uploadFile('input', __dirname + '/assets/file-to-upload.txt'); + const filePath = path.relative(process.cwd(), __dirname + '/assets/file-to-upload.txt'); + await page.uploadFile('input', filePath); expect(await page.evaluate(() => { let input = document.querySelector('input'); return input.files[0].name;