001 /* 002 * Created on Oct 20, 2006 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 @2006-2010 the original author or authors. 015 */ 016 package org.fest.swing.fixture; 017 018 import static org.fest.swing.fixture.ComponentFixtureValidator.notNullRobot; 019 020 import java.util.regex.Pattern; 021 022 import javax.swing.JOptionPane; 023 024 import org.fest.swing.core.*; 025 import org.fest.swing.driver.JOptionPaneDriver; 026 import org.fest.swing.exception.ComponentLookupException; 027 import org.fest.swing.timing.Timeout; 028 029 /** 030 * Understands functional testing of <code>{@link JOptionPane}</code>s: 031 * <ul> 032 * <li>user input simulation</li> 033 * <li>state verification</li> 034 * <li>property value query</li> 035 * </ul> 036 * 037 * @author Alex Ruiz 038 */ 039 public class JOptionPaneFixture extends ContainerFixture<JOptionPane> implements CommonComponentFixture { 040 041 private JOptionPaneDriver driver; 042 043 /** 044 * Creates a new <code>{@link JOptionPaneFixture}</code>. 045 * @param robot finds a showing {@code JOptionPane}, which will be managed by this fixture. 046 * @throws NullPointerException if <code>robot</code> is <code>null</code>. 047 * @throws ComponentLookupException if a showing {@code JOptionPane} could not be found. 048 * @throws ComponentLookupException if more than one showing {@code JOptionPane} is found. 049 */ 050 public JOptionPaneFixture(Robot robot) { 051 this(robot, findShowingOptionPane(robot)); 052 } 053 054 private static JOptionPane findShowingOptionPane(Robot robot) { 055 notNullRobot(robot); 056 return robot.finder().findByType(JOptionPane.class, true); 057 } 058 059 /** 060 * Creates a new <code>{@link JOptionPaneFixture}</code>. 061 * @param robot performs simulation of user events on the given {@code JOptionPane}. 062 * @param target the {@code JOptionPane} to be managed by this fixture. 063 * @throws NullPointerException if <code>robot</code> is <code>null</code>. 064 * @throws IllegalArgumentException if <code>target</code> is <code>null</code>. 065 */ 066 public JOptionPaneFixture(Robot robot, JOptionPane target) { 067 super(robot, target); 068 driver(new JOptionPaneDriver(robot)); 069 } 070 071 /** 072 * Sets the <code>{@link JOptionPaneDriver}</code> to be used by this fixture. 073 * @param newDriver the new <code>JOptionPaneDriver</code>. 074 * @throws NullPointerException if the given driver is <code>null</code>. 075 */ 076 protected final void driver(JOptionPaneDriver newDriver) { 077 validateNotNull(newDriver); 078 driver = newDriver; 079 } 080 081 /** 082 * Returns the title of this fixture's <code>{@link JOptionPane}</code>. 083 * @return the title of this fixture's {@code JOptionPane}. 084 * @since 1.2 085 */ 086 public String title() { 087 return driver.title(target); 088 } 089 090 /** 091 * Returns a fixture wrapping the "OK" button in this fixture's <code>{@link JOptionPane}</code>. This method is 092 * locale-independent and platform-independent. 093 * @return a fixture wrapping the "OK" button. 094 * @throws ComponentLookupException if the a "OK" button cannot be found. 095 */ 096 public JButtonFixture okButton() { 097 return new JButtonFixture(robot, driver.okButton(target)); 098 } 099 100 /** 101 * Returns a fixture wrapping the "Cancel" button in this fixture's <code>{@link JOptionPane}</code>. This method is 102 * locale-independent and platform-independent. 103 * @return a fixture wrapping the "Cancel" button. 104 * @throws ComponentLookupException if the a "Cancel" button cannot be found. 105 */ 106 public JButtonFixture cancelButton() { 107 return new JButtonFixture(robot, driver.cancelButton(target)); 108 } 109 110 /** 111 * Returns a fixture wrapping the "Yes" button in this fixture's <code>{@link JOptionPane}</code>. This method is 112 * locale-independent and platform-independent. 113 * @return a fixture wrapping the "Yes" button. 114 * @throws ComponentLookupException if the a "Yes" button cannot be found. 115 */ 116 public JButtonFixture yesButton() { 117 return new JButtonFixture(robot, driver.yesButton(target)); 118 } 119 120 /** 121 * Returns a fixture wrapping the "No" button in this fixture's <code>{@link JOptionPane}</code>. This method is 122 * locale-independent and platform-independent. 123 * @return a fixture wrapping the "No" button. 124 * @throws ComponentLookupException if the a "No" button cannot be found. 125 */ 126 public JButtonFixture noButton() { 127 return new JButtonFixture(robot, driver.noButton(target)); 128 } 129 130 /** 131 * Finds and returns a fixture wrapping a button (this fixture's <code>{@link JOptionPane}</code>) matching the 132 * given text. 133 * @param text the text of the button to find. It can be a regular expression. 134 * @return a fixture wrapping a button matching the given text. 135 * @throws ComponentLookupException if the a button with the given text cannot be found. 136 */ 137 public JButtonFixture buttonWithText(String text) { 138 return new JButtonFixture(robot, driver.buttonWithText(target, text)); 139 } 140 141 /** 142 * Finds and returns a fixture wrapping a button (this fixture's <code>{@link JOptionPane}</code>) matching the 143 * given text. 144 * @param pattern the regular expression pattern to match. 145 * @return a fixture wrapping a button matching the given regular expression pattern. 146 * @throws NullPointerException if the given regular expression pattern is <code>null</code>. 147 * @throws ComponentLookupException if the a button with the given text cannot be found. 148 * @since 1.2 149 */ 150 public JButtonFixture buttonWithText(Pattern pattern) { 151 return new JButtonFixture(robot, driver.buttonWithText(target, pattern)); 152 } 153 154 /** 155 * Simulates a user clicking this fixture's <code>{@link JOptionPane}</code>. 156 * @return this fixture. 157 * @throws IllegalStateException if this fixture's {@code JOptionPane} is disabled. 158 * @throws IllegalStateException if this fixture's {@code JOptionPane} is not showing on the screen. 159 */ 160 public JOptionPaneFixture click() { 161 driver.click(target); 162 return this; 163 } 164 165 /** 166 * Simulates a user clicking this fixture's <code>{@link JOptionPane}</code>. 167 * @param button the button to click. 168 * @throws NullPointerException if the given <code>MouseButton</code> is <code>null</code>. 169 * @throws IllegalStateException if this fixture's {@code JOptionPane} is disabled. 170 * @throws IllegalStateException if this fixture's {@code JOptionPane} is not showing on the screen. 171 * @return this fixture. 172 */ 173 public JOptionPaneFixture click(MouseButton button) { 174 driver.click(target, button); 175 return this; 176 } 177 178 /** 179 * Simulates a user clicking this fixture's <code>{@link JOptionPane}</code>. 180 * @param mouseClickInfo specifies the button to click and the times the button should be clicked. 181 * @return this fixture. 182 * @throws NullPointerException if the given <code>MouseClickInfo</code> is <code>null</code>. 183 * @throws IllegalStateException if this fixture's {@code JOptionPane} is disabled. 184 * @throws IllegalStateException if this fixture's {@code JOptionPane} is not showing on the screen. 185 */ 186 public JOptionPaneFixture click(MouseClickInfo mouseClickInfo) { 187 driver.click(target, mouseClickInfo); 188 return this; 189 } 190 191 /** 192 * Simulates a user right-clicking this fixture's <code>{@link JOptionPane}</code>. 193 * @return this fixture. 194 * @throws IllegalStateException if this fixture's {@code JOptionPane} is disabled. 195 * @throws IllegalStateException if this fixture's {@code JOptionPane} is not showing on the screen. 196 */ 197 public JOptionPaneFixture rightClick() { 198 driver.rightClick(target); 199 return this; 200 } 201 202 /** 203 * Simulates a user double-clicking this fixture's <code>{@link JOptionPane}</code>. 204 * @return this fixture. 205 * @throws IllegalStateException if this fixture's {@code JOptionPane} is disabled. 206 * @throws IllegalStateException if this fixture's {@code JOptionPane} is not showing on the screen. 207 */ 208 public JOptionPaneFixture doubleClick() { 209 driver.doubleClick(target); 210 return this; 211 } 212 213 /** 214 * Gives input focus to this fixture's <code>{@link JOptionPane}</code>. 215 * @return this fixture. 216 * @throws IllegalStateException if this fixture's {@code JOptionPane} is disabled. 217 * @throws IllegalStateException if this fixture's {@code JOptionPane} is not showing on the screen. 218 */ 219 public JOptionPaneFixture focus() { 220 driver.focus(target); 221 return this; 222 } 223 224 /** 225 * Asserts that this fixture's <code>{@link JOptionPane}</code> is displaying an error message. 226 * @return this fixture. 227 */ 228 public JOptionPaneFixture requireErrorMessage() { 229 driver.requireErrorMessage(target); 230 return this; 231 } 232 233 /** 234 * Asserts that this fixture's <code>{@link JOptionPane}</code> is displaying an information 235 * message. 236 * @return this fixture. 237 */ 238 public JOptionPaneFixture requireInformationMessage() { 239 driver.requireInformationMessage(target); 240 return this; 241 } 242 243 /** 244 * Asserts that this fixture's <code>{@link JOptionPane}</code> is displaying a warning message. 245 * @return this fixture. 246 */ 247 public JOptionPaneFixture requireWarningMessage() { 248 driver.requireWarningMessage(target); 249 return this; 250 } 251 252 /** 253 * Asserts that this fixture's <code>{@link JOptionPane}</code> is displaying a question. 254 * @return this fixture. 255 */ 256 public JOptionPaneFixture requireQuestionMessage() { 257 driver.requireQuestionMessage(target); 258 return this; 259 } 260 261 /** 262 * Asserts that this fixture's <code>{@link JOptionPane}</code> is displaying a plain message. 263 * @return this fixture. 264 */ 265 public JOptionPaneFixture requirePlainMessage() { 266 driver.requirePlainMessage(target); 267 return this; 268 } 269 270 /** 271 * Simulates a user pressing given key with the given modifiers on this fixture's <code>{@link JOptionPane}</code>. 272 * Modifiers is a mask from the available <code>{@link java.awt.event.InputEvent}</code> masks. 273 * @param keyPressInfo specifies the key and modifiers to press. 274 * @return this fixture. 275 * @throws NullPointerException if the given <code>KeyPressInfo</code> is <code>null</code>. 276 * @throws IllegalArgumentException if the given code is not a valid key code. 277 * @see KeyPressInfo 278 */ 279 public JOptionPaneFixture pressAndReleaseKey(KeyPressInfo keyPressInfo) { 280 driver.pressAndReleaseKey(target, keyPressInfo); 281 return this; 282 } 283 284 /** 285 * Simulates a user pressing and releasing the given keys this fixture's <code>{@link JOptionPane}</code>. This method 286 * does not affect the current focus. 287 * @param keyCodes one or more codes of the keys to press. 288 * @return this fixture. 289 * @throws NullPointerException if the given array of codes is <code>null</code>. 290 * @throws IllegalArgumentException if any of the given code is not a valid key code. 291 * @see java.awt.event.KeyEvent 292 */ 293 public JOptionPaneFixture pressAndReleaseKeys(int... keyCodes) { 294 driver.pressAndReleaseKeys(target, keyCodes); 295 return this; 296 } 297 298 /** 299 * Simulates a user pressing the given key on this fixture's <code>{@link JOptionPane}</code>. 300 * @param keyCode the code of the key to press. 301 * @return this fixture. 302 * @throws IllegalArgumentException if any of the given code is not a valid key code. 303 * @see java.awt.event.KeyEvent 304 */ 305 public JOptionPaneFixture pressKey(int keyCode) { 306 driver.pressKey(target, keyCode); 307 return this; 308 } 309 310 /** 311 * Simulates a user releasing the given key on this fixture's <code>{@link JOptionPane}</code>. 312 * @param keyCode the code of the key to release. 313 * @return this fixture. 314 * @throws IllegalArgumentException if any of the given code is not a valid key code. 315 * @see java.awt.event.KeyEvent 316 */ 317 public JOptionPaneFixture releaseKey(int keyCode) { 318 driver.releaseKey(target, keyCode); 319 return this; 320 } 321 322 /** 323 * Asserts that the title of this fixture's <code>{@link JOptionPane}</code> matches the given value. 324 * @param title the title to match. It can be a regular expression. 325 * @return this fixture. 326 * @throws AssertionError if this fixture's </code>JOptionPaneFixture</code> does not have the given title. 327 */ 328 public JOptionPaneFixture requireTitle(String title) { 329 driver.requireTitle(target, title); 330 return this; 331 } 332 333 /** 334 * Asserts that the title of this fixture's <code>{@link JOptionPane}</code> matches the given regular expression 335 * pattern. 336 * @param pattern the regular expression pattern to match. 337 * @return this fixture. 338 * @throws NullPointerException if the given regular expression is <code>null</code>. 339 * @throws AssertionError if this fixture's </code>JOptionPaneFixture</code> does not have the given title. 340 * @since 1.2 341 */ 342 public JOptionPaneFixture requireTitle(Pattern pattern) { 343 driver.requireTitle(target, pattern); 344 return this; 345 } 346 347 /** 348 * Asserts that the message of this fixture's <code>{@link JOptionPane}</code> matches the given value. 349 * @param message the message to verify. If it is a <code>String</code>, it can be specified as a regular expression. 350 * @return this fixture. 351 * @throws AssertionError if the message in this fixture's </code>JOptionPaneFixture</code> is not equal to or does 352 * not match the given message. 353 */ 354 public JOptionPaneFixture requireMessage(Object message) { 355 driver.requireMessage(target, message); 356 return this; 357 } 358 359 /** 360 * Asserts that the message of this fixture's <code>{@link JOptionPane}</code> matches the given regular expression 361 * pattern. If the message in the {@code JOptionPane} is not a <code>String</code>, this method will use the 362 * <code>toString</code> representation of such message. 363 * @param pattern the regular expression to match. 364 * @return this fixture. 365 * @throws NullPointerException if the given regular expression pattern is <code>null</code>. 366 * @throws AssertionError if the message in this fixture's </code>JOptionPaneFixture</code> does not match the given 367 * regular expression pattern. 368 * @since 1.2 369 */ 370 public JOptionPaneFixture requireMessage(Pattern pattern) { 371 driver.requireMessage(target, pattern); 372 return this; 373 } 374 375 /** 376 * Asserts that this fixture's <code>{@link JOptionPane}</code> has the given options. 377 * @param options the options to verify. 378 * @return this fixture. 379 * @throws AssertionError if this fixture's </code>JOptionPaneFixture</code> does not have the given options. 380 */ 381 public JOptionPaneFixture requireOptions(Object[] options) { 382 driver.requireOptions(target, options); 383 return this; 384 } 385 386 /** 387 * Asserts that this fixture's <code>{@link JOptionPane}</code> has input focus. 388 * @return this fixture. 389 * @throws AssertionError if this fixture's {@code JOptionPane} does not have input focus. 390 */ 391 public JOptionPaneFixture requireFocused() { 392 driver.requireFocused(target); 393 return this; 394 } 395 396 /** 397 * Asserts that this fixture's <code>{@link JOptionPane}</code> is enabled. 398 * @return this fixture. 399 * @throws AssertionError if this fixture's {@code JOptionPane} is disabled. 400 */ 401 public JOptionPaneFixture requireEnabled() { 402 driver.requireEnabled(target); 403 return this; 404 } 405 406 /** 407 * Asserts that this fixture's <code>{@link JOptionPane}</code> is enabled. 408 * @param timeout the time this fixture will wait for the component to be enabled. 409 * @return this fixture. 410 * @throws org.fest.swing.exception.WaitTimedOutError if this fixture's {@code JOptionPane} is never enabled. 411 */ 412 public JOptionPaneFixture requireEnabled(Timeout timeout) { 413 driver.requireEnabled(target, timeout); 414 return this; 415 } 416 417 /** 418 * Asserts that this fixture's <code>{@link JOptionPane}</code> is disabled. 419 * @return this fixture. 420 * @throws AssertionError if this fixture's {@code JOptionPane} is enabled. 421 */ 422 public JOptionPaneFixture requireDisabled() { 423 driver.requireDisabled(target); 424 return this; 425 } 426 427 /** 428 * Asserts that this fixture's <code>{@link JOptionPane}</code> is visible. 429 * @return this fixture. 430 * @throws AssertionError if this fixture's {@code JOptionPane} is not visible. 431 */ 432 public JOptionPaneFixture requireVisible() { 433 driver.requireVisible(target); 434 return this; 435 } 436 437 /** 438 * Asserts that this fixture's <code>{@link JOptionPane}</code> is not visible. 439 * @return this fixture. 440 * @throws AssertionError if this fixture's {@code JOptionPane} is visible. 441 */ 442 public JOptionPaneFixture requireNotVisible() { 443 driver.requireNotVisible(target); 444 return this; 445 } 446 }