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

如何在Protractor中使用sendKeys()实现单次单文件上传?

解决Protractor文件上传重复上传旧文件的问题

我之前在做Protractor E2E测试时也碰到过完全一样的问题——第一次单文件上传正常,换文件名后第二次上传居然重复传了第一个文件。排查下来,核心原因基本都是文件输入框(input[type="file"])的旧值没有被正确清空,或者元素引用/异步时序出了问题。下面是几个亲测有效的解决方案:

1. 上传前强制清空文件输入框

sendKeys()给file input传路径时,并不会自动覆盖旧值(尤其是在某些浏览器缓存机制下),所以每次上传前必须主动清空。你可以用两种方式实现:

方式A:使用Protractor自带的clear()方法

it("=> it will upload document", function () {
    browser.setFileDetector(new remote.FileDetector());
    let exePath = path.resolve(__dirname, '../bbb/' + fileName);
    
    $('input[type="file"]').isDisplayed().then(function () {
        let fileInput = $('input[type="file"]');
        // 先清空输入框,再传入新路径
        fileInput.clear().then(() => {
            fileInput.sendKeys(exePath);
        });
    });
});

方式B:执行原生JS强制清空(更稳妥)

如果clear()方法偶尔失效,直接用JS操作DOM清空value:

it("=> it will upload document", function () {
    browser.setFileDetector(new remote.FileDetector());
    let exePath = path.resolve(__dirname, '../bbb/' + fileName);
    
    $('input[type="file"]').isDisplayed().then(function () {
        let fileInput = $('input[type="file"]');
        // 用JS清空输入框值
        browser.executeScript("arguments[0].value = '';", fileInput.getWebElement()).then(() => {
            fileInput.sendKeys(exePath);
        });
    });
});

2. 每次上传都重新定位元素

有时候页面在上传后会有DOM更新(比如提示上传成功、重置上传区域),之前缓存的元素引用可能已经处于异常状态。所以不要复用元素对象,每次上传前重新查找:

it("=> it will upload document", function () {
    browser.setFileDetector(new remote.FileDetector());
    let exePath = path.resolve(__dirname, '../bbb/' + fileName);
    
    $('input[type="file"]').isDisplayed().then(function () {
        // 每次都重新获取元素
        $('input[type="file"]').clear().then(() => {
            $('input[type="file"]').sendKeys(exePath);
        });
    });
});

3. 确认文件名变量已正确更新

别忽略最基础的问题——检查fileName变量是否真的换成了新文件名。可以加个日志打印验证:

let exePath = path.resolve(__dirname, '../bbb/' + fileName);
console.log('当前上传路径:', exePath); // 控制台确认路径是否指向新文件

4. 用Async/Await优化异步时序(推荐)

Protractor的控制流有时候会导致异步操作时序混乱,换成async/await写法能让代码逻辑更清晰,避免时序问题:

it("=> it will upload document", async function () {
    browser.setFileDetector(new remote.FileDetector());
    let exePath = path.resolve(__dirname, '../bbb/' + fileName);
    
    // 等待元素显示
    await $('input[type="file"]').isDisplayed();
    
    let fileInput = await $('input[type="file"]');
    await fileInput.clear();
    await fileInput.sendKeys(exePath);
});

优先尝试第一种清空输入框的方案,大部分情况下都能解决重复上传的问题。如果还是不行,结合后面的方法排查元素定位和变量更新的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:28:11