Clover coverage report - clover
Coverage timestamp: Sat Oct 8 2005 22:54:17 EDT
file stats: LOC: 886   Methods: 47
NCLOC: 763   Classes: 6
 
 Source file Conditionals Statements Methods TOTAL
RobotTest.java 47% 88.5% 87.2% 84.2%
coverage coverage
 1   
 package abbot.tester;
 2   
 
 3   
 import java.applet.Applet;
 4   
 import java.awt.*;
 5   
 import java.awt.datatransfer.*;
 6   
 import java.awt.dnd.*;
 7   
 import java.awt.event.*;
 8   
 import java.io.*;
 9   
 import java.lang.reflect.Constructor;
 10   
 import java.util.ArrayList;
 11   
 
 12   
 import javax.swing.*;
 13   
 import javax.swing.border.EmptyBorder;
 14   
 
 15   
 import junit.extensions.abbot.*;
 16   
 import junit.extensions.abbot.Timer;
 17   
 import abbot.*;
 18   
 import abbot.script.AppClassLoader;
 19   
 import abbot.util.AWT;
 20   
 import abbot.util.WeakAWTEventListener;
 21   
 import abbot.util.Bugs;
 22   
 
 23   
 /** Unit test to verify Robot operation. */
 24   
 
 25   
 public class RobotTest extends ComponentTestFixture {
 26   
 
 27   
     class Flag { volatile boolean flag; }
 28   
 
 29  2
     public void testWaitForIdle() {
 30  2
         final Flag flag = new Flag();
 31  2
         SwingUtilities.invokeLater(new Runnable() {
 32  2
             public void run() {
 33  2
                 try { Thread.sleep(1000); }
 34   
                 catch(InterruptedException e) { }
 35  2
                 flag.flag = true;
 36   
             }
 37   
         });
 38  2
         getRobot().waitForIdle();
 39  2
         assertTrue("Did not wait for event dispatch to finish", flag.flag);
 40   
     }
 41   
 
 42   
     private volatile boolean pump;
 43   
     private volatile boolean waitStarted;
 44   
     private volatile boolean waitTerminated;
 45   
     private volatile boolean gotTimeout;
 46   
     // FIXME: on fast CPUs running linux (up through 1.5),
 47   
     // it has been found that waitForIdle will wait forever
 48   
     // when a dialog is shown.  need to reproduce that scenario
 49   
     // here to ensure we don't hang.
 50  0
     public void xtestWaitForIdleTimeout() throws Exception {
 51  0
         Robot robot = new Robot() {
 52  0
             protected boolean isQueueBlocked(EventQueue q) {
 53  0
                 return false;
 54   
             }
 55  0
             protected boolean postInvocationEvent(EventQueue q,
 56   
                                                   Toolkit toolkit,
 57   
                                                   long timeout) {
 58  0
                 if (super.postInvocationEvent(q, toolkit, timeout)) {
 59  0
                     System.err.println("x");
 60  0
                     pump = false;
 61  0
                     gotTimeout = true;
 62  0
                     return true;
 63   
                 }
 64  0
                 return false;
 65   
             }
 66   
         };
 67   
 
 68  0
         final Runnable EMPTY = new Runnable() {
 69  0
             public void run() {
 70  0
                 if (pump) {
 71  0
                     System.err.print(".");
 72  0
                     SwingUtilities.invokeLater(this);
 73   
                 }
 74   
             }
 75   
         };
 76  0
         JFrame frame = new JFrame(getName());
 77  0
         showWindow(frame);
 78   
 
 79  0
         pump = true;
 80   
         // Put wait for idle on a different thread in case it blocks
 81  0
         new Thread("wait for idle") {
 82  0
             public void run() {
 83  0
                 waitStarted = true;
 84  0
                 System.err.println("start pump");
 85  0
                 try {
 86  0
                     SwingUtilities.invokeAndWait(EMPTY);
 87   
                 }
 88   
                 catch(Throwable t) { }
 89  0
                 System.err.println("waitForIdle");
 90  0
                 getRobot().waitForIdle();
 91  0
                 waitTerminated = true;
 92   
             }
 93   
         }.start();
 94   
 
 95  0
         while (!waitStarted) {
 96  0
             Thread.sleep(100);
 97   
         }
 98  0
         System.err.println("test thread wait");
 99  0
         Timer timer = new Timer();
 100  0
         while (!waitTerminated) {
 101  0
             if (timer.elapsed() > 10000) {
 102  0
                 fail("Idle wait should not block unreasonably long");
 103   
             }
 104  0
             System.err.print("+");
 105  0
             Thread.sleep(10);
 106   
         }
 107  0
         pump = false;
 108  0
         assertTrue("Idle wait should time out", gotTimeout);
 109   
     }
 110   
 
 111  2
     public void testEventPostDelay() throws Exception {
 112  2
         if (Robot.getEventMode() != Robot.EM_ROBOT)
 113  1
             return;
 114  1
         JLabel label = new JLabel(getName());
 115  1
         MouseWatcher ml = new MouseWatcher();
 116  1
         label.addMouseListener(ml);
 117  1
         showFrame(label);
 118  1
         java.awt.Robot r = Robot.getRobot();
 119  1
         Point pt = label.getLocationOnScreen();
 120  1
         r.mouseMove(pt.x + label.getWidth()/2,
 121   
                     pt.y + label.getHeight()/2);
 122  1
         r.mousePress(MouseEvent.BUTTON1_MASK);
 123  1
         r.mouseRelease(MouseEvent.BUTTON1_MASK);
 124  1
         r.delay(Robot.getEventPostDelay());
 125  1
         long now = System.currentTimeMillis();
 126  1
         robot.waitForIdle();
 127  1
         if (!ml.gotPress) {
 128  0
             Timer timer = new Timer();
 129  0
             while (!ml.gotPress) {
 130  0
                 robot.delay(5);
 131  0
                 if (timer.elapsed() > 5000)
 132  0
                     fail("Mouse press never registered");
 133   
             }
 134  0
             long arrived = System.currentTimeMillis();
 135  0
             fail("MOUSE_PRESSED event not yet generated, "
 136   
                  + "after " + Robot.getEventPostDelay()
 137   
                  + "ms, actual additional delay was " 
 138   
                  + (arrived - now) + "ms");
 139   
         }
 140   
     }
 141   
 
 142   
     /** Ensure image capture gets the right image. */
 143  2
     public void testImageCapture() throws Throwable {
 144   
         // Don't need to test this under AWT mode, where we might get a false
 145   
         // negative anyway
 146  2
         if (Robot.getEventMode() == Robot.EM_AWT)
 147  1
             return;
 148   
 
 149  1
         final int X = 100;
 150  1
         final int Y = 100;
 151  1
         File gif = new File("test/abbot/tester/image.gif");
 152  1
         ImageIcon icon = new ImageIcon(gif.toURL());
 153  1
         JLabel label1 = new JLabel(icon);
 154  1
         JLabel label2 = new JLabel(icon);
 155  1
         final JFrame frame = new JFrame(getName());
 156  1
         frame.setLocation(X, Y);
 157  1
         JPanel pane = (JPanel)frame.getContentPane();
 158  1
         pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS));
 159   
         //Ensure OSX growbox doesn't obscure the picture
 160  1
         pane.setBorder(new EmptyBorder(20,20,20,20));
 161  1
         pane.add(label1);
 162  1
         pane.add(label2);
 163  1
         frame.pack();
 164  1
         frame.setResizable(false);
 165  1
         frame.setLocation(X, Y);
 166  1
         showWindow(frame);
 167  1
         robot.focus(frame, true);
 168   
         
 169  1
         File jpg = new File("test/abbot/tester/image.jpg");
 170  1
         ImageComparator ic = new ImageComparator();
 171  1
         int status = icon.getImageLoadStatus();
 172  1
         int DONE =
 173   
             MediaTracker.ERRORED|MediaTracker.ABORTED|MediaTracker.COMPLETE;
 174  1
         Timer timer = new Timer();
 175  1
         while ((status & DONE) == 0) {
 176  0
             if (timer.elapsed() > 5000)
 177  0
                 fail("Icon image failed to load or error within 5s");
 178  0
             robot.sleep();
 179  0
             status = icon.getImageLoadStatus();
 180   
         }
 181  1
         if ((status & DONE) != MediaTracker.COMPLETE) {
 182  0
             fail("Icon image load failed: status=" + status);
 183   
         }
 184  1
         robot.activate(frame);
 185  1
         robot.waitForIdle();
 186   
 
 187  1
         assertTrue("Captured wrong image (1)",
 188   
                    ic.compare(robot.capture(label1), jpg) == 0);
 189  1
         assertTrue("Captured wrong image (2)",
 190   
                    ic.compare(robot.capture(label2), jpg) == 0);
 191   
     }
 192   
 
 193   
     private class MenuListener implements ActionListener {
 194   
         public int actionCount = 0;
 195   
         public boolean gotAction = false;
 196  26
         public void actionPerformed(ActionEvent ev) {
 197  26
             ++actionCount;
 198  26
             gotAction = true;
 199   
         }
 200   
     }
 201   
 
 202  2
     public void testSelectAWTMenuItem() {
 203  2
         MenuBar mb = new MenuBar();
 204  2
         Menu menu = new Menu("File");
 205  2
         menu.add(new MenuItem("One"));
 206  2
         MenuItem mi = new MenuItem("Two");
 207  2
         MenuListener ml1 = new MenuListener();
 208  2
         MenuListener ml2 = new MenuListener();
 209  2
         mi.addActionListener(ml1);
 210  2
         menu.add(mi);
 211  2
         Menu sub = new Menu("Submenu");
 212  2
         sub.add(new MenuItem("Sub one"));
 213  2
         MenuItem mi2 = new MenuItem("Sub two");
 214  2
         mi2.addActionListener(ml2);
 215  2
         sub.add(mi2);
 216  2
         menu.add(sub);
 217  2
         mb.add(menu);
 218  2
         JFrame frame = new JFrame(getName());
 219  2
         frame.setMenuBar(mb);
 220   
         // Ensure we have a proper size for linux
 221  2
         showWindow(frame, new Dimension(200, 100));
 222   
         /*
 223   
         robot.selectAWTMenuItem(mi);
 224   
         robot.waitForIdle();
 225   
         assertTrue("AWT Menu item in menubar menu not hit", ml1.gotAction);
 226   
         robot.selectAWTMenuItem(mi2);
 227   
         robot.waitForIdle();
 228   
         assertTrue("AWT Menu item in menubar submenu not hit", ml2.gotAction);
 229   
 
 230   
         ml1.gotAction = ml2.gotAction = false;
 231   
         robot.selectAWTMenuItem(frame, mi.getLabel());
 232   
         robot.waitForIdle();
 233   
         assertTrue("AWT Menu item in menubar menu not hit", ml1.gotAction);
 234   
         robot.selectAWTMenuItem(frame, mi2.getLabel());
 235   
         robot.waitForIdle();
 236   
         assertTrue("AWT Menu item in menubar submenu not hit", ml2.gotAction);
 237   
         */
 238  2
         ml1.gotAction = false;
 239  2
         String PATH = "File|Two";
 240  2
         robot.selectAWTMenuItem(frame, PATH);
 241  2
         robot.waitForIdle();
 242  2
         assertTrue("AWT Menu item identified by path '" + PATH + "' not hit",
 243   
                    ml1.gotAction);
 244   
     }
 245   
 
 246  2
     public void testAWTPopupMenuSelection() {
 247  2
         if (Robot.getEventMode() == Robot.EM_AWT
 248   
             && Bugs.showAWTPopupMenuBlocks()) {
 249   
             //fail("This test would block");
 250  1
             return;
 251   
         }
 252   
 
 253  1
         PopupMenu popup = new PopupMenu();
 254  1
         popup.add(new MenuItem("One"));
 255  1
         MenuItem mi = new MenuItem("Two");
 256  1
         MenuListener ml1 = new MenuListener();
 257  1
         MenuListener ml2 = new MenuListener();
 258  1
         mi.addActionListener(ml1);
 259  1
         popup.add(mi);
 260  1
         Menu sub = new Menu("Submenu");
 261  1
         sub.add(new MenuItem("Sub one"));
 262  1
         MenuItem mi2 = new MenuItem("Sub two");
 263  1
         mi2.addActionListener(ml2);
 264  1
         sub.add(mi2);
 265  1
         popup.add(sub);
 266  1
         JFrame frame = new JFrame(getName());
 267  1
         frame.add(popup);
 268  1
         showWindow(frame, new Dimension(200, 200));
 269   
 
 270  1
         robot.selectAWTPopupMenuItem(mi);
 271  1
         robot.waitForIdle();
 272  1
         assertTrue("AWT PopupMenu item not hit", ml1.gotAction);
 273  1
         robot.selectAWTPopupMenuItem(mi2);
 274  1
         robot.waitForIdle();
 275  1
         assertTrue("AWT PopupMenu item in submenu not hit", ml2.gotAction);
 276   
 
 277  1
         ml1.gotAction = ml2.gotAction = false;
 278  1
         robot.selectAWTPopupMenuItem(frame, mi.getLabel());
 279  1
         robot.waitForIdle();
 280  1
         assertTrue("AWT PopupMenu item not hit", ml1.gotAction);
 281  1
         robot.selectAWTPopupMenuItem(frame, mi2.getLabel());
 282  1
         robot.waitForIdle();
 283  1
         assertTrue("AWT PopupMenu item in submenu not hit", ml2.gotAction);
 284   
     }
 285   
 
 286  2
     public void testSelectMenuItem() {
 287  2
         JMenuBar mb = new JMenuBar();
 288  2
         JMenu menu = new JMenu("File");
 289  2
         menu.add(new JMenuItem("One"));
 290  2
         JMenuItem mi1 = new JMenuItem("Two");
 291  2
         MenuListener ml1 = new MenuListener();
 292  2
         mi1.addActionListener(ml1);
 293  2
         menu.add(mi1);
 294  2
         JMenu sub = new JMenu("Submenu");
 295  2
         sub.add(new JMenuItem("Sub one"));
 296  2
         JMenuItem mi2 = new JMenuItem("Sub two");
 297  2
         MenuListener ml2 = new MenuListener();
 298  2
         mi2.addActionListener(ml2);
 299  2
         sub.add(mi2);
 300  2
         menu.add(sub);
 301  2
         mb.add(menu);
 302  2
         JFrame frame = new JFrame(getName());
 303  2
         frame.getContentPane().add(new JLabel(getName()));
 304  2
         frame.setJMenuBar(mb);
 305  2
         showWindow(frame);
 306   
 
 307  2
         robot.selectMenuItem(mi1);
 308  2
         assertTrue("Standard menu item not selected", ml1.gotAction);
 309   
     }
 310   
 
 311  2
     public void testSelectMenuItemByPath() {
 312  2
         JMenuBar mb = new JMenuBar();
 313  2
         JMenu menu = new JMenu("File");
 314   
 
 315  2
         JMenuItem mi1 = new JMenuItem("Two");
 316  2
         JMenu sub = new JMenu("Submenu");
 317  2
         JMenuItem mi2 = new JMenuItem("File");
 318  2
         MenuListener ml = new MenuListener();
 319  2
         mi2.addActionListener(ml);
 320   
 
 321  2
         mb.add(menu);
 322  2
         menu.add(new JMenuItem("One"));
 323  2
         menu.add(sub);
 324  2
         sub.add(new JMenuItem("Sub one"));
 325  2
         sub.add(mi2);
 326   
 
 327  2
         JFrame frame = new JFrame(getName());
 328  2
         frame.getContentPane().add(new JLabel(getName()));
 329  2
         frame.setJMenuBar(mb);
 330  2
         showWindow(frame);
 331   
 
 332  2
         String path =
 333   
             menu.getText() + "|" + sub.getText() + "|" + mi2.getText();
 334  2
         robot.selectMenuItem(frame, path);
 335  2
         assertTrue("Select menu item by path failed", ml.gotAction);
 336   
     }
 337   
 
 338  2
     public void testSelectMenuItemLongItemTraversal() {
 339   
         // The following should not cause problems:
 340   
         // ------------
 341   
         // |menu|menu1|
 342   
         // ------------------------
 343   
         // |really long menu item |
 344   
         // ------------------------
 345  2
         JMenuBar mb = new JMenuBar();
 346  2
         JMenu menu1 = new JMenu("A");
 347  2
         JMenuItem mi = new JMenuItem("This is a really long menu item such that the center of the item is way out there");
 348  2
         menu1.add(mi);
 349  2
         JMenu menu2 = new JMenu("B");
 350  2
         menu2.add(new JMenuItem("About"));
 351  2
         mb.add(menu1);
 352  2
         mb.add(menu2);
 353  2
         MenuListener ml = new MenuListener();
 354  2
         mi.addActionListener(ml);
 355  2
         JFrame frame = new JFrame(getName());
 356  2
         frame.getContentPane().add(new JLabel(getName()));
 357  2
         frame.setJMenuBar(mb);
 358  2
         showWindow(frame);
 359   
 
 360  2
         robot.selectMenuItem(mi);
 361  2
         assertTrue("Long menu item missed", ml.gotAction);
 362   
     }
 363   
 
 364  2
     public void testSelectSubmenuItem() {
 365  2
         JMenuBar mb = new JMenuBar();
 366  2
         JMenu menu = new JMenu("File");
 367  2
         menu.add(new JMenuItem("One"));
 368  2
         JMenuItem mi1 = new JMenuItem("Two");
 369  2
         MenuListener ml1 = new MenuListener();
 370  2
         mi1.addActionListener(ml1);
 371  2
         menu.add(mi1);
 372  2
         JMenu sub = new JMenu("Submenu");
 373  2
         sub.add(new JMenuItem("Sub one"));
 374  2
         JMenuItem mi2 = new JMenuItem("Sub two");
 375  2
         MenuListener ml2 = new MenuListener();
 376  2
         mi2.addActionListener(ml2);
 377  2
         sub.add(mi2);
 378  2
         menu.add(sub);
 379  2
         mb.add(menu);
 380  2
         JFrame frame = new JFrame(getName());
 381  2
         frame.getContentPane().add(new JLabel(getName()));
 382  2
         frame.setJMenuBar(mb);
 383  2
         showWindow(frame);
 384   
 
 385  2
         robot.selectMenuItem(mi2);
 386  2
         assertTrue("Submenu item not selected", ml2.gotAction);
 387   
     }
 388   
 
 389  2
     public void testMenuSelectionWithParentShowing() {
 390  2
         JMenuBar mb = new JMenuBar();
 391  2
         JMenu menu = new JMenu("File");
 392  2
         menu.add(new JMenuItem("One"));
 393  2
         JMenuItem mi1 = new JMenuItem("Two");
 394  2
         MenuListener ml1 = new MenuListener();
 395  2
         mi1.addActionListener(ml1);
 396  2
         menu.add(mi1);
 397  2
         mb.add(menu);
 398   
 
 399  2
         JFrame frame = new JFrame(getName());
 400  2
         frame.getContentPane().add(new JLabel(getName()));
 401  2
         frame.setJMenuBar(mb);
 402  2
         showWindow(frame);
 403   
 
 404  2
         robot.click(menu);
 405  2
         robot.waitForIdle();
 406  2
         robot.selectMenuItem(mi1);
 407  2
         robot.waitForIdle();
 408  2
         assertTrue("Menu it main menu not hit when parent already open",
 409   
                    ml1.gotAction);
 410   
     }
 411   
 
 412  2
     public void testSelectNestedMenuItem() {
 413   
         // Repeatedly select a nested menu item
 414  2
         JMenuBar mb = new JMenuBar();
 415  2
         mb.add(new JMenu("Action Management"));
 416  2
         JMenu menu = new JMenu("Risk Management");
 417  2
         mb.add(menu);
 418  2
         mb.add(new JMenu("BPComs"));
 419  2
         mb.add(new JMenu("Tools"));
 420  2
         mb.add(new JMenu("Actions"));
 421  2
         mb.add(new JMenu("Window"));
 422  2
         mb.add(new JMenu("Help"));
 423  2
         JMenu sub1 = new JMenu("Position Enquiry");
 424  2
         menu.add(sub1);
 425  2
         menu.add(new JMenu("Static Data Management"));
 426  2
         menu.add(new JMenu("Excession Management"));
 427  2
         sub1.add(new JMenu("Cash Account"));
 428  2
         JMenu sub2 = new JMenu("Safekeeping Account");
 429  2
         sub1.add(sub2);
 430  2
         sub1.add(new JMenu("Client"));
 431  2
         sub1.add(new JMenu("RCA"));
 432  2
         JMenuItem mi = new JMenuItem("Search...");
 433  2
         sub2.add(mi);
 434  2
         MenuListener ml = new MenuListener();
 435  2
         mi.addActionListener(ml);
 436  2
         JFrame frame = new JFrame(getName());
 437  2
         frame.setJMenuBar(mb);
 438  2
         showWindow(frame);
 439   
 
 440  2
         int REPEAT = 5;
 441  2
         for (int i=0;i < REPEAT;i++) { 
 442  10
             robot.selectMenuItem(mi);
 443  10
             robot.waitForIdle();
 444   
         }
 445  2
         assertEquals("Some menu activations failed", REPEAT, ml.actionCount);
 446   
     }
 447   
 
 448   
     private class MouseWatcher extends MouseAdapter {
 449   
         public volatile boolean gotPress = false;
 450   
         public volatile boolean gotRelease = false;
 451   
         public volatile boolean gotClick = false;
 452   
         public volatile int clickCount = 0;
 453   
         public volatile boolean popupTrigger = false;
 454   
         public volatile Component source = null;
 455   
         public volatile int modifiers = 0;
 456   
         public volatile Point where = null;
 457  13
         public void mousePressed(MouseEvent me) {
 458  13
             gotPress = true;
 459  13
             source = me.getComponent();
 460  13
             popupTrigger = me.isPopupTrigger();
 461  13
             modifiers = me.getModifiers();
 462  13
             where = me.getPoint();
 463   
         }
 464  13
         public void mouseReleased(MouseEvent me) {
 465  13
             gotRelease = true;
 466  13
             popupTrigger = popupTrigger || me.isPopupTrigger();
 467   
         }
 468  13
         public void mouseClicked(MouseEvent me) {
 469  13
             gotClick = true;
 470  13
             clickCount = me.getClickCount();
 471   
         }
 472   
     }
 473   
 
 474   
     /** Verify proper click operation.  You may need to set
 475   
         Robot.mouseReleaseDelay if this fails intermittently. */
 476  2
     public void testClick() {
 477  2
         MouseWatcher mw = new MouseWatcher();
 478  2
         JFrame frame = new JFrame(getName());
 479  2
         frame.addMouseListener(mw);
 480  2
         showWindow(frame, new Dimension(200, 200), true);
 481  2
         robot.click(frame);
 482  2
         robot.waitForIdle();
 483  2
         assertTrue("Never received press", mw.gotPress);
 484  2
         assertEquals("Wrong event source", frame, mw.source);
 485  2
         assertTrue("Never received release", mw.gotRelease);
 486  2
         assertTrue("Never received click", mw.gotClick);
 487  2
         assertEquals("No modifiers expected", 
 488   
                      AWT.getMouseModifiers(MouseEvent.BUTTON1_MASK), 
 489   
                      AWT.getMouseModifiers(mw.modifiers));
 490  2
         assertTrue("Unexpected popup trigger", !mw.popupTrigger);
 491   
     }
 492   
 
 493   
     /** Double clicks. */
 494  2
     public void testMultipleClicks() {
 495  2
         MouseWatcher mw = new MouseWatcher();
 496  2
         JFrame frame = new JFrame(getName());
 497  2
         showWindow(frame, new Dimension(200, 200));
 498  2
         JPanel pane = (JPanel)frame.getContentPane();
 499  2
         pane.addMouseListener(mw);
 500  2
         robot.click(pane, 
 501   
                     pane.getWidth()/2,
 502   
                     pane.getHeight()/2,
 503   
                     InputEvent.BUTTON1_MASK, 2);
 504  2
         Timer timer = new Timer();
 505  2
         while (mw.clickCount < 2) {
 506  0
             if (timer.elapsed() > EVENT_GENERATION_DELAY)
 507  0
                 fail("Never received a double click");
 508  0
             robot.sleep();
 509   
         }
 510   
     }
 511   
 
 512  2
     public void testClickAt() {
 513  2
         MouseWatcher mw = new MouseWatcher();
 514  2
         JFrame frame = new JFrame(getName());
 515  2
         frame.addMouseListener(mw);
 516  2
         showWindow(frame, new Dimension(200, 200));
 517   
         // Make sure we don't click in the title or border...
 518  2
         Insets insets = frame.getInsets();
 519  2
         Point at = new Point(insets.left,insets.top);
 520  2
         robot.click(frame, at.x, at.y);
 521  2
         robot.waitForIdle();
 522  2
         assertTrue("Never received press", mw.gotPress);
 523  2
         assertEquals("Wrong event source", frame, mw.source);
 524  2
         assertTrue("Never received release", mw.gotRelease);
 525  2
         assertTrue("Never received click", mw.gotClick);
 526  2
         assertEquals("Wrong mouse coordinates", at, mw.where);
 527  2
         assertEquals("No modifiers expected", 
 528   
                      AWT.getMouseModifiers(MouseEvent.BUTTON1_MASK), 
 529   
                      AWT.getMouseModifiers(mw.modifiers));
 530  2
         assertTrue("Unexpected popup trigger", !mw.popupTrigger);
 531   
     }
 532   
 
 533  2
     public void testClickPopup() {
 534  2
         MouseWatcher mw = new MouseWatcher();
 535  2
         JFrame frame = new JFrame(getName());
 536  2
         frame.addMouseListener(mw);
 537  2
         showWindow(frame, new Dimension(200, 200));
 538  2
         robot.click(frame, AWTConstants.POPUP_MASK);
 539  2
         robot.waitForIdle();
 540  2
         assertTrue("Never received press", mw.gotPress);
 541  2
         assertEquals("Wrong event source", frame, mw.source);
 542  2
         assertTrue("Never received release", mw.gotRelease);
 543  2
         assertTrue("Never received click", mw.gotClick);
 544  2
         assertEquals("Wrong modifiers", 
 545   
                      AWT.getMouseModifiers(AWTConstants.POPUP_MASK), 
 546   
                      AWT.getMouseModifiers(mw.modifiers));
 547  2
         assertTrue("Should be popup trigger", mw.popupTrigger);
 548   
     }
 549   
 
 550  2
     public void testClickTertiary() {
 551  2
         MouseWatcher mw = new MouseWatcher();
 552  2
         JFrame frame = new JFrame(getName());
 553  2
         frame.addMouseListener(mw);
 554  2
         showWindow(frame, new Dimension(200, 200));
 555  2
         int mask = AWTConstants.TERTIARY_MASK;
 556  2
         robot.click(frame, mask);
 557  2
         robot.waitForIdle();
 558   
         // w32 uses CTRL as a modifier prior to 1.4, I guess in case you don't
 559   
         // have a 3-button mouse.
 560  2
         if (Platform.isWindows()
 561   
             && Platform.JAVA_VERSION < Platform.JAVA_1_4) {
 562  0
             mask |= InputEvent.CTRL_MASK;
 563   
         }
 564   
 
 565  2
         assertTrue("Never received press", mw.gotPress);
 566  2
         assertEquals("Wrong event source", frame, mw.source);
 567  2
         assertTrue("Never received release", mw.gotRelease);
 568  2
         assertTrue("Never received click", mw.gotClick);
 569  2
         assertEquals("Wrong modifiers", 
 570   
                      AWT.getMouseModifiers(mask),
 571   
                      AWT.getMouseModifiers(mw.modifiers));
 572  2
         assertTrue("Unexpected popup trigger", !mw.popupTrigger);
 573   
     }
 574   
 
 575  2
     public void testFocusSingleFrame() {
 576  2
         JTextField tf = new JTextField("Default focus goes here");
 577  2
         JTextField tf2 = new JTextField("Requested focus goes here");
 578  2
         JPanel pane = new JPanel();
 579  2
         pane.add(tf);
 580  2
         pane.add(tf2);
 581  2
         showFrame(pane);
 582  2
         robot.focus(tf2, true);
 583  2
         assertTrue("Default TextField should not have focus", !tf.hasFocus());
 584  2
         assertTrue("Next TextField should have focus", tf2.hasFocus());
 585  2
         robot.focus(tf, true);
 586  2
         assertTrue("First TextField should have focus", tf.hasFocus());
 587   
     }
 588   
 
 589   
     // FIXME sporadic failures on linux (AWT mode)
 590  2
     public void testFocusMultipleFrames() {
 591  2
         JTextField tf = new JTextField("Default focus goes here");
 592  2
         JTextField tf2 = new JTextField("Requested focus goes here");
 593  2
         JTextField tf3 = new JTextField("Next it goes here");
 594  2
         JPanel pane = new JPanel();
 595  2
         pane.add(tf);
 596  2
         pane.add(tf2);
 597  2
         showFrame(pane);
 598  2
         JFrame frame = new JFrame(getName() + " 2");
 599  2
         frame.getContentPane().add(tf3);
 600  2
         showWindow(frame);
 601  2
         robot.focus(tf2, true);
 602  2
         assertTrue("Second text field didn't get focus", tf2.hasFocus());
 603  2
         robot.focus(tf3, true);
 604  2
         assertTrue("Third text field didn't get focus", tf3.hasFocus());
 605   
     }
 606   
 
 607   
     private class KeyWatcher extends KeyAdapter {
 608   
         public volatile boolean gotPress = false;
 609   
         public volatile boolean gotRelease = false;
 610   
         public volatile boolean gotTyped = false;
 611   
         public volatile int keyCode = KeyEvent.VK_UNDEFINED;
 612   
         public volatile int modifiers = 0;
 613  10
         public void keyPressed(KeyEvent ke) {
 614  10
             gotPress = true;
 615  10
             keyCode = ke.getKeyCode();
 616  10
             modifiers = ke.getModifiers();
 617   
         }
 618  10
         public void keyReleased(KeyEvent ke) {
 619  10
             gotRelease = true;
 620   
         }
 621  6
         public void keyTyped(KeyEvent ke) {
 622  6
             gotTyped = true;
 623   
         }
 624   
     }
 625   
 
 626  2
     public void testPlainKey() {
 627  2
         KeyWatcher kw = new KeyWatcher();
 628  2
         JTextField tf = new JTextField();
 629  2
         tf.setColumns(10);
 630  2
         tf.addKeyListener(kw);
 631  2
         JPanel pane = new JPanel();
 632  2
         pane.add(tf);
 633  2
         showFrame(pane);
 634  2
         robot.focus(tf, true);
 635  2
         int code = KeyEvent.VK_A;
 636  2
         robot.key(code);
 637  2
         robot.waitForIdle();
 638  2
         assertTrue("Never received key press", kw.gotPress);
 639  2
         assertTrue("Never received release", kw.gotRelease);
 640  2
         assertTrue("Never received type", kw.gotTyped);
 641  2
         assertEquals("Wrong key code", code, kw.keyCode);
 642  2
         assertEquals("Wrong modifiers", 0, kw.modifiers);
 643   
     }
 644   
 
 645  2
     public void testKey() {
 646  2
         JTextField tf1 = new JTextField();
 647  2
         KeyWatcher kw = new KeyWatcher();
 648  2
         tf1.addKeyListener(kw);
 649  2
         showFrame(tf1);
 650  2
         robot.focus(tf1, true);
 651  2
         robot.key(KeyEvent.VK_A);
 652  2
         robot.waitForIdle();
 653  2
         assertTrue("Never received key press", kw.gotPress);
 654  2
         assertEquals("Wrong key code", KeyEvent.VK_A, kw.keyCode);
 655  2
         assertEquals("Wrong modifiers", 0, kw.modifiers);
 656   
 
 657  2
         kw.gotPress = false;
 658  2
         robot.key(KeyEvent.VK_A, KeyEvent.SHIFT_MASK);
 659  2
         robot.waitForIdle();
 660  2
         assertTrue("Never received key press", kw.gotPress);
 661  2
         assertEquals("Wrong key code", KeyEvent.VK_A, kw.keyCode);
 662  2
         assertEquals("Wrong modifiers", KeyEvent.SHIFT_MASK, kw.modifiers);
 663   
     }
 664   
 
 665   
     /** Generate some things which we know we don't have key mappings for. */
 666  2
     public void testKeyString() {
 667  2
         JPanel pane = new JPanel();
 668  2
         JTextField tf1 = new JTextField();
 669  2
         JTextField tf2 = new JTextField();
 670  2
         tf1.setColumns(10);
 671  2
         tf2.setColumns(10);
 672  2
         pane.add(tf1);
 673  2
         pane.add(tf2);
 674  2
         Frame frame = showFrame(pane);
 675  2
         robot.activate(frame);
 676  2
         robot.waitForIdle();
 677  2
         robot.focus(tf1, true);
 678  2
         String keymap = "The quick brown fox jumped over the lazy dog"
 679   
             + "`1234567890-=~!@#$%^&*()_+[]\\{}|;':\",./<>?";
 680  2
         robot.keyString(keymap);
 681  2
         robot.waitForIdle();
 682  2
         assertEquals("Wrong text typed", keymap, tf1.getText());
 683   
 
 684   
         // Throw in some French; should work just as well for any other...
 685  2
         String string = "Un \u00e9l\u00e9ment gr\u00e2ce \u00e0 l'index";
 686  2
         robot.focus(tf2, true);
 687  2
         robot.keyString(string);
 688  2
         robot.waitForIdle();
 689  2
         assertEquals("Wrong non-keymap text typed", string, tf2.getText());
 690   
     }
 691   
 
 692  2
     public void testEndKey() {
 693  2
         TextField tf = new TextField(getName());
 694  2
         KeyWatcher watcher = new KeyWatcher();
 695  2
         tf.addKeyListener(watcher);
 696  2
         showFrame(tf);
 697  2
         robot.focus(tf, true);
 698  2
         robot.key(KeyEvent.VK_END);
 699  2
         robot.waitForIdle();
 700  2
         Timer timer = new Timer();
 701  2
         while (!watcher.gotPress) {
 702  0
             if (timer.elapsed() > EVENT_GENERATION_DELAY)
 703  0
                 fail("Never got key press");
 704  0
             robot.sleep();
 705   
         }
 706  2
         assertEquals("Wrong keycode was generated",
 707   
                      KeyEvent.VK_END, watcher.keyCode);
 708  2
         while (!watcher.gotRelease) {
 709  0
             if (timer.elapsed() > EVENT_GENERATION_DELAY)
 710  0
                 fail("Never got key release");
 711  0
             robot.sleep();
 712   
         }
 713   
     }
 714   
 
 715  2
     public void testFindFocusOwner() {
 716  2
         JPanel pane = new JPanel();
 717  2
         JTextField tf1 = new JTextField("tf 1");
 718  2
         tf1.setName("tf 1");
 719  2
         JTextField tf2 = new JTextField("tf 2");
 720  2
         tf2.setName("tf 2");
 721  2
         pane.add(tf1);
 722  2
         pane.add(tf2);
 723  2
         showFrame(pane);
 724  2
         robot.focus(tf2, true);
 725  2
         assertEquals("Wrong focus detected",
 726   
                      Robot.toString(tf2),
 727   
                      Robot.toString(robot.findFocusOwner()));
 728   
     }
 729   
 
 730  2
     public void testIconify() throws Throwable {
 731  2
         Frame frame = showFrame(new JLabel(getName()));
 732  2
         robot.iconify(frame);
 733   
         // Give the WM time to put the window away
 734  2
         Timer timer = new Timer();
 735  2
         while (frame.getState() != Frame.ICONIFIED) {
 736  0
             if (timer.elapsed() > EVENT_GENERATION_DELAY)
 737  0
                 fail("Frame not iconified, state " + frame.getState());
 738  0
             robot.sleep();
 739   
         }
 740  2
         robot.deiconify(frame);
 741  2
         timer.reset();
 742  2
         while (frame.getState() != Frame.NORMAL) {
 743  2
             if (timer.elapsed() > EVENT_GENERATION_DELAY)
 744  0
                 fail("Frame not restored, state " + frame.getState());
 745  2
             robot.sleep();
 746   
         }
 747   
     }
 748   
 
 749  2
     public void testMaximize() {
 750  2
         Frame frame = showFrame(new JLabel(getName()));
 751  2
         Dimension size = frame.getSize();
 752  2
         robot.maximize(frame);
 753  2
         Timer timer = new Timer();
 754  2
         while (frame.getSize().equals(size)) {
 755  51
             if (timer.elapsed() > EVENT_GENERATION_DELAY)
 756  0
                 fail("Frame size not changed");
 757  51
             robot.sleep();
 758   
         }
 759  2
         robot.normalize(frame);
 760   
         // Don't bother testing normalize (it won't work on 1.3.1)
 761   
     }
 762   
 
 763   
     private class EnterExitListener implements AWTEventListener {
 764   
         public AWTEvent exited;
 765   
         public AWTEvent entered;
 766  6
         public void eventDispatched(AWTEvent event) {
 767  6
             if (event.getID() == MouseEvent.MOUSE_ENTERED) {
 768  4
                 entered = event;
 769   
             }
 770  2
             else if (event.getID() == MouseEvent.MOUSE_EXITED) {
 771  2
                 exited = event;
 772   
             }
 773   
         }
 774   
     }
 775   
 
 776  2
     public void testEnterExitGeneration() {
 777  2
         JPanel panel = new JPanel();
 778  2
         JLabel label1 = new JLabel("Source"); label1.setName("label 1");
 779  2
         JLabel label2 = new JLabel("Destination"); label2.setName("label 2");
 780   
 
 781  2
         panel.add(label1);
 782  2
         panel.add(label2);
 783  2
         Frame f = showFrame(panel, new Dimension(200, 200));
 784  2
         f.setName(getName());
 785   
         // Ensure we have a state to start with
 786  2
         robot.mouseMove(label1);
 787  2
         robot.waitForIdle();
 788   
         // Add the listener *after* the mouse is within the first component
 789  2
         EnterExitListener eel = new EnterExitListener();
 790  2
         new WeakAWTEventListener(eel, MouseEvent.MOUSE_EVENT_MASK);
 791  2
         robot.mouseMove(label2);
 792  2
         robot.waitForIdle();
 793   
 
 794  2
         assertEquals("Expect no exit event w/o motion listeners",
 795   
                      null, eel.exited);
 796  2
         assertEquals("Expect no enter event w/o motion listeners",
 797   
                      null, eel.entered);
 798   
 
 799  2
         MouseListener ml = new MouseAdapter() { };
 800  2
         label1.addMouseListener(ml);
 801  2
         label2.addMouseListener(ml);
 802   
 
 803  2
         robot.mouseMove(label1);
 804  2
         robot.waitForIdle();
 805   
 
 806  2
         assertEquals("Expect no exit event (last component was frame)",
 807   
                      null, eel.exited);
 808  2
         assertEquals("Enter event was expected",
 809   
                      label1, eel.entered.getSource());
 810   
 
 811  2
         eel.entered = eel.exited = null;
 812   
 
 813  2
         robot.mouseMove(label2);
 814  2
         robot.waitForIdle();
 815  2
         assertEquals("Exit event was expected", 
 816   
                      label1, eel.exited.getSource());
 817  2
         assertEquals("Enter event was expected",
 818   
                      label2, eel.entered.getSource());
 819   
     }
 820   
 
 821  2
     public void testGetModifiers() {
 822  2
         Object[][] modifiers = {
 823   
             { "ALT", new Integer(InputEvent.ALT_MASK) },
 824   
             { "ALT_GRAPH", new Integer(InputEvent.ALT_GRAPH_MASK) },
 825   
             { "SHIFT", new Integer(InputEvent.SHIFT_MASK) },
 826   
             { "CTRL", new Integer(InputEvent.CTRL_MASK) },
 827   
             { "META", new Integer(InputEvent.META_MASK) },
 828   
             { "BUTTON1", new Integer(InputEvent.BUTTON1_MASK) },
 829   
             { "BUTTON2", new Integer(InputEvent.BUTTON2_MASK) },
 830   
             { "BUTTON3", new Integer(InputEvent.BUTTON3_MASK) },
 831   
             { "POPUP", new Integer(AWTConstants.POPUP_MASK) },
 832   
             { "TERTIARY", new Integer(AWTConstants.TERTIARY_MASK) },
 833   
             { "ALT|CTRL|SHIFT", new Integer(InputEvent.ALT_MASK
 834   
                                             |InputEvent.CTRL_MASK
 835   
                                             |InputEvent.SHIFT_MASK) },
 836   
         };
 837  2
         for (int i=0;i < modifiers.length;i++) {
 838  22
             String mod = (String)modifiers[i][0];
 839  22
             assertEquals("Wrong value for string modifier " + mod, 
 840   
                          modifiers[i][1],
 841   
                          new Integer(AWT.getModifiers(mod)));
 842   
         }
 843  2
         for (int i=0;i < modifiers.length;i++) {
 844  22
             String mod = modifiers[i][0].toString() + "_MASK";
 845  22
             assertEquals("Wrong value for string modifier " + mod,
 846   
                          modifiers[i][1],
 847   
                          new Integer(AWT.getModifiers(mod)));
 848   
         }
 849   
     }
 850   
 
 851  2
     public void testMouselessModifierMask() {
 852  2
         JButton b = new JButton("Push Me");
 853  2
         b.setMnemonic(KeyEvent.VK_P);
 854  2
         showFrame(b);
 855  2
         final Flag flag = new Flag();
 856  2
         b.addActionListener(new ActionListener() {
 857  2
             public void actionPerformed(ActionEvent e) {
 858  2
                 flag.flag = true;
 859   
             }
 860   
         });
 861  2
         robot.key(KeyEvent.VK_P, Robot.MOUSELESS_MODIFIER_MASK);
 862  2
         robot.waitForIdle();
 863  2
         assertTrue("Button not activated, probably incorrect mouseless modifier",
 864   
                    flag.flag);
 865   
     }
 866   
 
 867   
     /** Create a new test case with the given name. */
 868  56
     public RobotTest(String name) { super(name); }
 869   
     /** Note the event mode when reporting this test's name. */
 870  266
     public String getName() { 
 871  266
         return Robot.getEventMode() == Robot.EM_AWT
 872   
             ? super.getName() + " (AWT mode)"
 873   
             : super.getName();
 874   
     }
 875   
 
 876   
     private Robot robot;
 877  56
     protected void setUp() {
 878  56
         robot = getRobot();
 879   
     }
 880   
 
 881   
     /** Provide for repetitive testing on individual tests. */
 882  0
     public static void main(String[] args) {
 883  0
         RepeatHelper.runTests(args, RobotTest.class);
 884   
     }
 885   
 }
 886