如何借助WebDriver Extensions在Selenium Grid上实现文件上传?
嘿,我太懂你这种困扰了——本地用Robot类搞文件上传顺得不行,一放到Selenium Grid分布式环境直接歇菜,毕竟Robot是吃本地桌面操作的,远程节点根本管不着。下面给你几个用WebDriver Extensions配合Selenium实现跨环境文件上传的靠谱方案,全都是Grid友好型的:
这是Selenium原生支持的方法,完全适配Grid环境,核心思路就是找到页面里的<input type="file">元素,直接把文件的绝对路径传给它的sendKeys方法就行,不需要模拟键盘回车那一套。
用WebDriver Extensions的封装类来写会更简洁:
// 定位文件上传的input元素(用WebDriver Extensions的UploadElement) UploadElement uploadInput = $(UploadElement.class, By.id("file-upload")); // 传入本地文件的绝对路径 uploadInput.sendKeys("/Users/you/Documents/test-file.png"); // 如果需要点击上传按钮触发提交,再补个点击操作 $(Button.class, By.id("submit-upload")).click();
这里的UploadElement是WebDriver Extensions专门为文件上传元素做的封装,比普通WebElement更贴合场景,调用起来更顺手。
很多网站为了美观会把原生的<input type="file">设为隐藏,这时候我们可以先用JavaScript把它临时显示出来,再用上面的方法操作:
// 先找到隐藏的input元素 WebElement hiddenUploadInput = driver.findElement(By.id("hidden-file-input")); // 用JS修改样式让它可见(不用全屏显示,只要能被Selenium定位到就行) ((JavascriptExecutor) driver).executeScript( "arguments[0].style.visibility = 'visible'; " + "arguments[0].style.height = '20px'; " + "arguments[0].style.width = '100px';", hiddenUploadInput ); // 转成WebDriver Extensions的UploadElement来操作 UploadElement uploadElement = new UploadElement(driver, hiddenUploadInput); uploadElement.sendKeys("/Users/you/Documents/test-file.png");
如果你嫌手动写定位和sendKeys麻烦,WebDriver Extensions还提供了FileUploadActions工具类,一行代码就能搞定上传:
// 直接传入driver、元素定位器和文件对象 FileUploadActions.uploadFile(driver, By.id("file-upload"), new File("/Users/you/Documents/test-file.png"));
这个方法内部已经帮你处理了元素定位、sendKeys操作,甚至会自动处理一些常见的元素状态问题,非常省心,而且完全支持Selenium Grid。
最后再啰嗦一句:
千万别再依赖Robot类做分布式环境的文件上传了!Robot是基于本地桌面的模拟操作,只能控制跑测试代码的那台机器,根本没法触及Selenium Grid的远程节点。而上面的几种方法都是基于Web协议的操作,不管是本地还是Grid环境都能稳定运行。
内容的提问来源于stack exchange,提问作者AshaThor

