由於近期一直被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();