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