2009/05/20 - Apache Shale has been retired.

For more information, please explore the Attic.

View Javadoc

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          super(name);
59  
60      }
61  
62  
63      // ------------------------------------------------------ Instance Variables
64  
65  
66      /***
67       * <p>The most recently retrieved page from the server.</p>
68       */
69      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      protected URL url = null;
79  
80  
81      /***
82       * <p>The web client for this test case.</p>
83       */
84      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          String url = System.getProperty("url");
99          this.url = new URL(url + "/");
100 
101         // Initialize HtmlUnit constructs for this test case
102         webClient = new WebClient();
103 
104     }
105 
106 
107     /***
108      * <p>Return the set of tests included in this test suite.</p>
109      */
110     public static Test suite() {
111 
112         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         page = null;
123         url = null;
124         webClient = null;
125 
126     }
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         Iterator elements = page.getAllHtmlChildElements();
142         while (elements.hasNext()) {
143             HtmlElement element = (HtmlElement) elements.next();
144             if (element instanceof HtmlBody) {
145                 return ((HtmlBody) element);
146             }
147         }
148         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             return (page.getHtmlElementById(id));
166         } catch (ElementNotFoundException e) {
167             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         Iterator forms = page.getForms().iterator();
185         while (forms.hasNext()) {
186             HtmlForm form = (HtmlForm) forms.next();
187             if (id.equals(form.getAttributeValue("id"))) {
188                 return (form);
189             }
190         }
191         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         Iterator elements = page.getAllHtmlChildElements();
205         while (elements.hasNext()) {
206             HtmlElement element = (HtmlElement) elements.next();
207             if (element instanceof HtmlHead) {
208                 return ((HtmlHead) element);
209             }
210         }
211         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         HtmlPage page = (HtmlPage) anchor.click();
228         this.page = page;
229         return page;
230 
231     }
232 
233 
234     /***
235      * <p>Return the currently stored page reference.</p>
236      */
237     protected HtmlPage page() {
238 
239         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         HtmlPage page = (HtmlPage) webClient.getPage(url(path));
258         this.page = page;
259         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         this.page = page;
274 
275     }
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         HtmlPage page = (HtmlPage) submit.click();
290         this.page = page;
291         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         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         if (path.charAt(0) != '/') {
322             throw new IllegalArgumentException("Context path '" + path
323                                                + "' does not start with '/'");
324         }
325         return new URL(url, path.substring(1));
326 
327     }
328 
329 
330 }