天天看點

使用JAVA Robot 擴充Webdriver 模拟鍵盤滑鼠操作

使用 Robot 類來操作 Keys 沒有枚舉出來的按鍵操作

1.在 WebDriver 中,Keys 枚舉出了鍵盤上大多數的非字母類按鍵,從 F1 到 F10,NUMPAD0 到 NUMPAD9、ALT\TAB\CTRL\SHIFT 等等,你可以通過以下連結檢視 Keys 枚舉出來的所有按鍵,Enum Keys。 但是并沒有列出鍵盤上的所有按鍵,比如字母鍵 a、b、c、d … z,一些符号鍵比如:‘ {}\[] ’、‘ \ ’、‘。’、‘ ? ’、‘:’、‘ + ’、‘ - ’、‘ = ’、、‘“”’,還有一些不常用到的功能鍵如 PrtSc、ScrLk/NmLk。對于字母鍵和符号鍵,前面我們已經提到可以直接使用 sendKeys(“a”),sendKeys(“/”) 的方式來觸發這些鍵盤事件。而對于一些功能組合鍵,如 Fn + NmLk 來關閉或者打開數字鍵,或者 Alt+PrtSC 來抓取目前螢幕的活動視窗并儲存到圖檔,通過 WebDriver 的 Keys 是沒辦法操作的。 這個時候我們就需要用到 Java 的 Robot 類來實作對這類組合鍵的操作了。

2.下面就以對 Alt+PrtSc 為例介紹一下 Robot 對鍵盤的操作。如代碼清單 10。

通過 Robot 發出組合鍵動作
public static void sendComposeKeys(String fileName) throws Exception { 
Robot robot = new Robot(); 
robot.keyPress(java.awt.event.KeyEvent.VK_ALT); 
robot.keyPress(java.awt.event.KeyEvent.VK_PRINTSCREEN); ,
robot.keyRelease(java.awt.event.KeyEvent.VK_ALT); 
Clipboard sysc = Toolkit.getDefaultToolkit().getSystemClipboard(); 
Transferable data = sysc.getContents(null); 
 if (data != null) { 
 if (data.isDataFlavorSupported(DataFlavor.imageFlavor)) { 
Image image = (Image) data 
.getTransferData(DataFlavor.imageFlavor); 
writeImageToFile(image, fileName); 
	} 
}  }      

Robot 類對鍵盤的處理是通過 keyPress(int keycode)、keyRelease(int keycode) 方法來實作的,其中他們需要的參數是鍵盤按鍵對應的虛拟鍵碼,虛拟鍵碼的值可以通過 KeyEvent 類來擷取。在 Java API 中對于虛拟鍵碼的解釋如下: 虛拟鍵碼用于報告按下了鍵盤上的哪個鍵,而不是一次或多次鍵擊組合生成的字元(如 "A" 是由 shift + "a" 生成的)。 例如,按下 Shift 鍵會生成 keyCode 為 VK_SHIFT 的 KEY_PRESSED 事件,而按下 'a' 鍵将生成 keyCode 為 VK_A 的 KEY_PRESSED 事件。釋放 'a' 鍵後,會激發 keyCode 為 VK_A 的 KEY_RELEASED 事件。另外,還會生成一個 keyChar 值為 'A' 的 KEY_TYPED 事件。 按下和釋放鍵盤上的鍵會導緻(依次)生成以下鍵事件:

KEY_PRESSED

KEY_TYPED(隻在可生成有效 Unicode 字元時産生。)

KEY_RELEASED

是以當測試中需要用到按下鍵盤 Alt+PrtSc 鍵的時候,隻需要執行代碼清單 10 中兩個 keyPress() 和一個 keyRelease() 方法即可。

3.當這兩個按鍵執行結束之後,螢幕上面的活動視窗已經儲存到剪切闆中。如果需要将其儲存本地圖檔,隻需要從剪切闆讀取并通過 JPEGImageEncoder 類或者 ImageIO 類将其寫入本地即可。

使用 JPEGImageEncoder 将 Image 對象儲存到本地
/** 
 * 
 * @Description: 這個方法用來将 Image 對象儲存到本地,主要是通過 JPEGImageEncoder 類來實作圖像的
 * 儲存
 * @param image : 要儲存的 Image 對象
 * @param filename : 儲存圖檔的檔案名稱
 */ 
 public static void writeImageToFile(Image image, String fileName) { 
		 try { 
			 // 擷取 Image 對象的寬度和高度, 這裡的參數為 null 表示不需要通知任何觀察者
 int width = image.getWidth(null);
			 int height = image.getHeight(null); 
			 BufferedImage bi = new BufferedImage(width, height, 
					 BufferedImage.TYPE_INT_RGB); 
 // 通過 BufferedImage 繪制圖像并儲存在其對象中
			 bi.getGraphics().drawImage(image, 0, 0, null); 
			 // 建構圖像名稱及儲存路徑
			 String name = Const.DIRECTORY + fileName + Const.FORMAT; 
			 File dir = new File(Const.DIRECTORY); 
			 if (!dir.exists()) { 
				 dir.mkdir(); 
			 } 
			 FileOutputStream out = new FileOutputStream(name); 
			 @SuppressWarnings("restriction") 
			 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 
 encoder.encode(bi); 
			 out.flush(); 
 out.close(); 
		 } catch (Exception e) { 
			 e.printStackTrace(); 
		 } 
	 }      

通過 JPEGImageEncoder 類将 Image 對象寫到本地檔案流,注意 Image 對象是在代碼清單 10 中的如下語句擷取到的:

Clipboard sysc = Toolkit.getDefaultToolkit().getSystemClipboard(); 
		 Transferable data = sysc.getContents(null); 
		 if (data != null) { 
			 if (data.isDataFlavorSupported(DataFlavor.imageFlavor)) { 
				 Image image = (Image) data 
						 .getTransferData(DataFlavor.imageFlavor); 
				 writeImageToFile(image, fileName); 
			 } 
		 }      
 使用 ImageIO 将 Image 對象儲存到本地
/** 
 * 
 * @Description: 通過使用 ImageIO 類來儲存 Image 對象為本地圖檔
 * @param image : 需要儲存的 Image 對象
 * @param filename : 檔案名
 */ 
 public static void saveImage(Image image, String fileName) throws Exception { 
	 // 擷取 Image 對象的高度和寬度
	 int width = image.getWidth(null); 
	 int height = image.getHeight(null); 
	 BufferedImage bi = new BufferedImage(width, height, 
			 BufferedImage.TYPE_INT_RGB); 
	 Graphics g = bi.getGraphics(); 
     //通過 BufferedImage 繪制圖像并儲存在其對象中
	 g.drawImage(image, 0, 0, width, height, null); 
	 g.dispose(); 
	 File f = new File(fileName); 
	 // 通過 ImageIO 将圖像寫入到檔案
	 ImageIO.write(bi, "jpg", f); 
	 }      

繼續閱讀