剧作家:从不能使用的非输入元素上传文件page.setInputFiles?



我正在通过剧作家的非输入HTML标签上传文件。

例如,您可以像这样使用setInputFiles,这是有效的:

await page.setInputFiles('input[type="file"]', './headphone.png')

但显然setInputFiles只适用于输入元素,像这样的东西将是错误的:

await page.setInputFiles('label.ImageUpload__label ', './headphone.png');

我正在处理的HTML是这样的:

<div id="ImageUpload" class="ImageUpload u-marginB10">
<label class="ImageUpload__label js-dragdrop-area" for="selectFileMultiple">
<span class="ImageUpload__hide">drag and drop or select files</span>
<span class="ImageUpload__text"><span class="js-dragdrop-num">10</span>up to</span>
</label>
</div>

那么,是否有可能将文件上传到这样的HTML元素与剧作家?

NodeJs: https://playwright.dev/docs/api/class-filechooser

page.on("filechooser", (fileChooser: FileChooser) => {
fileChooser.setFiles(["/path/to/a/file"]);
})

Python: https://playwright.dev/python/docs/api/class-filechooser/

with page.expect_file_chooser() as fc_info:
page.click("upload")
file_chooser = fc_info.value
file_chooser.set_files("/path/to/a/file")

Java: https://playwright.dev/java/docs/api/class-filechooser

FileChooser fileChooser = page.waitForFileChooser(() -> 
page.click("upload"));
fileChooser.setFiles(Paths.get("myfile.pdf"));

使用setInputFiles(selector, files[, options])函数上传文件。此方法接受输入元素的选择器和要上传的文件的路径。

"files"参数可以是相对路径(相对于当前工作目录),也可以是绝对路径。我强烈建议您使用绝对路径来确保可预测的行为。

test("upload a file", async ({ page }) => {
console.log(resolve(__dirname, "bar.png"));
await page.goto("http://127.0.0.1:8080/upload-file/");
await page.locator('input[name="foo"]').click();
await page
.locator('input[name="foo"]')
.setInputFiles(resolve(__dirname, "bar.png"));
await page.click("input[type=submit]");
});

或者,您可以将文件读入Buffer并将drop事件分派到具有DataTransfer负载的目标元素上。这在测试拖放区域时非常有用:

const dataTransfer = await page.evaluateHandle(
async ({ fileHex, localFileName, localFileType }) => {
const dataTransfer = new DataTransfer();
dataTransfer.items.add(
new File([fileHex], localFileName, { type: localFileType })
);
return dataTransfer;
},
{
fileHex: (await readFile(resolve(__dirname, "bar.png"))).toString("hex"),
localFileName: fileName,
localFileType: fileType,
}
);
await page.dispatchEvent("#drop_zone", "drop", { dataTransfer });
await expect(page.locator("text=bar.png")).toBeVisible();

您可以使用createDataTransfer实用程序从playwright-utilities:

进一步简化上述代码:
const dataTransfer = await createDataTransfer({
page,
filePath: resolve(__dirname, "bar.png"),
fileName: "bar.png",
fileType: "image/png",
});
await page.dispatchEvent("#drop_zone", "drop", { dataTransfer });
await expect(page.locator("text=bar.png")).toBeVisible();

通过克隆剧作家游乐场存储库在本地尝试这个例子:

git clone --branch test/upload-file https://punkpeye@github.com/punkpeye/playwright-playground.git
cd playwright-playground
npm install
npx playwright test tests/upload-file

在我的情况下找到了另一种上传方法。我们从内存中创建一个缓冲区,并将文件拖放到上传按钮上。

// Read your file into a buffer.
const buffer = readFileSync('file.pdf');
// Create the DataTransfer and File
const dataTransfer = await scope.page.evaluateHandle((data) => {
const dt = new DataTransfer();
// Convert the buffer to a hex array
const file = new File([data.toString('hex')], 'file.pdf', { type: 'application/pdf' });
dt.items.add(file);
return dt;
}, buffer);
// Now dispatch
await page.dispatchEvent('YOUR_TARGET_SELECTOR', 'drop', { dataTransfer });

如果使用typescript,将此添加到文件的顶部:

import {readFileSync} from 'fs';

Github issue: https://github.com/microsoft/playwright/issues/10667#issuecomment-998397241

我有同样的问题,所以我决定使用AutoIt

AutoIt v3是一种类似basic的免费脚本语言,用于自动执行Windows GUI和通用脚本。

我使用AutoIT来处理Windows文件上传对话框,这是使用剧作家无法处理的。


创建脚本
  1. 下载AutoIt: https://www.autoitscript.com/site/autoit/downloads/
  2. 打开SciTE脚本编辑器并输入以下内容:
WinWaitActive("Choose files")
Send("C:ChromeDrivertext.txt") 
Send("{ENTER}")

如果不行,把选择文件改成上传对话框左上角的任意标题。

  1. 点击保存并命名为upload。
  2. . au3并将其保存在测试的根目录中。

保存位置示例

  1. 右键单击新创建的文件并单击Compile Script

在测试中执行脚本

在node.js中创建子进程模块的execFile函数参考:https://nodejs.org/api/child_process.html child_process_child_process_execfile_file_args_options_callback

将其添加到.spec的顶部。测试文件:

var exec = require('child_process').execFile;
var upload_script = function(){
exec('upload.exe', function(err, data) {  
console.log(err)                  
});  
}

打开上传对话框,然后调用测试

中的函数
// Click Browse
await page.locator('#browse').click();
// Execute Upload Script
upload_script();

你必须运行你的测试头,否则它将无法工作:

npx剧作家测试——head

最新更新