You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Playwright测试中使用setInputFiles时如何关闭文件选择对话框

解决Playwright文件上传对话框挂起问题

在Playwright自动化测试中,使用setInputFiles设置上传文件时,若先点击上传按钮触发系统文件选择对话框,会出现对话框无法关闭、测试挂起的问题。

原问题代码

测试代码片段:

await page.getByTestId('upload-button').click();

const filePath= path.join(__dirname, "rootPath", "secPath", "package.nupkg");
await page.browseInputField.isVisible();
await page.browseInputField.setInputFiles(filePath);

页面DOM中的文件输入元素:

<input id="browseFileInput" data-testid="browseFileInput" class="browseFileInput" type="file" accept=".nupkg">

最小复现示例

测试页面(test_page.html):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test Page for File Input</title>
</head>
<body>
    <input id="browseFileInput" data-testid="browseFileInput" class="browseFileInput" type="file" accept=".nupkg">
    <button id="upload-button" data-testid="upload-button">Upload</button>

    <script>
        document.getElementById('upload-button').addEventListener('click', function() {
            document.getElementById('browseFileInput').click();
        });
    </script>
</body>
</html>

原测试脚本:

const { chromium } = require('playwright');
const path = require('path');

(async () => {
    const browser = await chromium.launch();
    const page = await browser.newPage();
    await page.goto('file:///path/to/test_page.html');

    await page.click('[data-testid="upload-button"]');

    const filePath = path.join(__dirname, "rootPath", "secPath", "package.nupkg");
    await page.setInputFiles('[data-testid="browseFileInput"]', filePath);

    // Here comes the question - how I close the opened browse dialog?
})();

解决方案

方案1:直接操作文件输入元素,跳过触发系统对话框

系统文件选择对话框属于浏览器/OS级别的控件,Playwright无法直接控制。因此可以绕过点击上传按钮的步骤,直接找到type="file"的输入元素并调用setInputFiles,这样不会触发对话框:

修改后的测试代码:

const { chromium } = require('playwright');
const path = require('path');

(async () => {
    const browser = await chromium.launch();
    const page = await browser.newPage();
    await page.goto('file:///path/to/test_page.html');

    // 直接操作file输入元素,无需点击上传按钮
    const filePath = path.join(__dirname, "rootPath", "secPath", "package.nupkg");
    await page.setInputFiles('[data-testid="browseFileInput"]', filePath);

    // 后续可以继续模拟点击上传按钮提交(如果需要)
    await page.click('[data-testid="upload-button"]');

    await browser.close();
})();

方案2:监听对话框事件并自动关闭(若必须点击上传按钮)

如果业务逻辑要求必须先点击上传按钮,可以通过监听dialog事件来自动关闭系统文件对话框:

修改后的测试代码:

const { chromium } = require('playwright');
const path = require('path');

(async () => {
    const browser = await chromium.launch();
    const page = await browser.newPage();
    
    // 监听对话框事件,自动关闭
    page.on('dialog', async dialog => {
        await dialog.dismiss();
    });

    await page.goto('file:///path/to/test_page.html');

    await page.click('[data-testid="upload-button"]');
    
    // 设置文件后继续流程
    const filePath = path.join(__dirname, "rootPath", "secPath", "package.nupkg");
    await page.setInputFiles('[data-testid="browseFileInput"]', filePath);

    await browser.close();
})();

说明

  • 方案1是最优解,因为直接操作文件输入元素是Playwright推荐的文件上传方式,完全避免了系统对话框的干扰。
  • 方案2仅适用于必须点击上传按钮的场景,但注意dialog.dismiss()会关闭对话框,需要确保设置文件的操作不受影响。

内容的提问来源于stack exchange,提问作者Renya Karasuma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 17:57:07