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 }