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 }