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