使用JAVA Robot 扩展Webdriver 模拟键盘鼠标操作

来源:互联网 发布:周璇 五月的风 知乎 编辑:程序博客网 时间:2024/05/16 05:41

使用 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);  }


0 0
原创粉丝点击