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 }