fix(setInputFiles): make it work with CSP enabled (#3756)
We used to do fetch() to decode the file buffer. However, this is blocked by strict CSP policy. Instead, we can use explicit string -> bytes conversion, and trade performance for CSP compliance.
This commit is contained in:
parent
f232f34dae
commit
c190310335
|
|
@ -452,7 +452,7 @@ export class InjectedScript {
|
|||
throw new Error('Not a checkbox');
|
||||
}
|
||||
|
||||
async setInputFiles(node: Node, payloads: { name: string, mimeType: string, buffer: string }[]) {
|
||||
setInputFiles(node: Node, payloads: { name: string, mimeType: string, buffer: string }[]) {
|
||||
if (node.nodeType !== Node.ELEMENT_NODE)
|
||||
return 'Node is not of type HTMLElement';
|
||||
const element: Element | undefined = node as Element;
|
||||
|
|
@ -463,10 +463,10 @@ export class InjectedScript {
|
|||
if (type !== 'file')
|
||||
return 'Not an input[type=file] element';
|
||||
|
||||
const files = await Promise.all(payloads.map(async file => {
|
||||
const result = await fetch(`data:${file.mimeType};base64,${file.buffer}`);
|
||||
return new File([await result.blob()], file.name, {type: file.mimeType});
|
||||
}));
|
||||
const files = payloads.map(file => {
|
||||
const bytes = Uint8Array.from(atob(file.buffer), c => c.charCodeAt(0));
|
||||
return new File([bytes], file.name, { type: file.mimeType });
|
||||
});
|
||||
const dt = new DataTransfer();
|
||||
for (const file of files)
|
||||
dt.items.add(file);
|
||||
|
|
|
|||
|
|
@ -115,6 +115,15 @@ it('should work when file input is not attached to DOM', async ({page, server})
|
|||
expect(chooser).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should work with CSP', async ({page, server}) => {
|
||||
server.setCSP('/empty.html', 'default-src "none"');
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
await page.setContent(`<input type=file>`);
|
||||
await page.setInputFiles('input', path.join(__dirname, '/assets/file-to-upload.txt'));
|
||||
expect(await page.$eval('input', input => input.files.length)).toBe(1);
|
||||
expect(await page.$eval('input', input => input.files[0].name)).toBe('file-to-upload.txt');
|
||||
});
|
||||
|
||||
it('should respect timeout', async ({page, playwright}) => {
|
||||
let error = null;
|
||||
await page.waitForEvent('filechooser', {timeout: 1}).catch(e => error = e);
|
||||
|
|
|
|||
Loading…
Reference in a new issue