feedback 1

This commit is contained in:
Max Schmitt 2024-06-06 23:27:13 +02:00
parent cfa92b479d
commit 4f72d983a7
7 changed files with 38 additions and 25 deletions

View file

@ -953,7 +953,7 @@ When all steps combined have not finished during the specified [`option: timeout
Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then they
are resolved relative to the current working directory. For empty array, clears the selected files.
In order to upload a directory (`[webkitdirectory]`) pass the path to the directory.
For inputs with a `[webkitdirectory]` attribute, only a single directory path is supported.
This method expects [ElementHandle] to point to an
[input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), targets the control instead.

View file

@ -2164,7 +2164,7 @@ When all steps combined have not finished during the specified [`option: timeout
* since: v1.14
Upload file or multiple files into `<input type=file>`.
In order to upload a directory (`[webkitdirectory]`) pass the path to the directory.
For inputs with a `[webkitdirectory]` attribute, only a single directory path is supported.
**Usage**

View file

@ -3927,7 +3927,7 @@ An object containing additional HTTP headers to be sent with every request. All
Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then they
are resolved relative to the current working directory. For empty array, clears the selected files.
In order to upload a directory (`[webkitdirectory]`) pass the path to the directory.
For inputs with a `[webkitdirectory]` attribute, only a single directory path is supported.
This method expects [`param: selector`] to point to an
[input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). However, if the element is inside the `<label>` element that has an associated [control](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/control), targets the control instead.

View file

@ -262,9 +262,9 @@ export async function convertInputFiles(files: string | FilePayload | string[] |
if (items.some(item => typeof item === 'string')) {
if (!items.every(item => typeof item === 'string'))
throw new Error('File paths cannot be mixed with buffers');
const directoryCount = (await Promise.all(items.map(async item => (await fs.promises.stat(item as string)).isDirectory()))).filter(Boolean).length;
if (directoryCount > 1)
throw new Error('Only one directory can be uploaded at a time');
const itemFileType = (await Promise.all(items.map(async item => (await fs.promises.stat(item as string)).isDirectory() ? 'directory' : 'file')));
if (new Set(itemFileType).size > 1 || itemFileType.filter(type => type === 'directory').length > 1)
throw new Error('File paths must be all files or a single directory');
if (context._connection.isRemote()) {
let streams: channels.WritableStreamChannel[] | undefined;

View file

@ -648,8 +648,8 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
fs.promises.access(localPath, fs.constants.F_OK)
)));
const isDirectoryUpload = localPaths.length === 1 ? (await fs.promises.stat(localPaths[0])).isDirectory() : false;
const waitForChangeEvent = isDirectoryUpload ? this.evaluateInUtility(([_, node]) => new Promise<any>(fulfil => {
node.addEventListener('change', fulfil, { once: true });
const waitForChangeEvent = isDirectoryUpload ? this.evaluateInUtility(([_, node]) => new Promise<any>(fulfill => {
node.addEventListener('change', fulfill, { once: true });
}), undefined) : Promise.resolve();
await this._page._delegate.setInputFilePaths(retargeted, localPaths);
await waitForChangeEvent;

View file

@ -4055,8 +4055,8 @@ export interface Page {
* instead. Read more about [locators](https://playwright.dev/docs/locators).
*
* Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then
* they are resolved relative to the current working directory. For empty array, clears the selected files. In order
* to upload a directory (`[webkitdirectory]`) pass the path to the directory.
* they are resolved relative to the current working directory. For empty array, clears the selected files. For inputs
* with a `[webkitdirectory]` attribute, only a single directory path is supported.
*
* This method expects `selector` to point to an
* [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). However, if the element is inside
@ -10580,8 +10580,8 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
* instead. Read more about [locators](https://playwright.dev/docs/locators).
*
* Sets the value of the file input to these file paths or files. If some of the `filePaths` are relative paths, then
* they are resolved relative to the current working directory. For empty array, clears the selected files. In order
* to upload a directory (`[webkitdirectory]`) pass the path to the directory.
* they are resolved relative to the current working directory. For empty array, clears the selected files. For inputs
* with a `[webkitdirectory]` attribute, only a single directory path is supported.
*
* This method expects {@link ElementHandle} to point to an
* [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). However, if the element is inside
@ -12788,8 +12788,8 @@ export interface Locator {
}): Promise<void>;
/**
* Upload file or multiple files into `<input type=file>`. In order to upload a directory (`[webkitdirectory]`) pass
* the path to the directory.
* Upload file or multiple files into `<input type=file>`. For inputs with a `[webkitdirectory]` attribute, only a
* single directory path is supported.
*
* **Usage**
*

View file

@ -37,20 +37,17 @@ it('should upload the file', async ({ page, server, asset }) => {
}, input)).toBe('contents of the file');
});
async function createTestDirectoryStructure() {
const baseDir = path.join(it.info().outputDir, 'file-upload-test');
await fs.promises.mkdir(baseDir, { recursive: true });
await fs.promises.writeFile(path.join(baseDir, 'file1.txt'), 'file1 content');
await fs.promises.writeFile(path.join(baseDir, 'file2'), 'file2 content');
await fs.promises.mkdir(path.join(baseDir, 'sub-dir'));
await fs.promises.writeFile(path.join(baseDir, 'sub-dir', 'really.txt'), 'sub-dir file content');
return baseDir;
}
it('should upload a folder', async ({ page, server, browserName, headless, browserMajorVersion }) => {
await page.goto(server.PREFIX + '/input/folderupload.html');
const input = await page.$('input');
const dir = await createTestDirectoryStructure();
const dir = path.join(it.info().outputDir, 'file-upload-test');
{
await fs.promises.mkdir(dir, { recursive: true });
await fs.promises.writeFile(path.join(dir, 'file1.txt'), 'file1 content');
await fs.promises.writeFile(path.join(dir, 'file2'), 'file2 content');
await fs.promises.mkdir(path.join(dir, 'sub-dir'));
await fs.promises.writeFile(path.join(dir, 'sub-dir', 'really.txt'), 'sub-dir file content');
}
await input.setInputFiles(dir);
expect(new Set(await page.evaluate(e => [...e.files].map(f => f.webkitRelativePath), input))).toEqual(new Set([
// https://issues.chromium.org/issues/345393164
@ -70,6 +67,22 @@ it('should upload a folder', async ({ page, server, browserName, headless, brows
}
});
it('should upload a folder and throw for multiple directories', async ({ page, server, browserName, headless, browserMajorVersion }) => {
await page.goto(server.PREFIX + '/input/folderupload.html');
const input = await page.$('input');
const dir = path.join(it.info().outputDir, 'file-upload-test');
{
await fs.promises.mkdir(path.join(dir, 'folder1'), { recursive: true });
await fs.promises.writeFile(path.join(dir, 'folder1', 'file1.txt'), 'file1 content');
await fs.promises.mkdir(path.join(dir, 'folder2'), { recursive: true });
await fs.promises.writeFile(path.join(dir, 'folder2', 'file2.txt'), 'file2 content');
}
await expect(input.setInputFiles([
path.join(dir, 'folder1'),
path.join(dir, 'folder2'),
])).rejects.toThrow('File paths must be all files or a single directory');
});
it('should upload a file after popup', async ({ page, server, asset }) => {
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/29923' });
await page.goto(server.PREFIX + '/input/fileupload.html');