Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||||||
AbstractHtmlUnitTestCase |
|
| 1.8666666666666667;1.867 |
1 | /* |
|
2 | * Licensed to the Apache Software Foundation (ASF) under one or more |
|
3 | * contributor license agreements. See the NOTICE file distributed with |
|
4 | * this work for additional information regarding copyright ownership. |
|
5 | * The ASF licenses this file to you under the Apache License, Version 2.0 |
|
6 | * (the "License"); you may not use this file except in compliance with |
|
7 | * the License. You may obtain a copy of the License at |
|
8 | * |
|
9 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
10 | * |
|
11 | * Unless required by applicable law or agreed to in writing, software |
|
12 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
14 | * See the License for the specific language governing permissions and |
|
15 | * limitations under the License. |
|
16 | */ |
|
17 | ||
18 | package org.apache.shale.test.htmlunit; |
|
19 | ||
20 | import com.gargoylesoftware.htmlunit.ElementNotFoundException; |
|
21 | import com.gargoylesoftware.htmlunit.WebClient; |
|
22 | import com.gargoylesoftware.htmlunit.html.HtmlAnchor; |
|
23 | import com.gargoylesoftware.htmlunit.html.HtmlBody; |
|
24 | import com.gargoylesoftware.htmlunit.html.HtmlElement; |
|
25 | import com.gargoylesoftware.htmlunit.html.HtmlForm; |
|
26 | import com.gargoylesoftware.htmlunit.html.HtmlHead; |
|
27 | import com.gargoylesoftware.htmlunit.html.HtmlPage; |
|
28 | import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput; |
|
29 | import java.io.IOException; |
|
30 | import java.net.URL; |
|
31 | import java.util.Iterator; |
|
32 | import junit.framework.Test; |
|
33 | import junit.framework.TestCase; |
|
34 | import junit.framework.TestSuite; |
|
35 | ||
36 | ||
37 | ||
38 | /** |
|
39 | * <p>Abstract base class for system integration tests based on HtmlUnit. |
|
40 | * These tests will expect a system property named <code>url</code> to be |
|
41 | * present, which will define the URL (including the context path, but |
|
42 | * without a trailing slash) of the application to be tested.</p> |
|
43 | */ |
|
44 | ||
45 | public abstract class AbstractHtmlUnitTestCase extends TestCase { |
|
46 | ||
47 | ||
48 | // ------------------------------------------------------------ Constructors |
|
49 | ||
50 | ||
51 | /** |
|
52 | * <p>Construct a new instance of this test case.</p> |
|
53 | * |
|
54 | * @param name Name of the new test case |
|
55 | */ |
|
56 | public AbstractHtmlUnitTestCase(String name) { |
|
57 | ||
58 | 0 | super(name); |
59 | ||
60 | 0 | } |
61 | ||
62 | ||
63 | // ------------------------------------------------------ Instance Variables |
|
64 | ||
65 | ||
66 | /** |
|
67 | * <p>The most recently retrieved page from the server.</p> |
|
68 | */ |
|
69 | 0 | protected HtmlPage page = null; |
70 | ||
71 | ||
72 | /** |
|
73 | * <p>The calculated URL for the installed "systest" web application. |
|
74 | * This value is based on a system property named <code>url</code>, |
|
75 | * which must be defined as part of the command line that executes |
|
76 | * each test case.</p> |
|
77 | */ |
|
78 | 0 | protected URL url = null; |
79 | ||
80 | ||
81 | /** |
|
82 | * <p>The web client for this test case.</p> |
|
83 | */ |
|
84 | 0 | protected WebClient webClient = null; |
85 | ||
86 | ||
87 | // ------------------------------------------------------ Test Setup Methods |
|
88 | ||
89 | ||
90 | /** |
|
91 | * <p>Set up the instance variables required for this test case.</p> |
|
92 | * |
|
93 | * @exception Exception if an error occurs |
|
94 | */ |
|
95 | protected void setUp() throws Exception { |
|
96 | ||
97 | // Calculate the URL for the installed "systest" web application |
|
98 | 0 | String url = System.getProperty("url"); |
99 | 0 | this.url = new URL(url + "/"); |
100 | ||
101 | // Initialize HtmlUnit constructs for this test case |
|
102 | 0 | webClient = new WebClient(); |
103 | ||
104 | 0 | } |
105 | ||
106 | ||
107 | /** |
|
108 | * <p>Return the set of tests included in this test suite.</p> |
|
109 | */ |
|
110 | public static Test suite() { |
|
111 | ||
112 | 0 | return (new TestSuite(AbstractHtmlUnitTestCase.class)); |
113 | ||
114 | } |
|
115 | ||
116 | ||
117 | /** |
|
118 | * <p>Tear down instance variables required by this test case.</p> |
|
119 | */ |
|
120 | protected void tearDown() throws Exception { |
|
121 | ||
122 | 0 | page = null; |
123 | 0 | url = null; |
124 | 0 | webClient = null; |
125 | ||
126 | 0 | } |
127 | ||
128 | ||
129 | ||
130 | // ------------------------------------------------------- Protected Methods |
|
131 | ||
132 | ||
133 | /** |
|
134 | * <p>Return the body element for the most recently retrieved page. |
|
135 | * If there is no such element, return <code>null</code>.</p> |
|
136 | * |
|
137 | * @exception Exception if an error occurs |
|
138 | */ |
|
139 | protected HtmlBody body() throws Exception { |
|
140 | ||
141 | 0 | Iterator elements = page.getAllHtmlChildElements(); |
142 | 0 | while (elements.hasNext()) { |
143 | 0 | HtmlElement element = (HtmlElement) elements.next(); |
144 | 0 | if (element instanceof HtmlBody) { |
145 | 0 | return ((HtmlBody) element); |
146 | } |
|
147 | 0 | } |
148 | 0 | return (null); |
149 | ||
150 | } |
|
151 | ||
152 | ||
153 | /** |
|
154 | * <p>Return the HTML element with the specified <code>id</code> from the |
|
155 | * most recently retrieved page. If there is no such element, return |
|
156 | * <code>null</code>.</p> |
|
157 | * |
|
158 | * @param id Identifier of the requested element. |
|
159 | * |
|
160 | * @exception Exception if an error occurs |
|
161 | */ |
|
162 | protected HtmlElement element(String id) throws Exception { |
|
163 | ||
164 | try { |
|
165 | 0 | return (page.getHtmlElementById(id)); |
166 | 0 | } catch (ElementNotFoundException e) { |
167 | 0 | return (null); |
168 | } |
|
169 | ||
170 | } |
|
171 | ||
172 | ||
173 | /** |
|
174 | * <p>Return the form with the specified <code>id</code> from the most |
|
175 | * recently retrieved page. If there is no such form, return |
|
176 | * <code>null</code>.<p> |
|
177 | * |
|
178 | * @param id Identifier of the requested form. |
|
179 | * |
|
180 | * @exception Exception if an error occurs |
|
181 | */ |
|
182 | protected HtmlForm form(String id) throws Exception { |
|
183 | ||
184 | 0 | Iterator forms = page.getForms().iterator(); |
185 | 0 | while (forms.hasNext()) { |
186 | 0 | HtmlForm form = (HtmlForm) forms.next(); |
187 | 0 | if (id.equals(form.getAttributeValue("id"))) { |
188 | 0 | return (form); |
189 | } |
|
190 | 0 | } |
191 | 0 | return (null); |
192 | ||
193 | } |
|
194 | ||
195 | ||
196 | /** |
|
197 | * <p>Return the head element for the most recently retrieved page. |
|
198 | * If there is no such element, return <code>null</code>.</p> |
|
199 | * |
|
200 | * @exception Exception if an error occurs |
|
201 | */ |
|
202 | protected HtmlHead head() throws Exception { |
|
203 | ||
204 | 0 | Iterator elements = page.getAllHtmlChildElements(); |
205 | 0 | while (elements.hasNext()) { |
206 | 0 | HtmlElement element = (HtmlElement) elements.next(); |
207 | 0 | if (element instanceof HtmlHead) { |
208 | 0 | return ((HtmlHead) element); |
209 | } |
|
210 | 0 | } |
211 | 0 | return (null); |
212 | ||
213 | } |
|
214 | ||
215 | ||
216 | /** |
|
217 | * <p>Click the specified hyperlink, and retrieve the subsequent page, |
|
218 | * saving a reference so that other utility methods may be used to |
|
219 | * retrieve information from it.</p> |
|
220 | * |
|
221 | * @param anchor Anchor component to click |
|
222 | * |
|
223 | * @exception IOException if an input/output error occurs |
|
224 | */ |
|
225 | protected HtmlPage link(HtmlAnchor anchor) throws IOException { |
|
226 | ||
227 | 0 | HtmlPage page = (HtmlPage) anchor.click(); |
228 | 0 | this.page = page; |
229 | 0 | return page; |
230 | ||
231 | } |
|
232 | ||
233 | ||
234 | /** |
|
235 | * <p>Return the currently stored page reference.</p> |
|
236 | */ |
|
237 | protected HtmlPage page() { |
|
238 | ||
239 | 0 | return this.page; |
240 | ||
241 | } |
|
242 | ||
243 | ||
244 | /** |
|
245 | * <p>Retrieve and return the page at the specified context relative path. |
|
246 | * Save a reference to this page so that other utility methods may be used |
|
247 | * to retrieve information from it.</p> |
|
248 | * |
|
249 | * @param path Context relative path |
|
250 | * |
|
251 | * @exception IllegalArgumentException if the context relative path |
|
252 | * does not begin with a '/' character |
|
253 | * @exception Exception if a different error occurs |
|
254 | */ |
|
255 | protected HtmlPage page(String path) throws Exception { |
|
256 | ||
257 | 0 | HtmlPage page = (HtmlPage) webClient.getPage(url(path)); |
258 | 0 | this.page = page; |
259 | 0 | return (page); |
260 | ||
261 | } |
|
262 | ||
263 | ||
264 | /** |
|
265 | * <p>Reset the stored page reference to the specified value. This is |
|
266 | * useful for scenarios testing resubmit of the same page (simulating the |
|
267 | * user pressing the back button and then submitting again).</p> |
|
268 | * |
|
269 | * @param page Previously saved page to which to reset |
|
270 | */ |
|
271 | protected void reset(HtmlPage page) { |
|
272 | ||
273 | 0 | this.page = page; |
274 | ||
275 | 0 | } |
276 | ||
277 | ||
278 | /** |
|
279 | * <p>Submit the current page, using the specified component, and retrieve |
|
280 | * the subsequent page, saving a reference so that other utility methods |
|
281 | * may be used to retrieve information from it.</p> |
|
282 | * |
|
283 | * @param submit Submit button component to click |
|
284 | * |
|
285 | * @exception IOException if an input/output error occurs |
|
286 | */ |
|
287 | protected HtmlPage submit(HtmlSubmitInput submit) throws IOException { |
|
288 | ||
289 | 0 | HtmlPage page = (HtmlPage) submit.click(); |
290 | 0 | this.page = page; |
291 | 0 | return page; |
292 | ||
293 | } |
|
294 | ||
295 | ||
296 | /** |
|
297 | * <p>Return the page title from the most recently retrieved page. |
|
298 | * Any leading and trailing whitespace will be trimmed.</p> |
|
299 | * |
|
300 | * @exception Exception if an error occurs |
|
301 | */ |
|
302 | protected String title() throws Exception { |
|
303 | ||
304 | 0 | return (page.getTitleText().trim()); |
305 | ||
306 | } |
|
307 | ||
308 | ||
309 | /** |
|
310 | * <p>Calculate and return an absolute URL for the specified context |
|
311 | * relative path, which must begin with a '/' character.</p> |
|
312 | * |
|
313 | * @param path Context relative path |
|
314 | * |
|
315 | * @exception IllegalArgumentException if the context relative path |
|
316 | * does not begin with a '/' character |
|
317 | * @exception Exception if a different error ocurs |
|
318 | */ |
|
319 | protected URL url(String path) throws Exception { |
|
320 | ||
321 | 0 | if (path.charAt(0) != '/') { |
322 | 0 | throw new IllegalArgumentException("Context path '" + path |
323 | + "' does not start with '/'"); |
|
324 | } |
|
325 | 0 | return new URL(url, path.substring(1)); |
326 | ||
327 | } |
|
328 | ||
329 | ||
330 | } |