1 /* 2 * Copyright (c) 2007, 2017, 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 package org.jemmy.input; 24 25 26 import java.awt.AWTException; 27 import java.awt.BorderLayout; 28 import java.awt.Button; 29 import java.awt.EventQueue; 30 import java.awt.Frame; 31 import java.awt.Robot; 32 import java.awt.event.InputEvent; 33 import java.awt.event.KeyAdapter; 34 import java.awt.event.KeyEvent; 35 import java.awt.event.MouseAdapter; 36 import java.awt.event.MouseEvent; 37 import java.io.File; 38 import java.lang.reflect.InvocationTargetException; 39 import org.jemmy.Point; 40 import org.jemmy.control.Wrap; 41 import org.jemmy.env.Environment; 42 import org.jemmy.env.Timeout; 43 import org.jemmy.image.AWTImage; 44 import org.jemmy.interfaces.Keyboard; 45 import org.jemmy.interfaces.Keyboard.KeyboardButton; 46 import org.jemmy.interfaces.Keyboard.KeyboardButtons; 47 import org.jemmy.interfaces.Keyboard.KeyboardModifiers; 48 import org.jemmy.interfaces.Modifier; 49 import org.jemmy.interfaces.Mouse; 50 import org.jemmy.interfaces.Mouse.MouseButton; 51 import org.jemmy.interfaces.Mouse.MouseButtons; 52 import org.jemmy.timing.State; 53 import org.jemmy.timing.Waiter; 54 import org.testng.annotations.AfterClass; 55 import org.testng.annotations.AfterMethod; 56 import org.testng.annotations.BeforeClass; 57 import org.testng.annotations.BeforeMethod; 58 import org.testng.annotations.Test; 59 60 import static org.testng.Assert.assertFalse; 61 import static org.testng.Assert.assertTrue; 62 63 64 /** 65 * 66 * @author Alexander Kouznetsov <mrkam@mail.ru> 67 */ 68 public class RobotDriverTest { 69 70 final static Timeout TIMEOUT = new Timeout("Wait for state to be reached", 10000); 71 final static Timeout DELTA_TIMEOUT = new Timeout("Delta timeout of wait for state to be reached", 1000); 72 73 public RobotDriverTest() { 74 } 75 76 @BeforeClass 77 public static void setUpClass() throws Exception { 78 File workdir = new File(System.getProperty("user.dir") + File.separator + 79 "build" + File.separator + 80 "test" + File.separator + 81 "results"); 82 workdir.mkdirs(); 83 AWTImage.setImageRoot(workdir); 84 } 85 86 @AfterClass 87 public static void tearDownClass() throws Exception { 88 RobotDriver.exit(); 89 } 90 91 Frame frm; 92 Button btn; 93 Wrap<Object> area; 94 private volatile boolean mousePressed; 95 private volatile boolean mouseReleased; 96 private volatile boolean mouseMoved; 97 private volatile boolean mouseClicked; 98 private volatile boolean mouseDragged; 99 private volatile boolean keyPressed; 100 private volatile boolean keyReleased; 101 RobotDriver instance; 102 Robot rb; 103 104 @BeforeMethod 105 public void setUp() throws InterruptedException, AWTException, InvocationTargetException { 106 EventQueue.invokeAndWait(new Runnable() { 107 108 public void run() { 109 frm = new Frame("some frame"); 110 frm.setSize(100, 100); 111 frm.setLocation(100, 100); 112 btn = new Button("some button"); 113 MouseAdapter m = new MouseAdapter() { 114 115 @Override 116 public void mousePressed(MouseEvent e) { 117 System.out.println("mousePressed event triggered: " + e); 118 System.out.flush(); 119 if ((e.getButton() & MouseEvent.BUTTON1) != 0 && e.isShiftDown()) { 120 mousePressed = true; 121 } 122 } 123 124 @Override 125 public void mouseReleased(MouseEvent e) { 126 System.out.println("mouseReleased event triggered: " + e); 127 System.out.flush(); 128 if ((e.getButton() & MouseEvent.BUTTON2) != 0 && e.isControlDown()) { 129 mouseReleased = true; 130 } 131 } 132 133 @Override 134 public void mouseMoved(MouseEvent e) { 135 System.out.println("mouseMoved event triggered: " + e); 136 System.out.flush(); 137 mouseMoved = true; 138 } 139 140 @Override 141 public void mouseClicked(MouseEvent e) { 142 System.out.println("mouseClicked event triggered: " + e); 143 System.out.flush(); 144 if ((e.getButton() & MouseEvent.BUTTON3) != 0 && e.isAltDown()) { 145 mouseClicked = true; 146 } 147 } 148 149 @Override 150 public void mouseDragged(MouseEvent e) { 151 System.out.println("mouseDragged event triggered: " + e); 152 System.out.flush(); 153 if ((e.getModifiers() & MouseEvent.BUTTON2_MASK) != 0) { 154 mouseDragged = true; 155 } 156 } 157 158 }; 159 btn.addMouseListener(m); 160 btn.addMouseMotionListener(m); 161 btn.addKeyListener(new KeyAdapter() { 162 163 @Override 164 public void keyPressed(KeyEvent e) { 165 System.out.println("keyPressed event triggered: " + e); 166 System.out.flush(); 167 if (e.getKeyCode() == KeyEvent.VK_A && e.isShiftDown()) { 168 keyPressed = true; 169 } 170 } 171 172 @Override 173 public void keyReleased(KeyEvent e) { 174 System.out.println("keyReleased event triggered: " + e); 175 System.out.flush(); 176 if (e.getKeyCode() == KeyEvent.VK_B) { 177 keyReleased = true; 178 } 179 } 180 181 }); 182 frm.add(btn, BorderLayout.SOUTH); 183 frm.doLayout(); 184 instance = new RobotDriver(Environment.getEnvironment()); 185 frm.setVisible(true); 186 btn.requestFocusInWindow(); 187 } 188 }); 189 190 rb = new Robot(); 191 rb.waitForIdle(); 192 193 RobotExecutor.get().setRunInOtherJVM(true); 194 } 195 196 @AfterMethod 197 public void tearDown() throws InterruptedException, InvocationTargetException { 198 EventQueue.invokeAndWait(new Runnable() { 199 200 public void run() { 201 frm.setVisible(false); 202 } 203 }); 204 } 205 206 // /** 207 // * Test of createScreenCapture method, of class RobotDriver. 208 // */ 209 // @Test 210 // public void testCreateScreenCaptureLocally() throws AWTException, InterruptedException { 211 // System.out.println("testCreateScreenCaptureLocally"); 212 // Thread.sleep(3000); 213 // Rectangle screenRect = new Rectangle(100, 100, 100, 100); 214 // RobotExecutor.get().setRunInOtherJVM(false); 215 // Image expResult = new AWTImage(new Robot().createScreenCapture(new java.awt.Rectangle(100, 100, 100, 100))); 216 // Image result = RobotDriver.createScreenCapture(screenRect); 217 // Image diff = expResult.compareTo(result); 218 // if (diff != null) { 219 // diff.save("testCreateScreenCaptureLocally.png"); 220 // fail(); 221 // } 222 // } 223 // 224 // /** 225 // * Test of createScreenCapture method, of class RobotDriver. 226 // */ 227 // @Test 228 // public void testCreateScreenCaptureRemotely() throws AWTException, InterruptedException { 229 // System.out.println("testCreateScreenCaptureRemotely"); 230 // Thread.sleep(3000); 231 // Rectangle screenRect = new Rectangle(100, 100, 100, 100); 232 // RobotExecutor.get().setRunInOtherJVM(true); 233 // Image expResult = new AWTImage(new Robot().createScreenCapture(new java.awt.Rectangle(100, 100, 100, 100))); 234 // Image result = RobotDriver.createScreenCapture(screenRect); 235 // RobotDriver.createScreenCapture(screenRect); 236 // Image diff = expResult.compareTo(result); 237 // if (diff != null) { 238 // diff.save("testCreateScreenCaptureRemotely.png"); 239 // fail(); 240 // } 241 // } 242 // 243 // /** 244 // * Test of createScreenCapture method, of class RobotDriver. 245 // */ 246 // @Test 247 // public void testCreateScreenCaptureRemotely2() throws AWTException, InterruptedException { 248 // System.out.println("testCreateScreenCaptureRemotely2"); 249 // Thread.sleep(3000); 250 // Rectangle screenRect = new Rectangle(100, 100, 100, 100); 251 // RobotExecutor.get().setRunInOtherJVM(true); 252 // Image expResult = new AWTImage(new Robot().createScreenCapture(new java.awt.Rectangle(100, 100, 100, 100))); 253 // Image result = RobotDriver.createScreenCapture(screenRect); 254 // Image diff = expResult.compareTo(result); 255 // if (diff != null) { 256 // diff.save("testCreateScreenCaptureRemotely2.png"); 257 // fail(); 258 // } 259 // } 260 261 /** 262 * Test of pressMouse method, of class RobotDriver. 263 */ 264 @Test 265 public void testPressMouse() throws InterruptedException { 266 System.out.println("pressMouse"); 267 Thread.sleep(3000); 268 // new Thread() { 269 // 270 // @Override 271 // public void run() { 272 MouseButton mouseButton = MouseButtons.BUTTON1; 273 Modifier modifiers[] = new Modifier[] {KeyboardModifiers.SHIFT_DOWN_MASK}; 274 mousePressed = false; 275 java.awt.Point locationOnScreen = btn.getLocationOnScreen(); 276 System.out.println("Pressing mouse"); 277 instance.moveMouse(new Point(locationOnScreen.x + btn.getWidth() / 2, locationOnScreen.y + btn.getHeight() / 2)); 278 instance.pressMouse(mouseButton, modifiers); 279 instance.releaseMouse(mouseButton, modifiers); 280 281 rb.waitForIdle(); 282 new Waiter(TIMEOUT, DELTA_TIMEOUT).ensureState(new State<Boolean>(){ 283 284 public Boolean reached() { 285 return mousePressed ? true: null; 286 } 287 288 }); 289 290 // } 291 // 292 // }.start(); 293 } 294 295 /** 296 * Test of releaseMouse method, of class RobotDriver. 297 */ 298 @Test 299 public void testReleaseMouse() throws InterruptedException { 300 System.out.println("releaseMouse"); 301 Thread.sleep(3000); 302 MouseButton mouseButton = MouseButtons.BUTTON2; 303 Modifier modifiers[] = new Modifier[] {KeyboardModifiers.CTRL_DOWN_MASK}; 304 mouseReleased = false; 305 java.awt.Point locationOnScreen = btn.getLocationOnScreen(); 306 instance.moveMouse(new Point(locationOnScreen.x + btn.getWidth() / 2, locationOnScreen.y + btn.getHeight() / 2)); 307 System.out.println("Pressing mouse"); 308 instance.pressMouse(mouseButton, modifiers); 309 System.out.println("Releasing mouse"); 310 instance.releaseMouse(mouseButton, modifiers); 311 312 rb.waitForIdle(); 313 new Waiter(TIMEOUT, DELTA_TIMEOUT).ensureState(new State<Boolean>(){ 314 315 public Boolean reached() { 316 return mouseReleased ? true: null; 317 } 318 319 }); 320 assertTrue(mouseReleased); 321 } 322 323 /** 324 * Test of moveMouse method, of class RobotDriver. 325 */ 326 @Test 327 public void testMoveMouse() throws InterruptedException { 328 System.out.println("moveMouse"); 329 Thread.sleep(3000); 330 mouseMoved = false; 331 java.awt.Point locationOnScreen = btn.getLocationOnScreen(); 332 System.out.println("Moving mouse"); 333 Point startPoint = new Point(locationOnScreen.x, locationOnScreen.y); 334 Point endPoint = new Point(locationOnScreen.x + btn.getWidth(), locationOnScreen.y + btn.getHeight()); 335 double steps = 5; //Math.max(btn.getWidth(), btn.getHeight()); 336 double dx = (endPoint.x - startPoint.x) / steps; 337 double dy = (endPoint.y - startPoint.y) / steps; 338 for(int i = 0; i < steps; i++) { 339 Point point = new Point(startPoint.x + dx * i, startPoint.y + dy * i); 340 instance.moveMouse(point); 341 Thread.sleep(100); 342 } 343 344 rb.waitForIdle(); 345 new Waiter(TIMEOUT, DELTA_TIMEOUT).ensureState(new State<Boolean>(){ 346 347 public Boolean reached() { 348 return mouseMoved ? true: null; 349 } 350 351 }); 352 assertTrue(mouseMoved); 353 } 354 355 /** 356 * Test of moveMouse method with smoothness set Integer.MAX_VALUE 357 * of class RobotDriver. 358 */ 359 @Test 360 public void testMoveNonSmoothMouse() throws InterruptedException { 361 System.out.println("testMoveNonSmoothMouse"); 362 Thread.sleep(3000); 363 mouseMoved = false; 364 java.awt.Point locationOnScreen = btn.getLocationOnScreen(); 365 System.out.println("Moving mouse"); 366 Point startPoint = new Point(locationOnScreen.x - 10, locationOnScreen.y - 10); 367 Point endPoint = new Point(locationOnScreen.x + btn.getWidth() + 10, locationOnScreen.y + btn.getHeight() + 10); 368 instance.moveMouse(startPoint); 369 Thread.sleep(100); 370 instance.moveMouse(endPoint); 371 Thread.sleep(2000); 372 373 rb.waitForIdle(); 374 new Waiter(TIMEOUT, DELTA_TIMEOUT).ensureState(new State<Boolean>(){ 375 376 public Boolean reached() { 377 return !mouseMoved ? true : null; 378 } 379 380 }); 381 assertFalse(mouseMoved); 382 } 383 384 /** 385 * Test of clickMouse method, of class RobotDriver. 386 */ 387 @Test 388 public void testClickMouse() throws InterruptedException { 389 System.out.println("clickMouse"); 390 Thread.sleep(3000); 391 mouseClicked = false; 392 java.awt.Point locationOnScreen = btn.getLocationOnScreen(); 393 Point point = new Point(locationOnScreen.x + btn.getWidth() / 2, locationOnScreen.y + btn.getHeight() / 2); 394 int clickCount = 1; 395 MouseButton mouseButton = MouseButtons.BUTTON3; 396 Modifier modifiers[] = new Modifier[] {KeyboardModifiers.ALT_DOWN_MASK}; 397 Timeout mouseClick = new Timeout("mouseClick", 100); 398 System.out.println("Clicking mouse"); 399 instance.clickMouse(point, clickCount, mouseButton, mouseClick, modifiers); 400 401 rb.waitForIdle(); 402 new Waiter(TIMEOUT, DELTA_TIMEOUT).ensureState(new State<Boolean>(){ 403 404 public Boolean reached() { 405 return mouseClicked ? true: null; 406 } 407 408 }); 409 assertTrue(mouseClicked); 410 } 411 412 /** 413 * Test of dragNDrop method, of class RobotDriver. 414 */ 415 @Test 416 public void testDragNDrop() throws InterruptedException { 417 System.out.println("dragNDrop"); 418 java.awt.Point locationOnScreen = btn.getLocationOnScreen(); 419 Point startPoint = new Point(locationOnScreen.x + btn.getWidth() / 2, locationOnScreen.y + btn.getHeight() / 2); 420 Point endPoint = new Point(frm.getLocationOnScreen().x + frm.getWidth() / 2, frm.getLocationOnScreen().y + frm.getHeight() / 2); 421 MouseButton mouseButton = MouseButtons.BUTTON2; 422 Modifier modifiers[] = new Modifier[] {}; 423 Timeout before = new Timeout("before", 500); 424 Timeout after = new Timeout("after", 500); 425 mouseDragged = false; 426 instance.dragNDrop(startPoint, endPoint, mouseButton, modifiers, before, after); 427 428 rb.waitForIdle(); 429 new Waiter(TIMEOUT, DELTA_TIMEOUT).ensureState(new State<Boolean>(){ 430 431 public Boolean reached() { 432 return mouseDragged ? true: null; 433 } 434 435 }); 436 assertTrue(mouseDragged); 437 } 438 439 /** 440 * Test of pressKey method, of class RobotDriver. 441 */ 442 @Test 443 public void testPressKey() throws InterruptedException { 444 System.out.println("pressKey"); 445 KeyboardButton kbdButton = KeyboardButtons.A; 446 Modifier modifiers[] = new Modifier[] {KeyboardModifiers.SHIFT_DOWN_MASK}; 447 keyPressed = false; 448 instance.pressKey(kbdButton, modifiers); 449 instance.releaseKey(kbdButton, modifiers); 450 451 rb.waitForIdle(); 452 new Waiter(TIMEOUT, DELTA_TIMEOUT).ensureState(new State<Boolean>(){ 453 454 public Boolean reached() { 455 return keyPressed ? true: null; 456 } 457 458 }); 459 assertTrue(keyPressed); 460 } 461 462 /** 463 * Test of releaseKey method, of class RobotDriver. 464 */ 465 @Test 466 public void testReleaseKey() throws InterruptedException { 467 System.out.println("releaseKey"); 468 KeyboardButton kbdButton = KeyboardButtons.B; 469 Modifier modifiers[] = new Modifier[] {}; 470 keyReleased = false; 471 instance.pressKey(kbdButton, modifiers); 472 instance.releaseKey(kbdButton, modifiers); 473 474 rb.waitForIdle(); 475 new Waiter(TIMEOUT, DELTA_TIMEOUT).ensureState(new State<Boolean>(){ 476 477 public Boolean reached() { 478 return keyReleased ? true: null; 479 } 480 481 }); 482 assertTrue(keyReleased); 483 } 484 }