本文首先探討了編寫 Selenium 腳本時的兩種最簡單、經常使用的截圖方法,接着重點介紹了在難以利用普通截圖方法獲取到截圖時,如何利用 Selenium 獲取到的元素分析網頁內容,進而繪製出所須要的圖像的方法。javascript
翻譯驗證測試 (Translation Verification Test) 是全球化測試的重要組成部分。在翻譯驗證測試準備階段,翻譯驗證測試技術支持人員常常須要截取大量的圖片給各個國家的測試人員。爲了節省時間,實現自動化 截圖已經是大勢所趨。通常狀況下,咱們直接使用 Selenium 的 getScreenshotAs() 方法就能夠知足多數狀況下的須要。然而,該方法對不少懸浮框和下拉菜單的處理卻不盡人意。接下來讓咱們一塊兒來看看在實際應用中咱們均可以選擇哪些方法。css
1、利用 Selenium 的 getScreenshotAs() 方法java
利用 TakesScreenshot 接口提供的 getScreenshotAs() 方法捕捉屏幕,是咱們在開發 Selenium 腳本時最經常使用的方法。getScreenshotAs() 函數能夠返回 BASE6四、BYTES 或 FILE 類型的數據。當指定返回類型爲 BASE64 的時候 ,會返回一個 base64 編碼字符串;當指定返回類型爲 BYTES 的時候,會返回一個 bytes 數組; 當指定返回類型爲 FILE 的時候,會將獲取到的截圖存放到一個臨時文件中,以供複製到指定的文件。該方法能夠知足最基本的需求。如清單 1 所示, captureScreen() 方法會將整個屏幕截下來,並將圖片保存爲 jpg 文件。數組
清單 1. 利用 Selenium 自帶的方法截圖瀏覽器
public static void captureScreen(WebDriver driver,String screenName) throws IOException{ //判斷是否存在screenpath目錄 if(!(new File(screenpath).isDirectory())){ new File(screenpath).mkdir(); } File screenShotFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE); FileUtils.copyFile(screenShotFile, new File(screenpath+screenName+".jpg")); }
Selenium 的 getScreenshotAs() 方法並不能處理一些更爲複雜的問題,如對某些懸浮框、下拉菜單選項進行截圖時,該方法返回的圖片中並不包含懸浮框、下拉菜單部分。此時,能夠選擇採用 Robot 類的 createScreenCapture() 方法。ide
2、利用 Robot 類的 createScreenCapture() 方法函數
利用 Java 的 Robot 類能夠完成一些與操做系統有關的底層輸入,經過 Robot 類的 createScreenCapture() 方法能夠截取到和 PrtSc 按鍵相同效果的圖片。該方法簡單易用,且功能強大,基本能夠知足大部分需求。測試
清單 2. 利用 Robot 截圖編碼
public static void captureScreen(String screenName, int x, int y, int width, int height) { try { BufferedImage capture = null; Rectangle area = new Rectangle(x, y, width, height); Robot robot = new Robot(); capture = robot.createScreenCapture(area); String fn = screenpath + screenName + ".jpg"; FileOutputStream out = new FileOutputStream(fn); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); encoder.encode(capture); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); } }
對於某些氣泡懸浮框,如 title 屬性值,須要將鼠標懸浮在元素上才能夠顯示出來。採用 Selenium 的 Actions 類去模擬鼠標操做,能夠解決一些經過 javascript、css 控制的鼠標移動、懸浮操做 ,可是對於 title 這樣的氣泡懸浮框卻無能爲力,由於 Actions 方法只是模擬鼠標操做,而 title 屬性值須要在真實的鼠標懸浮在元素上時纔會顯示出來。此時,能夠先使用 Robot 類的 mouseMove() 方法將鼠標移到指定屏幕位置,再進行截圖。spa
清單 3. 在 Robot 類的 mouseMove() 方法中應用 Selenium 獲取到的點座標
Robot robot = newRobot(); Point point = element.getLocation(); robot.mouseMove(point.x+55, point.y+90);
mouseMove() 中的點座標爲 Selenium 獲取到的元素的屏幕座標,而經過 getLocation() 方法得到的元素座標爲元素相對於瀏覽器內的 document 對象的座標,因此須要進行微調。
因爲 Robot 類操做的是一些操做系統事件,因此在某些系統(如 X-Window 系統)中若是 Robot 類訪問鼠標、鍵盤的操做須要特定權限,那麼可能會拋出 AWTException。然而,在多平臺上實現截圖並非咱們在本文中須要考慮的內容。利用 Robot 類的截圖方法能夠截取指定區域的屏幕,相比第一種方法更加靈活,功能也更增強大。
3、解析網頁頁面,動態生成圖片
對於頁面中某些氣泡懸浮框(如圖 1 中的「到百度首 頁」字符串),如 title 和 alt 屬性值,雖然使用 Robot 能夠截取到,可是須要調節座標位置。在咱們實際應用中,因爲咱們通常都是經過 Remote Desktop Connection Manager 鏈接多臺遠程虛擬機,屏幕的大小有時會發生改變,於是元素的座標位置也常常須要調節。
圖 1. 氣泡懸浮框示例
實現思路
因此對於此類狀況,咱們能夠經過另一種方式解決,即解析網頁頁面,取出 title 屬性值,並根據 title 信息繪製成圖片,最後將繪製好的圖片添加到原來的圖中並返回整張圖片。從理論上講,全部的頁面元素,咱們均可以經過此方法實現截圖。實現方法如清單 4 所示。
清單 4. 抓取完整的屏幕截圖
public static void captureFlyover(WebDriver driver,String xpath,String screenName) throws Exception{ BufferedImage img; BufferedImage img1; //img1爲抓取的不包含tooltip的屏幕截圖 img1 = gsscScreenshotImage(driver); //img爲將懸浮框添加到img1後返回的屏幕截圖 img = gsscAddTooltip(driver.findElement(By.xpath(xpath)), img1); ImageIO.write(img, "png", new File(screenpath+screenName+".jpg")); }
其中, gsscScreenshotImage() 方法調用的是第一種方式中的 getScreenshotAs() 方法。接着,咱們來看一下 gsscAddTooltip() 的實現方式。咱們首先在 gsscCreateTooltip() 建立了 tooltip 圖像。根據傳入的 Selenium 獲取到的 element 對象,咱們能夠獲取到元素的 title 和 font-family 等屬性值以及元素的座標位置。根據這些信息,咱們建立出一個 img 圖像。咱們將圖像的背景色設置爲 #F5FCDE。但爲了更加逼真,咱們還能夠經過 getCssValue() 方法獲取到更多和元素有關的信息,如 background、border、padding 等等。