chore: force localPaths to be resolved (#13544)
This commit is contained in:
parent
d44cfb93cb
commit
11179982fc
|
|
@ -284,7 +284,7 @@ export async function convertInputFiles(files: string | FilePayload | string[] |
|
|||
}));
|
||||
return { streams };
|
||||
}
|
||||
return { localPaths: items as string[] };
|
||||
return { localPaths: items.map(f => path.resolve(f as string)) as string[] };
|
||||
}
|
||||
|
||||
const filePayloads: SetInputFilesFiles = await Promise.all(items.map(async item => {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ import { JSHandleDispatcher, serializeResult, parseArgument } from './jsHandleDi
|
|||
import type { FrameDispatcher } from './frameDispatcher';
|
||||
import type { CallMetadata } from '../instrumentation';
|
||||
import type { WritableStreamDispatcher } from './writableStreamDispatcher';
|
||||
|
||||
import { assert } from '../../utils';
|
||||
import path from 'path';
|
||||
export class ElementHandleDispatcher extends JSHandleDispatcher implements channels.ElementHandleChannel {
|
||||
_type_ElementHandle = true;
|
||||
|
||||
|
|
@ -155,6 +156,8 @@ export class ElementHandleDispatcher extends JSHandleDispatcher implements chann
|
|||
throw new Error('Neither localPaths nor streams is specified');
|
||||
localPaths = params.streams.map(c => (c as WritableStreamDispatcher).path());
|
||||
}
|
||||
for (const p of localPaths)
|
||||
assert(path.isAbsolute(p) && path.resolve(p) === p, 'Paths provided to localPaths must be absolute and fully resolved.');
|
||||
return await this._elementHandle.setInputFiles(metadata, { localPaths }, params);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import type { ResponseDispatcher } from './networkDispatchers';
|
|||
import { RequestDispatcher } from './networkDispatchers';
|
||||
import type { CallMetadata } from '../instrumentation';
|
||||
import type { WritableStreamDispatcher } from './writableStreamDispatcher';
|
||||
import { assert } from '../../utils';
|
||||
import path from 'path';
|
||||
|
||||
export class FrameDispatcher extends Dispatcher<Frame, channels.FrameChannel> implements channels.FrameChannel {
|
||||
_type_Frame = true;
|
||||
|
|
@ -215,6 +217,8 @@ export class FrameDispatcher extends Dispatcher<Frame, channels.FrameChannel> im
|
|||
throw new Error('Neither localPaths nor streams is specified');
|
||||
localPaths = params.streams.map(c => (c as WritableStreamDispatcher).path());
|
||||
}
|
||||
for (const p of localPaths)
|
||||
assert(path.isAbsolute(p) && path.resolve(p) === p, 'Paths provided to localPaths must be absolute and fully resolved.');
|
||||
return await this._frame.setInputFiles(metadata, params.selector, { localPaths }, params);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,55 @@ it('should upload large file', async ({ page, server, browserName, isMac }, test
|
|||
await Promise.all([uploadFile, file1.filepath].map(fs.promises.unlink));
|
||||
});
|
||||
|
||||
it('should upload large file with relative path', async ({ page, server, browserName, isMac }, testInfo) => {
|
||||
it.skip(browserName === 'webkit' && isMac && parseInt(os.release(), 10) < 20, 'WebKit for macOS 10.15 is frozen and does not have corresponding protocol features.');
|
||||
it.slow();
|
||||
await page.goto(server.PREFIX + '/input/fileupload.html');
|
||||
const uploadFile = testInfo.outputPath('200MB.zip');
|
||||
const str = 'A'.repeat(4 * 1024);
|
||||
const stream = fs.createWriteStream(uploadFile);
|
||||
for (let i = 0; i < 50 * 1024; i++) {
|
||||
await new Promise<void>((fulfill, reject) => {
|
||||
stream.write(str, err => {
|
||||
if (err)
|
||||
reject(err);
|
||||
else
|
||||
fulfill();
|
||||
});
|
||||
});
|
||||
}
|
||||
await new Promise(f => stream.end(f));
|
||||
const input = page.locator('input[type="file"]');
|
||||
const events = await input.evaluateHandle(e => {
|
||||
const events = [];
|
||||
e.addEventListener('input', () => events.push('input'));
|
||||
e.addEventListener('change', () => events.push('change'));
|
||||
return events;
|
||||
});
|
||||
const relativeUploadPath = path.relative(process.cwd(), uploadFile);
|
||||
expect(path.isAbsolute(relativeUploadPath)).toBeFalsy();
|
||||
await input.setInputFiles(relativeUploadPath);
|
||||
expect(await input.evaluate(e => (e as HTMLInputElement).files[0].name)).toBe('200MB.zip');
|
||||
expect(await events.evaluate(e => e)).toEqual(['input', 'change']);
|
||||
const serverFilePromise = new Promise<formidable.File>(fulfill => {
|
||||
server.setRoute('/upload', async (req, res) => {
|
||||
const form = new formidable.IncomingForm({ uploadDir: testInfo.outputPath() });
|
||||
form.parse(req, function(err, fields, f) {
|
||||
res.end();
|
||||
const files = f as Record<string, formidable.File>;
|
||||
fulfill(files.file1);
|
||||
});
|
||||
});
|
||||
});
|
||||
const [file1] = await Promise.all([
|
||||
serverFilePromise,
|
||||
page.click('input[type=submit]')
|
||||
]);
|
||||
expect(file1.originalFilename).toBe('200MB.zip');
|
||||
expect(file1.size).toBe(200 * 1024 * 1024);
|
||||
await Promise.all([uploadFile, file1.filepath].map(fs.promises.unlink));
|
||||
});
|
||||
|
||||
it('should work @smoke', async ({ page, asset }) => {
|
||||
await page.setContent(`<input type=file>`);
|
||||
await page.setInputFiles('input', asset('file-to-upload.txt'));
|
||||
|
|
|
|||
Loading…
Reference in a new issue