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