《手把手教你》系列技巧篇(五十四)-java+ selenium自动化测试-上传文件-中篇(详细教程)
1.简介
在实际工作中,我们进行web自动化的时候,文件上传是很常见的操作,例如上传用户头像,上传身份证信息等。所以宏哥打算按上传文件的分类对其进行一下讲解和分享。
2.为什么selenium没有提供API?
想必小伙伴们或者童鞋们一定很好奇,既然上传文件在自动化这么常见而且经常用到,那么为什么Selenium的webdriver为什么不提供方法(API),宏哥这里解释一下原因:因为上传文件需要打开window窗口,webdriver是无法对window的控件操作的,换句话说就是:selenium无法识别非web的控件,上传文件窗口为系统自带,无法识别窗口元素。所以没有提供方法,需要我们换个思路去上传文件。
3.上传文件分类
首先,我们要区分出上传按钮的种类,大体上可以分为两种,一种是input框,另外一种就比较复杂,通过js、flash等实现,标签非input。
上传文件有两种场景:input控制上传和非input控件上传。大多数情况都是input控件上传文件,只有非常少数的使用自定义的非input上传文件。今天宏哥这一篇文章就用来介绍非input控件上传文件。
4.非input控件上传文件
非input控件上传文件,我们要引入外部插件上传。这种上传千奇百怪,有用a标签的,有用div的,有用button的,有用object的,我们没有办法通过直接在网页上处理掉这些上传,唯一的办法就是打开OS弹框,去处理弹框。有两种方法一种通过pywin32上传(这种只支持python语言),另一种是通过autoit上传(python和java都支持,其他的没有实践过)。这里我们只会讲到autoit上传文件。
4.1非input控件上传文件
宏哥总结了一下,大体上有以下几种解决方案:
(1)autoIT,借助外力,我们去调用其生成的au3或exe文件。
(2)Python pywin32库,识别对话框句柄,进而操作
(3)SendKeys库
(4)keybd_event,跟3类似,不过是模拟按键,ctrl+a,ctrl+c, ctrl+v…
5.项目实战
介绍纯Java的方式去处理,web上本地上传图片的功能。这个过程,我们还是需要用到Robot这个类,由于在web上点击了本地上传图片后,弹出的框很特殊,selenium无法识别这个弹窗,所以在selnium中没有直接的方法去实现上传本地文件。
5.1大致流程
其实也是上边提到的第四种解决方案,模拟键盘操作。宏哥利用Robot的大致流程是这样的:
1.用selnium点击web上本地上传文件的按钮
2.在弹窗,文件路径输入框默认是光标聚焦,我们把文件在磁盘上的路径,通过拷贝和黏贴方法写上去。
3.通过按下回车站,默认触发弹窗的确定按钮,完成了文件上传过程。
5.2测试场景
打开百度首页,搜索按钮左侧有一个照相机的图标,点击可以选择图片搜索,我们通过本地上传图片的过程来模拟文件自动化上传操作,上传成功后,百度识图会识别是不是百度搜索的图片,如果是,就会显示图片的信息,如果不是,就会识别失败,提示重新上传。准备条件,你在百度图片搜索一个图片,保存到你桌面,例如宏哥找到一个关于selenium的图片,然后保存在桌面的test文件夹,名称为北京宏哥的拼音首字母:bjhg.jpeg。
5.3代码设计
5.4参考代码
package lessons; import java.awt.Robot; import java.awt.Toolkit; import java.awt.datatransfer.StringSelection; import java.awt.event.KeyEvent; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; /** * @author 北京-宏哥 * * @公众号:北京宏哥 * * @《手把手教你》系列技巧篇(五十三)-java+ selenium自动化测试-上传文件-中篇(详细教程) * * @2021年12月12日 */ public class FileUpload { public static void main(String[] args) throws Exception { System.setProperty("webdriver.gecko.driver",".\\Tools\\geckodriver.exe"); WebDriver driver = new FirefoxDriver(); driver.manage().window().maximize(); driver.get("https://www.baidu.com"); // 指定图片的路径,这里我放桌面上 StringSelection sel = new StringSelection( "C:\\Users\\DELL\\Desktop\\test\\bjhg.jpeg"); // 把图片文件路径复制到剪贴板 Toolkit.getDefaultToolkit().getSystemClipboard().setContents(sel, null); System.out.println("selection" + sel); // 点击照相机这个按钮 driver.findElement(By.xpath("//*/span[@class='soutu-btn']")).click(); // 点击本地上传图片 driver.findElement(By.xpath("//*/input[@class='upload-pic']")).click(); // 新建一个Robot类的对象 Robot robot = new Robot(); Thread.sleep(1000); // 按下回车 robot.keyPress(KeyEvent.VK_ENTER); // 释放回车 robot.keyRelease(KeyEvent.VK_ENTER); // 按下 CTRL+V robot.keyPress(KeyEvent.VK_CONTROL); robot.keyPress(KeyEvent.VK_V); // 释放 CTRL+V robot.keyRelease(KeyEvent.VK_CONTROL); robot.keyRelease(KeyEvent.VK_V); Thread.sleep(1000); // 点击回车 Enter robot.keyPress(KeyEvent.VK_ENTER); robot.keyRelease(KeyEvent.VK_ENTER); Thread.sleep(5000); System.out.println("browser will be close"); driver.quit(); } }
5.5运行代码
1.运行代码,右键Run AS->Java Appliance,控制台输出,如下图所示:
2.运行代码后电脑端的浏览器的动作,如下小视频所示:
6.小结
奇怪了,细心地小伙伴或者童鞋们。一定会发现宏哥之前的代码都是用火狐浏览器,结果录制的视频却是Chrome浏览器,原因是:开始Chrome浏览器不可以模拟成功,宏哥就换了Firefox浏览器成功了,第二天宏哥抱着试一下的心理,结果也成功了。但是原因没有找到,开始宏哥以为是Chrome浏览器版本高,而宏哥的Firefox是一个低版本的,所以换了Firefox,但是Chrome今天可以成功,那就不是版本问题,而且宏哥怀疑是图片的名字中英文,但是试过了也是没有关系的。但是宏哥还是提醒各位最好用英文的。实在找不到原因了,有知道可以留言宏哥哦!!!
好了,今天时间也不是很早了,宏哥今天就讲解和分享到这里,感谢您耐心的阅读,下一篇讲解借助工具来处理非input控件上传文件。
感谢您花时间阅读此篇文章,如果您觉得这篇文章你学到了东西也是为了犒劳下博主的码字不易不妨打赏一下吧,让博主能喝上一杯咖啡,在此谢过了!
如果您觉得阅读本文对您有帮助,请点一下左下角“推荐”按钮,您的
本文版权归作者和博客园共有,来源网址:https://www.cnblogs.com/du-hong 欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利!
公众号(关注宏哥)                                                                                 客服微信