如何在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
相关产品推荐
相关产品推荐

