feedback 1
This commit is contained in:
parent
cfa92b479d
commit
4f72d983a7
|
|
@ -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
|
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.
|
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
|
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.
|
[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.
|
||||||
|
|
|
||||||
|
|
@ -2164,7 +2164,7 @@ When all steps combined have not finished during the specified [`option: timeout
|
||||||
* since: v1.14
|
* since: v1.14
|
||||||
|
|
||||||
Upload file or multiple files into `<input type=file>`.
|
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**
|
**Usage**
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
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.
|
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
|
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.
|
[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.
|
||||||
|
|
|
||||||
|
|
@ -262,9 +262,9 @@ export async function convertInputFiles(files: string | FilePayload | string[] |
|
||||||
if (items.some(item => typeof item === 'string')) {
|
if (items.some(item => typeof item === 'string')) {
|
||||||
if (!items.every(item => typeof item === 'string'))
|
if (!items.every(item => typeof item === 'string'))
|
||||||
throw new Error('File paths cannot be mixed with buffers');
|
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;
|
const itemFileType = (await Promise.all(items.map(async item => (await fs.promises.stat(item as string)).isDirectory() ? 'directory' : 'file')));
|
||||||
if (directoryCount > 1)
|
if (new Set(itemFileType).size > 1 || itemFileType.filter(type => type === 'directory').length > 1)
|
||||||
throw new Error('Only one directory can be uploaded at a time');
|
throw new Error('File paths must be all files or a single directory');
|
||||||
|
|
||||||
if (context._connection.isRemote()) {
|
if (context._connection.isRemote()) {
|
||||||
let streams: channels.WritableStreamChannel[] | undefined;
|
let streams: channels.WritableStreamChannel[] | undefined;
|
||||||
|
|
|
||||||
|
|
@ -648,8 +648,8 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||||
fs.promises.access(localPath, fs.constants.F_OK)
|
fs.promises.access(localPath, fs.constants.F_OK)
|
||||||
)));
|
)));
|
||||||
const isDirectoryUpload = localPaths.length === 1 ? (await fs.promises.stat(localPaths[0])).isDirectory() : false;
|
const isDirectoryUpload = localPaths.length === 1 ? (await fs.promises.stat(localPaths[0])).isDirectory() : false;
|
||||||
const waitForChangeEvent = isDirectoryUpload ? this.evaluateInUtility(([_, node]) => new Promise<any>(fulfil => {
|
const waitForChangeEvent = isDirectoryUpload ? this.evaluateInUtility(([_, node]) => new Promise<any>(fulfill => {
|
||||||
node.addEventListener('change', fulfil, { once: true });
|
node.addEventListener('change', fulfill, { once: true });
|
||||||
}), undefined) : Promise.resolve();
|
}), undefined) : Promise.resolve();
|
||||||
await this._page._delegate.setInputFilePaths(retargeted, localPaths);
|
await this._page._delegate.setInputFilePaths(retargeted, localPaths);
|
||||||
await waitForChangeEvent;
|
await waitForChangeEvent;
|
||||||
|
|
|
||||||
12
packages/playwright-core/types/types.d.ts
vendored
12
packages/playwright-core/types/types.d.ts
vendored
|
|
@ -4055,8 +4055,8 @@ export interface Page {
|
||||||
* instead. Read more about [locators](https://playwright.dev/docs/locators).
|
* 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
|
* 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
|
* they are resolved relative to the current working directory. For empty array, clears the selected files. For inputs
|
||||||
* to upload a directory (`[webkitdirectory]`) pass the path to the directory.
|
* with a `[webkitdirectory]` attribute, only a single directory path is supported.
|
||||||
*
|
*
|
||||||
* This method expects `selector` to point to an
|
* 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
|
* [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).
|
* 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
|
* 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
|
* they are resolved relative to the current working directory. For empty array, clears the selected files. For inputs
|
||||||
* to upload a directory (`[webkitdirectory]`) pass the path to the directory.
|
* with a `[webkitdirectory]` attribute, only a single directory path is supported.
|
||||||
*
|
*
|
||||||
* This method expects {@link ElementHandle} to point to an
|
* 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
|
* [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>;
|
}): Promise<void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upload file or multiple files into `<input type=file>`. In order to upload a directory (`[webkitdirectory]`) pass
|
* Upload file or multiple files into `<input type=file>`. For inputs with a `[webkitdirectory]` attribute, only a
|
||||||
* the path to the directory.
|
* single directory path is supported.
|
||||||
*
|
*
|
||||||
* **Usage**
|
* **Usage**
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -37,20 +37,17 @@ it('should upload the file', async ({ page, server, asset }) => {
|
||||||
}, input)).toBe('contents of the file');
|
}, 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 }) => {
|
it('should upload a folder', async ({ page, server, browserName, headless, browserMajorVersion }) => {
|
||||||
await page.goto(server.PREFIX + '/input/folderupload.html');
|
await page.goto(server.PREFIX + '/input/folderupload.html');
|
||||||
const input = await page.$('input');
|
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);
|
await input.setInputFiles(dir);
|
||||||
expect(new Set(await page.evaluate(e => [...e.files].map(f => f.webkitRelativePath), input))).toEqual(new Set([
|
expect(new Set(await page.evaluate(e => [...e.files].map(f => f.webkitRelativePath), input))).toEqual(new Set([
|
||||||
// https://issues.chromium.org/issues/345393164
|
// 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('should upload a file after popup', async ({ page, server, asset }) => {
|
||||||
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/29923' });
|
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/29923' });
|
||||||
await page.goto(server.PREFIX + '/input/fileupload.html');
|
await page.goto(server.PREFIX + '/input/fileupload.html');
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue