您的位置:軟件測(cè)試 > 開源軟件測(cè)試 > 開源功能測(cè)試工具 > Selenium
Selenium WebDriver中一些鼠標(biāo)和鍵盤事件的使用
作者:網(wǎng)絡(luò)轉(zhuǎn)載 發(fā)布時(shí)間:[ 2015/6/26 14:38:43 ] 推薦標(biāo)簽:功能測(cè)試工具

  清單 9. 修飾鍵方法 KeyDown(theKey)、keyUp(theKey)
  Actions action = new Actions(driver);
  action.keyDown(Keys.CONTROL);// 按下 Ctrl 鍵
  action.keyDown(Keys.SHIFT);// 按下 Shift 鍵
  action.keyDown(Key.ALT);// 按下 Alt 鍵
  action.keyUp(Keys.CONTROL);// 釋放 Ctrl 鍵
  action.keyUp(Keys.SHIFT);// 釋放 Shift 鍵
  action.keyUp(Keys.ALT);// 釋放 Alt 鍵
  所以要通過(guò) Alt+F4 來(lái)關(guān)閉當(dāng)前的活動(dòng)窗口,可以通過(guò)下面語(yǔ)句來(lái)實(shí)現(xiàn):action.keyDown(Keys.ALT).keyDown(Keys.F4).keyUp(Keys.ALT).perform();
  而如果是對(duì)于像鍵盤上面的字母鍵 a,b,c,d... 等的組合使用,可以通過(guò)以下語(yǔ)句實(shí)現(xiàn) :action.keyDown(Keys.CONTROL).sednKeys(“a”).perform();
  在 WebDriver API 中,KeyDown(Keys theKey)、KeyUp(Keys theKey) 方法的參數(shù)只能是修飾鍵:Keys.SHIFT、Keys.ALT、Keys.CONTROL, 否者將拋出 IllegalArgumentException 異常。 其次對(duì)于 action.keyDown(theKey) 方法的調(diào)用,如果沒有顯示的調(diào)用 action.keyUp(theKey) 或者 action.sendKeys(Keys.NULL) 來(lái)釋放的話,這個(gè)按鍵將一直保持按住狀態(tài)。
  使用 Robot 類來(lái)操作 Keys 沒有枚舉出來(lái)的按鍵操作
  1.在 WebDriver 中,Keys 枚舉出了鍵盤上大多數(shù)的非字母類按鍵,從 F1 到 F10,NUMPAD0 到 NUMPAD9、ALTTABCTRLSHIFT 等等,你可以通過(guò)以下鏈接查看 Keys 枚舉出來(lái)的所有按鍵,Enum Keys。 但是并沒有列出鍵盤上的所有按鍵,比如字母鍵 a、b、c、d … z,一些符號(hào)鍵比如:‘ {}[] ’、‘ ’、‘。’、‘ ? ’、‘:’、‘ + ’、‘ - ’、‘ = ’、、‘“”’,還有一些不常用到的功能鍵如 PrtSc、ScrLk/NmLk。對(duì)于字母鍵和符號(hào)鍵,前面我們已經(jīng)提到可以直接使用 sendKeys(“a”),sendKeys(“/”) 的方式來(lái)觸發(fā)這些鍵盤事件。而對(duì)于一些功能組合鍵,如 Fn + NmLk 來(lái)關(guān)閉或者打開數(shù)字鍵,或者 Alt+PrtSC 來(lái)抓取當(dāng)前屏幕的活動(dòng)窗口并保存到圖片,通過(guò) WebDriver 的 Keys 是沒辦法操作的。 這個(gè)時(shí)候我們需要用到 Java 的 Robot 類來(lái)實(shí)現(xiàn)對(duì)這類組合鍵的操作了。
  2.下面以對(duì) Alt+PrtSc 為例介紹一下 Robot 對(duì)鍵盤的操作。如代碼清單 10。
  清單 10. 通過(guò) Robot 發(fā)出組合鍵動(dòng)作
  /**
  *
  * @Description: 這個(gè)方法用來(lái)模擬發(fā)送組合鍵 Alt + PrtSc, 當(dāng)組合鍵盤事件執(zhí)行之后,屏幕上的活動(dòng)窗口
  * 被截取并且存儲(chǔ)在剪切板了。 接下來(lái)是通過(guò)讀取剪切板數(shù)據(jù)轉(zhuǎn)換成 Image 圖像對(duì)象并保存到本地。
  * @param filename : 要保存的圖像的名稱
  */
  public static void sendComposeKeys(String fileName) throws Exception {
  // 構(gòu)建 Robot 對(duì)象,用來(lái)操作鍵盤
  Robot robot = new Robot();
  // 模擬按下鍵盤動(dòng)作,這里通過(guò)使用 KeyEvent 類來(lái)獲取對(duì)應(yīng)鍵盤(ALT)的虛擬鍵碼
  robot.keyPress(java.awt.event.KeyEvent.VK_ALT);
  // 按下 PrtSC 鍵
  robot.keyPress(java.awt.event.KeyEvent.VK_PRINTSCREEN);
  // 釋放鍵盤動(dòng)作,當(dāng)這個(gè)動(dòng)作完成之后,模擬組合鍵 Alt + PrtSC 的過(guò)程已經(jīng)完成,
  //此時(shí)屏幕活動(dòng)窗口一被截取并存入到剪切板
  robot.keyRelease(java.awt.event.KeyEvent.VK_ALT);
  // 獲取系統(tǒng)剪切板實(shí)例
  Clipboard sysc = Toolkit.getDefaultToolkit().getSystemClipboard();
  // 通過(guò) getContents() 方法可以將剪切板內(nèi)容獲取并存入 Transferable 對(duì)象中
  Transferable data = sysc.getContents(null);
  if (data != null) {
  /***
  判斷從剪切板獲取的對(duì)象內(nèi)容是否為 Java Image 類, 如果是將直接轉(zhuǎn)化為 Image 對(duì)象。
  到此為止,我們從發(fā)出組合鍵到抓取活動(dòng)窗口,再讀取剪切板并存入 Image 對(duì)象的過(guò)程
  完成了,接下來(lái)要做的是需要將 Image 對(duì)象保存到本地。
  */
  if (data.isDataFlavorSupported(DataFlavor.imageFlavor)) {
  Image image = (Image) data
  .getTransferData(DataFlavor.imageFlavor);
  writeImageToFile(image, fileName);
  }
  }
  }
  Robot 類對(duì)鍵盤的處理是通過(guò) keyPress(int keycode)、keyRelease(int keycode) 方法來(lái)實(shí)現(xiàn)的,其中他們需要的參數(shù)是鍵盤按鍵對(duì)應(yīng)的虛擬鍵碼,虛擬鍵碼的值可以通過(guò) KeyEvent 類來(lái)獲取。在 Java API 中對(duì)于虛擬鍵碼的解釋如下: 虛擬鍵碼用于報(bào)告按下了鍵盤上的哪個(gè)鍵,而不是一次或多次鍵擊組合生成的字符(如 "A" 是由 shift + "a" 生成的)。 例如,按下 Shift 鍵會(huì)生成 keyCode 為 VK_SHIFT 的 KEY_PRESSED 事件,而按下 'a' 鍵將生成 keyCode 為 VK_A 的 KEY_PRESSED 事件。釋放 'a' 鍵后,會(huì)激發(fā) keyCode 為 VK_A 的 KEY_RELEASED 事件。另外,還會(huì)生成一個(gè) keyChar 值為 'A' 的 KEY_TYPED 事件。 按下和釋放鍵盤上的鍵會(huì)導(dǎo)致(依次)生成以下鍵事件:
  KEY_PRESSED
  KEY_TYPED(只在可生成有效 Unicode 字符時(shí)產(chǎn)生。)
  KEY_RELEASED
  所以當(dāng)測(cè)試中需要用到按下鍵盤 Alt+PrtSc 鍵的時(shí)候,只需要執(zhí)行代碼清單 10 中兩個(gè) keyPress() 和一個(gè) keyRelease() 方法即可。
  3.當(dāng)這兩個(gè)按鍵執(zhí)行結(jié)束之后,屏幕上面的活動(dòng)窗口已經(jīng)保存到剪切板中。如果需要將其保存本地圖片,只需要從剪切板讀取并通過(guò) JPEGImageEncoder 類或者 ImageIO 類將其寫入本地即可。
  清單 11. 使用 JPEGImageEncoder 將 Image 對(duì)象保存到本地
  /**
  *
  * @Description: 這個(gè)方法用來(lái)將 Image 對(duì)象保存到本地,主要是通過(guò) JPEGImageEncoder 類來(lái)實(shí)現(xiàn)圖像的
  * 保存
  * @param image : 要保存的 Image 對(duì)象
  * @param filename : 保存圖片的文件名稱
  */
  public static void writeImageToFile(Image image, String fileName) {
  try {
  // 獲取 Image 對(duì)象的寬度和高度, 這里的參數(shù)為 null 表示不需要通知任何觀察者
  int width = image.getWidth(null);
  int height = image.getHeight(null);
  BufferedImage bi = new BufferedImage(width, height,
  BufferedImage.TYPE_INT_RGB);
  // 通過(guò) BufferedImage 繪制圖像并保存在其對(duì)象中
  bi.getGraphics().drawImage(image, 0, 0, null);
  // 構(gòu)建圖像名稱及保存路徑
  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();
  }
  }
  代碼清單 11 是通過(guò) JPEGImageEncoder 類將 Image 對(duì)象寫到本地文件流,注意 Image 對(duì)象是在代碼清單 10 中的如下語(yǔ)句獲取到的:
  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);
  }
  }
  清單 12. 使用 ImageIO 將 Image 對(duì)象保存到本地
  /**
  *
  * @Description: 通過(guò)使用 ImageIO 類來(lái)保存 Image 對(duì)象為本地圖片
  * @param image : 需要保存的 Image 對(duì)象
  * @param filename : 文件名
  */
  public static void saveImage(Image image, String fileName) throws Exception {
  // 獲取 Image 對(duì)象的高度和寬度
  int width = image.getWidth(null);
  int height = image.getHeight(null);
  BufferedImage bi = new BufferedImage(width, height,
  BufferedImage.TYPE_INT_RGB);
  Graphics g = bi.getGraphics();
  //通過(guò) BufferedImage 繪制圖像并保存在其對(duì)象中
  g.drawImage(image, 0, 0, width, height, null);
  g.dispose();
  File f = new File(fileName);
  // 通過(guò) ImageIO 將圖像寫入到文件
  ImageIO.write(bi, "jpg", f);
  }
  使用 sendKeys(keysToSend) 批量上傳文件
  在 Selenium2.0 之前,要上傳文件是比較麻煩的一件事件,因?yàn)辄c(diǎn)擊 Upload File 控件會(huì)彈出 Windows 窗口以提供用戶選擇文件,但是 Window 窗口已經(jīng)是瀏覽器之外的組件,所以 Selenium 本身沒辦法控制, 而必須使用 Java Robot 類來(lái)模擬鍵盤去操作剪切板實(shí)現(xiàn)上傳功能,而且及其不穩(wěn)定。 在 Selenium 2.0 之后,WebDriver 解決了這個(gè)問題。前面已經(jīng)談到過(guò),直接使用 WebElement 類的 sendKeys(keysToSend) 方法可以實(shí)現(xiàn)文件上傳了。但是如果想批量上傳文件,使用 element.sendKeys(“C:\test\upload\test1.txt”, “C:\test\upload\test2.txt”...) 方法也是不行的,它能通過(guò)執(zhí)行,但是實(shí)際上沒有上傳成功。這時(shí)可以通過(guò)循環(huán)的方式來(lái)實(shí)現(xiàn)文件的批量上傳,代碼清單 13 是我在百度云上面批量上傳文件的測(cè)試。
  清單 13. 批量上傳文件
  /**
  *
  * @Description: 在百度云上測(cè)試文件批量上傳功能,主要是通過(guò)循環(huán)的方式去做單一
  * 的上傳動(dòng)作 , 登陸過(guò)程已經(jīng)去掉
  */
  @Test
  public void test_mutilUploadFile() throws Exception {
  System.out.println("upload start");
  // 獲取上傳控件元素
  WebElement uploadButton = driver.findElement(By.name("html5uploader"));
  // 構(gòu)建上傳文件路徑,將需要上傳的文件添加到 CharSequence 數(shù)組
  CharSequence[] files = new CharSequence[5];
  files[0] = "C:\test\test1.txt";
  files[1] = "C:\test\test2.txt";
  files[2] = "C:\test\test3.txt";
  files[3] = "C:\test\test4.txt";
  files[4] = "C:\test\test5.txt";
  // 循環(huán)列出每支需要上傳的文件路徑,做單一上傳動(dòng)作
  for(CharSequence file: files){
  uploadButton.sendKeys(file);
  }
  Thread.sleep(2000);
  System.out.println("upload end");
  }
  當(dāng)執(zhí)行結(jié)束后,效果如圖 1。
  圖 1. 批量上傳文件

  結(jié)束語(yǔ)
  在 Selenium WebDriver 中,有了 Actions 類和 Keys 枚舉對(duì)鍵盤和鼠標(biāo)的操作已經(jīng)做的非常到位,再結(jié)合 Java 本身 Robot、KeyEvent 等類的使用,基本上可以滿足工作中遇到的對(duì)鼠標(biāo)鍵盤操作的應(yīng)用了。
  其次要注意的地方是 WebDriver 對(duì)瀏覽器的支持問題,Selenium WebDriver 支持的瀏覽器非常廣泛,從 IE、Firefox、Chrome 到 Safari 等瀏覽器, WebDriver 都有相對(duì)應(yīng)的實(shí)現(xiàn):InterntExplorerDriver、FirefoxDriver、ChromeDriver、SafariDriver、AndroidDriver、 IPhoneDriver、HtmlUnitDriver 等。根據(jù)個(gè)人的經(jīng)驗(yàn),F(xiàn)irefox 以及 Chrome 瀏覽器對(duì) WebDriver 的支持好了,F(xiàn)irefox 搭上 Firebug 以及 Firepath, 在寫腳本的過(guò)程中非常方便,而 ChromeDriver 是 Google 公司自己支持與維護(hù)的項(xiàng)目。HtmlUnitDriver 速度快,一個(gè)純 Java 實(shí)現(xiàn)的瀏覽器。IE 比較慢,而且對(duì)于 Xpath 等支持不是很好。更多關(guān)于 Selenium WebDriver 的知識(shí),大家可以從下面的鏈接去訪問 Selenium 官方文檔。

上一頁(yè)12下一頁(yè)
軟件測(cè)試工具 | 聯(lián)系我們 | 投訴建議 | 誠(chéng)聘英才 | 申請(qǐng)使用列表 | 網(wǎng)站地圖
滬ICP備07036474 2003-2017 版權(quán)所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd