001 /*
002 * Created on Mar 1, 2008
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005 * in compliance with the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License
010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011 * or implied. See the License for the specific language governing permissions and limitations under
012 * the License.
013 *
014 * Copyright @2008-2010 the original author or authors.
015 */
016 package org.fest.swing.core;
017
018 import java.awt.*;
019 import java.awt.event.InputEvent;
020
021 import javax.swing.JPopupMenu;
022
023 import org.fest.swing.exception.ActionFailedException;
024 import org.fest.swing.exception.ComponentLookupException;
025 import org.fest.swing.hierarchy.ComponentHierarchy;
026 import org.fest.swing.lock.ScreenLock;
027
028 /**
029 * Understands simulation of user events on a GUI <code>{@link Component}</code>.
030 *
031 * @author Alex Ruiz
032 * @author Yvonne Wang
033 */
034 public interface Robot {
035
036 /**
037 * Returns the <code>{@link ComponentHierarchy}</code> being used by this robot.
038 * @return the <code>ComponentHierarchy</code> being used by this robot.
039 */
040 ComponentHierarchy hierarchy();
041
042 /**
043 * Returns the <code>{@link ComponentFinder}</code> being used by this robot.
044 * @return the <code>ComponentFinder</code> being used by this robot.
045 */
046 ComponentFinder finder();
047
048 /**
049 * Returns the <code>{@link BasicComponentPrinter}</code> being used by this robot.
050 * @return the <code>ComponentPrinter</code> being used by this robot.
051 */
052 ComponentPrinter printer();
053
054 /**
055 * Safely display a window with proper EDT synchronization. This method blocks until the <code>{@link Window}</code>
056 * is showing and ready for input.
057 * @param w the window to display.
058 */
059 void showWindow(Window w);
060
061 /**
062 * Safely display a window with proper EDT synchronization. This method blocks until the <code>{@link Window}</code>
063 * is showing and ready for input.
064 * @param w the window to display.
065 * @param size the size of the window to display.
066 */
067 void showWindow(Window w, Dimension size);
068
069 /**
070 * <p>
071 * Safely display a window with proper EDT synchronization. This method blocks until the window is showing. This
072 * method will return even when the window is a modal dialog, since the show method is called on the event dispatch
073 * thread. The window will be packed if the pack flag is set, and set to the given size if it is non-<code>null</code>.
074 * </p>
075 * Modal dialogs may be shown with this method without blocking.
076 * @param w the window to display.
077 * @param size the size of the window to display.
078 * @param pack flag that indicates if the window should be packed or not. By packed we mean calling
079 * <code>w.pack()</code>.
080 */
081 void showWindow(final Window w, final Dimension size, final boolean pack);
082
083 /**
084 * Simulates a user closing the given window.
085 * @param w the window to close.
086 */
087 void close(Window w);
088
089 /**
090 * Gives input focus to the given <code>{@link Component}</code>. Note that the component may not yet have focus when
091 * this method returns.
092 * @param c the component to give focus to.
093 */
094 void focus(Component c);
095
096 /**
097 * Gives input focus to the given <code>{@link Component}</code> and waits until the <code>{@link Component}</code>
098 * has focus.
099 * @param c the component to give focus to.
100 */
101 void focusAndWaitForFocusGain(Component c);
102
103 /**
104 * Cleans up any used resources (keyboard, mouse, open windows and <code>{@link ScreenLock}</code>) used by this
105 * robot.
106 */
107 void cleanUp();
108
109 /**
110 * Cleans up any used resources (keyboard, mouse and <code>{@link ScreenLock}</code>) used by this robot. This method
111 * <strong>does not</strong> dispose any open windows.
112 * <p>
113 * <strong>Note:</strong> The preferred method to use to clean up resources is <code>{@link #cleanUp()}</code>. Using
114 * <code>{@link #cleanUpWithoutDisposingWindows()}</code> may leave many windows open after each test. Use it on very
115 * special cases. Please read <a href="http://code.google.com/p/fest/issues/detail?id=138" target="_blank">bug 138</a>
116 * for more details.
117 * </p>
118 */
119 void cleanUpWithoutDisposingWindows();
120
121 /**
122 * Simulates a user clicking once the given <code>{@link Component}</code> using the left mouse button.
123 * @param c the <code>Component</code> to click on.
124 * @throws ActionFailedException if the component to click is out of the boundaries of the screen.
125 */
126 void click(Component c);
127
128 /**
129 * Simulates a user right-clicking the given <code>{@link Component}</code>.
130 * @param c the <code>Component</code> to click on.
131 * @throws ActionFailedException if the component to click is out of the boundaries of the screen.
132 */
133 void rightClick(Component c);
134
135 /**
136 * Simulates a user clicking once the given <code>{@link Component}</code> using the given mouse button.
137 * @param c the <code>Component</code> to click on.
138 * @param button the mouse button to use.
139 * @throws ActionFailedException if the component to click is out of the boundaries of the screen.
140 */
141 void click(Component c, MouseButton button);
142
143 /**
144 * Simulates a user double-clicking the given <code>{@link Component}</code>.
145 * @param c the <code>Component</code> to click on.
146 * @throws ActionFailedException if the component to click is out of the boundaries of the screen.
147 */
148 void doubleClick(Component c);
149
150 /**
151 * Simulates a user clicking the given mouse button, the given times on the given <code>{@link Component}</code>.
152 * @param c the <code>Component</code> to click on.
153 * @param button the mouse button to click.
154 * @param times the number of times to click the given mouse button.
155 * @throws ActionFailedException if the component to click is out of the boundaries of the screen.
156 */
157 void click(Component c, MouseButton button, int times);
158
159 /**
160 * Simulates a user clicking at the given position on the given <code>{@link Component}</code>.
161 * @param c the <code>Component</code> to click on.
162 * @param where the given coordinates, relative to the given <code>Component</code>.
163 * @throws ActionFailedException if the component to click is out of the boundaries of the screen.
164 */
165 void click(Component c, Point where);
166
167 /**
168 * Simulates a user clicking the given mouse button, the given times at the given position on the given
169 * <code>{@link Component}</code>.
170 * @param c the <code>Component</code> to click on.
171 * @param where the given coordinates, relative to the given <code>Component</code>.
172 * @param button the mouse button to click.
173 * @param times the number of times to click the given mouse button.
174 * @throws ActionFailedException if the component to click is out of the boundaries of the screen.
175 */
176 void click(Component c, Point where, MouseButton button, int times);
177
178 /**
179 * Simulates a user clicking the given mouse button, the given times at the given absolute coordinates.
180 * @param where the coordinates where to click.
181 * @param button the mouse button to click.
182 * @param times the number of times to click the given mouse button.
183 */
184 void click(Point where, MouseButton button, int times);
185
186 /**
187 * Simulates a user pressing a mouse button.
188 * @param button the mouse button to press.
189 */
190 void pressMouse(MouseButton button);
191
192 /**
193 * Simulates a user pressing the left mouse button on the given <code>{@link Component}</code>.
194 * @param c the <code>Component</code> to click on.
195 * @param where the given coordinates, relative to the given <code>Component</code>.
196 */
197 void pressMouse(Component c, Point where);
198
199 /**
200 * Simulates a user pressing the given mouse button on the given <code>{@link Component}</code>.
201 * @param c the <code>Component</code> to click on.
202 * @param where the given coordinates, relative to the given <code>Component</code>.
203 * @param button the mouse button to press.
204 */
205 void pressMouse(Component c, Point where, MouseButton button);
206
207 /**
208 * Simulates a user pressing the given mouse button on the given coordinates.
209 * @param where the position where to press the given mouse button.
210 * @param button the mouse button to press.
211 * @since 1.1
212 */
213 void pressMouse(Point where, MouseButton button);
214
215 /**
216 * Simulates a user moving the mouse pointer to the center of the given <code>{@link Component}</code>.
217 * @param c the given <code>Component</code>.
218 */
219 void moveMouse(Component c);
220
221 /**
222 * Simulates a user moving the mouse pointer to the given coordinates relative to the given
223 * <code>{@link Component}</code>.
224 * @param c the given <code>Component</code>.
225 * @param p the given coordinates, relative to the given <code>Component</code>.
226 * @throws ActionFailedException if the given component is not showing and ready for input.
227 */
228 void moveMouse(Component c, Point p);
229
230 /**
231 * Simulates a user moving the mouse pointer to the given coordinates relative to the given
232 * <code>{@link Component}</code>.
233 * @param c the given <code>Component</code>.
234 * @param x X coordinate, relative to the given <code>Component</code>.
235 * @param y Y coordinate, relative to the given <code>Component</code>.
236 * @throws ActionFailedException if the given component is not showing and ready for input.
237 */
238 void moveMouse(Component c, int x, int y);
239
240 /**
241 * Simulates a user moving the mouse pointer to the given coordinates.
242 * @param p the given coordinates.
243 * @since 1.1
244 */
245 void moveMouse(Point p);
246
247 /**
248 * Simulates a user moving the mouse pointer to the given coordinates.
249 * @param x X coordinate.
250 * @param y Y coordinate.
251 * @since 1.1
252 */
253 void moveMouse(int x, int y);
254
255 /**
256 * Releases the given mouse button.
257 * @param button the mouse button to release.
258 */
259 void releaseMouse(MouseButton button);
260
261 /**
262 * Releases any mouse button(s) used by the robot.
263 */
264 void releaseMouseButtons();
265
266 /**
267 * Moves the mouse pointer over to the given <code>{@link Component}</code> and rotates the scroll wheel on
268 * wheel-equipped mice.
269 * @param c the given <code>Component</code>.
270 * @param amount number of "notches" to move the mouse wheel. Negative values indicate movement up/away from the user,
271 * while positive values indicate movement down/towards the user.
272 */
273 void rotateMouseWheel(Component c, int amount);
274
275 /**
276 * Rotates the scroll wheel on wheel-equipped mice.
277 * @param amount number of "notches" to move the mouse wheel. Negative values indicate movement up/away from the user,
278 * while positive values indicate movement down/towards the user.
279 */
280 void rotateMouseWheel(int amount);
281
282 /**
283 * Makes the mouse pointer show small quick jumpy movements on the given <code>{@link Component}</code>.
284 * @param c the given <code>Component</code>.
285 */
286 void jitter(Component c);
287
288 /**
289 * Makes the mouse pointer show small quick jumpy movements on the given <code>{@link Component}</code> at the given
290 * point.
291 * @param c the given <code>Component</code>.
292 * @param where the given point.
293 */
294 void jitter(Component c, Point where);
295
296 /**
297 * Simulates a user entering the given text. Note that this method the key strokes to the component that has input
298 * focus.
299 * @param text the text to enter.
300 */
301 void enterText(String text);
302
303 /**
304 * Types the given character. Note that this method sends the key strokes to the component that has input focus.
305 * @param character the character to type.
306 */
307 void type(char character);
308
309 /**
310 * Type the given key code with the given modifiers. Modifiers is a mask from the available
311 * <code>{@link java.awt.event.InputEvent}</code> masks.
312 * @param keyCode the code of the key to press.
313 * @param modifiers the given modifiers.
314 * @throws IllegalArgumentException if the given code is not a valid key code.
315 */
316 void pressAndReleaseKey(int keyCode, int... modifiers);
317
318 /**
319 * Simulates a user pressing and releasing the given keys. This method does not affect the current focus.
320 * @param keyCodes one or more codes of the keys to press.
321 * @see java.awt.event.KeyEvent
322 * @throws IllegalArgumentException if any of the given codes is not a valid key code.
323 */
324 void pressAndReleaseKeys(int... keyCodes);
325
326 /**
327 * Simulates a user pressing given key. This method does not affect the current focus.
328 * @param keyCode the code of the key to press.
329 * @see java.awt.event.KeyEvent
330 * @throws IllegalArgumentException if the given code is not a valid key code.
331 */
332 void pressKey(int keyCode);
333
334 /**
335 * Simulates a user releasing the given key. This method does not affect the current focus.
336 * @param keyCode the code of the key to release.
337 * @see java.awt.event.KeyEvent
338 * @throws IllegalArgumentException if the given code is not a valid key code.
339 */
340 void releaseKey(int keyCode);
341
342 /**
343 * Presses the appropriate modifiers corresponding to the given mask. Use mask values from
344 * <code>{@link InputEvent}</code>.
345 * @param modifierMask the given mask.
346 * @see InputEvent
347 */
348 void pressModifiers(int modifierMask);
349
350 /**
351 * Releases the appropriate modifiers corresponding to the given mask. Use mask values from
352 * <code>{@link InputEvent}</code>.
353 * @param modifierMask the given mask.
354 * @see InputEvent
355 */
356 void releaseModifiers(int modifierMask);
357
358 /**
359 * Wait for an idle AWT event queue. Note that this is different from the implementation of
360 * <code>java.awt.Robot.waitForIdle()</code>, which may have events on the queue when it returns. Do <strong>NOT</strong>
361 * use this method if there are animations or other continual refreshes happening, since in that case it may never
362 * return.
363 * @throws IllegalThreadStateException if this method is called from the event dispatch thread.
364 */
365 void waitForIdle();
366
367 /**
368 * Indicates whether the robot is currently in a dragging operation.
369 * @return <code>true</code> if the robot is currently in a dragging operation, <code>false</code> otherwise.
370 */
371 boolean isDragging();
372
373 /**
374 * Indicates whether the given <code>{@link Component}</code> is ready for input.
375 * @param c the given <code>Component</code>.
376 * @return <code>true</code> if the given <code>Component</code> is ready for input, <code>false</code> otherwise.
377 * @throws ActionFailedException if the given <code>Component</code> does not have a <code>Window</code> ancestor.
378 */
379 boolean isReadyForInput(Component c);
380
381 /**
382 * Shows a pop-up menu.
383 * @param invoker the component to invoke the pop-up menu from.
384 * @return the displayed pop-up menu.
385 * @throws org.fest.swing.exception.ComponentLookupException if a pop-up menu cannot be found.
386 */
387 JPopupMenu showPopupMenu(Component invoker);
388
389 /**
390 * Shows a pop-up menu at the given coordinates.
391 * @param invoker the component to invoke the pop-up menu from.
392 * @param location the given coordinates for the pop-up menu.
393 * @return the displayed pop-up menu.
394 * @throws ComponentLookupException if a pop-up menu cannot be found.
395 */
396 JPopupMenu showPopupMenu(Component invoker, Point location);
397
398 /**
399 * Returns the currently active pop-up menu, if any. If no pop-up is currently showing, returns <code>null</code>.
400 * @return the currently active pop-up menu or <code>null</code>, if no pop-up is currently showing.
401 */
402 JPopupMenu findActivePopupMenu();
403
404 /**
405 * Ensures that there is no <code>{@link javax.swing.JOptionPane}</code> showing, and potentially blocking GUI tests.
406 * @throws AssertionError if there is one or more <code>JOptionPane</code>s showing on the screen.
407 */
408 void requireNoJOptionPaneIsShowing();
409
410 /**
411 * Returns the configuration settings for this <code>{@link Robot}</code>.
412 * @return the configuration settings for this <code>Robot</code>.
413 */
414 Settings settings();
415
416 /**
417 * Indicates whether this <code>Robot</code> is active. Being "active" means that <code>{@link #cleanUp()}</code> has
418 * not been called yet.
419 * @return <code>true</code> if this <code>Robot</code> is active, <code>false</code> otherwise.
420 */
421 boolean isActive();
422 }