做过Web自动化测试的人都知到,我们使用WebDriver来驱动各种浏览器,并对浏览器进行操作。
当在浏览器操作过程中遇到要与Windows界面进行交互的时候,WebDriver就没办法了,他只能驱动浏览器网页。
查阅资料后,今天学习了下,发现一种新方式利用AutoIt来对Windows进行操作。
流程思路:
通过WebDriver点击右键之后,出现菜单上有Save As(另存为)按钮,在通过Robot模拟移动键盘进行操作,然后调用AutoIt生成的可执行exe文件来 操作弹出的Windows界面。
1、首先去AutoIt的主页下载安装,安装选择默认路径即可。
https://www.autoitscript.com/site/autoit/downloads/
2、安装后可看到如下:
AutoIt Windows Info | 用于帮助我们识Windows控件信息 |
Compile Script to.exe | 用于将AutoIt生成 exe 执行文件。 |
Run Script | 用于执行AutoIt脚本。 |
SciTE Script Editor | 用于编写AutoIt脚本。 |
3、程序中打开AutoIt Windows Info
这里红字需要特别注意下,用Finder Tool按住不放拖到'Save As'窗口最外面的边缘处,软件会聚焦识别
点到control可以看到具体信息
下面定位文件名框,以及按钮“保存”“取消”都是一样的
4、SciTE Script Editor编辑脚本
完了之后可以使用已经安装的AutoIt自带的SciTE Script Editor来编辑脚本,也可以用其他的文本编辑器来编辑脚本!
;该脚本的语法是: ;分号代表注释
;ControlFocus ( "title", "窗口文本", controlID) 设置输入焦点到指定窗口的某个控件上
;WinWait ( "title题" , "窗口文本" , 超时时间 ) 暂停脚本的执行直至指定窗口存在(出现)为止
;ControlSetText ( "title", "窗口文本", controlID, "新文本" ) 修改指定控件的文本
;Sleep ( 延迟 ) 使脚本暂停指定时间段
;ControlClick ( "title", "窗口文本", 控件ID , 按钮 , 点击次数 ) 向指定控件发送鼠标点击命令
;其中,title即AutoIt Window Info识别出的Title字段,controlID即AutoIt Window Info识别
;出的Class和Instance的拼接,如上图拼接后的结果应为:Button1
;第一步:聚焦另存为窗口,title:另存为,"text",controlId:写ID可以识别
ControlFocus("Save As","","")
;暂停脚本的执行直至指定窗口存在(出现)为止
WinWait("[CLASS:#32770]","",10)
;第二步:填充文件名地址,其中$CmdLine[1]代表exe执行时的动态参数,
;例如 kuang.exe "D:/test/a.html",这样就可以动态改变地址的名字,通过python
;ControlSetText("另存为","","Edit1",$CmdLine[1])
;上述的我并没有尝试成功,所以使用固定文件名
ControlSetText("Save As","","Edit1","D:\test\outputReport\downLoadPDFDoc.pdf")
;延时函数
Sleep(2000)
;第三步:点击保存按钮,进行下载,title:另存为,"text"写成空,controlId:写成Button2(ClassnameNN)也可以识别
ControlClick("Save As","","Button1")
更新:今天搞定了$CmdLine[1]的正确使用方式
ControlSetText("另存为","","Edit1",$CmdLine[1]) 【调用代码如下面红色更新:】
写完脚本后,可以f5运行下脚本,前提是你的浏览器另存为框处于打开状态。以此来检验脚本哪里需要修改。存储为.au3的格式。
尝试没问题之后就打开AutoIt 中的生成自动化windows的exe。
最后就是在Java+Selenium的代码中调用生成的exe自动化操作文件,实现右键另存为(Save As)文件的下载功能。Java的调用如下:
Runtime.getRuntime().exec("D:\\test\\download.exe");
其中我写的完整的代码如下:
其中Test Case的逻辑是:
页面跳转到某个PDF链接,我想将其下载下来,但是PDF无法使用Selenium来获取网页元素,所以只能采取右键Save As这样的方式来下载PDF文件。
当然我的链接你可能用不了,你在测试的时候可以换成任意的网页链接都可以。
package cn.seleniumcn;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.io.IOException;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
public class testChromeDriver {
WebDriver driver;
@Test
public void testOne() throws Exception {
// driver = new FirefoxDriver();
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("http://pspdf.morningstar.com/v1/equityquant?productid=pdfengine&langid=en-US&secid=0P000001GY&showstar=yes");
WebElement myElement = driver.findElement(By.xpath("//*[@id='plugin']"));
Actions action = new Actions(driver);
action.moveToElement(myElement);//移动到元素上
Thread.sleep(1000);
action.contextClick(myElement).build().perform();
//模拟键盘操作(这里是移动向下方向键)
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_DOWN);
Thread.sleep(1000);
robot.keyPress(KeyEvent.VK_DOWN);
Thread.sleep(1000);
robot.keyPress(KeyEvent.VK_DOWN);
Thread.sleep(1000);
robot.keyPress(KeyEvent.VK_ENTER);
Thread.sleep(1000);
try {
//调用你使用Compile Script to.exe生成的可执行exe文件
//对Windows窗体进行操作:更换文件名,并保存到指定文件夹
Runtime.getRuntime().exec("D:\\test\\download.exe");
} catch (IOException e) {
e.printStackTrace();
}
}
@AfterClass
public void tearDown(){
driver.quit();
}
}
更新:
如上文更新所示:
如果在脚本中使用了$CmdLine[1]这个参数,那么在外部Java调用exe的时候需要注意带入参数,这样就能够实现参数自动,不用每次更换问文件名以及文件地址而更换脚本文件exe,这又是一个很大的进步啊。
新的调用代码模块如下:
String folderPath = "D:\\dataSource\\outputReport";
File file = new File(folderPath);
file.mkdirs();//新建文件夹
Thread.sleep(1000);
//Runtime.getRuntime().exec("D:\\test\\download.exe");
String fileName = "D:\\dataSource\\outputReport\\downLoadPDFDoc.pdf";
//Runtime.getRuntime().exec("D:\\test\\download.exe inputfile OutputfilePath");
Runtime.getRuntime().exec("D:\\test\\download.exe -p "+ fileName);
//注意一定要用\\,不要使用/