001 /* 002 * Created on Apr 9, 2007 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 @2007-2010 the original author or authors. 015 */ 016 package org.fest.swing.fixture; 017 018 import java.awt.Point; 019 import java.util.regex.Pattern; 020 021 import javax.swing.JComboBox; 022 import javax.swing.JList; 023 024 import org.fest.swing.cell.JComboBoxCellReader; 025 import org.fest.swing.core.*; 026 import org.fest.swing.driver.BasicJComboBoxCellReader; 027 import org.fest.swing.driver.JComboBoxDriver; 028 import org.fest.swing.exception.*; 029 import org.fest.swing.timing.Timeout; 030 031 /** 032 * Understands functional testing of <code>{@link JComboBox}</code>es: 033 * <ul> 034 * <li>user input simulation</li> 035 * <li>state verification</li> 036 * <li>property value query</li> 037 * </ul> 038 * <p> 039 * The conversion between the values given in tests and the values being displayed by a <code>{@link JComboBox}</code> 040 * renderer is performed by a <code>{@link JComboBoxCellReader}</code>. This fixture uses a 041 * <code>{@link JComboBoxCellReader}</code> by default. 042 * </p> 043 * 044 * @author Alex Ruiz 045 * @author Yvonne Wang 046 */ 047 public class JComboBoxFixture extends ComponentFixture<JComboBox> implements CommonComponentFixture, 048 EditableComponentFixture, ItemGroupFixture, JComponentFixture, JPopupMenuInvokerFixture { 049 050 private JComboBoxDriver driver; 051 052 /** 053 * Creates a new <code>{@link JComboBoxFixture}</code>. 054 * @param robot performs simulation of user events on the given <code>JComboBox</code>. 055 * @param target the <code>JComboBox</code> to be managed by this fixture. 056 * @throws NullPointerException if <code>robot</code> is <code>null</code>. 057 * @throws NullPointerException if <code>target</code> is <code>null</code>. 058 */ 059 public JComboBoxFixture(Robot robot, JComboBox target) { 060 super(robot, target); 061 createDriver(); 062 } 063 064 /** 065 * Creates a new <code>{@link JComboBoxFixture}</code>. 066 * @param robot performs simulation of user events on a <code>JComboBox</code>. 067 * @param comboBoxName the name of the <code>JComboBox</code> to find using the given <code>Robot</code>. 068 * @throws NullPointerException if <code>robot</code> is <code>null</code>. 069 * @throws ComponentLookupException if a matching <code>JComboBox</code> could not be found. 070 * @throws ComponentLookupException if more than one matching <code>JComboBox</code> is found. 071 */ 072 public JComboBoxFixture(Robot robot, String comboBoxName) { 073 super(robot, comboBoxName, JComboBox.class); 074 createDriver(); 075 } 076 077 private void createDriver() { 078 driver(new JComboBoxDriver(robot)); 079 } 080 081 /** 082 * Sets the <code>{@link JComboBoxDriver}</code> to be used by this fixture. 083 * @param newDriver the new <code>JComboBoxDriver</code>. 084 * @throws NullPointerException if the given driver is <code>null</code>. 085 */ 086 protected final void driver(JComboBoxDriver newDriver) { 087 validateNotNull(newDriver); 088 driver = newDriver; 089 } 090 091 /** 092 * Simulates a user clicking this fixture's <code>{@link JComboBox}</code>. 093 * @return this fixture. 094 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 095 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 096 */ 097 public JComboBoxFixture click() { 098 driver.click(target); 099 return this; 100 } 101 102 /** 103 * Simulates a user clicking this fixture's <code>{@link JComboBox}</code>. 104 * @param button the button to click. 105 * @return this fixture. 106 * @throws NullPointerException if the given <code>MouseButton</code> is <code>null</code>. 107 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 108 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 109 */ 110 public JComboBoxFixture click(MouseButton button) { 111 driver.click(target, button); 112 return this; 113 } 114 115 /** 116 * Simulates a user clicking this fixture's <code>{@link JComboBox}</code>. 117 * @param mouseClickInfo specifies the button to click and the times the button should be clicked. 118 * @return this fixture. 119 * @throws NullPointerException if the given <code>MouseClickInfo</code> is <code>null</code>. 120 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 121 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 122 */ 123 public JComboBoxFixture click(MouseClickInfo mouseClickInfo) { 124 driver.click(target, mouseClickInfo); 125 return this; 126 } 127 128 /** 129 * Simulates a user double-clicking this fixture's <code>{@link JComboBox}</code>. 130 * @return this fixture. 131 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 132 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 133 */ 134 public JComboBoxFixture doubleClick() { 135 driver.doubleClick(target); 136 return this; 137 } 138 139 /** 140 * Simulates a user right-clicking this fixture's <code>{@link JComboBox}</code>. 141 * @return this fixture. 142 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 143 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 144 */ 145 public JComboBoxFixture rightClick() { 146 driver.rightClick(target); 147 return this; 148 } 149 150 /** 151 * Returns the <code>String</code> representation of the elements in this fixture's <code>{@link JComboBox}</code>, 152 * using this fixture's <code>{@link JComboBoxCellReader}</code>. 153 * @return the <code>String</code> representation of the elements in this fixture's <code>JComboBox</code>. 154 * @see #cellReader(JComboBoxCellReader) 155 */ 156 public String[] contents() { 157 return driver.contentsOf(target); 158 } 159 160 /** 161 * Simulates a user entering the specified text in the <code>{@link JComboBox}</code>, replacing any text. This action 162 * is executed only if the <code>{@link JComboBox}</code> is editable. 163 * @param text the text to enter. 164 * @return this fixture. 165 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 166 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 167 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not editable. 168 */ 169 public JComboBoxFixture replaceText(String text) { 170 driver.replaceText(target, text); 171 return this; 172 } 173 174 /** 175 * Simulates a user selecting the text in the <code>{@link JComboBox}</code>. This action is executed only if the 176 * <code>{@link JComboBox}</code> is editable. 177 * @return this fixture. 178 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 179 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 180 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not editable. 181 */ 182 public JComboBoxFixture selectAllText() { 183 driver.selectAllText(target); 184 return this; 185 } 186 187 /** 188 * Simulates a user entering the specified text in this fixture's <code>{@link JComboBox}</code>. This action is 189 * executed only if the <code>{@link JComboBox}</code> is editable. 190 * @param text the text to enter. 191 * @return this fixture. 192 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 193 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 194 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not editable. 195 * @throws ActionFailedException if this fixture's <code>JComboBox</code> does not have an editor. 196 */ 197 public JComboBoxFixture enterText(String text) { 198 driver.enterText(target, text); 199 return this; 200 } 201 202 /** 203 * Gives input focus to this fixture's <code>{@link JComboBox}</code>. 204 * @return this fixture. 205 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 206 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 207 */ 208 public JComboBoxFixture focus() { 209 driver.focus(target); 210 return this; 211 } 212 213 /** 214 * Finds and returns the {@link JList} in the pop-up raised by this fixture's <code>{@link JComboBox}</code>. 215 * @return the <code>JList</code> in the pop-up raised by this fixture's <code>JComboBox</code>. 216 * @throws ComponentLookupException if the <code>JList</code> in the pop-up could not be found. 217 */ 218 public JList list() { 219 return driver.dropDownList(); 220 } 221 222 /** 223 * Simulates a user pressing given key with the given modifiers on this fixture's <code>{@link JComboBox}</code>. 224 * Modifiers is a mask from the available <code>{@link java.awt.event.InputEvent}</code> masks. 225 * @param keyPressInfo specifies the key and modifiers to press. 226 * @return this fixture. 227 * @throws NullPointerException if the given <code>KeyPressInfo</code> is <code>null</code>. 228 * @throws IllegalArgumentException if the given code is not a valid key code. 229 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 230 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 231 * @see KeyPressInfo 232 */ 233 public JComboBoxFixture pressAndReleaseKey(KeyPressInfo keyPressInfo) { 234 driver.pressAndReleaseKey(target, keyPressInfo); 235 return this; 236 } 237 238 /** 239 * Simulates a user pressing and releasing the given keys on this fixture's <code>{@link JComboBox}</code>. 240 * @param keyCodes one or more codes of the keys to press. 241 * @return this fixture. 242 * @throws NullPointerException if the given array of codes is <code>null</code>. 243 * @throws IllegalArgumentException if any of the given code is not a valid key code. 244 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 245 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 246 * @see java.awt.event.KeyEvent 247 */ 248 public JComboBoxFixture pressAndReleaseKeys(int... keyCodes) { 249 driver.pressAndReleaseKeys(target, keyCodes); 250 return this; 251 } 252 253 /** 254 * Simulates a user pressing the given key on this fixture's <code>{@link JComboBox}</code>. 255 * @param keyCode the code of the key to press. 256 * @return this fixture. 257 * @throws IllegalArgumentException if any of the given code is not a valid key code. 258 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 259 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 260 * @see java.awt.event.KeyEvent 261 */ 262 public JComboBoxFixture pressKey(int keyCode) { 263 driver.pressKey(target, keyCode); 264 return this; 265 } 266 267 /** 268 * Simulates a user releasing the given key on this fixture's <code>{@link JComboBox}</code>. 269 * @param keyCode the code of the key to release. 270 * @return this fixture. 271 * @throws IllegalArgumentException if any of the given code is not a valid key code. 272 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 273 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 274 * @see java.awt.event.KeyEvent 275 */ 276 public JComboBoxFixture releaseKey(int keyCode) { 277 driver.releaseKey(target, keyCode); 278 return this; 279 } 280 281 /** 282 * Clears the selection in this fixture's <code>{@link JComboBox}</code>. Since this method does not simulate user 283 * input, it does not verifies that this fixture's <code>JComboBox</code> is enabled and showing. 284 * @return this fixture. 285 * @since 1.2 286 */ 287 public JComboBoxFixture clearSelection() { 288 driver.clearSelection(target); 289 return this; 290 } 291 292 /** 293 * Simulates a user selecting an item in this fixture's <code>{@link JComboBox}</code>. 294 * @param index the index of the item to select. 295 * @return this fixture. 296 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 297 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 298 * @throws IndexOutOfBoundsException if the given index is negative or greater than the index of the last item in the 299 * <code>JComboBox</code>. 300 */ 301 public JComboBoxFixture selectItem(int index) { 302 driver.selectItem(target, index); 303 return this; 304 } 305 306 /** 307 * Simulates a user selecting an item in this fixture's <code>{@link JComboBox}</code>. The text of the item to 308 * select must match the given <code>String</code>. Such text is retrieved by this fixture's 309 * <code>{@link JComboBoxCellReader}</code>. 310 * @param text the text of the item to select. It can be a regular expression. 311 * @return this fixture. 312 * @throws LocationUnavailableException if an element matching the given text cannot be found. 313 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 314 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 315 * @see #cellReader(JComboBoxCellReader) 316 */ 317 public JComboBoxFixture selectItem(String text) { 318 driver.selectItem(target, text); 319 return this; 320 } 321 322 /** 323 * Simulates a user selecting an item in this fixture's <code>{@link JComboBox}</code>. The text of the item to 324 * select must match the given regular expression pattern. Such text is retrieved by this fixture's 325 * <code>{@link JComboBoxCellReader}</code>. 326 * @param pattern the regular expression pattern to match. 327 * @return this fixture. 328 * @throws LocationUnavailableException if an element matching the given pattern cannot be found. 329 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 330 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 331 * @throws NullPointerException if the given regular expression pattern is <code>null</code>. 332 * @see #cellReader(JComboBoxCellReader) 333 * @since 1.2 334 */ 335 public JComboBoxFixture selectItem(Pattern pattern) { 336 driver.selectItem(target, pattern); 337 return this; 338 } 339 340 /** 341 * Returns the <code>String</code> representation of the value of an item in this fixture's 342 * <code>{@link JComboBox}</code>, using this fixture's <code>{@link JComboBoxCellReader}</code>. 343 * @param index the index of the item to return. 344 * @return the <code>String</code> representation of the value of an item in this fixture's <code>JComboBox</code>. 345 * @throws IndexOutOfBoundsException if the given index is negative or greater than the index of the last item in the 346 * <code>JComboBox</code>. 347 * @see #cellReader(JComboBoxCellReader) 348 */ 349 public String valueAt(int index) { 350 return driver.value(target, index); 351 } 352 353 /** 354 * Asserts that this fixture's <code>{@link JComboBox}</code> is enabled. 355 * @return this fixture. 356 * @throws AssertionError if this fixture's <code>JComboBox</code> is disabled. 357 */ 358 public JComboBoxFixture requireEnabled() { 359 driver.requireEnabled(target); 360 return this; 361 } 362 /** 363 * Asserts that this fixture's <code>{@link JComboBox}</code> has input focus. 364 * @return this fixture. 365 * @throws AssertionError if this fixture's <code>JComboBox</code> does not have input focus. 366 */ 367 public JComboBoxFixture requireFocused() { 368 driver.requireFocused(target); 369 return this; 370 } 371 372 373 /** 374 * Asserts that this fixture's <code>{@link JComboBox}</code> is enabled. 375 * @param timeout the time this fixture will wait for the component to be enabled. 376 * @return this fixture. 377 * @throws org.fest.swing.exception.WaitTimedOutError if this fixture's <code>JComboBox</code> is never enabled. 378 */ 379 public JComboBoxFixture requireEnabled(Timeout timeout) { 380 driver.requireEnabled(target, timeout); 381 return this; 382 } 383 384 /** 385 * Asserts that this fixture's <code>{@link JComboBox}</code> is disabled. 386 * @return this fixture. 387 * @throws AssertionError if this fixture's <code>JComboBox</code> is enabled. 388 */ 389 public JComboBoxFixture requireDisabled() { 390 driver.requireDisabled(target); 391 return this; 392 } 393 394 /** 395 * Asserts that this fixture's <code>{@link JComboBox}</code> is visible. 396 * @return this fixture. 397 * @throws AssertionError if this fixture's <code>JComboBox</code> is not visible. 398 */ 399 public JComboBoxFixture requireVisible() { 400 driver.requireVisible(target); 401 return this; 402 } 403 404 /** 405 * Asserts that this fixture's <code>{@link JComboBox}</code> is not visible. 406 * @return this fixture. 407 * @throws AssertionError if this fixture's <code>JComboBox</code> is visible. 408 */ 409 public JComboBoxFixture requireNotVisible() { 410 driver.requireNotVisible(target); 411 return this; 412 } 413 414 /** 415 * Asserts that this fixture's <code>{@link JComboBox}</code> is editable. 416 * @throws AssertionError if this fixture's <code>JComboBox</code> is not editable. 417 * @return this fixture. 418 */ 419 public JComboBoxFixture requireEditable() { 420 driver.requireEditable(target); 421 return this; 422 } 423 424 /** 425 * Asserts that this fixture's <code>{@link JComboBox}</code> is not editable. 426 * @throws AssertionError if this fixture's <code>JComboBox</code> is editable. 427 * @return this fixture. 428 */ 429 public JComboBoxFixture requireNotEditable() { 430 driver.requireNotEditable(target); 431 return this; 432 } 433 434 /** 435 * Verifies that the <code>String</code> representation of the selected item in this fixture's 436 * <code>{@link JComboBox}</code> matches the given text. 437 * @param value the text to match. It can be a regular expression. 438 * @return this fixture. 439 * @throws AssertionError if the selected item does not match the given text. 440 * @see #cellReader(JComboBoxCellReader) 441 */ 442 public JComboBoxFixture requireSelection(String value) { 443 driver.requireSelection(target, value); 444 return this; 445 } 446 447 /** 448 * Verifies that this fixture's <code>{@link JComboBox}</code> has the expected number of items 449 * @param expected the expected number of items. 450 * @return this fixture. 451 * @throws AssertionError if the number of items in this fixture's <code>JComboBox</code> is not equal to the expected 452 * one. 453 * @since 1.2 454 */ 455 public JComboBoxFixture requireItemCount(int expected) { 456 driver.requireItemCount(target, expected); 457 return this; 458 } 459 460 /** 461 * Verifies that the <code>String</code> representation of the selected item in this fixture's 462 * <code>{@link JComboBox}</code> matches the given regular expression pattern. 463 * @param pattern the regular expression pattern to match. 464 * @return this fixture. 465 * @throws NullPointerException if the given regular expression pattern is <code>null</code>. 466 * @throws AssertionError if the selected item does not match the given regular expression pattern. 467 * @see #cellReader(JComboBoxCellReader) 468 * @since 1.2 469 */ 470 public JComboBoxFixture requireSelection(Pattern pattern) { 471 driver.requireSelection(target, pattern); 472 return this; 473 } 474 475 /** 476 * Verifies that the index of the selected item in this fixture's <code>{@link JComboBox}</code> is equal to the given 477 * value. 478 * @param index the expected selection index. 479 * @return this fixture. 480 * @throws AssertionError if the selected index is not equal to the given one. 481 * @since 1.2 482 */ 483 public JComboBoxFixture requireSelection(int index) { 484 driver.requireSelection(target, index); 485 return this; 486 } 487 488 /** 489 * Verifies that this fixture's <code>{@link JComboBox}</code> does not have any selection. 490 * @return this fixture. 491 * @throws AssertionError if this fixture's <code>JComboBox</code> has a selection. 492 */ 493 public JComboBoxFixture requireNoSelection() { 494 driver.requireNoSelection(target); 495 return this; 496 } 497 498 /** 499 * Asserts that the toolTip in this fixture's <code>{@link JComboBox}</code> matches the given value. 500 * @param expected the given value. It can be a regular expression. 501 * @return this fixture. 502 * @throws AssertionError if the toolTip in this fixture's <code>JComboBox</code> does not match the given value. 503 * @since 1.2 504 */ 505 public JComboBoxFixture requireToolTip(String expected) { 506 driver.requireToolTip(target, expected); 507 return this; 508 } 509 510 /** 511 * Asserts that the toolTip in this fixture's <code>{@link JComboBox}</code> matches the given regular expression 512 * pattern. 513 * @param pattern the regular expression pattern to match. 514 * @return this fixture. 515 * @throws NullPointerException if the given regular expression pattern is <code>null</code>. 516 * @throws AssertionError if the toolTip in this fixture's <code>JComboBox</code> does not match the given regular 517 * expression pattern. 518 * @since 1.2 519 */ 520 public JComboBoxFixture requireToolTip(Pattern pattern) { 521 driver.requireToolTip(target, pattern); 522 return this; 523 } 524 525 /** 526 * Returns the client property stored in this fixture's <code>{@link JComboBox}</code>, under the given key. 527 * @param key the key to use to retrieve the client property. 528 * @return the value of the client property stored under the given key, or <code>null</code> if the property was 529 * not found. 530 * @throws NullPointerException if the given key is <code>null</code>. 531 * @since 1.2 532 */ 533 public Object clientProperty(Object key) { 534 return driver.clientProperty(target, key); 535 } 536 537 /** 538 * Shows a pop-up menu using this fixture's <code>{@link JComboBox}</code> as the invoker of the pop-up menu. 539 * @return a fixture that manages the displayed pop-up menu. 540 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 541 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 542 * @throws ComponentLookupException if a pop-up menu cannot be found. 543 */ 544 public JPopupMenuFixture showPopupMenu() { 545 return new JPopupMenuFixture(robot, driver.invokePopupMenu(target)); 546 } 547 548 /** 549 * Shows a pop-up menu at the given point using this fixture's <code>{@link JComboBox}</code> as the invoker of the 550 * pop-up menu. 551 * @param p the given point where to show the pop-up menu. 552 * @return a fixture that manages the displayed pop-up menu. 553 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is disabled. 554 * @throws IllegalStateException if this fixture's <code>JComboBox</code> is not showing on the screen. 555 * @throws ComponentLookupException if a pop-up menu cannot be found. 556 */ 557 public JPopupMenuFixture showPopupMenuAt(Point p) { 558 return new JPopupMenuFixture(robot, driver.invokePopupMenu(target, p)); 559 } 560 561 /** 562 * Updates the implementation of <code>{@link JComboBoxCellReader}</code> to use when comparing internal values 563 * of this fixture's <code>{@link JComboBox}</code> and the values expected in a test. The default implementation to 564 * use is <code>{@link BasicJComboBoxCellReader}</code>. 565 * @param cellReader the new <code>JComboBoxCellValueReader</code> to use. 566 * @return this fixture. 567 * @throws NullPointerException if <code>cellReader</code> is <code>null</code>. 568 */ 569 public JComboBoxFixture cellReader(JComboBoxCellReader cellReader) { 570 driver.cellReader(cellReader); 571 return this; 572 } 573 }