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
This commit is contained in:
Andrey Lushnikov 2017-07-28 00:06:57 -07:00
parent 0452644b83
commit d26e2399f2
4 changed files with 26 additions and 8 deletions

View File

@ -90,6 +90,7 @@
+ [frame.name()](#framename) + [frame.name()](#framename)
+ [frame.parentFrame()](#frameparentframe) + [frame.parentFrame()](#frameparentframe)
+ [frame.title()](#frametitle) + [frame.title()](#frametitle)
+ [frame.uploadFile(selector, ...filePaths)](#frameuploadfileselector-filepaths)
+ [frame.url()](#frameurl) + [frame.url()](#frameurl)
+ [frame.waitFor(selectorOrFunctionOrTimeout[, options])](#framewaitforselectororfunctionortimeout-options) + [frame.waitFor(selectorOrFunctionOrTimeout[, options])](#framewaitforselectororfunctionortimeout-options)
+ [frame.waitForFunction(pageFunction[, options, ...args])](#framewaitforfunctionpagefunction-options-args) + [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) #### page.uploadFile(selector, ...filePaths)
- `selector` <[string]> A query [selector] to a file input - `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. - returns: <[Promise]> Promise which resolves when the value is set.
#### page.url() #### page.url()
@ -900,6 +901,11 @@ Note: This value is calculated once when the frame is created, and will not upda
#### frame.title() #### frame.title()
- returns: <[Promise]<[string]>> Returns page's 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() #### frame.url()
- returns: <[string]> - returns: <[string]>

View File

@ -15,6 +15,7 @@
*/ */
let fs = require('fs'); let fs = require('fs');
let path = require('path');
let EventEmitter = require('events'); let EventEmitter = require('events');
let helper = require('./helper'); let helper = require('./helper');
@ -323,6 +324,21 @@ class Frame {
return new WaitTask(this, predicateCode, polling, timeout).promise; return new WaitTask(this, predicateCode, polling, timeout).promise;
} }
/**
* @param {string} selector
* @param {!Array<string>} 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 * @template T
* @param {string} selector * @param {string} selector

View File

@ -590,12 +590,7 @@ class Page extends EventEmitter {
* @return {!Promise} * @return {!Promise}
*/ */
async uploadFile(selector, ...filePaths) { async uploadFile(selector, ...filePaths) {
let expression = helper.evaluationString(selector => document.querySelector(selector), selector); return this.mainFrame().uploadFile(selector, ...filePaths);
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 });
} }
/** /**

View File

@ -875,7 +875,8 @@ describe('Puppeteer', function() {
})); }));
it('should upload the file', SX(async function(){ it('should upload the file', SX(async function(){
await page.navigate(PREFIX + '/input/fileupload.html'); 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(() => { expect(await page.evaluate(() => {
let input = document.querySelector('input'); let input = document.querySelector('input');
return input.files[0].name; return input.files[0].name;