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 java.util.HashMap;
  42 import java.util.HashSet;
  43 import java.util.Queue;
  44 import java.util.Random;
  45 import java.util.concurrent.ConcurrentLinkedQueue;
  46 import org.jemmy.Point;
  47 import org.jemmy.control.Wrap;
  48 import org.jemmy.env.Environment;
  49 import org.jemmy.env.Timeout;
  50 import org.jemmy.image.AWTImage;
  51 import org.jemmy.interfaces.Keyboard.KeyboardButton;
  52 import org.jemmy.interfaces.Modifier;
  53 import org.jemmy.interfaces.Mouse.MouseButton;
  54 import org.jemmy.interfaces.Mouse.MouseButtons;
  55 import org.jemmy.timing.State;
  56 import org.jemmy.timing.Waiter;
  57 import org.testng.annotations.AfterClass;
  58 import org.testng.annotations.AfterMethod;
  59 import org.testng.annotations.BeforeClass;
  60 import org.testng.annotations.BeforeMethod;
  61 import org.testng.annotations.Test;
  62 
  63 
  64 /**
  65  *
  66  * @author Alexander Kouznetsov <mrkam@mail.ru>
  67  */
  68 public class RobotDriver2Test {
  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 RobotDriver2Test() {
  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     RobotDriver instance;
  95     Robot rb;
  96     Queue<InputEvent> queue = new ConcurrentLinkedQueue<InputEvent>();
  97     static Random r = new Random();
  98 
  99     @BeforeMethod
 100     public void setUp() throws InterruptedException, AWTException, InvocationTargetException {
 101         EventQueue.invokeAndWait(new Runnable() {
 102 
 103             public void run() {
 104                 frm = new Frame("some frame");
 105                 frm.setSize(100, 100);
 106                 frm.setLocation(100, 100);
 107                 btn = new Button("some button");
 108                 MouseAdapter m = new MouseAdapter() {
 109 
 110                     @Override
 111                     public void mousePressed(MouseEvent e) {
 112                         System.out.println("mousePressed event triggered: " + e);
 113                         System.out.flush();
 114                         queue.add(e);
 115                     }
 116 
 117                     @Override
 118                     public void mouseReleased(MouseEvent e) {
 119                         System.out.println("mouseReleased event triggered: " + e);
 120                         System.out.flush();
 121                         queue.add(e);
 122                     }
 123 
 124                     @Override
 125                     public void mouseMoved(MouseEvent e) {
 126                         System.out.println("mouseMoved event triggered: " + e);
 127                         System.out.flush();
 128                         queue.add(e);
 129                     }
 130 
 131                     @Override
 132                     public void mouseClicked(MouseEvent e) {
 133                         System.out.println("mouseClicked event triggered: " + e);
 134                         System.out.flush();
 135                         queue.add(e);
 136                     }
 137 
 138                     @Override
 139                     public void mouseDragged(MouseEvent e) {
 140                         System.out.println("mouseDragged event triggered: " + e);
 141                         System.out.flush();
 142                         queue.add(e);
 143                     }
 144 
 145                 };
 146                 btn.addMouseListener(m);
 147                 btn.addMouseMotionListener(m);
 148                 btn.addKeyListener(new KeyAdapter() {
 149 
 150                     @Override
 151                     public void keyPressed(KeyEvent e) {
 152                         System.out.println("keyPressed event triggered: " + e);
 153                         System.out.flush();
 154                         queue.add(e);
 155                     }
 156 
 157                     @Override
 158                     public void keyReleased(KeyEvent e) {
 159                         System.out.println("keyReleased event triggered: " + e);
 160                         System.out.flush();
 161                         queue.add(e);
 162                     }
 163 
 164                 });
 165                 frm.add(btn, BorderLayout.SOUTH);
 166                 frm.doLayout();
 167                 instance = new RobotDriver(Environment.getEnvironment());
 168                 frm.setVisible(true);
 169                 btn.requestFocusInWindow();
 170             }
 171         });
 172 
 173         rb = new Robot();
 174         rb.waitForIdle();
 175 
 176         RobotExecutor.get().setRunInOtherJVM(true);
 177 
 178     }
 179 
 180     @AfterMethod
 181     public void tearDown() throws InterruptedException, InvocationTargetException {
 182         EventQueue.invokeAndWait(new Runnable() {
 183 
 184             public void run() {
 185                 frm.setVisible(false);
 186             }
 187         });
 188     }
 189 
 190 //    /**
 191 //     * Test of createScreenCapture method, of class RobotDriver.
 192 //     */
 193 //    @Test
 194 //    public void testCreateScreenCaptureLocally() throws AWTException, InterruptedException {
 195 //        System.out.println("testCreateScreenCaptureLocally");
 196 //        Thread.sleep(3000);
 197 //        Rectangle screenRect = new Rectangle(100, 100, 100, 100);
 198 //        RobotExecutor.get().setRunInOtherJVM(false);
 199 //        Image expResult = new AWTImage(new Robot().createScreenCapture(new java.awt.Rectangle(100, 100, 100, 100)));
 200 //        Image result = RobotDriver.createScreenCapture(screenRect);
 201 //        Image diff = expResult.compareTo(result);
 202 //        if (diff != null) {
 203 //            diff.save("testCreateScreenCaptureLocally.png");
 204 //            fail();
 205 //        }
 206 //    }
 207 //
 208 //    /**
 209 //     * Test of createScreenCapture method, of class RobotDriver.
 210 //     */
 211 //    @Test
 212 //    public void testCreateScreenCaptureRemotely() throws AWTException, InterruptedException {
 213 //        System.out.println("testCreateScreenCaptureRemotely");
 214 //        Thread.sleep(3000);
 215 //        Rectangle screenRect = new Rectangle(100, 100, 100, 100);
 216 //        RobotExecutor.get().setRunInOtherJVM(true);
 217 //        Image expResult = new AWTImage(new Robot().createScreenCapture(new java.awt.Rectangle(100, 100, 100, 100)));
 218 //        Image result = RobotDriver.createScreenCapture(screenRect);
 219 //        RobotDriver.createScreenCapture(screenRect);
 220 //        Image diff = expResult.compareTo(result);
 221 //        if (diff != null) {
 222 //            diff.save("testCreateScreenCaptureRemotely.png");
 223 //            fail();
 224 //        }
 225 //    }
 226 //
 227 //    /**
 228 //     * Test of createScreenCapture method, of class RobotDriver.
 229 //     */
 230 //    @Test
 231 //    public void testCreateScreenCaptureRemotely2() throws AWTException, InterruptedException {
 232 //        System.out.println("testCreateScreenCaptureRemotely2");
 233 //        Thread.sleep(3000);
 234 //        Rectangle screenRect = new Rectangle(100, 100, 100, 100);
 235 //        RobotExecutor.get().setRunInOtherJVM(true);
 236 //        Image expResult = new AWTImage(new Robot().createScreenCapture(new java.awt.Rectangle(100, 100, 100, 100)));
 237 //        Image result = RobotDriver.createScreenCapture(screenRect);
 238 //        Image diff = expResult.compareTo(result);
 239 //        if (diff != null) {
 240 //            diff.save("testCreateScreenCaptureRemotely2.png");
 241 //            fail();
 242 //        }
 243 //    }
 244 
 245     /**
 246      * Test of all RobotDriver methods invoked multiple times
 247      * @throws InterruptedException
 248      */
 249 //    @Test
 250     public void testAll() throws InterruptedException {
 251         for(int i = 0; i < 10; i++) {
 252             testPressMouse();
 253         }
 254     }
 255 
 256     public void test() throws InterruptedException {
 257 //        testPressMouse();
 258         testPressKey();
 259     }
 260 
 261     @Test
 262     public void test0() throws InterruptedException {
 263         test();
 264     }
 265 
 266     @Test
 267     public void test1() throws InterruptedException {
 268         test();
 269     }
 270 
 271     @Test
 272     public void test2() throws InterruptedException {
 273         test();
 274     }
 275 
 276     @Test
 277     public void test3() throws InterruptedException {
 278         test();
 279     }
 280 
 281     @Test
 282     public void test4() throws InterruptedException {
 283         test();
 284     }
 285 
 286     @Test
 287     public void test5() throws InterruptedException {
 288         test();
 289     }
 290 
 291     @Test
 292     public void test6() throws InterruptedException {
 293         test();
 294     }
 295 
 296     @Test
 297     public void test7() throws InterruptedException {
 298         test();
 299     }
 300 
 301     @Test
 302     public void test8() throws InterruptedException {
 303         test();
 304     }
 305 
 306     @Test
 307     public void test9() throws InterruptedException {
 308         test();
 309     }
 310 
 311     protected static final int[] MODIFIERS = new int[] {
 312             InputEvent.SHIFT_DOWN_MASK,
 313             InputEvent.CTRL_DOWN_MASK,
 314             InputEvent.ALT_DOWN_MASK,
 315             InputEvent.SHIFT_MASK,
 316             InputEvent.CTRL_MASK,
 317             InputEvent.ALT_MASK,
 318 //            MouseEvent.ALT_GRAPH_DOWN_MASK,
 319 //            MouseEvent.META_DOWN_MASK
 320         };
 321 
 322     public static int getModifiers() {
 323         int modifiersMask = r.nextInt(1 << MODIFIERS.length/2);
 324         int m = 0;
 325         System.out.print("Modifiers:");
 326         for (int i = 0; i < MODIFIERS.length/2; i++) {
 327             if ((modifiersMask & (1 << i)) != 0 ) {
 328                 m |= MODIFIERS[i];
 329                 System.out.print(" " + i);
 330             }
 331         }
 332         System.out.println("");
 333         return m;
 334     }
 335 
 336     protected static HashMap<Integer, Integer> normalizeMap =  new HashMap<Integer, Integer>();
 337     static {
 338         normalizeMap.put(InputEvent.SHIFT_MASK,InputEvent.SHIFT_DOWN_MASK);
 339         normalizeMap.put(InputEvent.CTRL_MASK,InputEvent.CTRL_DOWN_MASK);
 340         normalizeMap.put(InputEvent.ALT_MASK,InputEvent.ALT_DOWN_MASK);
 341         normalizeMap.put(InputEvent.META_MASK,InputEvent.META_DOWN_MASK);
 342     }
 343 
 344     protected static HashSet<Integer> normalize(HashSet<Integer> modifiers) {
 345         HashSet<Integer> normalized = new HashSet<Integer>();
 346         for (Integer mod : modifiers) {
 347             Integer n = normalizeMap.get(mod);
 348             if (n != null) {
 349                 normalized.add(n);
 350             } else {
 351                 normalized.add(mod);
 352             }
 353         }
 354         return normalized;
 355     }
 356 
 357     protected static HashSet<Integer> modifiers2Set(int mods) {
 358         HashSet<Integer> set = new HashSet<Integer>();
 359         for (int i = 0; i < MODIFIERS.length; i++) {
 360             if ((mods & MODIFIERS[i]) > 0) {
 361                 set.add(MODIFIERS[i]);
 362             }
 363         }
 364         return set;
 365    }
 366 
 367     protected static boolean compareModifiers(int m1, int m2) {
 368         return normalize(modifiers2Set(m1)).equals(normalize(modifiers2Set(m2)));
 369     }
 370     /**
 371      * Test of pressMouse method, of class RobotDriver.
 372      */
 373     public void testPressMouse() throws InterruptedException {
 374         System.out.println("pressMouse");
 375         Thread.sleep(3000);
 376         final int[] MOUSE_BUTTONS_1 = new int[] {
 377             MouseEvent.BUTTON1_MASK,
 378             MouseEvent.BUTTON2_MASK,
 379             MouseEvent.BUTTON3_MASK
 380         };
 381         final int[] MOUSE_BUTTONS_2 = new int[] {
 382             MouseEvent.BUTTON1,
 383             MouseEvent.BUTTON2,
 384             MouseEvent.BUTTON3
 385         };
 386         int bIndex = r.nextInt(MOUSE_BUTTONS_1.length);
 387         final int mouseButton1 = MOUSE_BUTTONS_1[bIndex];
 388         final int mouseButton2 = MOUSE_BUTTONS_2[bIndex];
 389         System.out.print("Button: " + bIndex + " Modifier:");
 390         final int modifiers = getModifiers();
 391         queue.clear();
 392         java.awt.Point locationOnScreen = btn.getLocationOnScreen();
 393         System.out.println("Pressing mouse");
 394         instance.moveMouse(new Point(locationOnScreen.x + btn.getWidth() / 2, locationOnScreen.y + btn.getHeight() / 2));
 395         AWTMap map = new AWTMap();
 396         MouseButton button = map.convertMouseButton(mouseButton1);
 397         Modifier[] converted_modifiers = map.convertModifiers(modifiers);
 398         instance.pressMouse(button, converted_modifiers);
 399         instance.releaseMouse(button, converted_modifiers);
 400 
 401         rb.waitForIdle();
 402         new Waiter(TIMEOUT, DELTA_TIMEOUT).ensureState(new State<Boolean>(){
 403 
 404             public Boolean reached() {
 405                 while(true) {
 406                     InputEvent e = queue.poll();
 407                     if (e != null) {
 408                         if (e instanceof MouseEvent) {
 409                             MouseEvent me = (MouseEvent) e;
 410                             if (me.getID() == MouseEvent.MOUSE_PRESSED && me.getButton() == mouseButton2 && (compareModifiers(me.getModifiers(), modifiers))) {
 411                                 return true;
 412                             }
 413                             if (me.getID() == MouseEvent.MOUSE_PRESSED) {
 414                                 System.out.println("Wrong combination of button and modifiers triggered:");
 415                                 System.out.println("me.getModifiers() = " + Integer.toString(me.getModifiers(), 2)  + ", modifiers = " + Integer.toString(modifiers, 2));
 416                                 System.out.println("expected: " + new MouseEvent(
 417                                         me.getComponent(), MouseEvent.MOUSE_PRESSED,
 418                                         me.getWhen(), modifiers, me.getX(), me.getY(), me.getClickCount(), me.isPopupTrigger(), mouseButton2));
 419                                 System.out.println("     got: " + me);
 420                             }
 421                         }
 422                     } else {
 423                         break;
 424                     }
 425                 }
 426                 return null;
 427             }
 428 
 429         });
 430 
 431         System.out.println("PASSED");
 432 
 433     }
 434 
 435 //    /**
 436 //     * Test of releaseMouse method, of class RobotDriver.
 437 //     */
 438 //    @Test
 439 //    public void testReleaseMouse() throws InterruptedException {
 440 //        System.out.println("releaseMouse");
 441 //        Thread.sleep(3000);
 442 //        int mouseButton = MouseEvent.BUTTON2_MASK;
 443 //        int modifiers = MouseEvent.CTRL_DOWN_MASK;
 444 //        mouseReleased = false;
 445 //        java.awt.Point locationOnScreen = btn.getLocationOnScreen();
 446 //        instance.moveMouse(new Point(locationOnScreen.x + btn.getWidth() / 2, locationOnScreen.y + btn.getHeight() / 2));
 447 //        System.out.println("Pressing mouse");
 448 //        instance.pressMouse(mouseButton, modifiers);
 449 //        System.out.println("Releasing mouse");
 450 //        instance.releaseMouse(mouseButton, modifiers);
 451 //
 452 //        rb.waitForIdle();
 453 //        new Waiter(TIMEOUT, DELTA_TIMEOUT).ensureState(new State<Boolean>(){
 454 //
 455 //            public Boolean reached() {
 456 //                return mouseReleased ? true: null;
 457 //            }
 458 //
 459 //        });
 460 //        assertTrue(mouseReleased);
 461 //    }
 462 //
 463 //    /**
 464 //     * Test of moveMouse method, of class RobotDriver.
 465 //     */
 466 //    @Test
 467 //    public void testMoveMouse() throws InterruptedException {
 468 //        System.out.println("moveMouse");
 469 //        Thread.sleep(3000);
 470 //        mouseMoved = false;
 471 //        java.awt.Point locationOnScreen = btn.getLocationOnScreen();
 472 //        System.out.println("Moving mouse");
 473 //        Point startPoint = new Point(locationOnScreen.x, locationOnScreen.y);
 474 //        Point endPoint = new Point(locationOnScreen.x + btn.getWidth(), locationOnScreen.y + btn.getHeight());
 475 //        double steps = 5; //Math.max(btn.getWidth(), btn.getHeight());
 476 //        double dx = (endPoint.x - startPoint.x) / steps;
 477 //        double dy = (endPoint.y - startPoint.y) / steps;
 478 //        for(int i = 0; i < steps; i++) {
 479 //            Point point = new Point(startPoint.x + dx * i, startPoint.y + dy * i);
 480 //            instance.moveMouse(point);
 481 //            Thread.sleep(100);
 482 //        }
 483 //
 484 //        rb.waitForIdle();
 485 //        new Waiter(TIMEOUT, DELTA_TIMEOUT).ensureState(new State<Boolean>(){
 486 //
 487 //            public Boolean reached() {
 488 //                return mouseMoved ? true: null;
 489 //            }
 490 //
 491 //        });
 492 //        assertTrue(mouseMoved);
 493 //    }
 494 //
 495 //    /**
 496 //     * Test of clickMouse method, of class RobotDriver.
 497 //     */
 498 //    @Test
 499 //    public void testClickMouse() throws InterruptedException {
 500 //        System.out.println("clickMouse");
 501 //        Thread.sleep(3000);
 502 //        mouseClicked = false;
 503 //        java.awt.Point locationOnScreen = btn.getLocationOnScreen();
 504 //        Point point = new Point(locationOnScreen.x + btn.getWidth() / 2, locationOnScreen.y + btn.getHeight() / 2);
 505 //        int clickCount = 1;
 506 //        int mouseButton = MouseEvent.BUTTON3_MASK;
 507 //        int modifiers = InputEvent.ALT_DOWN_MASK;
 508 //        Timeout mouseClick = new Timeout("mouseClick", 100);
 509 //        System.out.println("Clicking mouse");
 510 //        instance.clickMouse(point, clickCount, mouseButton, modifiers, mouseClick);
 511 //
 512 //        rb.waitForIdle();
 513 //        new Waiter(TIMEOUT, DELTA_TIMEOUT).ensureState(new State<Boolean>(){
 514 //
 515 //            public Boolean reached() {
 516 //                return mouseClicked ? true: null;
 517 //            }
 518 //
 519 //        });
 520 //        assertTrue(mouseClicked);
 521 //    }
 522 //
 523 //    /**
 524 //     * Test of dragNDrop method, of class RobotDriver.
 525 //     */
 526 //    @Test
 527 //    public void testDragNDrop() throws InterruptedException {
 528 //        System.out.println("dragNDrop");
 529 //        java.awt.Point locationOnScreen = btn.getLocationOnScreen();
 530 //        Point startPoint = new Point(locationOnScreen.x + btn.getWidth() / 2, locationOnScreen.y + btn.getHeight() / 2);
 531 //        Point endPoint = new Point(frm.getLocationOnScreen().x + frm.getWidth() / 2, frm.getLocationOnScreen().y + frm.getHeight() / 2);
 532 //        int mouseButton = MouseEvent.BUTTON2_MASK;
 533 //        int modifiers = 0;
 534 //        Timeout before = new Timeout("before", 500);
 535 //        Timeout after = new Timeout("after", 500);
 536 //        mouseDragged = false;
 537 //        instance.dragNDrop(startPoint, endPoint, mouseButton, modifiers, before, after);
 538 //
 539 //        rb.waitForIdle();
 540 //        new Waiter(TIMEOUT, DELTA_TIMEOUT).ensureState(new State<Boolean>(){
 541 //
 542 //            public Boolean reached() {
 543 //                return mouseDragged ? true: null;
 544 //            }
 545 //
 546 //        });
 547 //        assertTrue(mouseDragged);
 548 //    }
 549 
 550     /**
 551      * Test of pressKey method, of class RobotDriver.
 552      */
 553     public void testPressKey() throws InterruptedException {
 554         System.out.println("pressKey");
 555         Thread.sleep(3000);
 556 
 557         final int keyCode = KeyEvent.VK_A;
 558         final int modifiers = getModifiers();
 559         AWTMap map = new AWTMap();
 560         KeyboardButton button = map.convertKeyboardButton(keyCode);
 561         Modifier[] converted_modifiers = map.convertModifiers(modifiers);
 562 
 563         queue.clear();
 564 
 565         java.awt.Point locationOnScreen = btn.getLocationOnScreen();
 566         instance.clickMouse(new Point(locationOnScreen.x + btn.getWidth() / 2, locationOnScreen.y + btn.getHeight() / 2), 1,
 567                 MouseButtons.BUTTON1, DELTA_TIMEOUT);
 568 
 569         rb.waitForIdle();
 570 
 571         instance.pressKey(button, converted_modifiers);
 572         instance.releaseKey(button, converted_modifiers);
 573 
 574         rb.waitForIdle();
 575         new Waiter(TIMEOUT, DELTA_TIMEOUT).ensureState(new State<Boolean>(){
 576 
 577             public Boolean reached() {
 578                 while(true) {
 579                     InputEvent e = queue.poll();
 580                     if (e != null) {
 581                         if (e instanceof KeyEvent) {
 582                             KeyEvent ke = (KeyEvent) e;
 583                             if (ke.getID() == KeyEvent.KEY_PRESSED && ke.getKeyCode() == keyCode && compareModifiers(ke.getModifiers(), modifiers)) {
 584                                 return true;
 585                             }
 586                             if (ke.getID() == KeyEvent.KEY_PRESSED) {
 587                                 System.out.println("Wrong combination of button and modifiers triggered:");
 588                                 System.out.println("ke.getModifiers() = " + Integer.toString(ke.getModifiers(), 2)  + ", modifiers = " + Integer.toString(modifiers, 2));
 589                                 System.out.println("expected: " + new KeyEvent(ke.getComponent(), KeyEvent.KEY_PRESSED, ke.getWhen(), modifiers, keyCode, KeyEvent.CHAR_UNDEFINED));
 590                                 System.out.println("     got: " + ke);
 591                             }
 592                         }
 593                     } else {
 594                         break;
 595                     }
 596                 }
 597                 return null;
 598             }
 599 
 600         });
 601 
 602         System.out.println("PASSED");
 603     }
 604 
 605 //    /**
 606 //     * Test of releaseKey method, of class RobotDriver.
 607 //     */
 608 //    @Test
 609 //    public void testReleaseKey() throws InterruptedException {
 610 //        System.out.println("releaseKey");
 611 //        int keyCode = KeyEvent.VK_B;
 612 //        int modifiers = 0;
 613 //        keyReleased = false;
 614 //        instance.pressKey(keyCode, modifiers);
 615 //        instance.releaseKey(keyCode, modifiers);
 616 //
 617 //        rb.waitForIdle();
 618 //        new Waiter(TIMEOUT, DELTA_TIMEOUT).ensureState(new State<Boolean>(){
 619 //
 620 //            public Boolean reached() {
 621 //                return keyReleased ? true: null;
 622 //            }
 623 //
 624 //        });
 625 //        assertTrue(keyReleased);
 626 //    }
 627 
 628 }