du-hong

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.准备工作

   关于文件上传,宏哥前边已经介绍过几种方法了,今天这篇介绍一个第三方工具,叫AutoIt,简单来说,这个是一个能支持桌面GUI自动化的工具,它支持脚本语言编写。这里,我们用AutoIt来做文件上传的演示。在Selenium脚本中如果需要AutoIt来协助这个文件上传功能,大概步骤是这样的:

1.Selenium点击web产品上的文件上传按钮,弹窗上传框。

2.执行AutoIt实现准备好的脚本文件,这个脚本文件写了关于上传什么文件的一个.exe文件。

所以,我们先来介绍如何下载和安装AutoIt。

5.1下载和安装AutoIt

  文件上传是自动化中棘手的部分,目前selenium并没有提供上传的实现api,所以知道借助外力来完成,如AutoIt、sikuli。

AutoIt , 这是一个使用类似BASIC脚本语言的免费软件,它设计用于Windows GUI(图形用户界面)的自动化操作,利用模拟键盘按键,鼠标移动和窗口/控件的组合来实现自动化任务;

1.打开AutoIt的官网下载

AutoIt下载链接:https://www.autoitscript.com/site/autoit/downloads/ 或者点击下列图标进行下载!

      

2.点击下载zip

两种下载方法都可以,这里我想下载的是zip,解压出来如下图所示:

5.2上传脚本的编写

1.点击SciTe文件夹,我们打开脚本编辑器。

2.打开百度图片上传窗口,打开AutoIt Windows Info 工具,鼠标移动到Finder Tool,按住鼠标左键拖动到需要识别的windows控件上。拖动元素定位器上那个靶点形状按钮到文件上传弹窗,能够捕获到一些元素信息。用鼠标拖住工具上的Finder Tool的图标(即图中蓝色圈圈部分)到要识别的控件上,控件的唯一标识信息会显示在工具的左侧部分(图中红框标出的部分)。从显示的结果得知,此控件的Title=“打开”,Class为Edit,Instance=1。我们就是利用控件的这些信息,定位控件,编写脚本。

3.打开编辑器,根据控件Finder Tool识别到的信息来调用函数编写脚本;在AutoIt脚本编辑器里输入如下脚本,不要下面我写的备注哈。

我们这里需要知道有以下信息:

1.操作页面的title,用于固定操作的页面。
2.需要填入的信息,在输入框中填入“上传文件的路径及文件名”(windows操作)
3.点击“打开”按钮,实现文件上传。

根据以上所识别的控件信息,利用编辑器SciTE Script Editor,根据AutoIT的语法编写脚本。

实现文件上传需要的几个方法:

ControlFocus ( "窗口标题", "窗口文本", 控件ID)
---->设置输入焦点到指定窗口的某个控件上(即:控件ID“文件名”输入框的id)
WinWait ( "窗口标题" [, "窗口文本" [, 超时时间]] )
---->暂停脚本的执行直至指定窗口存在(出现)为止
ControlSetText ( "窗口标题", "窗口文本", 控件ID, "新文本" )
---->修改指定控件的文本(即:控件ID“文件名”输入框的id)
Sleep ( 延迟 )
---->使脚本暂停指定时间段
ControlClick ( "窗口标题", "窗口文本", 控件ID [, 按钮] [, 点击次数]] )
---->向指定控件发送鼠标点击命令(即:控件ID“打开”按钮的id)

其中,title即AutoIt Window Info识别出的Title字段,controlID即AutoIt Window Info识别出的Class和Instance的拼接,如上图拼接后的结果应为:Button1(即classnameNN)

;ControlFocus(("title","text",controllD)用于识别windows文件上传窗口
ControlFocus("打开","","")
;向文件名输入框输入本地要上传文件的路径
ControlSetText("打开","","Edit1","C:\Users\DELL\Desktop\test\upload\北京宏哥.jpeg")
Sleep(2000)
;点击上传窗口中的“打开“按钮
ControlClick("打开","","Button1")

5.3验证上传脚本是否正确

1.保存脚本文件为ChromFileUpload.au3格式,然后在AutoIt脚本编辑器中点击Tools菜单,tools=>go,执行脚本验证(前提是windows窗口必须是打开状态),验证成功,如下图所示:

5.4上传脚本编译成一个.exe文件

为了这个脚本能被java 程序调用,需要通过Compile Script to .exe (x64)工具生成exe文件(这个是通过.exe安装包安装的AutoIt)

1.AutoIt脚本编辑器中点击Tools菜单,选择compile,会在同路径下生成一个.exe的文件(这个是通过解压包安装的AutoIt)

2.提示Conversion complete转化完成:将ChromeFileUpload.exe拷贝到项目下,待会在Selenium脚本要使用。

5.5java代码执行exe文件

//实现文件上传。通过Runtime的静态方法获取Runtime对象
Runtime runtime = Runtime.getRuntime();
//通过Runtime对象调用exe方法
runtime.exec("C:\Users\DELL\Desktop\test\upload\ChromeFileUpload.exe");

6.项目实战

6.1代码设计

实现文件上传整体代码如下:

6.2参考代码

package lessons;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

/**
 * @author 北京-宏哥
 * 
 * @公众号:北京宏哥
 * 
 * @《手把手教你》系列技巧篇(五十三)-java+ selenium自动化测试-上传文件-下篇(详细教程)
 *
 * 2021年12月9日
 */
public class AutoItUpload {
    
    public static void main(String[] args) {
        
        System.setProperty("webdriver.gecko.driver", ".\\Tools\\chromedriver.exe"); //指定驱动路径
        WebDriver driver =new ChromeDriver();
        try {
            driver.get("https://www.baidu.com");
            driver.manage().window().maximize();
            // 点击照相机这个按钮
            driver.findElement(By.xpath("//*/span[@class='soutu-btn']")).click();
            // 点击本地上传图片
            driver.findElement(By.xpath("//*/input[@class='upload-pic']")).click();
            Thread.sleep(3000);
            //实现文件上传。通过Runtime的静态方法获取Runtime对象
            Runtime runtime = Runtime.getRuntime();
            //通过Runtime对象调用exe方法
            runtime.exec("C:/Users/DELL/Desktop/test/upload/ChromFileUpload.exe");
            Thread.sleep(5000);
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            System.out.println("执行结束,关闭浏览器");
            driver.quit();
        }
    }

}

6.3运行代码

1.运行代码,右键Run AS->Java Appliance,控制台输出,如下图所示:

2.运行代码后电脑端的浏览器的动作,如下小视频所示:

7.小结

 这样,我们就实现了利用AutoIt的自动上传功能。好了,今天时间也不是很早了,宏哥今天就讲解和分享到这里,感谢您耐心的阅读

相关文章: