001: package abbot.tester;
002:
003: import java.lang.reflect.*;
004:
005: import java.awt.*;
006: import java.awt.event.*;
007: import javax.swing.*;
008: import junit.extensions.abbot.*;
009: import abbot.DynamicLoadingConstants;
010: import abbot.finder.ComponentSearchException;
011: import abbot.finder.matchers.ClassMatcher;
012: import abbot.util.*;
013: import abbot.util.Bugs;
014:
015: /** Unit test to verify the base ComponentTester class.<p>
016:
017: <ul>
018: <li>Test all exported actions.
019: </ul>
020: */
021: // OSX uses a button/modifier combo to indicate MB2/3...ick
022: // w32 uses a button/modifier combo to indicate MB3...ick
023: public class ComponentTesterTest extends ComponentTestFixture implements
024: DynamicLoadingConstants {
025:
026: private ComponentTester tester;
027:
028: protected void setUp() {
029: tester = new ComponentTester();
030: }
031:
032: protected void tearDown() {
033: tester = null;
034: }
035:
036: private class ActionFlag extends AbstractAction {
037: public volatile boolean gotAction;
038:
039: public ActionFlag(String label) {
040: super (label);
041: }
042:
043: public void actionPerformed(ActionEvent ev) {
044: gotAction = true;
045: }
046: }
047:
048: public void testSelectPopupMenuItem() {
049: JPanel pane = new JPanel();
050: ActionFlag item1 = new ActionFlag("Item One");
051: ActionFlag item2 = new ActionFlag("Item Two");
052: JPopupMenu popup = new JPopupMenu();
053: popup.add(new JMenuItem(item1));
054: popup.add(new JMenuItem(item2));
055:
056: installPopup(pane, popup);
057: showFrame(pane, new Dimension(200, 200));
058:
059: // This implicitly tests "actionShowPopupMenu"
060: tester.actionSelectPopupMenuItem(pane, "Item One");
061: assertTrue("First popup menu item not selected",
062: item1.gotAction);
063:
064: tester.actionSelectPopupMenuItem(pane, "Item Two");
065: assertTrue("Second popup menu item not selected",
066: item2.gotAction);
067: }
068:
069: // Broken in 1.5 on linux; popup submenu gets dismissed if mouse button
070: // is not depressed
071: public void testSelectPopupSubMenuItem() {
072: JPanel pane = new JPanel();
073: ActionFlag item1 = new ActionFlag("Item One");
074: ActionFlag item2 = new ActionFlag("Item Two");
075: ActionFlag sub1 = new ActionFlag("Subitem One");
076: ActionFlag sub2 = new ActionFlag("Subitem Two");
077: JPopupMenu popup = new JPopupMenu();
078: popup.add(new JMenuItem(item1));
079: popup.add(new JMenuItem(item2));
080: JMenu submenu = new JMenu("Submenu");
081: submenu.add(new JMenuItem(sub1));
082: submenu.add(new JMenuItem(sub2));
083: popup.add(submenu);
084:
085: installPopup(pane, popup);
086: showFrame(pane, new Dimension(200, 200));
087:
088: tester.actionSelectPopupMenuItem(pane, "Subitem One");
089: assertTrue("First popup submenu item not selected",
090: sub1.gotAction);
091:
092: tester.actionSelectPopupMenuItem(pane, "Subitem Two");
093: assertTrue("Second popup submenu item not selected",
094: sub2.gotAction);
095: }
096:
097: public void testSelectPopupMenuItemByPath() {
098: JPanel pane = new JPanel();
099: ActionFlag item1 = new ActionFlag("Item One");
100: ActionFlag item2 = new ActionFlag("Item Two");
101: ActionFlag sub1 = new ActionFlag("Duplicate");
102: ActionFlag sub2 = new ActionFlag("Duplicate");
103: JPopupMenu popup = new JPopupMenu();
104: popup.add(new JMenuItem(item1));
105: popup.add(new JMenuItem(item2));
106: JMenu submenu = new JMenu("Submenu");
107: submenu.add(new JMenuItem(sub1));
108: popup.add(submenu);
109: JMenu submenu2 = new JMenu("Submenu2");
110: submenu2.add(new JMenuItem(sub2));
111: popup.add(submenu2);
112:
113: installPopup(pane, popup);
114: showFrame(pane, new Dimension(200, 200));
115:
116: // This implicitly tests "actionShowPopupMenu"
117: tester.actionSelectPopupMenuItem(pane, "Submenu|Duplicate");
118: assertTrue("First popup submenu item not selected",
119: sub1.gotAction);
120: tester.actionSelectPopupMenuItem(pane, "Submenu2|Duplicate");
121: assertTrue("Second popup submenu item not selected",
122: sub2.gotAction);
123: try {
124: tester.actionSelectPopupMenuItem(pane, "Ziggy");
125: fail("Selecting nonexistent item should fail");
126: } catch (ActionFailedException e) {
127: // expected
128: }
129: try {
130: tester
131: .actionSelectPopupMenuItem(pane,
132: "Item One|Duplicate");
133: fail("Selecting nonexistent path should fail");
134: } catch (ActionFailedException e) {
135: // expected
136: }
137: }
138:
139: /** Check translation between event IDs and integer values. */
140: public void testEventID() {
141: assertEquals("mouse press", MouseEvent.MOUSE_PRESSED, Robot
142: .getEventID(MouseEvent.class, "MOUSE_PRESSED"));
143: assertEquals("mouse release", MouseEvent.MOUSE_RELEASED, Robot
144: .getEventID(MouseEvent.class, "MOUSE_RELEASED"));
145: assertEquals("mouse click", MouseEvent.MOUSE_CLICKED, Robot
146: .getEventID(MouseEvent.class, "MOUSE_CLICKED"));
147: }
148:
149: /** Verify forward and back parsing of modifiers. */
150: public void testModifiers() {
151: // NOTE: As of Java 1.3, Meta and Control also map to button 2/3.
152: // Currently the symbolic button masks are preferred to the symbolic
153: // key masks.
154: assertEquals("shift", InputEvent.SHIFT_MASK, AWT
155: .getModifiers("SHIFT_MASK"));
156: assertEquals("button 1", InputEvent.BUTTON1_MASK, AWT
157: .getModifiers("BUTTON1_MASK"));
158: assertEquals("button 2", InputEvent.BUTTON2_MASK, AWT
159: .getModifiers("BUTTON2_MASK"));
160: assertEquals("button 3", InputEvent.BUTTON3_MASK, AWT
161: .getModifiers("BUTTON3_MASK"));
162: // combinations
163: assertEquals("shift + button 1", InputEvent.SHIFT_MASK
164: | InputEvent.BUTTON1_MASK, AWT
165: .getModifiers("SHIFT_MASK | BUTTON1_MASK"));
166: }
167:
168: /** Check virtual keycode parsing. */
169: public void testKeyCodeParsing() {
170: assertEquals("key 'A'", KeyEvent.VK_A, AWT.getKeyCode("VK_A"));
171: assertEquals("key '0'", KeyEvent.VK_0, AWT.getKeyCode("VK_0"));
172: }
173:
174: private class KeyWatcher extends KeyAdapter {
175: public volatile boolean gotPress = false;
176: public volatile boolean gotRelease = false;
177: public volatile boolean gotTyped = false;
178: public volatile int keyCode = KeyEvent.VK_UNDEFINED;
179: public volatile int modifiers = 0;
180:
181: public void keyPressed(KeyEvent ke) {
182: gotPress = true;
183: keyCode = ke.getKeyCode();
184: modifiers = ke.getModifiers();
185: }
186:
187: public void keyReleased(KeyEvent ke) {
188: gotRelease = true;
189: }
190:
191: public void keyTyped(KeyEvent ke) {
192: gotTyped = true;
193: }
194: }
195:
196: public void testKeyStroke() {
197: JTextField tf = new JTextField();
198: KeyWatcher kw = new KeyWatcher();
199: tf.addKeyListener(kw);
200: tf.setColumns(10);
201: showFrame(tf);
202: tester.actionFocus(tf);
203: int code = KeyEvent.VK_A;
204: int mods = KeyEvent.SHIFT_MASK;
205: tester.actionKeyStroke(code, mods);
206: assertTrue("Never received key press", kw.gotPress);
207: assertEquals("Wrong key code", code, kw.keyCode);
208: assertEquals("Wrong modifiers", AWT.getKeyModifiers(mods), AWT
209: .getKeyModifiers(kw.modifiers));
210: assertTrue("Never received release", kw.gotRelease);
211: assertTrue("Never received type", kw.gotTyped);
212: }
213:
214: private class MouseWatcher extends MouseAdapter {
215: public volatile boolean gotClick;
216: public volatile int clickCount;
217: public volatile int modifiers;
218:
219: public void mousePressed(MouseEvent me) {
220: modifiers = me.getModifiers();
221: }
222:
223: public void mouseClicked(MouseEvent me) {
224: gotClick = true;
225: clickCount = me.getClickCount();
226: modifiers = me.getModifiers();
227: }
228: }
229:
230: /** Ensure the advertised multiple click method works. */
231: // FIXME sporadic OSX failures
232: public void testDoubleClick() {
233: MouseWatcher mw = new MouseWatcher();
234: JTextField tf = new JTextField("SelectMe");
235: tf.addMouseListener(mw);
236: showFrame(tf);
237: tester.actionFocus(tf);
238: tester.actionClick(tf, tf.getWidth() / 2, tf.getHeight() / 2,
239: InputEvent.BUTTON1_MASK, 2);
240: assertEquals("Wrong number of clicks", 2, mw.clickCount);
241: tester.delay(AWTConstants.MULTI_CLICK_INTERVAL + 10);
242: }
243:
244: /** Ensure that we can send clicks close enough together to register as a
245: double click. */
246: public void testTwoClicks() {
247: MouseWatcher mw = new MouseWatcher();
248: JTextField tf = new JTextField("SelectMe");
249: tf.addMouseListener(mw);
250: showFrame(tf);
251: tester.actionFocus(tf);
252: tester.actionClick(tf);
253: tester.actionClick(tf);
254: assertEquals("Two clicks should make a double click", 2,
255: mw.clickCount);
256: }
257:
258: public void testClickWithControlModifier() {
259: MouseWatcher mw = new MouseWatcher();
260: JTextField tf = new JTextField("SelectMe");
261: tf.addMouseListener(mw);
262: showFrame(tf);
263: tester.actionFocus(tf);
264: tester.actionClick(tf, tf.getWidth() / 2, tf.getHeight() / 2,
265: InputEvent.BUTTON1_MASK | InputEvent.CTRL_MASK);
266: assertEquals("Wrong modifiers", InputEvent.BUTTON1_MASK
267: | InputEvent.CTRL_MASK, mw.modifiers);
268: }
269:
270: // obsolete functionality
271: public void testDeriveTag() {
272: Button button = new Button("AWT Button");
273: assertEquals("Tag should be the Button's label", button
274: .getLabel(), tester.deriveTag(button));
275: JButton jbutton = new JButton("JButton");
276: assertEquals("Tag should be the JButton's text", jbutton
277: .getText(), tester.deriveTag(jbutton));
278: JFrame frame = new JFrame("JFrame");
279: assertEquals("Tag should be the JFrame's title", frame
280: .getTitle(), tester.deriveTag(frame));
281: }
282:
283: public void testStripHTML() {
284: String html1 = "<html>simple</html>";
285: String strip1 = "simple";
286: String html2 = "<html><font color=\"red\" size=\"-1\">complex</font></html>";
287: String strip2 = "complex";
288: assertEquals("Simple html was not stripped", strip1,
289: ComponentTester.stripHTML(html1));
290: assertEquals("Complex html was not stripped", strip2,
291: ComponentTester.stripHTML(html2));
292: }
293:
294: public void testGetDefaultTester() throws Throwable {
295: String cname = DYNAMIC_COMPONENT_CLASSNAME;
296: ClassLoader cl = new abbot.util.NonDelegatingClassLoader(
297: DYNAMIC_CLASSPATH, getClass().getClassLoader());
298: Class cls = Class.forName(cname, true, cl);
299: assertEquals("Wrong class loader for test class", cl, cls
300: .getClassLoader());
301: ComponentTester customTester = ComponentTester.getTester(cls);
302: ComponentTester tester = ComponentTester
303: .getTester(java.awt.Component.class);
304: assertEquals("Wrong tester loaded", tester, customTester);
305: assertTrue("Class loaders should be different", !cls
306: .getClassLoader().equals(
307: tester.getClass().getClassLoader()));
308: }
309:
310: public void testFindTester() throws Throwable {
311: class Dialog extends JPanel {
312: }
313: ComponentTester tester = ComponentTester
314: .getTester(Dialog.class);
315: assertEquals("Wrong tester class loaded",
316: JComponentTester.class, tester.getClass());
317: }
318:
319: public void testEndKeyKeyStroke() {
320: TextField tf = new TextField(getName());
321: KeyWatcher kw = new KeyWatcher();
322: tf.addKeyListener(kw);
323: showFrame(tf);
324: tester.actionKeyStroke(tf, KeyEvent.VK_END);
325: assertTrue("Never received key press", kw.gotPress);
326: assertEquals("Wrong key code", KeyEvent.VK_END, kw.keyCode);
327: assertTrue("Never received key release", kw.gotRelease);
328: }
329:
330: // Make sure the select menu item action works on a popup regardless of
331: // how it was triggered.
332: public void testSelectFromButtonTriggeredPopup() {
333: final JButton button = new JButton(getName());
334: ActionFlag item1 = new ActionFlag("Item One");
335: ActionFlag item2 = new ActionFlag("Item Two");
336: ActionFlag sub1 = new ActionFlag("Subitem One");
337: ActionFlag sub2 = new ActionFlag("Subitem Two");
338: final JPopupMenu popup = new JPopupMenu();
339: JMenuItem mi1, mi2;
340: popup.add(new JMenuItem(item1));
341: popup.add(mi1 = new JMenuItem(item2));
342: JMenu submenu = new JMenu("Submenu");
343: submenu.add(new JMenuItem(sub1));
344: submenu.add(mi2 = new JMenuItem(sub2));
345: popup.add(submenu);
346:
347: button.addActionListener(new ActionListener() {
348: public void actionPerformed(ActionEvent e) {
349: popup.show(button, 0, button.getHeight());
350: }
351: });
352: showFrame(button, new Dimension(300, 200));
353:
354: tester.actionClick(button);
355: tester.actionSelectMenuItem(mi1);
356: assertTrue("First-level item on popup not selected",
357: item2.gotAction);
358:
359: tester.actionClick(button);
360: tester.actionSelectMenuItem(mi2);
361: assertTrue("2nd-level item on popup not selected",
362: sub2.gotAction);
363: }
364:
365: public void testSelectFromButtonTriggeredAWTPopup() {
366: if (Robot.getEventMode() == Robot.EM_AWT
367: && Bugs.showAWTPopupMenuBlocks()) {
368: //fail("This test would block");
369: return;
370: }
371:
372: final JButton button = new JButton(getName());
373: ActionFlag item2 = new ActionFlag("Item Two");
374: ActionFlag sub2 = new ActionFlag("Subitem Two");
375: final PopupMenu popup = new PopupMenu();
376: MenuItem mi1, mi2;
377: popup.add(new MenuItem("Item 1"));
378: popup.add(mi1 = new MenuItem("Item Two"));
379: Menu submenu = new Menu("Submenu");
380: submenu.add(new MenuItem("Subitem One"));
381: submenu.add(mi2 = new MenuItem("Subitem Two"));
382: popup.add(submenu);
383:
384: button.addActionListener(new ActionListener() {
385: public void actionPerformed(ActionEvent e) {
386: popup.show(button, 0, button.getHeight());
387: }
388: });
389: Frame frame = showFrame(button, new Dimension(300, 200));
390: frame.add(popup);
391: mi1.addActionListener(item2);
392: mi2.addActionListener(sub2);
393:
394: tester.click(button);
395: tester.actionSelectAWTPopupMenuItem(frame, mi1.getLabel());
396: assertTrue("First-level item on popup not selected",
397: item2.gotAction);
398:
399: tester.click(button);
400: tester.actionSelectAWTPopupMenuItem(frame, mi2.getLabel());
401: assertTrue("2nd-level item on popup not selected",
402: sub2.gotAction);
403: }
404:
405: public void testGetComponentActions() {
406: Method[] methods = tester.getComponentActions();
407: for (int i = 0; i < methods.length; i++) {
408: if (methods[i].getName().endsWith("ByLabel"))
409: fail("Deprecated method should be omitted");
410: }
411: }
412:
413: public void testGetPropertyMethods() {
414: Method[] methods = tester.getPropertyMethods();
415: for (int i = 0; i < methods.length; i++) {
416: String name = methods[i].getName();
417: if (name.equals("getTag") || name.equals("getTester")) {
418: fail("Non-property method should be omitted");
419: }
420: }
421: }
422:
423: public void testNoBlockOnKeyStrokeToActivateModalDialog()
424: throws Exception {
425: final KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_A,
426: KeyEvent.ALT_MASK);
427:
428: final JMenuItem b = new JMenuItem();
429: Action action = new AbstractAction("Save As") {
430: public void actionPerformed(ActionEvent e) {
431: new JFileChooser().showOpenDialog(b);
432: }
433: };
434: b.setAction(action);
435: JFrame f = new JFrame(getName());
436: JMenuBar mb = new JMenuBar();
437: JMenu file = new JMenu("File");
438: mb.add(file);
439: file.add(b);
440: f.setJMenuBar(mb);
441: f.getContentPane().add(new JLabel("test"));
442: b.setAccelerator(ks);
443: showWindow(f);
444: tester.actionKeyStroke(ks.getKeyCode(), ks.getModifiers());
445: try {
446: getFinder().find(new ClassMatcher(JFileChooser.class));
447: } catch (ComponentSearchException e) {
448: throw new RuntimeException("Dialog not opened on keystroke");
449: }
450: }
451:
452: public static void main(String[] args) {
453: RepeatHelper.runTests(args, ComponentTesterTest.class);
454: }
455: }
|