FileChooser.ts (2447B)
1 /** 2 * @license 3 * Copyright 2020 Google Inc. 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 import type {ElementHandle} from '../api/ElementHandle.js'; 8 import {assert} from '../util/assert.js'; 9 10 /** 11 * File choosers let you react to the page requesting for a file. 12 * 13 * @remarks 14 * `FileChooser` instances are returned via the {@link Page.waitForFileChooser} method. 15 * 16 * In browsers, only one file chooser can be opened at a time. 17 * All file choosers must be accepted or canceled. Not doing so will prevent 18 * subsequent file choosers from appearing. 19 * 20 * @example 21 * 22 * ```ts 23 * const [fileChooser] = await Promise.all([ 24 * page.waitForFileChooser(), 25 * page.click('#upload-file-button'), // some button that triggers file selection 26 * ]); 27 * await fileChooser.accept(['/tmp/myfile.pdf']); 28 * ``` 29 * 30 * @public 31 */ 32 export class FileChooser { 33 #element: ElementHandle<HTMLInputElement>; 34 #multiple: boolean; 35 #handled = false; 36 37 /** 38 * @internal 39 */ 40 constructor(element: ElementHandle<HTMLInputElement>, multiple: boolean) { 41 this.#element = element; 42 this.#multiple = multiple; 43 } 44 45 /** 46 * Whether file chooser allow for 47 * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#attr-multiple | multiple} 48 * file selection. 49 */ 50 isMultiple(): boolean { 51 return this.#multiple; 52 } 53 54 /** 55 * Accept the file chooser request with the given file paths. 56 * 57 * @remarks This will not validate whether the file paths exists. Also, if a 58 * path is relative, then it is resolved against the 59 * {@link https://nodejs.org/api/process.html#process_process_cwd | current working directory}. 60 * For locals script connecting to remote chrome environments, paths must be 61 * absolute. 62 */ 63 async accept(paths: string[]): Promise<void> { 64 assert( 65 !this.#handled, 66 'Cannot accept FileChooser which is already handled!', 67 ); 68 this.#handled = true; 69 await this.#element.uploadFile(...paths); 70 } 71 72 /** 73 * Closes the file chooser without selecting any files. 74 */ 75 async cancel(): Promise<void> { 76 assert( 77 !this.#handled, 78 'Cannot cancel FileChooser which is already handled!', 79 ); 80 this.#handled = true; 81 // XXX: These events should converted to trusted events. Perhaps do this 82 // in `DOM.setFileInputFiles`? 83 await this.#element.evaluate(element => { 84 element.dispatchEvent(new Event('cancel', {bubbles: true})); 85 }); 86 } 87 }