fix: don't throw on bad access (#8472)

This commit is contained in:
jrandolf 2022-06-07 16:17:21 +02:00 committed by GitHub
parent e14256010d
commit e8378666c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 19 deletions

View File

@ -801,9 +801,12 @@ export class ElementHandle<
/** /**
* This method expects `elementHandle` to point to an * This method expects `elementHandle` to point to an
* {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input | input element}. * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input | input element}.
*
* @param filePaths - Sets the value of the file input to these paths. * @param filePaths - Sets the value of the file input to these paths.
* If some of the `filePaths` are relative paths, then they are resolved * If a path is relative, then it is resolved against the
* relative to the {@link https://nodejs.org/api/process.html#process_process_cwd | current working directory} * {@link https://nodejs.org/api/process.html#process_process_cwd | current working directory}.
* Note for locals script connecting to remote chrome environments,
* paths must be absolute.
*/ */
async uploadFile(...filePaths: string[]): Promise<void> { async uploadFile(...filePaths: string[]): Promise<void> {
const isMultiple = await this.evaluate<(element: Element) => boolean>( const isMultiple = await this.evaluate<(element: Element) => boolean>(
@ -829,21 +832,14 @@ export class ElementHandle<
avoid paying the cost unnecessarily. avoid paying the cost unnecessarily.
*/ */
const path = await import('path'); const path = await import('path');
const fs = await import('fs');
// Locate all files and confirm that they exist. // Locate all files and confirm that they exist.
const files = await Promise.all( const files = filePaths.map((filePath) => {
filePaths.map(async (filePath) => { if (path.isAbsolute(filePath)) {
const resolvedPath: string = path.resolve(filePath); return filePath;
try { } else {
await fs.promises.access(resolvedPath, fs.constants.R_OK); return path.resolve(filePath);
} catch (error) { }
if (error && (error as NodeJS.ErrnoException).code === 'ENOENT') });
throw new Error(`${filePath} does not exist or is not readable`);
}
return resolvedPath;
})
);
const { objectId } = this._remoteObject; const { objectId } = this._remoteObject;
const { node } = await this._client.send('DOM.describeNode', { objectId }); const { node } = await this._client.send('DOM.describeNode', { objectId });
const { backendNodeId } = node; const { backendNodeId } = node;

View File

@ -235,7 +235,7 @@ describe('input tests', function () {
.catch((error_) => (error = error_)); .catch((error_) => (error = error_));
expect(error).not.toBe(null); expect(error).not.toBe(null);
}); });
it('should fail for non-existent files', async () => { it('should succeed even for non-existent files', async () => {
const { page } = getTestState(); const { page } = getTestState();
await page.setContent(`<input type=file>`); await page.setContent(`<input type=file>`);
@ -243,11 +243,29 @@ describe('input tests', function () {
page.waitForFileChooser(), page.waitForFileChooser(),
page.click('input'), page.click('input'),
]); ]);
let error = null; let error: Error | undefined;
await chooser await chooser
.accept(['file-does-not-exist.txt']) .accept(['file-does-not-exist.txt'])
.catch((error_) => (error = error_)); .catch((error_) => (error = error_));
expect(error).not.toBe(null); expect(error).toBeUndefined();
});
it('should error on read of non-existent files', async () => {
const { page } = getTestState();
await page.setContent(`<input type=file>`);
page
.waitForFileChooser()
.then((chooser) => chooser.accept(['file-does-not-exist.txt']));
expect(
await page.$eval('input', async (picker: HTMLInputElement) => {
picker.click();
await new Promise((x) => (picker.oninput = x));
const reader = new FileReader();
const promise = new Promise((fulfill) => (reader.onerror = fulfill));
reader.readAsText(picker.files[0]);
return promise.then(() => false);
})
).toBeFalsy();
}); });
it('should fail when accepting file chooser twice', async () => { it('should fail when accepting file chooser twice', async () => {
const { page } = getTestState(); const { page } = getTestState();