1 | // Jomic - a viewer for comic book archives. |
2 | // Copyright (C) 2004-2011 Thomas Aglassinger |
3 | // |
4 | // This program is free software: you can redistribute it and/or modify |
5 | // it under the terms of the GNU General Public License as published by |
6 | // the Free Software Foundation, either version 3 of the License, or |
7 | // (at your option) any later version. |
8 | // |
9 | // This program is distributed in the hope that it will be useful, |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | // GNU General Public License for more details. |
13 | // |
14 | // You should have received a copy of the GNU General Public License |
15 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | package net.sf.jomic; |
17 | |
18 | import java.awt.Window; |
19 | import java.io.File; |
20 | import java.io.IOException; |
21 | |
22 | import javax.swing.JMenu; |
23 | import javax.swing.JMenuItem; |
24 | |
25 | import org.apache.commons.logging.Log; |
26 | import org.apache.commons.logging.LogFactory; |
27 | |
28 | import junit.extensions.abbot.ComponentTestFixture; |
29 | import net.sf.jomic.common.JomicStartup; |
30 | import net.sf.jomic.common.PropertyConstants; |
31 | import net.sf.jomic.common.Settings; |
32 | import net.sf.jomic.tools.LocaleTools; |
33 | import net.sf.jomic.tools.StandardConstants; |
34 | import net.sf.jomic.tools.StringTools; |
35 | import net.sf.jomic.tools.TestTools; |
36 | import net.sf.jomic.ui.JomicFrame; |
37 | import net.sf.jomic.ui.JomicMenuBar; |
38 | import abbot.finder.ComponentNotFoundException; |
39 | import abbot.finder.MultipleComponentsFoundException; |
40 | import abbot.finder.matchers.ClassMatcher; |
41 | import abbot.finder.matchers.JMenuItemMatcher; |
42 | import abbot.finder.matchers.WindowMatcher; |
43 | |
44 | /** |
45 | * Test fixture for Jomic GUI tests based on Abbot. |
46 | * |
47 | * @author Thomas Aglassinger |
48 | */ |
49 | public class JomicTestFixture extends ComponentTestFixture |
50 | { |
51 | private Log logger; |
52 | private Settings settings; |
53 | private StringTools stringTools; |
54 | private TestTools testTools; |
55 | |
56 | public JomicTestFixture(String name) { |
57 | super(name); |
58 | } |
59 | |
60 | public JomicTestFixture() { |
61 | super(); |
62 | } |
63 | |
64 | /** |
65 | * Open Jomic frame with the default test comic already loaded. |
66 | */ |
67 | protected JomicFrame setUpJomicFrame() |
68 | throws ComponentNotFoundException, IOException, MultipleComponentsFoundException { |
69 | return setUpJomicFrame(testTools.getTestComicFile()); |
70 | } |
71 | |
72 | /** |
73 | * Open Jomic frame with <code>comicFile</code> already loaded. |
74 | */ |
75 | protected JomicFrame setUpJomicFrame(File comicFile) |
76 | throws ComponentNotFoundException, IOException, MultipleComponentsFoundException { |
77 | Jomic result = new Jomic(comicFile); |
78 | Jomic jomic = result; |
79 | |
80 | jomic.show(); |
81 | |
82 | JomicFrame jomicFrame = (JomicFrame) getFinder().find(new ClassMatcher(JomicFrame.class)); |
83 | |
84 | // Wait for "Go" menu to be enabled, indicating the comic has been |
85 | // loaded and the JomicFrame is basically ready to accept commands. |
86 | waitForOpen(); |
87 | |
88 | // Make sure we are at the front page showing only one page. |
89 | JMenuItem goFirstItem = (JMenuItem) getFinder().find(new JMenuItemMatcher("Go|First")); |
90 | |
91 | if (goFirstItem.isEnabled()) { |
92 | goFirstItem.doClick(); |
93 | } |
94 | settings.setTwoPageMode(false); |
95 | |
96 | return jomicFrame; |
97 | } |
98 | |
99 | private void setTestProperty(String name, String value) { |
100 | String fullName = PropertyConstants.SYSTEM_PROPERTY_PREFIX + name; |
101 | |
102 | if (logger.isInfoEnabled()) { |
103 | logger.info("setting test property " + fullName + " to " + stringTools.sourced(value)); |
104 | } |
105 | System.setProperty(fullName, value); |
106 | } |
107 | |
108 | /** |
109 | * Get timeout in milliseconds after which we should stop waiting for UI operations to be |
110 | * finished. |
111 | */ |
112 | protected long getTimeOut() { |
113 | return 10000; |
114 | } |
115 | |
116 | private JMenu getGoMenu() |
117 | throws ComponentNotFoundException, MultipleComponentsFoundException { |
118 | JMenu result = null; |
119 | JomicMenuBar menuBar = (JomicMenuBar) getFinder().find(new ClassMatcher(JomicMenuBar.class)); |
120 | int menuIndex = 0; |
121 | |
122 | while ((result == null) && (menuIndex < menuBar.getComponentCount())) { |
123 | JMenu currentMenu = menuBar.getMenu(menuIndex); |
124 | |
125 | if (currentMenu.getText().equals("Go")) { |
126 | result = currentMenu; |
127 | } else { |
128 | menuIndex += 1; |
129 | } |
130 | } |
131 | assert result != null; |
132 | return result; |
133 | } |
134 | |
135 | /** |
136 | * Find menu item in front most frame. |
137 | * |
138 | * @param itemPath a menu path, for example "File|Open next". |
139 | */ |
140 | protected JMenuItem findMenuItem(String itemPath) |
141 | throws ComponentNotFoundException, MultipleComponentsFoundException { |
142 | return (JMenuItem) getFinder().find(new JMenuItemMatcher(itemPath)); |
143 | } |
144 | |
145 | protected void fixtureSetUp() |
146 | throws Exception { |
147 | try { |
148 | super.fixtureSetUp(); |
149 | } catch (Throwable error) { |
150 | // Change Throwable to Exception due to style considerations. |
151 | throw new Exception("cannot set up abbot", error); |
152 | } |
153 | testTools = TestTools.instance(); |
154 | JomicStartup.instance().startup(); |
155 | LocaleTools.instance().setLocale("en"); |
156 | stringTools = StringTools.instance(); |
157 | settings = Settings.instance(); |
158 | logger = LogFactory.getLog(JomicTestFixture.class); |
159 | setTestProperty(PropertyConstants.TEST_IGNORE_EXIT, Boolean.TRUE.toString()); |
160 | setTestProperty(PropertyConstants.TEST_IGNORE_MESSAGE_DIALOGS, Boolean.TRUE.toString()); |
161 | } |
162 | |
163 | protected void fixtureTearDown() |
164 | throws Exception { |
165 | setTestProperty(PropertyConstants.TEST_IGNORE_MESSAGE_DIALOGS, Boolean.FALSE.toString()); |
166 | settings = null; |
167 | testTools = null; |
168 | try { |
169 | super.fixtureTearDown(); |
170 | } catch (Throwable error) { |
171 | // Change Throwable to Exception due to style considerations. |
172 | throw new Exception("cannot tear down abbot", error); |
173 | } |
174 | } |
175 | |
176 | protected void waitForOpen() |
177 | throws ComponentNotFoundException, MultipleComponentsFoundException { |
178 | JMenu goMenu = getGoMenu(); |
179 | long startTime = System.currentTimeMillis(); |
180 | |
181 | while (!goMenu.isEnabled()) { |
182 | try { |
183 | Thread.sleep(StandardConstants.TICK); |
184 | } catch (InterruptedException interruption) { |
185 | logger.warn("sleep interrupted, continuing", interruption); |
186 | } |
187 | if (System.currentTimeMillis() - startTime > getTimeOut()) { |
188 | throw new IllegalStateException("goMenu must be enabled before " + getTimeOut() |
189 | + " milliseconds have passed"); |
190 | } |
191 | } |
192 | |
193 | // HACK: Wait some time and hope the JomicFrame is really ready to accept commands.. |
194 | try { |
195 | Thread.sleep(1000); |
196 | } catch (InterruptedException interruption) { |
197 | logger.warn("sleep interrupted, moving on", interruption); |
198 | } |
199 | } |
200 | |
201 | protected Window waitForWindowToShow(String id) |
202 | throws ComponentNotFoundException, MultipleComponentsFoundException { |
203 | Window result; |
204 | long startTime = System.currentTimeMillis(); |
205 | |
206 | while (!isShowing(id) && (System.currentTimeMillis() - startTime < getTimeOut())) { |
207 | try { |
208 | Thread.sleep(StandardConstants.TICK); |
209 | } catch (InterruptedException interruption) { |
210 | logger.warn("sleep interrupted, continuing"); |
211 | } |
212 | } |
213 | if (!isShowing(id)) { |
214 | throw new IllegalStateException("window with id=" + StringTools.instance().sourced(id) |
215 | + " must show within " + getTimeOut() + " milliseconds"); |
216 | } |
217 | result = (Window) getFinder().find(new WindowMatcher(id, true)); |
218 | |
219 | // HACK: Wait some time to actually make the window visible. |
220 | try { |
221 | Thread.sleep(1000); |
222 | } catch (InterruptedException interruption) { |
223 | IllegalStateException error = new IllegalStateException("sleep interrupted"); |
224 | |
225 | error.initCause(interruption); |
226 | throw error; |
227 | } |
228 | |
229 | return result; |
230 | } |
231 | |
232 | } |