fix: update file chooser events (#11057)
This commit is contained in:
parent
eb99509a3a
commit
317f82055b
@ -10,10 +10,10 @@ Closes the file chooser without selecting any files.
|
|||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
class FileChooser {
|
class FileChooser {
|
||||||
cancel(): void;
|
cancel(): Promise<void>;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Returns:**
|
**Returns:**
|
||||||
|
|
||||||
void
|
Promise<void>
|
||||||
|
@ -133,31 +133,38 @@ export class CdpElementHandle<
|
|||||||
return path.resolve(filePath);
|
return path.resolve(filePath);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const {node} = await this.client.send('DOM.describeNode', {
|
|
||||||
objectId: this.id,
|
|
||||||
});
|
|
||||||
const {backendNodeId} = node;
|
|
||||||
|
|
||||||
/* The zero-length array is a special case, it seems that
|
/**
|
||||||
DOM.setFileInputFiles does not actually update the files in that case,
|
* The zero-length array is a special case, it seems that
|
||||||
so the solution is to eval the element value to a new FileList directly.
|
* DOM.setFileInputFiles does not actually update the files in that case, so
|
||||||
|
* the solution is to eval the element value to a new FileList directly.
|
||||||
*/
|
*/
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
|
// XXX: These events should converted to trusted events. Perhaps do this
|
||||||
|
// in `DOM.setFileInputFiles`?
|
||||||
await this.evaluate(element => {
|
await this.evaluate(element => {
|
||||||
element.files = new DataTransfer().files;
|
element.files = new DataTransfer().files;
|
||||||
|
|
||||||
// Dispatch events for this case because it should behave akin to a user action.
|
// Dispatch events for this case because it should behave akin to a user action.
|
||||||
element.dispatchEvent(new Event('input', {bubbles: true}));
|
element.dispatchEvent(
|
||||||
|
new Event('input', {bubbles: true, composed: true})
|
||||||
|
);
|
||||||
element.dispatchEvent(new Event('change', {bubbles: true}));
|
element.dispatchEvent(new Event('change', {bubbles: true}));
|
||||||
});
|
});
|
||||||
} else {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
node: {backendNodeId},
|
||||||
|
} = await this.client.send('DOM.describeNode', {
|
||||||
|
objectId: this.id,
|
||||||
|
});
|
||||||
await this.client.send('DOM.setFileInputFiles', {
|
await this.client.send('DOM.setFileInputFiles', {
|
||||||
objectId: this.id,
|
objectId: this.id,
|
||||||
files,
|
files,
|
||||||
backendNodeId,
|
backendNodeId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@throwIfDisposed()
|
@throwIfDisposed()
|
||||||
override async autofill(data: AutofillData): Promise<void> {
|
override async autofill(data: AutofillData): Promise<void> {
|
||||||
|
@ -87,11 +87,16 @@ export class FileChooser {
|
|||||||
/**
|
/**
|
||||||
* Closes the file chooser without selecting any files.
|
* Closes the file chooser without selecting any files.
|
||||||
*/
|
*/
|
||||||
cancel(): void {
|
async cancel(): Promise<void> {
|
||||||
assert(
|
assert(
|
||||||
!this.#handled,
|
!this.#handled,
|
||||||
'Cannot cancel FileChooser which is already handled!'
|
'Cannot cancel FileChooser which is already handled!'
|
||||||
);
|
);
|
||||||
this.#handled = true;
|
this.#handled = true;
|
||||||
|
// XXX: These events should converted to trusted events. Perhaps do this
|
||||||
|
// in `DOM.setFileInputFiles`?
|
||||||
|
await this.#element.evaluate(element => {
|
||||||
|
element.dispatchEvent(new Event('cancel', {bubbles: true}));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,7 +358,7 @@ describe('input tests', function () {
|
|||||||
let error!: Error;
|
let error!: Error;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fileChooser.cancel();
|
await fileChooser.cancel();
|
||||||
} catch (error_) {
|
} catch (error_) {
|
||||||
error = error_ as Error;
|
error = error_ as Error;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user