001 /*
002 * Created on Dec 16, 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.Point;
019 import java.util.regex.Pattern;
020
021 import javax.swing.JButton;
022
023 import org.fest.swing.core.*;
024 import org.fest.swing.driver.AbstractButtonDriver;
025 import org.fest.swing.exception.ComponentLookupException;
026 import org.fest.swing.exception.WaitTimedOutError;
027 import org.fest.swing.timing.Timeout;
028
029 /**
030 * Understands functional testing of <code>{@link JButton}</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 Yvonne Wang
038 * @author Alex Ruiz
039 */
040 public class JButtonFixture extends ComponentFixture<JButton> implements CommonComponentFixture,
041 JComponentFixture, JPopupMenuInvokerFixture, TextDisplayFixture {
042
043 private AbstractButtonDriver driver;
044
045 /**
046 * Creates a new <code>{@link JButtonFixture}</code>.
047 * @param target the <code>JButton</code> to be managed by this fixture.
048 * @param robot performs simulation of user events on the given <code>JButton</code>.
049 * @throws NullPointerException if <code>robot</code> is <code>null</code>.
050 * @throws NullPointerException if <code>target</code> is <code>null</code>.
051 */
052 public JButtonFixture(Robot robot, JButton target) {
053 super(robot, target);
054 createDriver();
055 }
056
057 /**
058 * Creates a new <code>{@link JButtonFixture}</code>.
059 * @param robot performs simulation of user events on a <code>JButton</code>.
060 * @param buttonName the name of the <code>JButton</code> to find using the given <code>RobotFixture</code>.
061 * @throws NullPointerException if <code>robot</code> is <code>null</code>.
062 * @throws ComponentLookupException if a matching <code>JButton</code> could not be found.
063 * @throws ComponentLookupException if more than one matching <code>JButton</code> is found.
064 */
065 public JButtonFixture(Robot robot, String buttonName) {
066 super(robot, buttonName, JButton.class);
067 createDriver();
068 }
069
070 private void createDriver() {
071 driver(new AbstractButtonDriver(robot));
072 }
073
074 /**
075 * Sets the <code>{@link AbstractButtonDriver}</code> to be used by this fixture.
076 * @param newDriver the new <code>AbstractButtonDriver</code>.
077 * @throws NullPointerException if the given driver is <code>null</code>.
078 */
079 protected final void driver(AbstractButtonDriver newDriver) {
080 validateNotNull(newDriver);
081 driver = newDriver;
082 }
083
084 /**
085 * Returns the text of this fixture's <code>{@link JButton}</code>.
086 * @return the text of this fixture's <code>JButton</code>.
087 */
088 public String text() {
089 return driver.textOf(target);
090 }
091
092 /**
093 * Simulates a user clicking this fixture's <code>{@link JButton}</code>.
094 * @return this fixture.
095 * @throws IllegalStateException if this fixture's <code>JButton</code> is disabled.
096 * @throws IllegalStateException if this fixture's <code>JButton</code> is not showing on the screen.
097 */
098 public JButtonFixture click() {
099 driver.click(target);
100 return this;
101 }
102
103 /**
104 * Simulates a user clicking this fixture's <code>{@link JButton}</code>.
105 * @param button the button to click.
106 * @return this fixture.
107 * @throws NullPointerException if the given <code>MouseButton</code> is <code>null</code>.
108 * @throws IllegalStateException if this fixture's <code>JButton</code> is disabled.
109 * @throws IllegalStateException if this fixture's <code>JButton</code> is not showing on the screen.
110 */
111 public JButtonFixture click(MouseButton button) {
112 driver.click(target, button);
113 return this;
114 }
115
116 /**
117 * Simulates a user clicking this fixture's <code>{@link JButton}</code>.
118 * @param mouseClickInfo specifies the button to click and the times the button should be clicked.
119 * @return this fixture.
120 * @throws NullPointerException if the given <code>MouseClickInfo</code> is <code>null</code>.
121 * @throws IllegalStateException if this fixture's <code>JButton</code> is disabled.
122 * @throws IllegalStateException if this fixture's <code>JButton</code> is not showing on the screen.
123 */
124 public JButtonFixture click(MouseClickInfo mouseClickInfo) {
125 driver.click(target, mouseClickInfo);
126 return this;
127 }
128
129 /**
130 * Simulates a user double-clicking this fixture's <code>{@link JButton}</code>.
131 * @return this fixture.
132 * @throws IllegalStateException if this fixture's <code>JButton</code> is disabled.
133 * @throws IllegalStateException if this fixture's <code>JButton</code> is not showing on the screen.
134 */
135 public JButtonFixture doubleClick() {
136 driver.doubleClick(target);
137 return this;
138 }
139
140 /**
141 * Simulates a user right-clicking this fixture's <code>{@link JButton}</code>.
142 * @return this fixture.
143 * @throws IllegalStateException if this fixture's <code>JButton</code> is disabled.
144 * @throws IllegalStateException if this fixture's <code>JButton</code> is not showing on the screen.
145 */
146 public JButtonFixture rightClick() {
147 driver.rightClick(target);
148 return this;
149 }
150
151 /**
152 * Gives input focus to this fixture's <code>{@link JButton}</code>.
153 * @return this fixture.
154 * @throws IllegalStateException if this fixture's <code>JButton</code> is disabled.
155 * @throws IllegalStateException if this fixture's <code>JButton</code> is not showing on the screen.
156 */
157 public JButtonFixture focus() {
158 driver.focus(target);
159 return this;
160 }
161
162 /**
163 * Simulates a user pressing given key with the given modifiers on this fixture's <code>{@link JButton}</code>.
164 * Modifiers is a mask from the available <code>{@link java.awt.event.InputEvent}</code> masks.
165 * @param keyPressInfo specifies the key and modifiers to press.
166 * @return this fixture.
167 * @throws NullPointerException if the given <code>KeyPressInfo</code> is <code>null</code>.
168 * @throws IllegalArgumentException if the given code is not a valid key code.
169 * @throws IllegalStateException if this fixture's <code>JButton</code> is disabled.
170 * @throws IllegalStateException if this fixture's <code>JButton</code> is not showing on the screen.
171 * @see KeyPressInfo
172 */
173 public JButtonFixture pressAndReleaseKey(KeyPressInfo keyPressInfo) {
174 driver.pressAndReleaseKey(target, keyPressInfo);
175 return this;
176 }
177
178 /**
179 * Simulates a user pressing and releasing the given keys on this fixture's <code>{@link JButton}</code>.
180 * @param keyCodes one or more codes of the keys to press.
181 * @return this fixture.
182 * @throws NullPointerException if the given array of codes is <code>null</code>.
183 * @throws IllegalArgumentException if any of the given code is not a valid key code.
184 * @throws IllegalStateException if this fixture's <code>JButton</code> is disabled.
185 * @throws IllegalStateException if this fixture's <code>JButton</code> is not showing on the screen.
186 * @see java.awt.event.KeyEvent
187 */
188 public JButtonFixture pressAndReleaseKeys(int... keyCodes) {
189 driver.pressAndReleaseKeys(target, keyCodes);
190 return this;
191 }
192
193 /**
194 * Simulates a user pressing the given key on this fixture's <code>{@link JButton}</code>.
195 * @param keyCode the code of the key to press.
196 * @return this fixture.
197 * @throws IllegalArgumentException if any of the given code is not a valid key code.
198 * @throws IllegalStateException if this fixture's <code>JButton</code> is disabled.
199 * @throws IllegalStateException if this fixture's <code>JButton</code> is not showing on the screen.
200 * @see java.awt.event.KeyEvent
201 */
202 public JButtonFixture pressKey(int keyCode) {
203 driver.pressKey(target, keyCode);
204 return this;
205 }
206
207 /**
208 * Simulates a user releasing the given key on this fixture's <code>{@link JButton}</code>.
209 * @param keyCode the code of the key to release.
210 * @return this fixture.
211 * @throws IllegalArgumentException if any of the given code is not a valid key code.
212 * @throws IllegalStateException if this fixture's <code>JButton</code> is disabled.
213 * @throws IllegalStateException if this fixture's <code>JButton</code> is not showing on the screen.
214 * @see java.awt.event.KeyEvent
215 */
216 public JButtonFixture releaseKey(int keyCode) {
217 driver.releaseKey(target, keyCode);
218 return this;
219 }
220
221 /**
222 * Asserts that this fixture's <code>{@link JButton}</code> has input focus.
223 * @return this fixture.
224 * @throws AssertionError if this fixture's <code>JButton</code> does not have input focus.
225 */
226 public JButtonFixture requireFocused() {
227 driver.requireFocused(target);
228 return this;
229 }
230
231 /**
232 * Asserts that this fixture's <code>{@link JButton}</code> is enabled.
233 * @return this fixture.
234 * @throws AssertionError if this fixture's <code>JButton</code> is disabled.
235 */
236 public JButtonFixture requireEnabled() {
237 driver.requireEnabled(target);
238 return this;
239 }
240
241 /**
242 * Asserts that this fixture's <code>{@link JButton}</code> is enabled.
243 * @param timeout the time this fixture will wait for the component to be enabled.
244 * @return this fixture.
245 * @throws WaitTimedOutError if this fixture's <code>JButton</code> is never enabled.
246 */
247 public JButtonFixture requireEnabled(Timeout timeout) {
248 driver.requireEnabled(target, timeout);
249 return this;
250 }
251
252 /**
253 * Asserts that this fixture's <code>{@link JButton}</code> is disabled.
254 * @return this fixture.
255 * @throws AssertionError if this fixture's <code>JButton</code> is enabled.
256 */
257 public JButtonFixture requireDisabled() {
258 driver.requireDisabled(target);
259 return this;
260 }
261
262 /**
263 * Asserts that this fixture's <code>{@link JButton}</code> is visible.
264 * @return this fixture.
265 * @throws AssertionError if this fixture's <code>JButton</code> is not visible.
266 */
267 public JButtonFixture requireVisible() {
268 driver.requireVisible(target);
269 return this;
270 }
271
272 /**
273 * Asserts that this fixture's <code>{@link JButton}</code> is not visible.
274 * @return this fixture.
275 * @throws AssertionError if this fixture's <code>JButton</code> is visible.
276 */
277 public JButtonFixture requireNotVisible() {
278 driver.requireNotVisible(target);
279 return this;
280 }
281
282 /**
283 * Asserts that the text of this fixture's <code>{@link JButton}</code> matches the specified value.
284 * @param expected the text to match. It can be a regular expression.
285 * @return this fixture.
286 * @throws AssertionError if the text of the target <code>JButton</code> does not match the given one.
287 */
288 public JButtonFixture requireText(String expected) {
289 driver.requireText(target, expected);
290 return this;
291 }
292
293 /**
294 * Asserts that the text of this fixture's <code>{@link JButton}</code> matches the given regular expression pattern.
295 * @param pattern the regular expression pattern to match.
296 * @return this fixture.
297 * @throws NullPointerException if the given regular expression pattern is <code>null</code>.
298 * @throws AssertionError if the text of the target <code>JButton</code> does not match the given regular expression
299 * pattern.
300 * @since 1.2
301 */
302 public JButtonFixture requireText(Pattern pattern) {
303 driver.requireText(target, pattern);
304 return this;
305 }
306
307 /**
308 * Asserts that the toolTip in this fixture's <code>{@link JButton}</code> matches the given value.
309 * @param expected the given value. It can be a regular expression.
310 * @return this fixture.
311 * @throws AssertionError if the toolTip in this fixture's <code>JButton</code> does not match the given value.
312 * @since 1.2
313 */
314 public JButtonFixture requireToolTip(String expected) {
315 driver.requireToolTip(target, expected);
316 return this;
317 }
318
319 /**
320 * Asserts that the toolTip in this fixture's <code>{@link JButton}</code> matches the given regular expression
321 * pattern.
322 * @param pattern the regular expression pattern to match.
323 * @return this fixture.
324 * @throws NullPointerException if the given regular expression pattern is <code>null</code>.
325 * @throws AssertionError if the toolTip in this fixture's <code>JButton</code> does not match the given regular
326 * expression.
327 * @since 1.2
328 */
329 public JButtonFixture requireToolTip(Pattern pattern) {
330 driver.requireToolTip(target, pattern);
331 return this;
332 }
333
334 /**
335 * Returns the client property stored in this fixture's <code>{@link JButton}</code>, under the given key.
336 * @param key the key to use to retrieve the client property.
337 * @return the value of the client property stored under the given key, or <code>null</code> if the property was
338 * not found.
339 * @throws NullPointerException if the given key is <code>null</code>.
340 * @since 1.2
341 */
342 public Object clientProperty(Object key) {
343 return driver.clientProperty(target, key);
344 }
345
346 /**
347 * Shows a pop-up menu using this fixture's <code>{@link JButton}</code> as the invoker of the pop-up menu.
348 * @return a fixture that manages the displayed pop-up menu.
349 * @throws IllegalStateException if this fixture's <code>JButton</code> is disabled.
350 * @throws IllegalStateException if this fixture's <code>JButton</code> is not showing on the screen.
351 * @throws ComponentLookupException if a pop-up menu cannot be found.
352 */
353 public JPopupMenuFixture showPopupMenu() {
354 return new JPopupMenuFixture(robot, driver.invokePopupMenu(target));
355 }
356
357 /**
358 * Shows a pop-up menu at the given point using this fixture's <code>{@link JButton}</code> as the invoker of the
359 * pop-up menu.
360 * @param p the given point where to show the pop-up menu.
361 * @return a fixture that manages the displayed pop-up menu.
362 * @throws IllegalStateException if this fixture's <code>JButton</code> is disabled.
363 * @throws IllegalStateException if this fixture's <code>JButton</code> is not showing on the screen.
364 * @throws ComponentLookupException if a pop-up menu cannot be found.
365 */
366 public JPopupMenuFixture showPopupMenuAt(Point p) {
367 return new JPopupMenuFixture(robot, driver.invokePopupMenu(target, p));
368 }
369 }
370