001    /*
002     * Created on Sep 5, 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 javax.swing.JMenuItem;
019    import javax.swing.JPopupMenu;
020    
021    import org.fest.swing.core.*;
022    import org.fest.swing.driver.JPopupMenuDriver;
023    import org.fest.swing.exception.ComponentLookupException;
024    import org.fest.swing.exception.WaitTimedOutError;
025    import org.fest.swing.timing.Timeout;
026    
027    /**
028     * Understands functional testing of <code>{@link JPopupMenu}</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 Yvonne Wang
036     */
037    public class JPopupMenuFixture extends ComponentFixture<JPopupMenu> implements CommonComponentFixture {
038    
039      private JPopupMenuDriver driver;
040      private final JMenuItemFinder menuItemFinder;
041    
042      /**
043       * Creates a new <code>{@link JPopupMenuFixture}</code>.
044       * @param robot performs simulation of user events on the given <code>JPopupMenu</code>.
045       * @param target the <code>JPopupMenu</code> to be managed by this fixture.
046       * @throws NullPointerException if <code>robot</code> is <code>null</code>.
047       * @throws NullPointerException if <code>target</code> is <code>null</code>.
048       */
049      public JPopupMenuFixture(Robot robot, JPopupMenu target) {
050        super(robot, target);
051        menuItemFinder = new JMenuItemFinder(robot, target);
052        driver(new JPopupMenuDriver(robot));
053      }
054    
055      /**
056       * Sets the <code>{@link JPopupMenuDriver}</code> to be used by this fixture.
057       * @param newDriver the new <code>JPopupMenuDriver</code>.
058       * @throws NullPointerException if the given driver is <code>null</code>.
059       */
060      protected final void driver(JPopupMenuDriver newDriver) {
061        validateNotNull(newDriver);
062        driver = newDriver;
063      }
064    
065      /**
066       * Finds a <code>{@link JMenuItem}</code>, contained in this fixture's <code>{@link JPopupMenu}</code>,
067       * which name matches the specified one.
068       * @param name the name to match.
069       * @return a fixture that manages the <code>JMenuItem</code> found.
070       * @throws ComponentLookupException if a <code>JMenuItem</code> having a matching name could not be found.
071       * @throws ComponentLookupException if more than one <code>JMenuItem</code> having a matching name is found.
072       */
073      public JMenuItemFixture menuItem(String name) {
074        return new JMenuItemFixture(robot, driver.menuItem(target, name));
075      }
076    
077      /**
078       * Finds a <code>{@link JMenuItem}</code>, contained in this fixture's <code>{@link JPopupMenu}</code>,
079       * that matches the specified search criteria.
080       * @param matcher contains the search criteria for finding a <code>JMenuItem</code>.
081       * @return a fixture that manages the <code>JMenuItem</code> found.
082       * @throws ComponentLookupException if a <code>JMenuItem</code> that matches the given search criteria could not be
083       * found.
084       * @throws ComponentLookupException if more than one <code>JMenuItem</code> that matches the given search criteria is
085       * found.
086       */
087      public JMenuItemFixture menuItem(GenericTypeMatcher<? extends JMenuItem> matcher) {
088        return new JMenuItemFixture(robot, driver.menuItem(target, matcher));
089      }
090    
091      /**
092       * Finds a <code>{@link JMenuItem}</code> in this fixture's <code>{@link JPopupMenu}</code>, which path matches
093       * the given one.
094       * <p>
095       * For example, if we are looking for the menu with text "New" contained under the menu with text "File", we can
096       * simply call
097       *
098       * <pre>
099       * JPopupMenuFixture popupMenu = tree.showPopupMenu();
100       * JMenuItemFixture menuItem = popupMenu.<strong>menuItemWithPath(&quot;File&quot;, &quot;Menu&quot;)</strong>;
101       * </pre>
102       *
103       * </p>
104       * @param path the path of the menu to find.
105       * @return a fixture that manages the <code>JMenuItem</code> found.
106       * @throws ComponentLookupException if a <code>JMenuItem</code> under the given path could not be found.
107       * @throws AssertionError if the <code>Component</code> found under the given path is not a <code>JMenuItem</code>.
108       */
109      public JMenuItemFixture menuItemWithPath(String... path) {
110        return new JMenuItemFixture(robot, menuItemFinder.menuItemWithPath(path));
111      }
112    
113      /**
114       * Returns the contents of this fixture's <code>{@link JPopupMenu}</code>.
115       * @return a <code>String</code> array representing the contents of this fixture's <code>JPopupMenu</code>.
116       */
117      public String[] menuLabels() {
118        return driver.menuLabelsOf(target);
119      }
120    
121      /**
122       * Simulates a user clicking this fixture's <code>{@link JPopupMenu}</code>.
123       * @return this fixture.
124       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is disabled.
125       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is not showing on the screen.
126       */
127      public JPopupMenuFixture click() {
128        driver.click(target);
129        return this;
130      }
131    
132      /**
133       * Simulates a user clicking this fixture's <code>{@link JPopupMenu}</code>.
134       * @param button the button to click.
135       * @return this fixture.
136       * @throws NullPointerException if the given <code>MouseButton</code> is <code>null</code>.
137       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is disabled.
138       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is not showing on the screen.
139       */
140      public JPopupMenuFixture click(MouseButton button) {
141        driver.click(target, button);
142        return this;
143      }
144    
145      /**
146       * Simulates a user clicking this fixture's <code>{@link JPopupMenu}</code>.
147       * @param mouseClickInfo specifies the button to click and the times the button should be clicked.
148       * @return this fixture.
149       * @throws NullPointerException if the given <code>MouseClickInfo</code> is <code>null</code>.
150       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is disabled.
151       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is not showing on the screen.
152       */
153      public JPopupMenuFixture click(MouseClickInfo mouseClickInfo) {
154        driver.click(target, mouseClickInfo);
155        return this;
156      }
157    
158      /**
159       * Simulates a user right-clicking this fixture's <code>{@link JPopupMenu}</code>.
160       * @return this fixture.
161       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is disabled.
162       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is not showing on the screen.
163       */
164      public JPopupMenuFixture rightClick() {
165        driver.rightClick(target);
166        return this;
167      }
168    
169      /**
170       * Simulates a user double-clicking this fixture's <code>{@link JPopupMenu}</code>.
171       * @return this fixture.
172       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is disabled.
173       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is not showing on the screen.
174       */
175      public JPopupMenuFixture doubleClick() {
176        driver.doubleClick(target);
177        return this;
178      }
179    
180      /**
181       * Gives input focus to this fixture's <code>{@link JPopupMenu}</code>.
182       * @return this fixture.
183       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is disabled.
184       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is not showing on the screen.
185       */
186      public JPopupMenuFixture focus() {
187        driver.focus(target);
188        return this;
189      }
190    
191      /**
192       * Simulates a user pressing given key with the given modifiers on this fixture's <code>{@link JPopupMenu}</code>.
193       * Modifiers is a mask from the available <code>{@link java.awt.event.InputEvent}</code> masks.
194       * @param keyPressInfo specifies the key and modifiers to press.
195       * @return this fixture.
196       * @throws NullPointerException if the given <code>KeyPressInfo</code> is <code>null</code>.
197       * @throws IllegalArgumentException if the given code is not a valid key code.
198       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is disabled.
199       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is not showing on the screen.
200       * @see KeyPressInfo
201       */
202      public JPopupMenuFixture pressAndReleaseKey(KeyPressInfo keyPressInfo) {
203        driver.pressAndReleaseKey(target, keyPressInfo);
204        return this;
205      }
206    
207      /**
208       * Simulates a user pressing and releasing the given keys on this fixture's <code>{@link JPopupMenu}</code>. This
209       * method does not affect the current focus.
210       * @param keyCodes one or more codes of the keys to press.
211       * @return this fixture.
212       * @throws NullPointerException if the given array of codes is <code>null</code>.
213       * @throws IllegalArgumentException if any of the given code is not a valid key code.
214       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is disabled.
215       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is not showing on the screen.
216       * @see java.awt.event.KeyEvent
217       */
218      public JPopupMenuFixture pressAndReleaseKeys(int... keyCodes) {
219        driver.pressAndReleaseKeys(target, keyCodes);
220        return this;
221      }
222    
223      /**
224       * Simulates a user pressing the given key on this fixture's <code>{@link JPopupMenu}</code>.
225       * @param keyCode the code of the key to press.
226       * @return this fixture.
227       * @throws IllegalArgumentException if any of the given code is not a valid key code.
228       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is disabled.
229       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is not showing on the screen.
230       * @see java.awt.event.KeyEvent
231       */
232      public JPopupMenuFixture pressKey(int keyCode) {
233        driver.pressKey(target, keyCode);
234        return this;
235      }
236    
237      /**
238       * Simulates a user releasing the given key on this fixture's <code>{@link JPopupMenu}</code>.
239       * @param keyCode the code of the key to release.
240       * @return this fixture.
241       * @throws IllegalArgumentException if any of the given code is not a valid key code.
242       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is disabled.
243       * @throws IllegalStateException if this fixture's <code>JPopupMenu</code> is not showing on the screen.
244       * @see java.awt.event.KeyEvent
245       */
246      public JPopupMenuFixture releaseKey(int keyCode) {
247        driver.releaseKey(target, keyCode);
248        return this;
249      }
250    
251      /**
252       * Asserts that this fixture's <code>{@link JPopupMenu}</code> has input focus.
253       * @return this fixture.
254       * @throws AssertionError if this fixture's <code>JPopupMenu</code> does not have input focus.
255       */
256      public JPopupMenuFixture requireFocused() {
257        driver.requireFocused(target);
258        return this;
259      }
260    
261      /**
262       * Asserts that this fixture's <code>{@link JPopupMenu}</code> is enabled.
263       * @return this fixture.
264       * @throws AssertionError if this fixture's <code>JPopupMenu</code> is disabled.
265       */
266      public JPopupMenuFixture requireEnabled() {
267        driver.requireEnabled(target);
268        return this;
269      }
270    
271      /**
272       * Asserts that this fixture's <code>{@link JPopupMenu}</code> is enabled.
273       * @param timeout the time this fixture will wait for the component to be enabled.
274       * @return this fixture.
275       * @throws WaitTimedOutError if this fixture's <code>JPopupMenu</code> is never enabled.
276       */
277      public JPopupMenuFixture requireEnabled(Timeout timeout) {
278        driver.requireEnabled(target, timeout);
279        return this;
280      }
281    
282      /**
283       * Asserts that this fixture's <code>{@link JPopupMenu}</code> is disabled.
284       * @return this fixture.
285       * @throws AssertionError if this fixture's <code>JPopupMenu</code> is enabled.
286       */
287      public JPopupMenuFixture requireDisabled() {
288        driver.requireDisabled(target);
289        return this;
290      }
291    
292      /**
293       * Asserts that this fixture's <code>{@link JPopupMenu}</code> is visible.
294       * @return this fixture.
295       * @throws AssertionError if this fixture's <code>JPopupMenu</code> is not visible.
296       */
297      public JPopupMenuFixture requireVisible() {
298        driver.requireVisible(target);
299        return this;
300      }
301    
302      /**
303       * Asserts that this fixture's <code>{@link JPopupMenu}</code> is not visible.
304       * @return this fixture.
305       * @throws AssertionError if this fixture's <code>JPopupMenu</code> is visible.
306       */
307      public JPopupMenuFixture requireNotVisible() {
308        driver.requireNotVisible(target);
309        return this;
310      }
311    }