firefox下载文件弹出框之终极解决方案-vbs模拟键盘操作
由于近期一直被firefox的保存文件弹出框困扰,摸索尝试过几种方法,已有的方法可以跑通但是对对效果不太满意,因此一直在寻找合适的解决办法。
最近发现了也可以通过VBS来处理弹出框,速度也不错,其原理就是模拟键盘操作,和rebot对象类型。现在对各种方法总结一下。
我们在测试中经常会遇到各种弹出框,对于弹出框主要有以下几类:
1. 新弹出浏览器窗口。
2. alert弹框。
3. 标准windows弹框。
对于第一种我们经常使用解决办法就是windowhandles判断句柄然后切换到相应窗口。
对于第二种我们就是利用selenium自带的switchto操作。
对于第三种经常使用的就是利用第三方工具AutoIt来操作。
这些解决方法各有千秋,根据实际情况来选择组好的方法。下面来具体分析:
1. 设置firefox profile来静默下载。
public static FirefoxProfile FirefoxDriverProfile() throws Exception { FirefoxProfile profile = new FirefoxProfile(); profile.setPreference("browser.download.dir", downloadFilePath); profile.setPreference("browser.download.folderList",2); browser.download.folderList 设置Firefox的默认 下载 文件夹。0是桌面;1是“我的下载”;2是自定义 profile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/xls, application/octet-stream, application/vnd.ms-excel, text/csv, application/zip"); return profile; }
经过实际观察,并不能每次都生效,稳定性不是太好,但是凑合着还能用。但是profile功能强大,能实现浏览器的定制化,例如加载插件。
2. 通过AutoIt来操作键盘。
由于不是标准windows框,AutoIt不能识别弹出框上的按钮。对于弹出标准windows弹框AutoIt首当其冲是最强大的,比如另存为弹出框。
3. 弹出框根本不是浏览器窗口,windowhandle方法也无效。
4. 通过VBS脚本实现键盘操作。先激活弹出框,然后点向下键,最后点回车,文件就被保存到默认路径了。
Dim checkOpenWindow Dim objShell Dim counter counter = 0 Set objShell = WScript.CreateObject( "WScript.Shell" ) Do ret = objShell.AppActivate("compare result.txt - Notepad") If ret = True Then objShell.SendKeys "{DOWN}" WScript.Sleep 2000 objShell.SendKeys "{ENTER}" Exit Do Elseif counter = 600 Then Exit Do End if Set ret = nothing counter = counter + 1 WScript.Sleep 1000 Loop
然后创建一个方法来封装这个vbs脚本。
public void save_excel() throws IOException, InterruptedException { String script = "SaveExcel.vbs"; String executable = "C:\\Windows\\SysWOW64\\wscript.exe"; String cmdArr [] = {executable, script}; Process result = Runtime.getRuntime().exec(cmdArr); result.waitFor(); }
这样完美解决了下载框弹出的问题,比之前其他的方法更加稳定,更加方便使用。
另外也记录一下robot模拟键盘的代码以供参考:
public void pressDownKey(){ Robot robot=null; try{ robot=new Robot(); } catch (AWTException e){ e.printStackTrace(); } robot.keyPress(KeyEvent.VK_DOWN); robot.keyRelease(KeyEvent.VK_DOWN); } public void pressEnterKy(){ Robot robot=null; try{ robot=new Robot(); } catch (AWTException e){ e.printStackTrace(); } robot.keyPress(KeyEvent.VK_ENTER); robot.keyRelease(KeyEvent.VK_ENTER); } RobotUtil robot = new RobotUtil(); robot.pressDownKey(); Thread.sleep(2000); robot.pressEnterKy();