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