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 java.awt.*;
019    
020    import org.fest.swing.core.*;
021    import org.fest.swing.core.Robot;
022    import org.fest.swing.driver.DialogDriver;
023    import org.fest.swing.exception.ActionFailedException;
024    import org.fest.swing.exception.ComponentLookupException;
025    import org.fest.swing.timing.Timeout;
026    
027    /**
028     * Understands functional testing of <code>{@link Dialog}</code>s:
029     * <ul>
030     * <li>user input simulation</li>
031     * <li>state verification</li>
032     * <li>property value query</li>
033     * </ul>
034     *
035     * @author Alex Ruiz
036     */
037    public class DialogFixture extends WindowFixture<Dialog> {
038    
039      private DialogDriver driver;
040    
041      /**
042       * Creates a new <code>{@link DialogFixture}</code>. This constructor creates a new <code>{@link Robot}</code>
043       * containing the current AWT hierarchy.
044       * @param target the <code>Dialog</code> to be managed by this fixture.
045       * @throws NullPointerException if <code>target</code> is <code>null</code>.
046       * @see BasicRobot#robotWithCurrentAwtHierarchy()
047       */
048      public DialogFixture(Dialog target) {
049        super(target);
050        createDriver();
051      }
052    
053      /**
054       * Creates a new <code>{@link DialogFixture}</code>.
055       * @param robot performs simulation of user events on the given <code>Dialog</code>.
056       * @param target the <code>Dialog</code> to be managed by this fixture.
057       * @throws NullPointerException if <code>robot</code> is <code>null</code>.
058       * @throws NullPointerException if <code>target</code> is <code>null</code>.
059       */
060      public DialogFixture(Robot robot, Dialog target) {
061        super(robot, target);
062        createDriver();
063      }
064    
065      /**
066       * Creates a new <code>{@link DialogFixture}</code>.
067       * @param robot performs simulation of user events on a <code>Dialog</code>.
068       * @param dialogName the name of the <code>Dialog</code> to find using the given <code>Robot</code>.
069       * @throws NullPointerException if <code>robot</code> is <code>null</code>.
070       * @throws ComponentLookupException if a <code>Dialog</code> having a matching name could not be found.
071       * @throws ComponentLookupException if more than one <code>Dialog</code> having a matching name is found.
072       */
073      public DialogFixture(Robot robot, String dialogName) {
074        super(robot, dialogName, Dialog.class);
075        createDriver();
076      }
077    
078      /**
079       * Creates a new <code>{@link DialogFixture}</code>. This constructor creates a new <code>{@link Robot}</code>
080       * containing the current AWT hierarchy.
081       * @param dialogName the name of the <code>Dialog</code> to find.
082       * @throws ComponentLookupException if a <code>Dialog</code> having a matching name could not be found.
083       * @throws ComponentLookupException if more than one <code>Dialog</code> having a matching name is found.
084       * @see BasicRobot#robotWithCurrentAwtHierarchy()
085       */
086      public DialogFixture(String dialogName) {
087        super(dialogName, Dialog.class);
088        createDriver();
089      }
090    
091      private void createDriver() {
092        driver(new DialogDriver(robot));
093      }
094    
095      /**
096       * Sets the <code>{@link DialogDriver}</code> to be used by this fixture.
097       * @param newDriver the new <code>DialogDriver</code>.
098       * @throws NullPointerException if the given driver is <code>null</code>.
099       */
100      protected final void driver(DialogDriver newDriver) {
101        validateNotNull(newDriver);
102        driver = newDriver;
103      }
104    
105      /**
106       * Simulates a user clicking this fixture's <code>{@link Dialog}</code>.
107       * @return this fixture.
108       */
109      public DialogFixture click() {
110        driver.click(target);
111        return this;
112      }
113    
114      /**
115       * Simulates a user clicking this fixture's <code>{@link Dialog}</code>.
116       * @param button the button to click.
117       * @return this fixture.
118       */
119      public DialogFixture click(MouseButton button) {
120        driver.click(target, button);
121        return this;
122      }
123    
124      /**
125       * Simulates a user clicking this fixture's <code>{@link Dialog}</code>.
126       * @param mouseClickInfo specifies the button to click and the times the button should be clicked.
127       * @return this fixture.
128       * @throws NullPointerException if the given <code>MouseClickInfo</code> is <code>null</code>.
129       */
130      public DialogFixture click(MouseClickInfo mouseClickInfo) {
131        driver.click(target, mouseClickInfo);
132        return this;
133      }
134    
135      /**
136       * Simulates a user double-clicking this fixture's <code>{@link Dialog}</code>.
137       * @return this fixture.
138       */
139      public DialogFixture doubleClick() {
140        driver.doubleClick(target);
141        return this;
142      }
143    
144      /**
145       * Gives input focus to this fixture's <code>{@link Dialog}</code>.
146       * @return this fixture.
147       */
148      public DialogFixture focus() {
149        driver.focus(target);
150        return this;
151      }
152    
153      /**
154       * Simulates a user moving this fixture's <code>{@link Dialog}</code> to the given point.
155       * @param p the point to move this fixture's <code>Dialog</code> to.
156       * @return this fixture.
157       * @throws ActionFailedException if the <code>Window</code> is not movable.
158       * @throws ActionFailedException if the given <code>Window</code> is not showing on the screen.
159       */
160      public DialogFixture moveTo(Point p) {
161        driver.moveTo(target, p);
162        return this;
163      }
164    
165      /**
166       * If fixture's <code>{@link Dialog}</code> is visible, brings it to the front and may make it the focused one.
167       * @return this fixture.
168       */
169      public DialogFixture moveToFront() {
170        driver.moveToFront(target);
171        return this;
172      }
173    
174    
175      /**
176       * If the given <code>{@link Dialog}</code> is visible, sends it to the back and may cause it to lose focus or
177       * activation if it is the focused or active.
178       * @return this fixture.
179       */
180      public DialogFixture moveToBack() {
181        driver.moveToBack(target);
182        return this;
183      }
184    
185      /**
186       * Simulates a user pressing given key with the given modifiers on this fixture's <code>{@link Dialog}</code>.
187       * Modifiers is a mask from the available <code>{@link java.awt.event.InputEvent}</code> masks.
188       * @param keyPressInfo specifies the key and modifiers to press.
189       * @return this fixture.
190       * @throws NullPointerException if the given <code>KeyPressInfo</code> is <code>null</code>.
191       * @throws IllegalArgumentException if the given code is not a valid key code.
192       * @see KeyPressInfo
193       */
194      public DialogFixture pressAndReleaseKey(KeyPressInfo keyPressInfo) {
195        driver.pressAndReleaseKey(target, keyPressInfo);
196        return this;
197      }
198    
199      /**
200       * Simulates a user pressing and releasing the given keys on this fixture's <code>{@link Dialog}</code>.
201       * @param keyCodes one or more codes of the keys to press.
202       * @return this fixture.
203       * @throws NullPointerException if the given array of codes is <code>null</code>.
204       * @throws IllegalArgumentException if any of the given code is not a valid key code.
205       * @see java.awt.event.KeyEvent
206       */
207      public DialogFixture pressAndReleaseKeys(int... keyCodes) {
208        driver.pressAndReleaseKeys(target, keyCodes);
209        return this;
210      }
211    
212      /**
213       * Simulates a user pressing the given key on this fixture's <code>{@link Dialog}</code>.
214       * @param keyCode the code of the key to press.
215       * @return this fixture.
216       * @throws IllegalArgumentException if the given code is not a valid key code.
217       * @see java.awt.event.KeyEvent
218       */
219      public DialogFixture pressKey(int keyCode) {
220        driver.pressKey(target, keyCode);
221        return this;
222      }
223    
224      /**
225       * Simulates a user releasing the given key on this fixture's <code>{@link Dialog}</code>.
226       * @param keyCode the code of the key to release.
227       * @return this fixture.
228       * @throws IllegalArgumentException if the given code is not a valid key code.
229       * @see java.awt.event.KeyEvent
230       */
231      public DialogFixture releaseKey(int keyCode) {
232        driver.releaseKey(target, keyCode);
233        return this;
234      }
235    
236      /**
237       * Asserts that this fixture's <code>{@link Dialog}</code> has input focus.
238       * @return this fixture.
239       * @throws AssertionError if this fixture's <code>Dialog</code> does not have input focus.
240       */
241      public DialogFixture requireFocused() {
242        driver.requireFocused(target);
243        return this;
244      }
245    
246      /**
247       * Asserts that this fixture's <code>{@link Dialog}</code> is disabled.
248       * @return this fixture.
249       * @throws AssertionError if this fixture's <code>Dialog</code> is enabled.
250       */
251      public DialogFixture requireDisabled() {
252        driver.requireDisabled(target);
253        return this;
254      }
255    
256      /**
257       * Asserts that this fixture's <code>{@link Dialog}</code> is enabled.
258       * @return this fixture.
259       * @throws AssertionError if this fixture's <code>Dialog</code> is disabled.
260       */
261      public DialogFixture requireEnabled() {
262        driver.requireEnabled(target);
263        return this;
264      }
265    
266      /**
267       * Asserts that this fixture's <code>{@link Dialog}</code> is enabled.
268       * @param timeout the time this fixture will wait for the component to be enabled.
269       * @return this fixture.
270       * @throws org.fest.swing.exception.WaitTimedOutError if this fixture's <code>Dialog</code> is never enabled.
271       */
272      public DialogFixture requireEnabled(Timeout timeout) {
273        driver.requireEnabled(target, timeout);
274        return this;
275      }
276    
277      /**
278       * Asserts that this fixture's <code>{@link Dialog}</code> is modal.
279       * @return this fixture.
280       * @throws AssertionError if this fixture's <code>Dialog</code> is not modal.
281       */
282      public DialogFixture requireModal() {
283        driver.requireModal(target);
284        return this;
285      }
286    
287      /**
288       * Asserts that this fixture's <code>{@link Dialog}</code> is not visible.
289       * @return this fixture.
290       * @throws AssertionError if this fixture's <code>Dialog</code> is visible.
291       */
292      public DialogFixture requireNotVisible() {
293        driver.requireNotVisible(target);
294        return this;
295      }
296    
297      /**
298       * Asserts that the size of this fixture's <code>{@link Dialog}</code> is equal to given one.
299       * @param size the given size to match.
300       * @return this fixture.
301       * @throws AssertionError if the size of this fixture's <code>Dialog</code> is not equal to the given size.
302       */
303      public DialogFixture requireSize(Dimension size) {
304        driver.requireSize(target, size);
305        return this;
306      }
307    
308      /**
309       * Asserts that this fixture's <code>{@link Dialog}</code> is visible.
310       * @return this fixture.
311       * @throws AssertionError if this fixture's <code>Dialog</code> is not visible.
312       */
313      public DialogFixture requireVisible() {
314        driver.requireVisible(target);
315        return this;
316      }
317    
318      /**
319       * Simulates a user resizing vertically this fixture's <code>{@link Dialog}</code>.
320       * @param height the height that this fixture's <code>Dialog</code> should have after being resized.
321       * @return this fixture.
322       * @throws ActionFailedException if the <code>Window</code> is not resizable.
323       */
324      public DialogFixture resizeHeightTo(int height) {
325        driver.resizeHeightTo(target, height);
326        return this;
327      }
328    
329      /**
330       * Simulates a user resizing this fixture's <code>{@link Dialog}</code>.
331       * @param size the size that the target window should have after being resized.
332       * @return this fixture.
333       * @throws ActionFailedException if the <code>Window</code> is not resizable.
334       */
335      public DialogFixture resizeTo(Dimension size) {
336        driver.resizeTo(target, size);
337        return this;
338      }
339    
340      /**
341       * Simulates a user resizing horizontally this fixture's <code>{@link Dialog}</code>.
342       * @param width the width that this fixture's <code>Dialog</code> should have after being resized.
343       * @return this fixture.
344       * @throws ActionFailedException if the <code>Window</code> is not resizable.
345       */
346      public DialogFixture resizeWidthTo(int width) {
347        driver.resizeWidthTo(target, width);
348        return this;
349      }
350    
351      /**
352       * Simulates a user right-clicking this fixture's <code>{@link Dialog}</code>.
353       * @return this fixture.
354       */
355      public DialogFixture rightClick() {
356        driver.rightClick(target);
357        return this;
358      }
359    
360      /**
361       * Shows this fixture's <code>{@link Dialog}</code>.
362       * @return this fixture.
363       */
364      public DialogFixture show() {
365        driver.show(target);
366        return this;
367      }
368    
369      /**
370       * Shows this fixture's <code>{@link Dialog}</code>, resized to the given size.
371       * @param size the size to resize this fixture's <code>Dialog</code> to.
372       * @return this fixture.
373       */
374      public DialogFixture show(Dimension size) {
375        driver.show(target, size);
376        return this;
377      }
378    
379      /**
380       * Shows a pop-up menu using this fixture's <code>{@link Dialog}</code> as the invoker of the pop-up menu.
381       * @return a fixture that manages the displayed pop-up menu.
382       * @throws IllegalStateException if this fixture's <code>Dialog</code> is disabled.
383       * @throws IllegalStateException if this fixture's <code>Dialog</code> is not showing on the screen.
384       * @throws ComponentLookupException if a pop-up menu cannot be found.
385       */
386      public JPopupMenuFixture showPopupMenu() {
387        return new JPopupMenuFixture(robot, driver.invokePopupMenu(target));
388      }
389    
390      /**
391       * Shows a pop-up menu at the given point using this fixture's <code>{@link Dialog}</code> as the invoker of the
392       * pop-up menu.
393       * @param p the given point where to show the pop-up menu.
394       * @return a fixture that manages the displayed pop-up menu.
395       * @throws IllegalStateException if this fixture's <code>Dialog</code> is disabled.
396       * @throws IllegalStateException if this fixture's <code>Dialog</code> is not showing on the screen.
397       * @throws ComponentLookupException if a pop-up menu cannot be found.
398       */
399      public JPopupMenuFixture showPopupMenuAt(Point p) {
400        return new JPopupMenuFixture(robot, driver.invokePopupMenu(target, p));
401      }
402    
403      /**
404       * Simulates a user closing this fixture's <code>{@link Dialog}</code>.
405       */
406      public void close() {
407        driver.close(target);
408      }
409    }