diff --git a/lib/JSHandle.js b/lib/JSHandle.js index a15be538380f6..5465f5b158361 100644 --- a/lib/JSHandle.js +++ b/lib/JSHandle.js @@ -15,7 +15,6 @@ */ const {helper, assert, debugError} = require('./helper'); -const path = require('path'); function createJSHandle(context, remoteObject) { const frame = context.frame(); @@ -302,8 +301,8 @@ class ElementHandle extends JSHandle { if (option.selected && !element.multiple) break; } - element.dispatchEvent(new Event('input', { 'bubbles': true })); - element.dispatchEvent(new Event('change', { 'bubbles': true })); + element.dispatchEvent(new Event('input', { bubbles: true })); + element.dispatchEvent(new Event('change', { bubbles: true })); return options.filter(option => option.selected).map(option => option.value); }, values); } @@ -312,9 +311,35 @@ class ElementHandle extends JSHandle { * @param {!Array} filePaths */ async uploadFile(...filePaths) { - const files = filePaths.map(filePath => path.resolve(filePath)); - const objectId = this._remoteObject.objectId; - await this._client.send('DOM.setFileInputFiles', { objectId, files }); + // These imports are only needed for `uploadFile`, so keep them + // scoped here to avoid paying the cost unnecessarily. + const path = require('path'); + const mime = require('mime-types'); + const fs = require('fs'); + const readFileAsync = helper.promisify(fs.readFile); + + const promises = filePaths.map(filePath => readFileAsync(filePath)); + const files = []; + for (let i = 0; i < filePaths.length; i++) { + const buffer = await promises[i]; + const filePath = path.basename(filePaths[i]); + const file = { + name: filePath, + content: buffer.toString('base64'), + mimeType: mime.lookup(filePath), + }; + files.push(file); + } + await this.evaluateHandle(async(element, files) => { + const dt = new DataTransfer(); + for (const item of files) { + const response = await fetch(`data:${item.mimeType};base64,${item.content}`); + const file = new File([await response.blob()], item.name); + dt.items.add(file); + } + element.files = dt.files; + element.dispatchEvent(new Event('input', { bubbles: true })); + }, files); } async tap() { diff --git a/package.json b/package.json index 59f86165cba6f..f36d356dbcee4 100644 --- a/package.json +++ b/package.json @@ -30,10 +30,12 @@ "author": "The Chromium Authors", "license": "Apache-2.0", "dependencies": { + "@types/mime-types": "^2.1.0", "debug": "^4.1.0", "extract-zip": "^1.6.6", "https-proxy-agent": "^3.0.0", "mime": "^2.0.3", + "mime-types": "^2.1.25", "progress": "^2.0.1", "proxy-from-env": "^1.0.0", "rimraf": "^2.6.1",