001: /*
002: * Copyright 2004 Timothy Wall
003: *
004: */
005: package abbot.util;
006:
007: import java.awt.Window;
008: import java.awt.event.InputEvent;
009: import java.awt.event.MouseAdapter;
010: import java.awt.event.MouseEvent;
011: import abbot.Log;
012: import abbot.Platform;
013: import abbot.i18n.Strings;
014: import abbot.tester.Robot;
015:
016: /**
017: Provides extant bug characterization of the current platform. For any bug
018: encountered, there should be a static method indicating whether the bug is
019: expected on the current platform, for example
020: {@link #showAWTPopupMenuBlocks()}.
021: See the source for <code>
022: <a href=../../../../test/abbot/util/BugsTest.java>BugsTest</a></code> for the
023: test implementations.
024: @author twall
025: */
026: public class Bugs {
027: private static java.util.ArrayList bugList = null;
028: private static boolean gotBug1Event = false;
029:
030: private Bugs() {
031: }
032:
033: /** Returns whether AWT menus have enable/disable problems. */
034: public static boolean hasMenuDisableBug() {
035: return Platform.isOSX()
036: && Platform.JAVA_VERSION >= Platform.JAVA_1_4
037: && Platform.JAVA_VERSION < 0x1424; // when it got fixed
038: }
039:
040: /** Returns whether KEY_TYPED events are sent to AWT listeners. */
041: public static boolean hasInputMethodInsteadOfKeyTyped() {
042: return Platform.isOSX()
043: && Platform.JAVA_VERSION >= Platform.JAVA_1_4
044: && Platform.JAVA_VERSION < 0x1424; // when it got fixed
045: }
046:
047: /** Returns whether windows send mouse motion events to AWT listeners. */
048: public static boolean hasMissingWindowMouseMotion() {
049: return Platform.isOSX()
050: && Platform.JAVA_VERSION >= Platform.JAVA_1_4
051: && Platform.JAVA_VERSION <= 0x1600; // most recent tested
052: }
053:
054: /** Returns whether mouse buttons 2/3 are swapped when using Robot. */
055: public static boolean hasRobotButtonsSwapped() {
056: return Platform.isOSX()
057: && Platform.JAVA_VERSION >= Platform.JAVA_1_4
058: && Platform.JAVA_VERSION <= 0x1425; // most recent tested
059: }
060:
061: /** Do we get multiple clicks even when the individual clicks are on
062: * different frames?
063: */
064: // Will we get incorrectly get multiple clicks on rapid robot clicks?
065: // frame1->click,frame2->click
066: // frame1->click,frame1->hide/show,frame1->click
067: public static boolean hasMultiClickFrameBug() {
068: // w32 (1.3.02) will count it even if it was on a different component!
069: // w32 (1.3.1_06) same
070: // w32 (1.4.1_02) same (sporadic)
071: // OSX (1.3.x, 1.4.1) has the same problem
072: // Haven't seen it on linux
073: return Platform.isWindows() || Platform.isOSX()
074: || Platform.JAVA_VERSION < Platform.JAVA_1_3;
075: }
076:
077: /** Returns whether there may be some scenarios in which the robot does
078: not function properly.
079: */
080: public static boolean needsRobotVerification() {
081: return Platform.isWindows();
082: }
083:
084: /** Prior to 1.4.1, hierarchy events are only sent if listeners are added
085: to a given component.
086: */
087: public static boolean hasHierarchyEventGenerationBug() {
088: return Platform.JAVA_VERSION < Platform.JAVA_1_4;
089: }
090:
091: /** OSX prior to 1.4 has really crappy key input handling. */
092: public static boolean hasKeyStrokeGenerationBug() {
093: return Platform.isOSX()
094: && Platform.JAVA_VERSION < Platform.JAVA_1_4;
095: }
096:
097: /** Returnes whether there a longer delay required between robot
098: generation and event queue posting for key events. */
099: public static boolean hasKeyInputDelay() {
100: return Platform.isOSX()
101: && Platform.JAVA_VERSION >= Platform.JAVA_1_4
102: && Platform.JAVA_VERSION <= 0x1425;
103: }
104:
105: /** Some OSX releases wouldn't restore an iconified Frame. */
106: public static boolean hasFrameDeiconifyBug() {
107: return Platform.isOSX() && Platform.JAVA_VERSION > 0x1310
108: && Platform.JAVA_VERSION < 0x1424;
109: }
110:
111: /** OS X (as of 1.3.1, v10.1.5), will sometimes send a click to the wrong
112: component after a mouse move. This continues to be an issue in 1.4.1
113: <p>
114: Linux x86 (1.3.1) has a similar problem, although it manifests it at
115: different times (need a bug test case for this one).
116: <p>
117: Solaris and HPUX probably share code with the linux VM implementation,
118: so the bug there is probably identical.
119: <p>
120: */
121: // FIXME add tests to determine presence of bug.
122: public static boolean hasRobotMotionBug() {
123: return Platform.isOSX()
124: || (!Platform.isWindows() && Platform.JAVA_VERSION < Platform.JAVA_1_4)
125: || Boolean.getBoolean("abbot.robot.need_jitter");
126: }
127:
128: /** Choice popup activates on mouse press, but locks up when the Robot
129: * attempts to post a mouse release.
130: */
131: public static boolean hasChoiceLockupBug() {
132: return Platform.isOSX()
133: && Platform.JAVA_VERSION < Platform.JAVA_1_4;
134: }
135:
136: /** Robot.keyPress(KeyEvent.VK_ESCAPE doesn't work. */
137: public static boolean hasEscapeGenerationBug() {
138: return Platform.isOSX()
139: && Platform.JAVA_VERSION < Platform.JAVA_1_4;
140: }
141:
142: /** Returns whether the Java event queue is suspended while an AWT popup
143: is showing. */
144: public static boolean showAWTPopupMenuBlocks() {
145: return Platform.isWindows()
146: && Platform.JAVA_VERSION <= Platform.JAVA_1_6;
147: }
148:
149: /** Locking key state is reported incorrectly. Later versions
150: (at least 1.4.2_11) throw UnsupportedOperationException).
151: */
152: public static boolean reportsIncorrectLockingKeyState() {
153: return Platform.isLinux() && Platform.JAVA_VERSION <= 0x1424;
154: }
155:
156: /** Whether drag/drop requires native events. */
157: // TODO: needs a test
158: public static boolean dragDropRequiresNativeEvents() {
159: return Platform.JAVA_VERSION <= 0x1425;
160: }
161:
162: /** Returns whether a {@link java.awt.FileDialog} requires an explicit
163: dismiss (ok/cancel). Ordinarily {@link Window#dispose()} will work.
164: */
165: public static boolean fileDialogRequiresDismiss() {
166: return Platform.isOSX()
167: && Platform.JAVA_VERSION <= 0x1600
168: // not sure exactly when this was fixed
169: || (Platform.isWindows() && Platform.JAVA_VERSION < 0x1412);
170: }
171:
172: /** Returns whether a {@link java.awt.FileDialog} misreports its screen
173: location.
174: */
175: public static boolean fileDialogMisreportsBounds() {
176: return (Platform.isOSX() && Platform.JAVA_VERSION <= 0x1600)
177: || (Platform.isWindows() && Platform.JAVA_VERSION <= Platform.JAVA_1_5);
178: }
179:
180: public static boolean fileDialogRequiresVisibleFrame() {
181: // Subsequent FileDialogs don't show up if the frame isn't visible,
182: // and a previous non-visible frame was disposed.
183: return Platform.isWindows() && Platform.JAVA_VERSION <= 0x1421;
184: }
185:
186: public static boolean hasTextComponentSelectionDelay() {
187: // TODO: write a test for this one
188: // Select TextComponent text, wait for idle, selection end not updated
189: return (Platform.isLinux() || Platform.isWindows())
190: && Platform.JAVA_VERSION <= 0x1424;
191: }
192:
193: public static boolean hasNoAWTInputOnTextFieldBug() {
194: return Platform.isLinux() && Platform.JAVA_VERSION < 0x1500
195: || Platform.isOSX() && Platform.JAVA_VERSION <= 0x1600;
196: }
197:
198: public static boolean locksUpOnScreenCapture() {
199: return Platform.isLinux() && Platform.JAVA_VERSION >= 0x1400
200: && Platform.JAVA_VERSION <= 0x1505;
201: }
202:
203: /** Check for certain robot-related bugs that will affect Abbot
204: * operation. Returns a String for each bug detected on the current
205: * system.
206: */
207: public static String[] bugCheck(final Window window) {
208: if (bugList == null) {
209: bugList = new java.util.ArrayList();
210: final int x = window.getWidth() / 2;
211: final int y = window.getHeight() / 2;
212: if (Platform.isWindows() && !Platform.isWindowsXP()
213: && Platform.JAVA_VERSION < Platform.JAVA_1_4) {
214: Log.debug("Checking for w32 bugs");
215: final int mask = InputEvent.BUTTON2_MASK;
216: MouseAdapter ma = new MouseAdapter() {
217: public void mouseClicked(MouseEvent e) {
218: gotBug1Event = true;
219: // w32 acceleration settings bug
220: if (e.getX() != x || e.getY() != y) {
221: bugList.add(Strings.get("Bug1"));
222: }
223: // w32 mouse button mapping bug
224: if ((e.getModifiers() & mask) != mask) {
225: bugList.add(Strings.get("Bug2"));
226: }
227: }
228: };
229: window.addMouseListener(ma);
230: Robot robot = new Robot();
231: robot.click(window, x, y, mask);
232: robot.waitForIdle();
233: window.toFront();
234: // Bogus acceleration may mean the event goes entirely
235: // elsewhere
236: if (!gotBug1Event) {
237: bugList.add(0, Strings.get("Bug1"));
238: }
239: window.removeMouseListener(ma);
240: } else if (Platform.isOSX()
241: && Platform.JAVA_VERSION < 0x1430) {
242: Log.debug("Checking for OSX bugs");
243: final int mask = InputEvent.BUTTON2_MASK;
244: MouseAdapter ma = new MouseAdapter() {
245: public void mouseClicked(MouseEvent e) {
246: if ((e.getModifiers() & mask) != mask) {
247: bugList.add(Strings.get("robot.bug3"));
248: }
249: }
250: };
251: window.addMouseListener(ma);
252: Robot robot = new Robot();
253: robot.click(window, x, y, mask);
254: robot.waitForIdle();
255: window.removeMouseListener(ma);
256: }
257: }
258: return (String[]) bugList.toArray(new String[bugList.size()]);
259: }
260:
261: }
|