1 /* 2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @summary Utility routines that wait for a window to be displayed or for colors to be visible 26 * @summary com.apple.junit.utils 27 */ 28 29 package test.java.awt.regtesthelpers; 30 31 import java.awt.*; 32 import java.awt.event.InputEvent; 33 import java.util.TimerTask; 34 import javax.swing.JButton; 35 36 public class RobotUtilities { 37 public static final int CLICK_DELAY = 20; // interval between mouse down and mouse up events 38 public static final int DOUBLE_CLICK_DELAY = 100; // interval between clicks of a double click 39 public static final int POST_MOVE_DELAY = 250; // allow some time for visual verification 40 public static final int PRE_TEST_DELAY = 250; // allow some time for frame to draw 41 public static final int POST_TEST_DELAY = 750; // allow some time for event processing/visual verification 42 43 public RobotUtilities() { 44 45 } 46 47 ///////////////////////////////////////////////////////////////////////////////////////////////// 48 ///////////////////////////////////////////////////////////////////////////////////////////////// 49 public static void pressKey(int num) { 50 Robot robot = getRobot(); 51 robot.keyPress(num); 52 } 53 54 ///////////////////////////////////////////////////////////////////////////////////////////////// 55 ///////////////////////////////////////////////////////////////////////////////////////////////// 56 public static void releaseKey(int num) { 57 Robot robot = getRobot(); 58 robot.keyRelease(num); 59 } 60 61 ///////////////////////////////////////////////////////////////////////////////////////////////// 62 ///////////////////////////////////////////////////////////////////////////////////////////////// 63 public static void typeKey(int num) { 64 Robot robot = getRobot(); 65 robot.keyPress(num); 66 robot.delay(CLICK_DELAY); 67 robot.keyRelease(num); 68 } 69 70 static Robot _robot; 71 private static Robot getRobot() { 72 if (_robot == null) { 73 try { _robot = new Robot(); } catch (AWTException e) { throw new RuntimeException(e); } 74 } 75 return _robot; 76 } 77 78 ///////////////////////////////////////////////////////////////////////////////////////////////// 79 // moveMouse - move the cusor to the specified location 80 ///////////////////////////////////////////////////////////////////////////////////////////////// 81 public static void moveMouseTo(int posX, int posY) { 82 Robot robot = getRobot(); 83 robot.mouseMove(posX , posY); 84 robot.delay(POST_MOVE_DELAY); 85 } 86 87 ///////////////////////////////////////////////////////////////////////////////////////////////// 88 // moveMouse - move the cusor to the specified location of the component 89 // positive values specify the offset from the top-left of the component 90 // negative values specify the offset from the bottom-right of the component 91 ///////////////////////////////////////////////////////////////////////////////////////////////// 92 public static void moveMouseTo(Component c, int posX, int posY) { 93 Point pt; 94 int x; 95 int y; 96 97 if(c == null) 98 return; 99 100 // Get the position of the component 101 pt = c.getLocationOnScreen(); 102 103 x = pt.x + posX; 104 if(posX < 0) 105 x += c.getWidth(); 106 107 y = pt.y + posY; 108 if(posY < 0) 109 y += c.getHeight(); 110 111 moveMouseTo(x, y); 112 // robot.mouseMove(x , y); 113 // robot.delay(POST_MOVE_DELAY); 114 } 115 116 ///////////////////////////////////////////////////////////////////////////////////////////////// 117 // moveMouse - move the cusor to the specified location of the component 118 // positive values specify the offset from the top-left of the component 119 // negative values specify the offset from the bottom-right of the component 120 ///////////////////////////////////////////////////////////////////////////////////////////////// 121 public static void moveMouseFromCenter(Component c, int offsetX, int offsetY) { 122 Point pt; 123 int x; 124 int y; 125 126 if(c == null) 127 return; 128 129 // Get the position of the component 130 pt = c.getLocationOnScreen(); 131 132 x = pt.x + offsetX + c.getWidth()/2; 133 134 y = pt.y + offsetY + c.getHeight()/2; 135 136 moveMouseTo(x, y); 137 } 138 139 ///////////////////////////////////////////////////////////////////////////////////////////////// 140 // moveMouseToCenter - move the cusor to the center of the component 141 ///////////////////////////////////////////////////////////////////////////////////////////////// 142 public static void moveMouseToCenter(Component c) { 143 Point pt; 144 int x; 145 int y; 146 147 if(c == null) 148 return; 149 150 // Get the position of the component 151 pt = c.getLocationOnScreen(); 152 153 x = pt.x + c.getWidth()/2; 154 155 y = pt.y + c.getHeight()/2; 156 157 moveMouseTo(x, y); 158 } 159 160 ///////////////////////////////////////////////////////////////////////////////////////////////// 161 ///////////////////////////////////////////////////////////////////////////////////////////////// 162 public static void pressMouseButton() { 163 Robot robot = getRobot(); 164 robot.mousePress(InputEvent.BUTTON1_MASK); 165 } 166 167 ///////////////////////////////////////////////////////////////////////////////////////////////// 168 ///////////////////////////////////////////////////////////////////////////////////////////////// 169 public static void releaseMouseButton() { 170 Robot robot = getRobot(); 171 robot.mouseRelease(InputEvent.BUTTON1_MASK); 172 } 173 174 ///////////////////////////////////////////////////////////////////////////////////////////////// 175 ///////////////////////////////////////////////////////////////////////////////////////////////// 176 public static void click() { 177 Robot robot = getRobot(); 178 robot.mousePress(InputEvent.BUTTON1_MASK); 179 robot.delay(CLICK_DELAY); 180 robot.mouseRelease(InputEvent.BUTTON1_MASK); 181 } 182 183 ///////////////////////////////////////////////////////////////////////////////////////////////// 184 ///////////////////////////////////////////////////////////////////////////////////////////////// 185 public static void click(Component c) { 186 Point pt; 187 int x; 188 int y; 189 190 if(c == null) 191 return; 192 193 // Get the position of the component 194 pt = c.getLocationOnScreen(); 195 196 x = pt.x + c.getWidth()/2; 197 y = pt.y + c.getHeight()/2; 198 199 moveMouseTo(x , y); 200 201 click(); 202 } 203 204 ///////////////////////////////////////////////////////////////////////////////////////////////// 205 ///////////////////////////////////////////////////////////////////////////////////////////////// 206 public static void doubleClick() { 207 Robot robot = getRobot(); 208 click(); 209 robot.delay(DOUBLE_CLICK_DELAY); 210 click(); 211 } 212 213 ///////////////////////////////////////////////////////////////////////////////////////////////// 214 ///////////////////////////////////////////////////////////////////////////////////////////////// 215 public static void doubleClick(Component c) { 216 Point pt; 217 int x; 218 int y; 219 220 if(c == null) 221 return; 222 223 // Get the position of the component 224 pt = c.getLocationOnScreen(); 225 226 x = pt.x + c.getWidth()/2; 227 y = pt.y + c.getHeight()/2; 228 229 moveMouseTo(x , y); 230 231 doubleClick(); 232 } 233 234 ///////////////////////////////////////////////////////////////////////////////////////////////// 235 ///////////////////////////////////////////////////////////////////////////////////////////////// 236 public static void tripleClick() { 237 Robot robot = getRobot(); 238 click(); 239 robot.delay(DOUBLE_CLICK_DELAY); 240 click(); 241 robot.delay(DOUBLE_CLICK_DELAY); 242 click(); 243 } 244 245 ///////////////////////////////////////////////////////////////////////////////////////////////// 246 ///////////////////////////////////////////////////////////////////////////////////////////////// 247 public static void tripleClick(Component c) { 248 Point pt; 249 int x; 250 int y; 251 252 if(c == null) 253 return; 254 255 // Get the position of the component 256 pt = c.getLocationOnScreen(); 257 258 x = pt.x + c.getWidth()/2; 259 y = pt.y + c.getHeight()/2; 260 261 moveMouseTo(x , y); 262 263 tripleClick(); 264 } 265 266 ///////////////////////////////////////////////////////////////////////////////////////////////// 267 // clickAt - click at specified point 268 ///////////////////////////////////////////////////////////////////////////////////////////////// 269 public static void clickAt(int posX, int posY) { 270 moveMouseTo(posX , posY); 271 click(); 272 } 273 274 ///////////////////////////////////////////////////////////////////////////////////////////////// 275 // clickAt - click at specified point in the component 276 // positive values specify the offset from the top-left of the component 277 // negative values specify the offset from the bottom-right of the component 278 ///////////////////////////////////////////////////////////////////////////////////////////////// 279 public static void clickAt(Component c, int posX, int posY) { 280 moveMouseTo(c, posX, posY); 281 click(); 282 } 283 284 ///////////////////////////////////////////////////////////////////////////////////////////////// 285 ///////////////////////////////////////////////////////////////////////////////////////////////// 286 public static void delay(int interval) { 287 Robot robot = getRobot(); 288 robot.delay(interval); 289 } 290 291 ///////////////////////////////////////////////////////////////////////////////////////////////// 292 // clickAndDrag - click and drag within the component 293 // positive values specify the offset from the top-left of the component 294 // negative values specify the offset from the bottom-right of the component 295 ///////////////////////////////////////////////////////////////////////////////////////////////// 296 public static void clickAndDrag(Component c, int startX, int startY, int endX, int endY) { 297 Point pt; 298 int x; 299 int y; 300 301 if(c == null) 302 return; 303 304 // Get the position of the component 305 pt = c.getLocationOnScreen(); 306 307 // Make adjustments for negative values of offset 308 x = pt.x + startX; 309 if(startX < 0) 310 x += c.getWidth(); 311 312 y = pt.y + startY; 313 if(startY < 0) 314 y += c.getHeight(); 315 316 317 moveMouseTo(x , y); 318 pressMouseButton(); 319 320 x = pt.x + endX; 321 if(endX < 0) 322 x += c.getWidth(); 323 324 y = pt.y + endY; 325 if(endY < 0) 326 y += c.getHeight(); 327 328 moveMouseTo(x , y); 329 releaseMouseButton(); 330 } 331 332 333 ///////////////////////////////////////////////////////////////////////////////////////////////// 334 // screenshot - take a screenshot and save to disk as a jpg 335 // basename - base name of the file. the file will be named <basename>.<timestamp>.jpg 336 // location - parent directory. If null, uses the current working directory. 337 // return value - the File for the newly created image. 338 // failure cases - if the basename is null, the file already exists, or location isn't a directory, returns null. 339 ///////////////////////////////////////////////////////////////////////////////////////////////// 340 public static java.io.File screenshot(String basename, java.io.File location) throws java.io.IOException, java.awt.AWTException { 341 if (basename == null) return null; 342 if (location != null) { 343 if (!location.exists() || !location.isDirectory()) { 344 return null; 345 } 346 } 347 348 Robot robot = getRobot(); 349 java.awt.image.BufferedImage screenshot = robot.createScreenCapture(new java.awt.Rectangle(java.awt.Toolkit.getDefaultToolkit().getScreenSize())); 350 351 java.util.GregorianCalendar calendar = new java.util.GregorianCalendar(); 352 StringBuffer sb = new StringBuffer(); 353 sb.append(basename); 354 sb.append("."); 355 sb.append(calendar.get(java.util.Calendar.YEAR)); 356 sb.append(calendar.get(java.util.Calendar.MONTH)); 357 sb.append(calendar.get(java.util.Calendar.DAY_OF_MONTH)); 358 sb.append(calendar.get(java.util.Calendar.HOUR_OF_DAY)); 359 sb.append(calendar.get(java.util.Calendar.MINUTE)); 360 sb.append(".png"); 361 362 java.io.File outputFile = new java.io.File(location, sb.toString()); 363 javax.imageio.ImageIO.write(screenshot, "png", outputFile); 364 365 return outputFile; 366 } 367 368 369 /* 370 * Utility function to walk the container heirarchy looking for a JButton 371 * matching a specific text string. For example, this is used to extract 372 * the "Cancel" button from a JDialog. 373 */ 374 375 public static JButton extractJButton( Container parent, String text ) { 376 JButton cancel = null; 377 Component[] c = parent.getComponents(); 378 for (int i = 0; i < c.length; i += 1) { 379 if (c[i]instanceof JButton) { 380 JButton b = (JButton) c[i]; 381 if (b.getText().equals( text )) { 382 cancel = (JButton) c[i]; 383 break; 384 } 385 } 386 else if (c[i]instanceof Container) { 387 cancel = extractJButton( (Container) c[i], text ); 388 } 389 } 390 return cancel; 391 } 392 393 394 /* 395 * Utility class that takes a JButton and, later on, clicks it 396 */ 397 398 public static class Clicker extends TimerTask { 399 JButton target = null; 400 private Exception cachedException; 401 402 // We need to know what to click 403 public Clicker( JButton target) { 404 super(); 405 this.target = target; 406 } 407 408 // This does the clicking 409 public void run() { 410 try { 411 Robot r = new Robot(); 412 Point pt = target.getLocationOnScreen(); 413 int x = pt.x + target.getWidth() / 2; 414 int y = pt.y + target.getHeight() / 2; 415 r.mouseMove( x, y ); 416 r.delay( 30 ); 417 r.mousePress( InputEvent.BUTTON1_MASK ); 418 r.delay( 101 ); 419 r.mouseRelease( InputEvent.BUTTON1_MASK ); 420 } 421 catch(Exception x) { 422 setCachedException(x); 423 } 424 } 425 426 void setCachedException(Exception cachedException) { 427 this.cachedException = cachedException; 428 } 429 430 public Exception getCachedException() { 431 return cachedException; 432 } 433 434 435 } 436 437 }