KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > jwebunit > HttpUnitDialog


1 /********************************************************************************
2  * Copyright (c) 2001, ThoughtWorks, Inc.
3  * Distributed open-source, see full license under licenses/jwebunit_license.txt
4  **********************************/

5 package net.sourceforge.jwebunit;
6
7 import com.meterware.httpunit.*;
8 import com.meterware.httpunit.cookies.CookieJar;
9
10 import net.sourceforge.jwebunit.util.ExceptionUtility;
11 import org.w3c.dom.*;
12 import org.xml.sax.SAXException JavaDoc;
13
14 import java.io.IOException JavaDoc;
15 import java.io.PrintStream JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Map JavaDoc;
20
21 /**
22  * Acts as the wrapper for HttpUnit access. A dialog is initialized with a given URL, and maintains conversational
23  * state as the dialog progresses through link navigation, form submission, etc. Public access is provided for
24  * wrappered HttpUnit objects.
25  *
26  * @author Jim Weaver
27  * @author Wilkes Joiner
28  */

29 public class HttpUnitDialog {
30     private WebClient wc;
31     private WebResponse resp;
32     private TestContext context;
33     private WebForm form;
34     private Map JavaDoc multiselectMap = new HashMap JavaDoc();
35
36     /**
37      * Begin a dialog with an initial URL and test client context.
38      *
39      * @param initialURL
40      * absolute url at which to begin dialog.
41      * @param context
42      * contains context information for the test client.
43      */

44     public HttpUnitDialog(String JavaDoc initialURL, TestContext context) {
45         this.context = context;
46         initWebClient();
47         try {
48             resp = wc.getResponse(new GetMethodWebRequest(initialURL));
49         } catch (Exception JavaDoc e) {
50             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
51         }
52     }
53
54     private void initWebClient() {
55         wc = (context != null) ? context.getWebClient() : new WebConversation();
56
57         wc.addClientListener(new WebClientListener() {
58             public void requestSent(WebClient webClient, WebRequest webRequest) {
59             }
60
61             public void responseReceived(WebClient webClient, WebResponse webResponse) {
62                 resp = webClient.getCurrentPage();
63                 form = null;
64                 multiselectMap.clear();
65             }
66         });
67     }
68     /**
69      * Return the window with the given name in the current conversation.
70      *
71      * @param windowName
72      */

73     public WebWindow getWindow(String JavaDoc windowName) {
74         return wc.getOpenWindow(windowName);
75     }
76     /**
77      * Return the HttpUnit WebClient object for this dialog.
78      */

79     public WebClient getWebClient() {
80         return wc;
81     }
82
83     /**
84      * Return the HttpUnit object which represents the current response.
85      */

86     public WebResponse getResponse() {
87         return resp;
88     }
89
90     /**
91      * Return the string representation of the current response, encoded as specified by the current
92      * {@link net.sourceforge.jwebunit.TestContext}.
93      */

94     public String JavaDoc getResponseText() {
95         try {
96             return context.toEncodedString(resp.getText());
97         } catch (IOException JavaDoc e) {
98             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
99         }
100     }
101
102     /**
103      * Return the page title of the current response page, encoded as specified by the current
104      * {@link net.sourceforge.jwebunit.TestContext}.
105      */

106     public String JavaDoc getResponsePageTitle() {
107         try {
108             return context.toEncodedString(resp.getTitle());
109         } catch (SAXException JavaDoc e) {
110             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
111         }
112     }
113
114     /**
115      * Contributed by Vivek Venugopalan.
116      */

117     private CookieJar getCookies() {
118         return (getResponse() != null) ? new CookieJar(getResponse()) : null;
119     }
120
121     public boolean hasCookie(String JavaDoc cookieName) {
122         CookieJar respJar = getCookies();
123         String JavaDoc[] cookieNames = respJar.getCookieNames();
124
125         for (int i = 0; i < cookieNames.length; i++) {
126             if (cookieNames[i].equals(cookieName)) {
127                 return true;
128             }
129         }
130         return false;
131     }
132
133     public String JavaDoc getCookieValue(String JavaDoc cookieName) {
134         return getCookies().getCookieValue(cookieName);
135     }
136
137     //TODO: Move other dump methods to dialog!!
138

139     /**
140      * <p>
141      * Return the current form active for the dialog. A form from the dialog's response is implicitly identified as
142      * active when an element from the form is inspected or set:
143      * </p>
144      * <ul>
145      * <li>{@link #getFormParameterValue}</li>
146      * <li>{@link #hasFormParameterNamed}</li>
147      * <li>{@link #getSubmitButton}</li>
148      * <li>{@link #setFormParameter}</li>
149      * </ul>
150      * <p>
151      * The active form can also be explicitly set by {@link #setWorkingForm}.
152      * </p>
153      * <p>
154      * If this method is called without the form having been implicitly or explicitly set, it will attempt to return
155      * the default first form on the response.
156      * </p>
157      *
158      * @exception UnableToSetFormException
159      * This runtime assertion failure will be raised if there is no form on the response.
160      * @return HttpUnit WebForm object representing the current active form from the response.
161      */

162     public WebForm getForm() {
163         if (form == null && hasForm())
164             setWorkingForm(getForm(0));
165         return form;
166     }
167
168     private WebForm getForm(int formIndex) {
169         try {
170             return resp.getForms()[formIndex];
171         } catch (SAXException JavaDoc e) {
172             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
173         }
174     }
175
176     private WebForm getForm(String JavaDoc nameOrID) {
177         try {
178             WebForm f = resp.getFormWithID(nameOrID);
179             return (f != null) ? f : resp.getFormWithName(nameOrID);
180         } catch (SAXException JavaDoc e) {
181             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
182         }
183     }
184
185     private WebForm getFormWithButton(String JavaDoc buttonName) {
186         if (hasForm()) {
187             for (int i = 0; i < getForms().length; i++) {
188                 WebForm webForm = getForms()[i];
189                 if (webForm.getSubmitButton(buttonName) != null)
190                     return webForm;
191             }
192         }
193         return null;
194     }
195
196     private WebForm getFormWithParameter(String JavaDoc paramName) {
197         if (hasForm()) {
198             for (int i = 0; i < getForms().length; i++) {
199                 WebForm webForm = getForms()[i];
200                 String JavaDoc[] names = webForm.getParameterNames();
201                 for (int j = 0; j < names.length; j++) {
202                     if (names[j].equals(paramName))
203                         return webForm;
204                 }
205
206             }
207         }
208         return null;
209     }
210
211     private WebForm[] getForms() {
212         try {
213             return resp.getForms();
214         } catch (SAXException JavaDoc e) {
215             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
216         }
217     }
218
219     private void checkFormStateWithParameter(String JavaDoc paramName) {
220         if (form == null) {
221             try {
222                 setWorkingForm(getFormWithParameter(paramName));
223             } catch (UnableToSetFormException e) {
224                 throw new UnableToSetFormException("Unable to set form based on parameter [" + paramName + "].");
225             }
226         }
227     }
228
229     private void checkFormStateWithButton(String JavaDoc buttonName) {
230         if (form == null) {
231             setWorkingForm(getFormWithButton(buttonName));
232         }
233     }
234
235     /**
236      * Set the form on the current response that the client wishes to work with explicitly by either the form name or
237      * id (match by id is attempted first).
238      *
239      * @param nameOrId
240      * name or id of the form to be worked with.
241      */

242     public void setWorkingForm(String JavaDoc nameOrId) {
243         setWorkingForm(getForm(nameOrId));
244     }
245
246     private void setWorkingForm(WebForm newForm) {
247         if (newForm == null)
248             throw new UnableToSetFormException("Attempted to set form to null.");
249         form = newForm;
250     }
251
252     /**
253      * Return true if the current response contains a form.
254      */

255     public boolean hasForm() {
256         try {
257             return resp.getForms().length > 0;
258         } catch (SAXException JavaDoc e) {
259             e.printStackTrace();
260             return false;
261         }
262     }
263
264     /**
265      * Return true if the current response contains a specific form.
266      *
267      * @param nameOrID
268      * name of id of the form to check for.
269      */

270     public boolean hasForm(String JavaDoc nameOrID) {
271         return getForm(nameOrID) != null;
272     }
273
274     /**
275      * Return true if a form parameter (input element) is present on the current response.
276      *
277      * @param paramName
278      * name of the input element to check for
279      */

280     public boolean hasFormParameterNamed(String JavaDoc paramName) {
281         try {
282             checkFormStateWithParameter(paramName);
283         } catch (UnableToSetFormException e) {
284             return false;
285         }
286         return getForm().hasParameterNamed(paramName);
287     }
288
289     /**
290      * Set a form parameter / input element to the provided value.
291      *
292      * @param paramName
293      * name of the input element
294      * @param paramValue
295      * parameter value to submit for the element.
296      */

297     public void setFormParameter(String JavaDoc paramName, String JavaDoc paramValue) {
298         checkFormStateWithParameter(paramName);
299         getForm().setParameter(paramName, paramValue);
300     }
301
302     public void updateFormParameter(String JavaDoc paramName, String JavaDoc paramValue) {
303         checkFormStateWithParameter(paramName);
304         if (!multiselectMap.containsKey(paramName))
305             multiselectMap.put(paramName, new ArrayList JavaDoc());
306         List JavaDoc values = (List JavaDoc) multiselectMap.get(paramName);
307         if (!values.contains(paramValue))
308             values.add(paramValue);
309         getForm().setParameter(paramName, (String JavaDoc[]) values.toArray(new String JavaDoc[0]));
310     }
311
312     /**
313      * Return the current value of a form input element.
314      *
315      * @param paramName
316      * name of the input element.
317      */

318     public String JavaDoc getFormParameterValue(String JavaDoc paramName) {
319         checkFormStateWithParameter(paramName);
320         return getForm().getParameterValue(paramName);
321     }
322
323     /**
324      * Specify that no parameter value should be submitted for a given input element. Typically used to uncheck check
325      * boxes.
326      *
327      * @param paramName
328      * name of the input element.
329      */

330     public void removeFormParameter(String JavaDoc paramName) {
331         checkFormStateWithParameter(paramName);
332         getForm().removeParameter(paramName);
333     }
334
335     public void removeFormParameterWithValue(String JavaDoc paramName, String JavaDoc value) {
336         checkFormStateWithParameter(paramName);
337         if (multiselectMap.containsKey(paramName)) {
338             List JavaDoc values = (List JavaDoc) multiselectMap.get(paramName);
339             values.remove(value);
340             getForm().setParameter(paramName, (String JavaDoc[]) values.toArray(new String JavaDoc[0]));
341         }
342     }
343
344     /**
345      * Return true if a form parameter (input element) is present on the current response preceded by a given label.
346      *
347      * @param paramLabel
348      * label of the input element to check for
349      */

350     public boolean hasFormParameterLabeled(String JavaDoc paramLabel) {
351         return null != getFormElementNameForLabel(paramLabel);
352     }
353
354     /**
355      * Return the name of a form parameter (input element) on the current response preceded by a givel label.
356      *
357      * @param formElementLabel
358      * label of the input element to fetch name.
359      */

360     public String JavaDoc getFormElementNameForLabel(String JavaDoc formElementLabel) {
361         try {
362             Document document = getResponse().getDOM();
363             Element root = document.getDocumentElement();
364             NodeList forms = root.getElementsByTagName("form");
365
366             for (int i = 0; i < forms.getLength(); i++) {
367                 Element form = (Element) forms.item(i);
368                 TextAndElementWalker walker =
369                     new TextAndElementWalker(form, new String JavaDoc[] { "input", "select", "textarea" });
370                 Element formElement = walker.getElementAfterText(formElementLabel);
371                 if (formElement != null) {
372                     return formElement.getAttribute("name");
373                 }
374             }
375
376             return null;
377         } catch (SAXException JavaDoc e) {
378             e.printStackTrace();
379             return null;
380         }
381     }
382
383     /**
384      * Return the HttpUnit SubmitButton with a given name.
385      *
386      * @param buttonName
387      * name of button.
388      */

389     public SubmitButton getSubmitButton(String JavaDoc buttonName) {
390         checkFormStateWithButton(buttonName);
391         return getForm().getSubmitButton(buttonName);
392     }
393
394     public String JavaDoc getSubmitButtonValue(String JavaDoc buttonName) {
395         return getSubmitButton(buttonName).getValue().trim();
396     }
397     
398     public boolean hasSubmitButton(String JavaDoc buttonName) {
399         try {
400             return getSubmitButton(buttonName) != null;
401         } catch (UnableToSetFormException e) {
402             return false;
403         }
404         
405     }
406
407     /**
408      * Return the HttpUnit Button with a given id.
409      *
410      * @param buttonId
411      */

412     public Button getButton(String JavaDoc buttonId) {
413         return getForm().getButtonWithID(buttonId);
414     }
415
416     
417     public boolean hasButton(String JavaDoc buttonId) {
418         try {
419             return getButton(buttonId) != null;
420         } catch (UnableToSetFormException e) {
421             return false;
422         }
423     }
424
425     /**
426      * Return true if given text is present anywhere in the current response.
427      *
428      * @param text
429      * string to check for.
430      */

431     public boolean isTextInResponse(String JavaDoc text) {
432         try {
433             return (context.toEncodedString(resp.getText()).indexOf(text) >= 0);
434         } catch (IOException JavaDoc e) {
435             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
436         }
437     }
438
439     /**
440      * Return true if given text is present in a specified table of the response.
441      *
442      * @param tableSummaryOrId
443      * table summary or id to inspect for expected text.
444      * @param text
445      * expected text to check for.
446      */

447     public boolean isTextInTable(String JavaDoc tableSummaryOrId, String JavaDoc text) {
448         WebTable table = getWebTableBySummaryOrId(tableSummaryOrId);
449         if (table == null) {
450             throw new RuntimeException JavaDoc("No table with summary or id [" + tableSummaryOrId + "] found in response.");
451         }
452         for (int row = 0; row < table.getRowCount(); row++) {
453             for (int col = 0; col < table.getColumnCount(); col++) {
454                 TableCell cell = table.getTableCell(row, col);
455                 if (cell != null) {
456                     String JavaDoc cellHtml = getNodeHtml(cell.getDOM());
457                     if (cellHtml.indexOf(text) != -1)
458                         return true;
459                 }
460             }
461         }
462         return false;
463     }
464
465     private String JavaDoc getNodeHtml(Node node) {
466         String JavaDoc nodeHtml = "";
467         NodeList children = node.getChildNodes();
468         for (int i = 0; i < children.getLength(); i++) {
469             Node child = children.item(i);
470             if (child.getNodeType() == Node.ELEMENT_NODE) {
471                 nodeHtml += "<" + child.getNodeName() + ">";
472             }
473             if (child.hasChildNodes()) {
474                 nodeHtml += getNodeHtml(child);
475             } else {
476                 nodeHtml += child.getNodeValue();
477             }
478             if (child.getNodeType() == Node.ELEMENT_NODE) {
479                 nodeHtml += "</" + child.getNodeName() + ">";
480             }
481         }
482         return context.toEncodedString(nodeHtml);
483     }
484
485     /**
486      * Return the text (without any markup) of the tree rooted at node.
487      */

488     private static String JavaDoc getNodeText(Node node) {
489         String JavaDoc nodeText = "";
490         NodeList children = node.getChildNodes();
491         for (int i = 0; i < children.getLength(); i++) {
492             Node child = children.item(i);
493             if (child.hasChildNodes()) {
494                 nodeText += getNodeText(child);
495             } else if (child.getNodeType() == Node.TEXT_NODE) {
496                 nodeText += ((Text) child).getData();
497             }
498         }
499         return nodeText;
500     }
501
502     /**
503      * Return the HttpUnit WebTable object representing a specified table in the current response. Null is returned if
504      * a parsing exception occurs looking for the table or no table with the id or summary could be found.
505      *
506      * @param tableSummaryOrId
507      * summary or id of the table to return.
508      */

509     public WebTable getWebTableBySummaryOrId(String JavaDoc tableSummaryOrId) {
510         WebTable table;
511         try {
512             table = resp.getTableWithSummary(tableSummaryOrId);
513             if (table == null) {
514                 table = resp.getTableWithID(tableSummaryOrId);
515             }
516         } catch (SAXException JavaDoc e) {
517             e.printStackTrace();
518             return null;
519         }
520         return table;
521     }
522
523     /**
524      * Return a sparse array (rows or columns without displayable text are removed) for a given table in the response.
525      *
526      * @param tableSummaryOrId
527      * summary or id of the table.
528      */

529     public String JavaDoc[][] getSparseTableBySummaryOrId(String JavaDoc tableSummaryOrId) {
530         WebTable table = getWebTableBySummaryOrId(tableSummaryOrId);
531         table.purgeEmptyCells();
532         String JavaDoc[][] sparseTableCellValues = table.asText();
533         return sparseTableCellValues;
534     }
535
536     /**
537      * Submit the current form with the default submit button. See {@link #getForm}for an explanation of how the
538      * current form is established.
539      */

540     public void submit() {
541         try {
542             resp = getForm().submit();
543         } catch (Exception JavaDoc e) {
544             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
545         }
546     }
547
548     /**
549      * Submit the current form with the specifed submit button. See {@link #getForm}for an explanation of how the
550      * current form is established.
551      *
552      * @param buttonName
553      * name of the button to use for submission.
554      */

555     public void submit(String JavaDoc buttonName) {
556         try {
557             getForm().getSubmitButton(buttonName).click();
558             resp = wc.getCurrentPage();
559         } catch (Exception JavaDoc e) {
560             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
561         }
562     }
563
564     /**
565      * Reset the current form. See {@link #getForm}for an explanation of how the current form is established.
566      */

567     public void reset() {
568         getForm().reset();
569     }
570
571     private void submitRequest(WebLink aLink) {
572         try {
573             aLink.click();
574             resp = wc.getCurrentPage();
575         } catch (Exception JavaDoc e) {
576             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
577         }
578     }
579
580     /**
581      * Return true if a link is present in the current response containing the specified text (note that HttpUnit uses
582      * contains rather than an exact match - if this is a problem consider using ids on the links to uniquely identify
583      * them).
584      *
585      * @param linkText
586      * text to check for in links on the response.
587      */

588     public boolean isLinkPresentWithText(String JavaDoc linkText) {
589         try {
590             return (resp.getLinkWith(linkText) != null);
591         } catch (SAXException JavaDoc e) {
592             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
593         }
594     }
595
596     /**
597      * Return true if a link is present in the current response containing the specified text (note that HttpUnit uses
598      * contains rather than an exact match - if this is a problem consider using ids on the links to uniquely identify
599      * them).
600      *
601      * @param linkText
602      * text to check for in links on the response.
603      * @param index
604      * The 0-based index, when more than one link with the same text is expected.
605      */

606     public boolean isLinkPresentWithText(String JavaDoc linkText, int index) {
607         return getLinkWithText(linkText, index) != null;
608     }
609
610     /**
611      * Return true if a link is present with a given image based on filename of image.
612      *
613      * @param imageFileName
614      * A suffix of the image's filename; for example, to match <tt>"images/my_icon.png"<tt>, you could just pass in
615      * <tt>"my_icon.png"<tt>.
616      */

617     public boolean isLinkPresentWithImage(String JavaDoc imageFileName) {
618         try {
619             return (resp.getFirstMatchingLink(new LinkImagePredicate(), imageFileName) != null);
620         } catch (SAXException JavaDoc e) {
621             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
622         }
623     }
624
625     /**
626      * Return true if a link is present in the current response with the specified id.
627      *
628      * @param anId
629      * link id to check for.
630      */

631     public boolean isLinkPresent(String JavaDoc anId) {
632         try {
633             return resp.getLinkWithID(anId) != null;
634         } catch (SAXException JavaDoc e) {
635             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
636         }
637     }
638
639     /**
640      * Navigate by submitting a request based on a link containing the specified text. A RuntimeException is thrown if
641      * no such link can be found.
642      *
643      * @param linkText
644      * text which link to be navigated should contain.
645      */

646     public void clickLinkWithText(String JavaDoc linkText) {
647         WebLink link = null;
648         try {
649             link = resp.getLinkWith(linkText);
650         } catch (SAXException JavaDoc e) {
651             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
652         }
653         if (link == null)
654             throw new RuntimeException JavaDoc("No Link found for \"" + linkText + "\"");
655         submitRequest(link);
656     }
657
658     public void clickLinkWithText(String JavaDoc linkText, int index) {
659         WebLink link = getLinkWithText(linkText, index);
660         if (link == null)
661             throw new RuntimeException JavaDoc("No Link found for \"" + linkText + "\" with index " + index);
662         submitRequest(link);
663     }
664
665     private WebLink getLinkWithText(String JavaDoc linkText, int index) {
666         WebLink link = null;
667         try {
668             WebLink links[] = resp.getLinks();
669             int count = 0;
670             for (int i = 0; i < links.length; ++i) {
671                 Node node = links[i].getDOMSubtree();
672                 if (nodeContainsText(node, linkText)) {
673                     if (count == index) {
674                         link = links[i];
675                         break;
676                     } else {
677                         count++;
678                     }
679                 }
680             }
681         } catch (SAXException JavaDoc e) {
682             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
683         }
684         return link;
685     }
686
687     public static boolean nodeContainsText(Node node, String JavaDoc linkText) {
688         return getNodeText(node).indexOf(linkText) != -1;
689     }
690
691     public void clickLinkWithTextAfterText(String JavaDoc linkText, String JavaDoc labelText) {
692         WebLink link = getLinkWithTextAfterText(linkText, labelText);
693         if (link == null)
694             throw new RuntimeException JavaDoc("No Link found for \"" + linkText + "\" with label \"" + labelText + "\"");
695         submitRequest(link);
696     }
697
698     private WebLink getLinkWithTextAfterText(String JavaDoc linkText, String JavaDoc labelText) {
699         try {
700             TextAndElementWalker walker =
701                 new TextAndElementWalker(resp.getDOM().getDocumentElement(), new String JavaDoc[] { "a" });
702             final Element linkElement = walker.getElementWithTextAfterText(linkText, labelText);
703             if (linkElement != null) {
704                 return resp.getFirstMatchingLink(new SameLinkPredicate(), linkElement);
705             }
706         } catch (SAXException JavaDoc e) {
707             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
708         }
709         return null;
710     }
711
712     private static class SameLinkPredicate implements HTMLElementPredicate {
713         public boolean matchesCriteria(Object JavaDoc found, Object JavaDoc given) {
714             WebLink link = (WebLink) found;
715             Element foundElement = (Element) link.getDOMSubtree();
716             Element givenElement = (Element) given;
717
718             NamedNodeMap foundAttributes = foundElement.getAttributes();
719             NamedNodeMap givenAttributes = givenElement.getAttributes();
720
721             if (foundAttributes.getLength() != givenAttributes.getLength()) {
722                 return false;
723             }
724
725             for (int i = 0; i < foundAttributes.getLength(); i++) {
726                 Attr foundAttribute = (Attr) foundAttributes.item(i);
727                 Attr givenAttribute = (Attr) givenAttributes.getNamedItem(foundAttribute.getName());
728                 if (!foundAttribute.getValue().equals(givenAttribute.getValue())) {
729                     return false;
730                 }
731             }
732
733             return true;
734         }
735     }
736
737     /**
738      * Navigate by submitting a request based on a link with a given ID. A RuntimeException is thrown if no such link
739      * can be found.
740      *
741      * @param anID
742      * id of link to be navigated.
743      */

744     public void clickLink(String JavaDoc anID) {
745         WebLink link = null;
746         try {
747             link = resp.getLinkWithID(anID);
748         } catch (SAXException JavaDoc e) {
749             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
750         }
751         if (link == null)
752             throw new RuntimeException JavaDoc("No Link found with ID \"" + anID + "\"");
753         submitRequest(link);
754
755     }
756
757     /**
758      * Navigate by submitting a request based on a link with a given image file name. A RuntimeException is thrown if
759      * no such link can be found.
760      *
761      * @param imageFileName
762      * A suffix of the image's filename; for example, to match <tt>"images/my_icon.png"<tt>, you could just pass in
763      * <tt>"my_icon.png"<tt>.
764      */

765     public void clickLinkWithImage(String JavaDoc imageFileName) {
766         WebLink link = null;
767         try {
768             link = resp.getFirstMatchingLink(new LinkImagePredicate(), imageFileName);
769         } catch (SAXException JavaDoc e) {
770             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
771         }
772         if (link == null)
773             throw new RuntimeException JavaDoc("No Link found with imageFileName \"" + imageFileName + "\"");
774         submitRequest(link);
775     }
776
777     /**
778      * Click the indicated button (input type=button).
779      *
780      * @param buttonId
781      */

782     public void clickButton(String JavaDoc buttonId) {
783         try {
784             getButton(buttonId).click();
785             resp = wc.getCurrentPage();
786         } catch (Exception JavaDoc e) {
787             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
788         }
789     }
790
791     /**
792      * Return true if a radio group contains the indicated option.
793      *
794      * @param radioGroup
795      * name of the radio group.
796      * @param radioOption
797      * value of the option to check for.
798      */

799     public boolean hasRadioOption(String JavaDoc radioGroup, String JavaDoc radioOption) {
800         WebForm[] forms = getForms();
801         for (int i = 0; i < forms.length; i++) {
802             WebForm form = forms[i];
803             String JavaDoc[] opts = form.getOptionValues(radioGroup);
804             for (int j = 0; j < opts.length; j++) {
805                 String JavaDoc opt = opts[j];
806                 if (radioOption.equals(opt))
807                     return true;
808             }
809         }
810         return false;
811     }
812
813     /**
814      * Return a string array of select box option labels.
815      *
816      * @param selectName
817      * name of the select box.
818      */

819     public String JavaDoc[] getOptionsFor(String JavaDoc selectName) {
820         return getForm().getOptions(selectName);
821     }
822
823     /**
824      * Return a string array of select box option values.
825      *
826      * @param selectName
827      * name of the select box.
828      */

829     public String JavaDoc[] getOptionValuesFor(String JavaDoc selectName) {
830         return getForm().getOptionValues(selectName);
831     }
832
833     /**
834      * Return the label of the currently selected item in a select box.
835      *
836      * @param selectName
837      * name of the select box.
838      */

839     public String JavaDoc getSelectedOption(String JavaDoc selectName) {
840         String JavaDoc val = getFormParameterValue(selectName);
841         String JavaDoc[] vals = getOptionValuesFor(selectName);
842         for (int i = 0; i < vals.length; i++) {
843             if (vals[i].equals(val))
844                 return getOptionsFor(selectName)[i];
845         }
846         return null;
847     }
848
849     /**
850      * Get the value for a given option of a select box.
851      *
852      * @param selectName
853      * name of the select box.
854      * @param option
855      * label of the option.
856      */

857     public String JavaDoc getValueForOption(String JavaDoc selectName, String JavaDoc option) {
858         String JavaDoc[] opts = getOptionsFor(selectName);
859         for (int i = 0; i < opts.length; i++) {
860             if (opts[i].equals(option))
861                 return getOptionValuesFor(selectName)[i];
862         }
863         throw new RuntimeException JavaDoc("Unable to find option " + option + " for " + selectName);
864     }
865
866     /**
867      * Select an option of a select box by display label.
868      *
869      * @param selectName
870      * name of the select box.
871      * @param option
872      * label of the option to select.
873      */

874     public void selectOption(String JavaDoc selectName, String JavaDoc option) {
875         setFormParameter(selectName, getValueForOption(selectName, option));
876     }
877
878     /**
879      * Return the org.w3c.dom.Element in the current response by id.
880      *
881      * @param anID
882      * id of the element.
883      */

884     public Element getElement(String JavaDoc anID) {
885         try {
886             return walkDOM(getResponse().getDOM().getDocumentElement(), anID);
887         } catch (Exception JavaDoc e) {
888             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
889         }
890     }
891
892     private Element walkDOM(Element element, String JavaDoc anID) {
893         if (element.getAttribute("id").equals(anID) || element.getAttribute("ID").equals(anID))
894             return element;
895         NodeList children = element.getChildNodes();
896         for (int i = 0; i < children.getLength(); i++) {
897             Node child = children.item(i);
898             if (child.getNodeType() == Node.ELEMENT_NODE) {
899                 Element el = walkDOM((Element) child, anID);
900                 if (el != null)
901                     return el;
902             }
903         }
904         return null;
905     }
906
907     /**
908      * Return true if a given string is contained within the specified element.
909      *
910      * @param element
911      * org.w3c.com.Element to inspect.
912      * @param text
913      * text to check for.
914      */

915     public boolean isTextInElement(Element element, String JavaDoc text) {
916         NodeList children = element.getChildNodes();
917         for (int i = 0; i < children.getLength(); i++) {
918             Node child = children.item(i);
919             if (child.getNodeType() == Node.TEXT_NODE) {
920                 if (((Text) child).getData().indexOf(text) != -1)
921                     return true;
922             }
923
924             if (child.getNodeType() == Node.ELEMENT_NODE) {
925                 if (isTextInElement((Element) child, text))
926                     return true;
927             }
928         }
929         return false;
930     }
931
932     /**
933      * Make the window with the given name in the current conversation active.
934      *
935      * @param windowName
936      */

937     public void gotoWindow(String JavaDoc windowName) {
938         setMainWindow(getWindow(windowName));
939     }
940
941     /**
942      * Make the root window in the current conversation active.
943      */

944     public void gotoRootWindow() {
945         setMainWindow(wc.getOpenWindows()[0]);
946     }
947
948     private void setMainWindow(WebWindow win) {
949         wc.setMainWindow(win);
950         resp = wc.getMainWindow().getCurrentPage();
951     }
952
953     /**
954      * Make the frame with the given name active in the current conversation.
955      *
956      * @param frameName
957      */

958     public void gotoFrame(String JavaDoc frameName) {
959         resp = getFrame(frameName);
960         form=null;
961     }
962
963     /**
964      * Return the response for the given frame in the current conversation.
965      *
966      * @param frameName
967      */

968     public WebResponse getFrame(String JavaDoc frameName) {
969         return wc.getMainWindow().getFrameContents(frameName);
970     }
971
972     /**
973      * Patch sumbitted by Alex Chaffee.
974      */

975     public void gotoPage(String JavaDoc url) {
976         try {
977             resp = wc.getResponse(url);
978         } catch (Exception JavaDoc e) {
979             throw new RuntimeException JavaDoc(ExceptionUtility.stackTraceToString(e));
980         }
981     }
982     
983     /**
984      * Dumps out all the cookies in the response received. The output is written to the passed in Stream
985      *
986      * @return void
987      */

988     public void dumpCookies(PrintStream JavaDoc stream) {
989         CookieJar respJar = getCookies();
990         String JavaDoc[] cookieNames = respJar.getCookieNames();
991         for (int i = 0; i < cookieNames.length; i++)
992             stream.print(cookieNames[i] + " : [" + respJar.getCookieValue(cookieNames[i]) + "]\n");
993     }
994
995     /**
996      * Dump html of current response to System.out - for debugging purposes.
997      *
998      * @param stream
999      */

1000    public void dumpResponse() {
1001        dumpResponse(System.out);
1002    }
1003    
1004    /**
1005     * Dump html of current response to a specified stream - for debugging purposes.
1006     *
1007     * @param stream
1008     */

1009    public void dumpResponse(PrintStream JavaDoc stream) {
1010        try {
1011            stream.println(getResponseText());
1012        } catch (Exception JavaDoc e) {
1013            e.printStackTrace();
1014            throw new RuntimeException JavaDoc(e.getMessage());
1015        }
1016    }
1017
1018    /**
1019     * Dump the table as the 2D array that is used for assertions - for debugging purposes.
1020     *
1021     * @param tableNameOrId
1022     * @param stream
1023     */

1024    public void dumpTable(String JavaDoc tableNameOrId, PrintStream JavaDoc stream) {
1025        dumpTable(tableNameOrId, getSparseTableBySummaryOrId(tableNameOrId), stream);
1026    }
1027
1028    /**
1029     * Dump the table as the 2D array that is used for assertions - for debugging purposes.
1030     *
1031     * @param tableNameOrId
1032     * @param table
1033     */

1034    public void dumpTable(String JavaDoc tableNameOrId, String JavaDoc[][] table) {
1035        dumpTable(tableNameOrId, table, System.out);
1036    }
1037
1038    /**
1039     * Dump the table as the 2D array that is used for assertions - for debugging purposes.
1040     *
1041     * @param tableNameOrId
1042     * @param table
1043     * @param stream
1044     */

1045    public void dumpTable(String JavaDoc tableNameOrId, String JavaDoc[][] table, PrintStream JavaDoc stream) {
1046        stream.print("\n" + tableNameOrId + ":");
1047        for (int i = 0; i < table.length; i++) {
1048            String JavaDoc[] cell = table[i];
1049            stream.print("\n\t");
1050            for (int j = 0; j < cell.length; j++) {
1051                stream.print("[" + cell[j] + "]");
1052            }
1053        }
1054    }
1055    
1056}
1057
Popular Tags