1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package net.sf.jameleon.plugin.jiffie.util;
21
22 import net.sf.jameleon.util.Configurator;
23 import net.sf.jameleon.util.JameleonUtility;
24
25 import com.jacob.com.ComFailException;
26
27 import net.sf.jiffie.*;
28 import net.sf.jiffie.xpath.JiffieXPath;
29
30 import junit.framework.Assert;
31
32 import org.jaxen.JaxenException;
33 import org.jaxen.XPath;
34
35 import java.util.ArrayList;
36 import java.util.Iterator;
37 import java.util.List;
38 import java.util.regex.Matcher;
39 import java.util.regex.Pattern;
40 import java.util.StringTokenizer;
41
42 /***
43 * This class was created to be used by the IEFunctionTag. The idea is to have the
44 * logic in this class and simply have have the IEFunctionTag be a facade. This
45 * should make unit testing much easier and the IEFunctionTag much smaller.
46 */
47 public class IHTMLElementFinder {
48
49 protected DocumentDelegate docDelegate;
50 private static String ELEMENT_CSS = "border : 5px solid #FF00FF;";
51 private static String FORM_FIELD_CSS = "background : #CCFF33;";
52 private static boolean CHECK_FOR_NON_STANDARD_ATTRIBUTES = false;
53
54 public IHTMLElementFinder(DocumentDelegate docDelegate) {
55 this.docDelegate = docDelegate;
56 Configurator config = Configurator.getInstance();
57 String elementCSS = config.getValue("jiffie-plugin.highlightedElementCss");
58 String formFieldCss = config.getValue("jiffie-plugin.highlightedFormFieldCss");
59 CHECK_FOR_NON_STANDARD_ATTRIBUTES = new Boolean(config.getValue("jiffie-plugin.checkForNonStandardAttr")).booleanValue();
60 if (elementCSS != null && elementCSS.trim().length() > 0) {
61 ELEMENT_CSS = elementCSS;
62 }
63 if (formFieldCss != null && formFieldCss.trim().length() > 0) {
64 FORM_FIELD_CSS = formFieldCss;
65 }
66 }
67
68 /***
69 * Gets the area HTML tag with the given alt text
70 * @param altText - the alt text that the desired area tag should have
71 * @return A matching area tag
72 */
73 public IHTMLElement getAreaElementByAltText(String altText) {
74 IHTMLElement areaElement = null;
75 try {
76 ElementList links = docDelegate.getDocument().getElementListByTag("area");
77 IHTMLElement element = null;
78 String alt;
79 Iterator it = links.iterator();
80 while (it.hasNext()) {
81 element = (IHTMLElement)it.next();
82 alt = getAttributeValue(element, "alt");
83 if (altText.equalsIgnoreCase(alt)) {
84 areaElement = element;
85 } else {
86 release(element);
87 }
88 }
89 } catch (JiffieException je) {
90 Assert.fail("Trouble retrieving area tag with '"+altText+"': "+JameleonUtility.getStack(je));
91 }
92 highlightFormField(areaElement);
93 return areaElement;
94 }
95
96 /***
97 * Gets an attribute's value for a given element
98 * @param element - The element that contains the attribute
99 * @param attributeName - The name of the attribute with the desired value
100 *
101 * @return the value for a attribute
102 * Contributed by Alex Eagar
103 */
104 public String getAttributeValue(IHTMLElement element, String attributeName) {
105 String value = null;
106 if (CHECK_FOR_NON_STANDARD_ATTRIBUTES) {
107 IHTMLAttributeCollection attributes = element.getAttributes();
108 int attributeCount = attributes.getLength();
109 for (int i = 0; i < attributeCount && value == null; i++) {
110 if (attributes.item(i).getName().equalsIgnoreCase(attributeName)) {
111 value = attributes.item(i).getValue();
112 }
113 }
114 }else{
115 value = element.getStringProperty(attributeName);
116 }
117 return value;
118 }
119
120 /***
121 * This method returns the IHTMLDOMNode identified by the given xpath. The IHTMLDOMNode could be either an
122 * IHTMLElement, an IHTMLDOMAttribute or an IHTMLDOMTextNode.
123 * @param xpath2evaluate - The xpath identifying the wanted node in the DOM.
124 * @return Depending on the given xpath either IHTMLElement, IHTMLDOMAttribute or IHTMLDOMTextNode.
125 */
126 public IHTMLDOMNode getByXPath(String xpath2evaluate) {
127 XPath xpath = null;
128 IHTMLDOMNode o = null;
129 if (xpath2evaluate != null && xpath2evaluate.length() > 0) {
130 IHTMLDocument2 doc = docDelegate.getDocument();
131 try {
132 xpath = new JiffieXPath(xpath2evaluate);
133 o = (IHTMLDOMNode) xpath.selectSingleNode(doc);
134 } catch (JaxenException e) {
135 throw new RuntimeException("Jaxen was not able to evaluate xpath: '" + xpath2evaluate + "'");
136 } catch (ClassCastException e) {
137 throw new RuntimeException("XPath did not evaluate to an IHTMLDOMNode");
138 } finally {
139 doc.release();
140 }
141 } else {
142 throw new RuntimeException("Please provide an xpath to identify the element.");
143 }
144 return o;
145 }
146
147 /***
148 * Gets the checkbox given by it's field name
149 *
150 * @param checkboxFieldName - the name of the checkbox
151 * @return the checkbox representing the field name.
152 * @throws RuntimeException if the field does not exist in the form.
153 */
154 public IHTMLInputElement getCheckbox(String checkboxFieldName) {
155 IHTMLInputElement checkbox = null;
156 if (docDelegate.getWorkingForm() != null) {
157 checkbox = (IHTMLInputElement) getFormElement("input", new String[]{"type", "name"}, new String[]{"checkbox", checkboxFieldName});
158 } else {
159 checkbox = (IHTMLInputElement) getIHTMLElement("input", new String[]{"type", "name"}, new String[]{"checkbox", checkboxFieldName});
160 }
161 highlightFormField(checkbox);
162 return checkbox;
163 }
164
165 /***
166 * Gets the checkbox given by it's field name and value
167 *
168 * @param checkboxFieldName - the name of the checkbox
169 * @param checkboxFieldValue - the value of the checkbox
170 * @return the checkbox representing the field name.
171 * @throws RuntimeException if the field does not exist in the form.
172 */
173 public IHTMLInputElement getCheckboxWithNameAndValue(String checkboxFieldName, String checkboxFieldValue) {
174 IHTMLInputElement checkbox = (IHTMLInputElement) getFormElement("input", new String[]{"type", "name", "value"}, new String[]{"checkbox", checkboxFieldName, checkboxFieldValue});
175 highlightFormField(checkbox);
176 return checkbox;
177 }
178
179 /***
180 * @param xpath2evaluate - The XPath identifying the element
181 * @return The IHTMLElement identified by the given XPath. Null ifthe XPath does not identify any element.
182 */
183 public IHTMLElement getElementByXPath (String xpath2evaluate) {
184 IHTMLDOMNode node = getByXPath(xpath2evaluate);
185 IHTMLElement element = null;
186 if (node != null) {
187 if (node instanceof IHTMLElement) {
188 element = (IHTMLElement) node;
189 } else {
190 release(element);
191 throw new RuntimeException("XPath did not evaluate to an IHTMLElement node. Node found is: " + node);
192 }
193 }
194 highlightElement(element);
195 return element;
196 }
197
198 /***
199 * @param xpath2evaluate - The XPath identifying the element
200 * @return A List of matching elements
201 */
202 public List getElementsByXPath(String xpath2evaluate) {
203 XPath xpath = null;
204 List l = new ArrayList();
205 if (xpath2evaluate != null && xpath2evaluate.length() > 0) {
206 IHTMLDocument2 doc = docDelegate.getDocument();
207 try {
208 xpath = new JiffieXPath(xpath2evaluate);
209 l = xpath.selectNodes(doc);
210 } catch (JaxenException e) {
211 throw new RuntimeException("Jaxen was not able to evaluate xpath: '" + xpath2evaluate + "'");
212 } finally {
213 doc.release();
214 }
215 } else {
216 throw new IllegalArgumentException("xpath2evaluate is a required field!");
217 }
218 return l;
219 }
220
221 /***
222 * Gets a frame by the id attribute
223 * @param container - the ElementContainer that contains the desired frame.
224 * @param frameId - the id of the frame
225 * @return the frame represented by the frame id
226 */
227 public IHTMLFrameBase2 getFrameWithId(ElementContainer container, String frameId){
228 return getFrame(container, "id", frameId);
229 }
230
231 /***
232 * Gets a frame by the id attribute
233 * @param frameId - the id of the frame
234 * @return the frame represented by the frame id
235 */
236 public IHTMLFrameBase2 getFrameWithId(String frameId){
237 return getFrameWithId(docDelegate.getDocument(),frameId);
238 }
239
240 /***
241 * Gets a frame by the name attribute
242 * @param container - the ElementContainer that contains the desired frame.
243 * @param frameName - the name of the frame
244 * @return the frame represented by the frame name
245 */
246 public IHTMLFrameBase2 getFrameWithName(ElementContainer container, String frameName){
247 return getFrame(container, "name", frameName);
248 }
249
250 /***
251 * Gets a frame by the name attribute
252 * @param frameName - the name of the frame
253 * @return the frame represented by the frame name
254 */
255 public IHTMLFrameBase2 getFrameWithName(String frameName){
256 return getFrameWithName(docDelegate.getDocument(),frameName);
257 }
258
259 /***
260 * Gets a frame by the src attribute
261 * @param container - the ElementContainer that contains the desired frame.
262 * @param frameSrc - the source of the frame
263 * @return the frame represented by the frame src
264 */
265 public IHTMLFrameBase2 getFrameWithSrc(ElementContainer container, String frameSrc){
266 return getFrame(container, "src", frameSrc);
267 }
268
269 /***
270 * Gets a frame by the src attribute
271 * @param frameSrc - the source of the frame
272 * @return the frame represented by the frame src
273 */
274 public IHTMLFrameBase2 getFrameWithSrc(String frameSrc){
275 return getFrameWithSrc(docDelegate.getDocument(),frameSrc);
276 }
277
278 /***
279 * Gets a frame by the name attribute
280 * @param container - the ElementContainer that contains the desired frame.
281 * @param attrName - the attribute with which to find the frame(name/id/src)
282 * @param attrValue - the name,id, or src of the frame. This can be a comma-separated
283 * list of names, ids or srcs.
284 * @return the frame represented by the frame name
285 */
286 public IHTMLFrameBase2 getFrame(ElementContainer container, String attrName, String attrValue){
287 List frameAttrValueList = parseStringOfTokens(attrValue, ",");
288 IHTMLFrameBase2 frame = null;
289 Iterator iter = frameAttrValueList.iterator();
290 while (iter.hasNext()) {
291 String frameAttrValue = (String)iter.next();
292 ElementContainer curContainer = container;
293 if (frame != null) {
294 try {
295 curContainer = frame.getDocument(true);
296 } catch (JiffieException je) {
297 throw new RuntimeException("No frame with " + attrName + " of "+ frameAttrValue + " exists in the current document", je);
298 }
299 }
300 frame = internalGetFrame(curContainer, attrName, frameAttrValue);
301 }
302 return frame;
303 }
304
305 /***
306 * Gets a frame by the specified attribute
307 * @param container - the ElementContainer that contains the desired frame.
308 * @param attrName - the attribute with which to find the frame (name, id, src)
309 * @param attrValue - the name,id, or src of the frame
310 * @return the frame represented by the frame name
311 */
312 protected IHTMLFrameBase2 internalGetFrame(ElementContainer container, String attrName, String attrValue){
313 IHTMLFrameBase2 frame = null;
314 Object obj = getIHTMLElement(container, "frame", attrName, attrValue);
315 if (obj != null) {
316 frame = (IHTMLFrameBase2)obj;
317 } else {
318 obj = getIHTMLElement(container, "iframe", attrName, attrValue);
319 if (obj != null) {
320 frame = (IHTMLFrameBase2)obj;
321 }
322 }
323 return frame;
324 }
325
326 /***
327 * Parses a comma-separated list.
328 * @param tokenSeparatedList - A token-delimited String
329 * @param token - The token to parse the String with
330 * @return A List of tokens from the comma-separated list
331 */
332 public List parseStringOfTokens(String tokenSeparatedList, String token) {
333 List retval = new ArrayList();
334 if (tokenSeparatedList != null && tokenSeparatedList.length() > 0) {
335 StringTokenizer tokenizer = new StringTokenizer(tokenSeparatedList, token);
336 while (tokenizer.hasMoreTokens()) {
337 retval.add(tokenizer.nextToken());
338 }
339 }
340 return retval;
341 }
342
343 /***
344 * Tries to get a form via the following methods in order.
345 * <ol>
346 * <li><code>getFormWithId()</code> - Gets a form with the expected id attribute
347 * <li><code>getFormWithName()</code> - Gets a form with the expected name attribute
348 * <li><code>getFormWithIndex()</code> - The parameter is converted to a number, representing
349 * the index of the form on the page.
350 * <li><code>getFormWithXPath</code> - Gets a form with the expected XPath
351 * </ol>
352 *
353 * @param formInfo - The form id or name or index or XPath identifying the form
354 * @return the first form that corresponds to the above mentioned or <code>null</code> if no <code>Form</code> is found.
355 */
356 public IHTMLFormElement getForm(String formInfo) {
357 IHTMLFormElement form = null;
358 if (formInfo == null) {
359 throw new RuntimeException(JameleonUtility.createErrMsg("Please provide something defining the form"));
360 }
361 try {
362 form = getFormWithId(formInfo);
363 if (form == null) {
364 form = getFormWithName(formInfo);
365 if (form == null) {
366 if (Character.isDigit(formInfo.charAt(0))) {
367 int index = new Integer(formInfo).intValue();
368 form = getFormWithIndex(index);
369 } else {
370 if (form == null) {
371 form = getFormWithXPath(formInfo);
372 }
373 }
374 }
375 }
376 } catch (Exception e) {
377 throw new RuntimeException(JameleonUtility.createErrMsg("Couldn't get form \"" + formInfo + "\""), e);
378 }
379 highlightElement(form);
380 return form;
381 }
382
383 /***
384 * Gets the first matching element with a given attribute and attribute value
385 * @param htmlTag - The name of the element or tag. For an input element, you'd pass "input"
386 * @param attributeName - The name of the attribute to exist in the element.
387 * @param attributeValue - The value of the name attribute to exist in the element.
388 */
389 public IHTMLElement getFormElement(String htmlTag, String attributeName, String attributeValue ) {
390 List elements = getFormElements(htmlTag);
391
392 IHTMLElement element = null;
393 IHTMLElement elementFound = null;
394 Iterator it = elements.iterator();
395 String attributeV;
396 while (it.hasNext() && elementFound == null) {
397 element = (IHTMLElement) it.next();
398 attributeV = getAttributeValue(element, attributeName);
399
400
401 if (attributeName != null && attributeName.equalsIgnoreCase("src")) {
402 if (attributeV != null && attributeV.endsWith(attributeValue)) {
403 elementFound = element;
404 }
405 } else {
406 if (attributeV != null && attributeV.equals(attributeValue)) {
407 elementFound = element;
408 }
409 }
410 if (elementFound == null) {
411 release(element);
412 }
413 }
414 highlightElement(elementFound);
415 return elementFound;
416 }
417
418 /***
419 * Gets the first matching element with given attributes and attribute values
420 * @param htmlTag - The name of the element or tag. For an input
421 * element, you'd pass "input"
422 * @param attributeNames - A List of names of attributes to
423 * exist in the element.
424 * @param attributeValues - A List of values of name attributes
425 * to exist in the element. Must be in
426 * the same order as attributeNames
427 */
428 public IHTMLElement getFormElement(String htmlTag, String[] attributeNames, String[] attributeValues ) {
429 List elements = getFormElements(htmlTag);
430
431 IHTMLElement element = null;
432 IHTMLElement elementFound = null;
433 Iterator it = elements.iterator();
434 String attributeV;
435 boolean matches = true;
436 while (it.hasNext() && elementFound == null) {
437 element = (IHTMLElement) it.next();
438 for (int i = 0; i < attributeNames.length && matches; i++) {
439 attributeV = getAttributeValue(element, attributeNames[i]);
440 if (attributeNames[i] != null && attributeNames[i].equalsIgnoreCase("src")) {
441 if (attributeV == null || !attributeV.endsWith(attributeValues[i])) {
442 matches = false;
443 }
444 } else {
445 if (attributeV == null || !attributeV.equals(attributeValues[i])) {
446 matches = false;
447 }
448 }
449 }
450 if (matches) {
451 elementFound = element;
452 } else {
453 release(element);
454 }
455 matches = true;
456 }
457 highlightElement(elementFound);
458 return elementFound;
459 }
460
461 /***
462 * Gets a list of html elements.
463 * @param htmlTag - The name of the element or tag. For an input element, you'd pass "input"
464 */
465 public List getFormElements(String htmlTag) {
466 ElementList elements = null;
467 if (docDelegate.getWorkingForm() != null) {
468 try {
469 elements = docDelegate.getWorkingForm().getElementListByTag(htmlTag);
470 } catch (JiffieException je) {
471 throw new RuntimeException("No "+ htmlTag + " elements exist in the working form", je);
472 }
473 } else {
474 throw new RuntimeException("There is no working form set!");
475 }
476 return elements;
477 }
478
479 /***
480 * Gets a list of elements with a given attribute and attribute value
481 * @param htmlTag - The name of the element or tag. For an input element, you'd pass "input"
482 * @param attributeName - The name of the attribute to exist in the element.
483 * @param attributeValue - The value of the name attribute to exist in the element.
484 */
485 public List getFormElements(String htmlTag, String attributeName, String attributeValue ) {
486 List elements = getFormElements(htmlTag);
487 List matchingElements = new ArrayList();
488
489 IHTMLElement element = null;
490 Iterator it = elements.iterator();
491 String attributeV;
492 boolean found = false;
493 while (it.hasNext()) {
494 element = (IHTMLElement) it.next();
495 attributeV = getAttributeValue(element, attributeName);
496
497
498 if (attributeName != null && attributeName.equalsIgnoreCase("src")) {
499 if (attributeV != null && attributeV.endsWith(attributeValue)) {
500 found = true;
501 }
502 } else {
503 if (attributeV != null && attributeV.equals(attributeValue)) {
504 found = true;
505 }
506 }
507 if (found) {
508 matchingElements.add(element);
509 } else {
510 release(element);
511 }
512 found = false;
513 }
514 return matchingElements;
515 }
516
517 /***
518 * Gets a list of elements with given attributes and attribute values
519 * @param htmlTag - The name of the element or tag. For an input
520 * element, you'd pass "input"
521 * @param attributeNames - A List of names of attributes to
522 * exist in the element.
523 * @param attributeValues - A List of values of name attributes
524 * to exist in the element. Must be in
525 * the same order as attributeNames
526 */
527 public List getFormElements(String htmlTag, String[] attributeNames, String[] attributeValues ) {
528 List elements = getFormElements(htmlTag);
529 List matchingElements = new ArrayList();
530
531 IHTMLElement element = null;
532 Iterator it = elements.iterator();
533 String attributeV;
534 boolean matches = true;
535 while (it.hasNext()) {
536 element = (IHTMLElement) it.next();
537 for (int i = 0; i < attributeNames.length && matches; i++) {
538 attributeV = getAttributeValue(element, attributeNames[i]);
539 if (attributeNames[i] != null && attributeNames[i].equalsIgnoreCase("src")) {
540 if (attributeV == null || !attributeV.endsWith(attributeValues[i])) {
541 matches = false;
542 }
543 } else {
544 if (attributeV == null || !attributeV.equals(attributeValues[i])) {
545 matches = false;
546 }
547 }
548 }
549 if (matches) {
550 matchingElements.add(element);
551 } else {
552 release(element);
553 }
554 matches = true;
555 }
556 return matchingElements;
557 }
558
559 public ElementList getForms() {
560 ElementList forms = null;
561 IHTMLDocument2 doc = docDelegate.getDocument();
562 try {
563 forms = doc.getElementListByTag("form");
564 } catch (JiffieException je) {
565 throw new RuntimeException("No forms exist on the current page", je);
566 } finally {
567 release(doc);
568 }
569 return forms;
570 }
571
572 /***
573 * Tries to get a form with the id attribute provided
574 *
575 * @param id - The name of the form to be returned.
576 * @return a form with corresponding to the given name.
577 */
578 public IHTMLFormElement getFormWithId(String id) {
579 IHTMLFormElement form = null;
580 IHTMLDocument2 doc = docDelegate.getDocument();
581 try {
582 IDispatch dis = doc.getElementById(id);
583 if (dis instanceof IHTMLFormElement) {
584 form = (IHTMLFormElement) dis;
585 } else {
586 release(dis);
587 }
588
589 } catch (Exception e) {
590 throw new RuntimeException(JameleonUtility.createErrMsg("Couldn't get a form with the given id \"" + id + "\""), e);
591 } finally {
592 release(doc);
593 }
594 highlightElement(form);
595 return form;
596 }
597
598 /***
599 * Tries to get the nth form on the page. When a form has no id or name attribute defined,
600 * this method gets all of the forms on the page and returns the nth form, defined by index
601 *
602 * @param index - The number representing the (n-1)th form. The first form would be 0
603 * @return a form with corresponding to the given name.
604 */
605 public IHTMLFormElement getFormWithIndex(int index) {
606 IHTMLFormElement form = null;
607 IHTMLDocument2 doc = docDelegate.getDocument();
608 try {
609 ElementList formList = doc.getElementListByTag("form");
610 if (formList.size() > index) {
611 Object obj = formList.item(index);
612 if (obj instanceof IHTMLFormElement) {
613 form = (IHTMLFormElement) obj;
614 }
615 } else {
616 throw new RuntimeException ("Couldn't get a form with the given index \"" + index + "\"");
617 }
618 } catch (JiffieException e) {
619 Assert.fail("Couldn't get a form with the given index \"" + index + "\"");
620 } finally {
621 release(doc);
622 }
623 highlightElement(form);
624 return form;
625 }
626
627 /***
628 * Tries to get a form with the name attribute provided
629 *
630 * @param name - The name of the form to be returned.
631 * @return a form with corresponding to the given name.
632 */
633 public IHTMLFormElement getFormWithName(String name) {
634 IHTMLFormElement form = null;
635 IHTMLDocument2 doc = docDelegate.getDocument();
636 try {
637 Object obj = doc.getElementByName(name);
638 if (obj instanceof IHTMLFormElement) {
639 form = (IHTMLFormElement) obj;
640 }
641 } catch (Exception e) {
642 throw new RuntimeException(JameleonUtility.createErrMsg("Couldn't get a form with the given name \"" + name + "\""), e);
643 } finally {
644 doc.release();
645 }
646 highlightElement(form);
647 return form;
648 }
649
650 /***
651 * Gets a form with the given XPATH.
652 * @param xpath - the XPATH of the form
653 * @return the form matching the provided XPATH.
654 */
655 public IHTMLFormElement getFormWithXPath(String xpath) {
656 IHTMLFormElement form = null;
657 IHTMLElement element = getElementByXPath(xpath);
658 if (element instanceof IHTMLFormElement) {
659 form = (IHTMLFormElement) element;
660 } else {
661 release(element);
662 }
663 highlightElement(form);
664 return form;
665 }
666
667 /***
668 * Gets the hidden field given by it's field name
669 *
670 * @param fieldName - the name of the hidden field
671 * @return the hidden field representing the field name.
672 * @throws RuntimeException if the field does not exist in the form.
673 */
674 public IHTMLInputElement getHiddenField(String fieldName) {
675 IHTMLInputElement hiddenField = null;
676 if (docDelegate.getWorkingForm() != null) {
677 hiddenField = (IHTMLInputElement) getFormElement("input", new String[]{"type", "name"}, new String[]{"hidden", fieldName});
678 } else {
679 hiddenField = (IHTMLInputElement) getIHTMLElement("input", new String[]{"type", "name"}, new String[]{"hidden", fieldName});
680 }
681 return hiddenField;
682 }
683
684 /***
685 * Gets the first matching IHTMLElement with the given html tag, attribute and attribute value
686 * @param container - The ElementContainer to use to get the attributes out of.
687 * @param htmlTag - The HTML tag to get back.
688 * @param attributeName - the attibute in the HTML element
689 * @param attributeValue - the value of attibute in the HTML element
690 * @return the first matching IHTMLElement with the given html tag, attribute and attribute value
691 */
692 public IHTMLElement getIHTMLElement(ElementContainer container, String htmlTag, String attributeName, String attributeValue){
693 IHTMLElement elementFound = null;
694 try {
695 ElementList list = container.getElementListByTag(htmlTag);
696 Iterator it = list.iterator();
697 IHTMLElement element;
698 String attrV;
699 while (it.hasNext() && elementFound == null) {
700 element = (IHTMLElement)it.next();
701 attrV = getAttributeValue(element, attributeName);
702 if (attributeValueMatches(attributeName,attributeValue,attrV)) {
703 elementFound = element;
704 } else {
705 release(element);
706 }
707 }
708 } catch (JiffieException je) {
709 throw new RuntimeException("Could not find a '"+htmlTag+"' with the "+attributeName+"="+attributeValue, je);
710 }
711 highlightElement(elementFound);
712 return elementFound;
713 }
714
715 /***
716 * Gets the first matching IHTMLElement with the given html tag, attribute and attribute value
717 * @param htmlTag - The HTML tag to get back.
718 * @param attributeName - the attibute in the HTML element
719 * @param attributeValue - the value of attibute in the HTML element
720 * @return the first matching IHTMLElement with the given html tag, attribute and attribute value
721 */
722 public IHTMLElement getIHTMLElement(String htmlTag, String attributeName, String attributeValue){
723 return getIHTMLElement(docDelegate.getDocument(), htmlTag, attributeName, attributeValue);
724 }
725
726 /***
727 * Gets the first matching IHTMLElement with the given html tag, attributes and attribute values
728 * @param container - The ElementContainer to use to get the attributes out of.
729 * @param htmlTag - The HTML tag to get back.
730 * @param attributeNames - a list of attibutes in the HTML element
731 * @param attributeValues - a list of values of attibutes in the same order as the names
732 * @return the first matching IHTMLElement with the given html tag, attribute and attribute value
733 */
734 public IHTMLElement getIHTMLElement(ElementContainer container, String htmlTag, String[] attributeNames, String[] attributeValues){
735 IHTMLElement elementFound = null;
736 try {
737 ElementList list = container.getElementListByTag(htmlTag);
738 Iterator it = list.iterator();
739 IHTMLElement element;
740 String attrV;
741 while (it.hasNext() && elementFound == null) {
742 boolean matches = true;
743 element = (IHTMLElement)it.next();
744 for (int i = 0; i < attributeValues.length && matches; i++) {
745 attrV = getAttributeValue(element, attributeNames[i]);
746 if (!attributeValueMatches(attributeNames[i], attributeValues[i], attrV)) {
747 matches = false;
748 }
749 }
750 if (matches) {
751 elementFound = element;
752 } else {
753 release(element);
754 }
755 }
756 } catch (JiffieException je) {
757 throw new RuntimeException("Could not find a matching '"+htmlTag+"' tag!", je);
758 }
759 highlightElement(elementFound);
760 return elementFound;
761 }
762
763 /***
764 * Gets the first matching IHTMLElement with the given html tag, attributes and attribute values
765 * @param htmlTag - The HTML tag to get back.
766 * @param attributeNames - a list of attibutes in the HTML element
767 * @param attributeValues - a list of values of attibutes in the same order as the names
768 * @return the first matching IHTMLElement with the given html tag, attribute and attribute value
769 */
770 public IHTMLElement getIHTMLElement(String htmlTag, String[] attributeNames, String[] attributeValues){
771 return getIHTMLElement(docDelegate.getDocument(),htmlTag,attributeNames, attributeValues);
772 }
773
774 /***
775 * Gets a List of matching IHTMLElements with the given html tag, attribute and attribute value
776 * @param container - The ElementContainer to use to get the attributes out of.
777 * @param htmlTag - The HTML tag to get back.
778 * @param attributeName - the attibute in the HTML element
779 * @param attributeValue - the value of attibute in the HTML element
780 * @return a List of matching IHTMLElements with the given html tag, attribute and attribute value
781 */
782 public List getIHTMLElements(ElementContainer container, String htmlTag, String attributeName, String attributeValue){
783 List elements = new ArrayList();
784 try {
785 ElementList list = container.getElementListByTag(htmlTag);
786 Iterator it = list.iterator();
787 IHTMLElement element;
788 String attrV;
789 while (it.hasNext()) {
790 element = (IHTMLElement)it.next();
791 attrV = getAttributeValue(element, attributeName);
792 if (attributeValueMatches(attributeName,attributeValue,attrV)) {
793 elements.add(element);
794 } else {
795 release(element);
796 }
797 }
798 } catch (JiffieException je) {
799 throw new RuntimeException("Could not find a '"+htmlTag+"' with the "+attributeName+"="+attributeValue, je);
800 }
801 return elements;
802 }
803
804 /***
805 * Gets a List of matching IHTMLElements with the given html tag, attribute and attribute value
806 * @param htmlTag - The HTML tag to get back.
807 * @param attributeName - the attibute in the HTML element
808 * @param attributeValue - the value of attibute in the HTML element
809 * @return a List of matching IHTMLElements with the given html tag, attribute and attribute value
810 */
811 public List getIHTMLElements(String htmlTag, String attributeName, String attributeValue){
812 return getIHTMLElements(docDelegate.getDocument(),htmlTag,attributeName,attributeValue);
813 }
814
815 /***
816 * Gets a List of matching IHTMLElements with the given html tag, attributes and attribute values
817 * @param container - The ElementContainer to use to get the attributes out of.
818 * @param htmlTag - The HTML tag to get back.
819 * @param attributeNames - a list of attibutes in the HTML element
820 * @param attributeValues - a list of values of attibutes in the same order as the names
821 * @return a List of matching IHTMLElements with the given html tag, attribute and attribute value
822 */
823 public List getIHTMLElements(ElementContainer container, String htmlTag, String[] attributeNames, String[] attributeValues){
824 List elements = new ArrayList();
825 try {
826 ElementList list = container.getElementListByTag(htmlTag);
827 Iterator it = list.iterator();
828 IHTMLElement element;
829 String attrV;
830 while (it.hasNext()) {
831 boolean matches = true;
832 element = (IHTMLElement)it.next();
833 for (int i = 0; i < attributeValues.length && matches; i++) {
834 attrV = getAttributeValue(element, attributeNames[i]);
835 if (!attributeValueMatches(attributeNames[i], attributeValues[i], attrV)) {
836 matches = false;
837 }
838 }
839 if (matches) {
840 elements.add(element);
841 } else {
842 release(element);
843 }
844 }
845 } catch (JiffieException je) {
846 throw new RuntimeException("Could not find a matching '"+htmlTag+"' tag!" , je);
847 }
848 return elements;
849 }
850
851 /***
852 * Gets a List of matching IHTMLElements with the given html tag, attributes and attribute values
853 * @param htmlTag - The HTML tag to get back.
854 * @param attributeNames - a list of attibutes in the HTML element
855 * @param attributeValues - a list of values of attibutes in the same order as the names
856 * @return a List of matching IHTMLElements with the given html tag, attribute and attribute value
857 */
858 public List getIHTMLElements(String htmlTag, String[] attributeNames, String[] attributeValues){
859 return getIHTMLElements(docDelegate.getDocument(),htmlTag,attributeNames, attributeValues);
860 }
861
862 /***
863 * Helper method to find a link with given img alt text
864 *
865 * @param text - The alt text of the img contained by the link
866 * @return The IHTMLAnchorElement for the link
867 */
868 public IHTMLAnchorElement getImageLinkWithAltText(String text) {
869 IHTMLAnchorElement link = null;
870
871 IHTMLDocument2 doc = docDelegate.getDocument();
872 try {
873 ElementList links = doc.getElementListByTag("a");
874
875 Iterator it = links.iterator();
876 IHTMLAnchorElement anchorElement;
877 IHTMLImgElement imgElement;
878 while (it.hasNext()) {
879 anchorElement = (IHTMLAnchorElement) it.next();
880 imgElement = (IHTMLImgElement) anchorElement.getElementByTag("img");
881 if (null != imgElement) {
882 if ( imgElement.getName().equalsIgnoreCase(text) ||
883 ( getAttributeValue(imgElement, "alt") != null
884 && getAttributeValue(imgElement, "alt").equalsIgnoreCase(text)
885 ) ) {
886 link = anchorElement;
887 break;
888 } else {
889 release(imgElement);
890 }
891 }
892 }
893 } catch (JiffieException je) {
894 throw new RuntimeException( JameleonUtility.createErrMsg("Could not find image link with alt text '" + text +"'!"), je);
895 } finally {
896 release(doc);
897 }
898 highlightElement(link);
899 return link;
900 }
901
902 /***
903 * Tries to get an input field by name. This method does not care what type of
904 * input field it is.
905 *
906 * @param inputFieldName - The name of the input field that exists in the current working form
907 * @return the first element with the provided name.
908 */
909 public IHTMLInputElement getInputFieldByName(String inputFieldName) {
910 IHTMLInputElement field = null;
911 try {
912 field = (IHTMLInputElement) docDelegate.getWorkingForm().getElementByNameAndTag(inputFieldName, "input");
913 } catch (JiffieException je) {
914 throw new RuntimeException( JameleonUtility.createErrMsg("Could not find the input field with the given name "+inputFieldName), je);
915 }
916 return field;
917 }
918
919 /***
920 * Tries to get an input field by name. This method does not care what type of
921 * input field it is.
922 *
923 * @param inputFieldName - The name of the input field that exists in the current working form
924 * @return the first element with the provided name.
925 */
926 public List getInputFieldsByName(String inputFieldName) {
927 return getIHTMLElements("input", "name", inputFieldName);
928 }
929
930 /***
931 * Tries to get a link via the following methods in order.
932 * <ol>
933 * <li><code>getLinkWith()</code> - Gets a link with the diplayed text
934 * <li><code>getLinkWithID()</code> - Gets a link with the <code>id</code> attribute set.
935 * <li><code>getImageLinkWithAltText</code> - Gets a link with the alt attribute or alt text.
936 * <li><code>getLinkWithName()</code> - Gets a link with the name attribute set.
937 * <li><code>getLinkWithImageSrc()</code> - Gets a link with the image src.
938 * </ol>
939 *
940 * @param text - The link text or the link id or the alt text or the link name.
941 * @return the first link that corresponds to the above mentioned or <code>null</code> if no <code>WebLink</code> is found.
942 * todo order should be id, name, label, imageText.
943 */
944 public IHTMLAnchorElement getLink(String text) {
945 IHTMLAnchorElement link = null;
946 boolean success = false;
947 int passes = 0;
948 while (!success && passes < 5) {
949 try {
950 link = getLinkWith(text);
951 if (link == null) {
952 link = getLinkWithID(text);
953 if (link == null) {
954 link = getImageLinkWithAltText(text);
955 if (link == null) {
956 link = getLinkWithName(text);
957 if (link == null) {
958 link = getLinkWithImageSrc(text);
959 }
960 }
961 }
962 }
963 success = true;
964 } catch (ComFailException e) {
965
966 success = false;
967 passes++;
968 }
969 }
970 highlightElement(link);
971 return link;
972 }
973
974 /***
975 * Helper method to find a link with contained text
976 *
977 * @param text - The text contained by the link
978 * @return The IHTMLAnchorElement for the link
979 */
980 public IHTMLAnchorElement getLinkWith(String text) {
981 IHTMLAnchorElement link = null;
982
983 IHTMLDocument2 doc = docDelegate.getDocument();
984 try {
985 ElementList links = doc.getElementListByTag("a");
986
987 Iterator it = links.iterator();
988
989 while (it.hasNext()) {
990 IHTMLAnchorElement anchorElement = (IHTMLAnchorElement) it.next();
991 if (anchorElement.getInnerText().trim().equalsIgnoreCase(text)) {
992 link = anchorElement;
993 break;
994 } else {
995 release(anchorElement);
996 }
997 }
998 } catch (JiffieException je) {
999 throw new RuntimeException( JameleonUtility.createErrMsg("Could not find link with the text '" + text +"'!"), je);
1000 } finally {
1001 release(doc);
1002 }
1003 highlightElement(link);
1004 return link;
1005 }
1006
1007 /***
1008 * Helper method to find a link with the regex
1009 * found in the href, and the text contained in the
1010 * inner text, ID, or name.
1011 *
1012 * @param regex - The regex to be found in the href attribute of the link
1013 * @param text - The text contained by the link
1014 * @return The IHTMLAnchorElement for the link
1015 */
1016 public IHTMLAnchorElement getLinkWithHref(String regex, String text) {
1017 IHTMLAnchorElement link = null;
1018
1019 IHTMLDocument2 doc = docDelegate.getDocument();
1020 try {
1021 boolean isTextNull = (text == null || text.length() == 0);
1022 ElementList links = doc.getElementListByTag("a");
1023 Matcher matcher = Pattern.compile(regex, Pattern.CASE_INSENSITIVE).matcher("");
1024
1025 Iterator it = links.iterator();
1026 while (it.hasNext()) {
1027 IHTMLAnchorElement anchorElement = (IHTMLAnchorElement) it.next();
1028 String href = anchorElement.getHref().trim();
1029 matcher.reset(href);
1030 if (matcher.find() && (isTextNull || (anchorElement.getInnerText().indexOf(text) > -1||
1031 anchorElement.getID().trim().equalsIgnoreCase(text) ||
1032 anchorElement.getName().trim().equalsIgnoreCase(text)))) {
1033 link = anchorElement;
1034 break;
1035 } else {
1036 release(anchorElement);
1037 }
1038 }
1039 } catch (JiffieException je) {
1040 throw new RuntimeException( JameleonUtility.createErrMsg("Could not find link with href like '" + regex +"'!"), je);
1041 } finally {
1042 release(doc);
1043 }
1044 highlightElement(link);
1045 return link;
1046 }
1047
1048 /***
1049 * Helper method to find all links with contained text
1050 *
1051 * @param text - The text contained by the links
1052 * @return The IHTMLAnchorElement for the link
1053 */
1054 public List getLinksWith(String text) {
1055 List links = new ArrayList();
1056
1057 IHTMLDocument2 doc = docDelegate.getDocument();
1058 try {
1059 ElementList allLinks = doc.getElementListByTag("a");
1060
1061 IHTMLAnchorElement anchorElement;
1062 Iterator it = allLinks.iterator();
1063 while (it.hasNext()) {
1064 anchorElement = (IHTMLAnchorElement) it.next();
1065 if (anchorElement.getInnerText().trim().equalsIgnoreCase(text)) {
1066 links.add(anchorElement);
1067 } else {
1068 release(anchorElement);
1069 }
1070 }
1071 } catch (JiffieException je) {
1072 throw new RuntimeException( "Could not find link with the text '" + text +"'!", je);
1073 } finally {
1074 release(doc);
1075 }
1076 return links;
1077 }
1078
1079 /***
1080 * Helper method to find a link with given id
1081 *
1082 * @param id - The id of the link
1083 * @return The IHTMLAnchorElement for the link
1084 */
1085 public IHTMLAnchorElement getLinkWithID(String id) {
1086 IHTMLAnchorElement link = null;
1087 IHTMLDocument2 doc = docDelegate.getDocument();
1088 try {
1089 link = (IHTMLAnchorElement) doc.getElementById(id);
1090 } catch (ClassCastException e) {
1091
1092 link = null;
1093 } catch (JiffieException je) {
1094 throw new RuntimeException( JameleonUtility.createErrMsg("Could not find link with id '" + id +"'!"), je);
1095 } finally {
1096 release(doc);
1097 }
1098 highlightElement(link);
1099 return link;
1100 }
1101
1102 /***
1103 * Helper method to find a link with given img src attribute
1104 *
1105 * @param src - The part of the src attribute of the img contained by the link
1106 * @return The IHTMLAnchorElement for the link
1107 */
1108 public IHTMLAnchorElement getLinkWithImageSrc(String src) {
1109 IHTMLAnchorElement link = null;
1110
1111 IHTMLDocument2 doc = docDelegate.getDocument();
1112 try {
1113 ElementList links = doc.getElementListByTag("a");
1114 Iterator it = links.iterator();
1115
1116 IHTMLAnchorElement anchorElement;
1117 IHTMLImgElement imgElement;
1118 while (it.hasNext()) {
1119 anchorElement = (IHTMLAnchorElement) it.next();
1120 imgElement = (IHTMLImgElement) anchorElement.getElementByTag("img");
1121 if (null != imgElement) {
1122 if (imgElement.getSrc() != null && imgElement.getSrc().indexOf(src) > 0) {
1123 link = anchorElement;
1124 break;
1125 } else {
1126 release(imgElement);
1127 }
1128 }
1129 }
1130 } catch (JiffieException je) {
1131 throw new RuntimeException( JameleonUtility.createErrMsg("Could not find image link with src '" + src +"'!"), je);
1132 } finally {
1133 release(doc);
1134 }
1135 highlightElement(link);
1136 return link;
1137 }
1138
1139 /***
1140 * Helper method to find a link with given name
1141 *
1142 * @param name - The name of the link to find
1143 * @return The IHTMLAnchorElement for the link
1144 */
1145 public IHTMLAnchorElement getLinkWithName(String name) {
1146 IHTMLAnchorElement link = null;
1147 IHTMLDocument2 doc = docDelegate.getDocument();
1148 try {
1149 IDispatch dis = doc.getElementByNameAndTag(name, "a");
1150 if (dis != null) {
1151 if (dis instanceof IHTMLAnchorElement) {
1152 link = (IHTMLAnchorElement) dis;
1153 } else {
1154 release(dis);
1155 throw new RuntimeException(JameleonUtility.createErrMsg("'"+name+"' is not a link. It is a " + dis));
1156 }
1157 }
1158 } catch (JiffieException je) {
1159 throw new RuntimeException(JameleonUtility.createErrMsg("Could not find link with name '"+name+"'"), je);
1160 } finally {
1161 release(doc);
1162 }
1163 highlightElement(link);
1164 return link;
1165 }
1166
1167 /***
1168 * Gets the text field given by it's field name
1169 *
1170 * @param passwordFieldName - the name of the password field
1171 * @return the password field representing the field name.
1172 * @throws RuntimeException if the field does not exist in the form.
1173 */
1174 public IHTMLInputElement getPasswordField(String passwordFieldName) {
1175 IHTMLInputElement password = null;
1176 if (docDelegate.getWorkingForm() != null) {
1177 password = (IHTMLInputElement) getFormElement("input", new String[]{"type", "name"}, new String[]{"password",passwordFieldName});
1178 } else {
1179 password = (IHTMLInputElement) getIHTMLElement("input", new String[]{"type", "name"}, new String[]{"password", passwordFieldName});
1180 }
1181 highlightFormField(password);
1182 return password;
1183 }
1184
1185
1186 /***
1187 * Gets the radio button with the specified name and value
1188 *
1189 * @param radioButtonName - the name of the radio button
1190 * @param value - the value to set the radio button to.
1191 * @return a radio button with the specified name and valud
1192 */
1193 public IHTMLInputElement getRadioButton(String radioButtonName, String value) {
1194 IHTMLInputElement radioButton = null;
1195 if (docDelegate.getWorkingForm() != null) {
1196 radioButton = (IHTMLInputElement) getFormElement("input", new String[]{"type", "name", "value"}, new String[]{"radio", radioButtonName, value});
1197 } else {
1198 radioButton = (IHTMLInputElement) getIHTMLElement("input", new String[]{"type", "name", "value"}, new String[]{"radio", radioButtonName, value});
1199 }
1200 highlightFormField(radioButton);
1201 return radioButton;
1202 }
1203
1204 /***
1205 * Gets the select field defined by <code>selectFieldName</code>
1206 *
1207 * @param selectFieldName - the name of the select field
1208 * @return the select field matching the <code>selectFieldName</code>.
1209 */
1210 public IHTMLSelectElement getSelectField(String selectFieldName) {
1211 IHTMLSelectElement select = null;
1212 if (docDelegate.getWorkingForm() != null) {
1213 select = (IHTMLSelectElement)getFormElement("select", "name", selectFieldName);
1214 } else {
1215 select = (IHTMLSelectElement)getIHTMLElement("select", "name", selectFieldName);
1216 }
1217 highlightFormField(select);
1218 return select;
1219 }
1220
1221 /***
1222 * Gets the currently selected option from the given select field defined by <code>selectFieldName</code>
1223 *
1224 * @param selectFieldName - the name of the select field
1225 * @return the select option currently selected.
1226 */
1227 public IHTMLOptionElement getSelectedOptionField(String selectFieldName) {
1228 IHTMLOptionElement selectedOption = null;
1229 try {
1230 IHTMLSelectElement ele = getSelectField(selectFieldName);
1231 if (ele != null) {
1232 int selectedIndex = ele.getSelectedIndex();
1233 ElementList options = ele.getElementListByTag("option");
1234 selectedOption = (IHTMLOptionElement)options.get(selectedIndex);
1235 } else {
1236 throw new RuntimeException("Could not get select field, " + selectFieldName + "!");
1237 }
1238 } catch (JiffieException je) {
1239 throw new RuntimeException("Could not get select field, " + selectFieldName + "!", je);
1240 }
1241 return selectedOption;
1242 }
1243
1244 /***
1245 * Gets the currently selected option from the given select field defined by <code>selectFieldName</code>
1246 *
1247 * @param selectFieldName - the name of the select field
1248 * @param displayedText - the text displayed in the browser
1249 * @return the select option currently selected.
1250 */
1251 public IHTMLOptionElement getSelectOptionWithText(String selectFieldName, String displayedText) {
1252 IHTMLOptionElement selectedOption = null;
1253 try {
1254 IHTMLSelectElement ele = getSelectField(selectFieldName);
1255 if (ele != null) {
1256 ElementList options = ele.getElementListByTag("option");
1257 Iterator it = options.iterator();
1258 String textValue;
1259 IHTMLOptionElement option;
1260 while (it.hasNext() && selectedOption == null) {
1261 option = (IHTMLOptionElement)it.next();
1262 textValue = option.getInnerText();
1263 if (textValue != null && textValue.equals(displayedText)) {
1264 selectedOption = option;
1265 } else {
1266 release(option);
1267 }
1268 }
1269 if (selectedOption == null) {
1270 throw new RuntimeException(displayedText +" option is not available for "+selectFieldName);
1271 }
1272 } else {
1273 throw new RuntimeException("Could not get select field, " + selectFieldName + "!");
1274 }
1275 } catch (JiffieException je) {
1276 throw new RuntimeException("Could not get select field, " + selectFieldName + "!", je);
1277 }
1278 return selectedOption;
1279 }
1280
1281
1282 /***
1283 * Tries to get a submit element in the following order.
1284 * <br/>
1285 * <ol>
1286 * <li><input type="submit" value="...">
1287 * <li><input type="image" src="...">
1288 * <li><input type="button" value="...">
1289 * </ol>
1290 *
1291 * @param id - The identifier of the submit element to find.
1292 * For submit and button types, it will try to match it with the value attribute.
1293 * For image input types, it will try to match it with the src or alt attribute.
1294 * @return The input element.
1295 * todo support find <button>...</button>.
1296 */
1297 public IHTMLInputElement getSubmit(String id) {
1298 IHTMLInputElement submit = getSubmit("submit", id);
1299 if (submit == null) {
1300 submit = getSubmit("image", id);
1301 if (submit == null) {
1302 submit = getSubmit("button", id);
1303 }
1304 }
1305 highlightElement(submit);
1306 return submit;
1307 }
1308
1309
1310 /***
1311 * Gets the submit button identified by it's value (the label shown in the browser). Supported ways of finding a
1312 * submit are:<br/>
1313 * <input type="submit" value="some value"><br />
1314 * <input type="image" src="jameleon.jpg" alt="alt text"><br />
1315 * <input type="button" value="some value" onclick="submit();"><br />
1316 * <button id="button tag" type="submit">button tag</button><br />
1317 *
1318 * @param type - type of submit field 'submit', 'image' or 'button'
1319 * @param value - the value of the submit field (this is the label of the submit button shown in the browser)
1320 * @return the input field representing the submit button or null if not found.
1321 * @throws RuntimeException if the field does not exist in the form.
1322 * todo introduce constants for supported types.
1323 */
1324 public IHTMLInputElement getSubmit(String type, String value) {
1325 IHTMLInputElement submit = null;
1326 List validType = new ArrayList();
1327 validType.add("submit");
1328 validType.add("image");
1329 validType.add("button");
1330 if (type == null || !validType.contains(type)) {
1331 throw new RuntimeException("Please provide a valid type: 'submit', 'image' or 'button'");
1332 }
1333 if (docDelegate.getWorkingForm() != null) {
1334 try {
1335 List inputElements = docDelegate.getWorkingForm().getElementListByTag("input");
1336 if (inputElements != null && !inputElements.isEmpty()) {
1337 Iterator it = inputElements.iterator();
1338 while (it.hasNext()) {
1339 IDispatch dis = (IDispatch)it.next();
1340 if (dis instanceof IHTMLInputElement) {
1341 IHTMLInputElement input = (IHTMLInputElement) dis;
1342 if (type.equals(input.getType())) {
1343 if ((type.equals("submit") || type.equals("button")) && input.getValue().equals(value)) {
1344 submit = (IHTMLInputElement) dis;
1345 } else if (type.equals("image") &&
1346 ( getAttributeValue(input, "alt").equals(value) ||
1347 getAttributeValue(input, "src").endsWith(value) ) ) {
1348 submit = (IHTMLInputElement) dis;
1349 } else {
1350 release(input);
1351 }
1352 } else {
1353 release(input);
1354 }
1355 } else {
1356 release(dis);
1357 }
1358 }
1359 } else {
1360 throw new RuntimeException("There are no input fields in the working form!");
1361 }
1362 } catch (JiffieException je) {
1363 throw new RuntimeException("Could not check " + value, je);
1364 }
1365 } else {
1366 throw new RuntimeException("There is no working form set!");
1367 }
1368 highlightElement(submit);
1369 return submit;
1370 }
1371
1372 /***
1373 * Gets a submit button by it's name from the working form
1374 *
1375 * @param buttonName - the name of the submit button
1376 * @return the submit button with the provided <code>buttonName</code>
1377 * @throws RuntimeException if the desired submit button isn't found in the working form.
1378 */
1379 public IHTMLInputElement getSubmitButtonWithName(String buttonName) {
1380 IHTMLInputElement submitButton = null;
1381 if (docDelegate.getWorkingForm() != null) {
1382 IHTMLInputElement tmpButton = getInputFieldByName(buttonName);
1383 if (tmpButton != null) {
1384 if ("submit".equals(tmpButton.getType()) ||
1385 "button".equals(tmpButton.getType()) ||
1386 "image".equals(tmpButton.getType())) {
1387 submitButton = tmpButton;
1388 } else {
1389 release(tmpButton);
1390 throw new RuntimeException(buttonName + " is not a submit button!");
1391 }
1392 } else {
1393 throw new RuntimeException(buttonName + " does not exist as a form submit button!");
1394 }
1395 } else {
1396 throw new RuntimeException("There is no working form set!");
1397 }
1398 highlightElement(submitButton);
1399 return submitButton;
1400 }
1401
1402 /***
1403 * Gets the first submit button by it's name from the working form
1404 *
1405 * @param buttonName - the name of the submit button
1406 * @param value - the value attribute of the button
1407 * @return the submit button with the provided <code>buttonName</code> and <code>value</code>.
1408 * @throws RuntimeException if the desired submit button isn't found in the working form.
1409 */
1410 public IHTMLInputElement getSubmitButtonWithNameAndValue(String buttonName, String value) {
1411 IHTMLInputElement submitButton = null;
1412 if (docDelegate.getWorkingForm() != null) {
1413 List elements = getInputFieldsByName(buttonName);
1414 if (elements != null && !elements.isEmpty()) {
1415 IHTMLInputElement tmpButton;
1416 Iterator it = elements.iterator();
1417 while (it.hasNext()) {
1418 tmpButton = (IHTMLInputElement)it.next();
1419 if (("submit".equals(tmpButton.getType()) ||
1420 "button".equals(tmpButton.getType()) ||
1421 "image".equals(tmpButton.getType())) &&
1422 value.equals(tmpButton.getValue())) {
1423 submitButton = tmpButton;
1424 break;
1425 } else {
1426 release(tmpButton);
1427 }
1428 }
1429 } else {
1430 throw new RuntimeException(buttonName + " does not exist as a form submit button!");
1431 }
1432 } else {
1433 throw new RuntimeException("There is no working form set!");
1434 }
1435 highlightElement(submitButton);
1436 return submitButton;
1437 }
1438
1439 /***
1440 * Gets the first submit button by it's value from the working form
1441 *
1442 * @param value - the value attribute of the button
1443 * @return the submit button with the provided <code>value</code>.
1444 * @throws RuntimeException if the desired submit button isn't found in
1445 * the working form.
1446 */
1447 public IHTMLInputElement getSubmitButtonWithValue(String value) {
1448 IHTMLInputElement submitButton = null;
1449 if (docDelegate.getWorkingForm() != null) {
1450 try {
1451 ElementList elements = docDelegate.getWorkingForm().getElementListByTag("input");
1452 if (elements != null) {
1453 Object obj;
1454 IHTMLInputElement tmpButton;
1455 Iterator it = elements.iterator();
1456 while (it.hasNext()) {
1457 obj = it.next();
1458 if (obj instanceof IHTMLInputElement) {
1459 tmpButton = (IHTMLInputElement) obj;
1460
1461 if (("submit".equals(tmpButton.getType()) ||
1462 "button".equals(tmpButton.getType()) ||
1463 "image".equals(tmpButton.getType())) &&
1464 value.equals(tmpButton.getValue())) {
1465 submitButton = tmpButton;
1466 break;
1467 } else {
1468 release(tmpButton);
1469 }
1470 }
1471 }
1472 } else {
1473 throw new RuntimeException("Could not find a submit button with the provided value: "+value);
1474 }
1475 } catch (JiffieException je) {
1476 throw new RuntimeException("Could not find a submit button with the provided value: "+value, je);
1477 }
1478 } else {
1479 throw new RuntimeException("There is no working form set!");
1480 }
1481 highlightElement(submitButton);
1482 return submitButton;
1483 }
1484
1485 /***
1486 * Gets the text field given by it's field name
1487 *
1488 * @param fieldName - the name of the text field
1489 * @return the text field representing the field name.
1490 * @throws RuntimeException if the field does not exist in the form.
1491 */
1492 public IHTMLInputElement getTextField(String fieldName) {
1493 IHTMLInputElement text = null;
1494 if (docDelegate.getWorkingForm() != null) {
1495 text = (IHTMLInputElement) getFormElement("input", new String[]{"type", "name"}, new String[]{"text", fieldName});
1496 } else {
1497 text = (IHTMLInputElement) getIHTMLElement("input", new String[]{"type", "name"}, new String[]{"text", fieldName});
1498 }
1499 highlightFormField(text);
1500 return text;
1501 }
1502
1503 /***
1504 * Gets the file input field given by it's field name
1505 *
1506 * @param fieldName - the name of the file input field
1507 * @return the file input field representing the field name.
1508 * @throws RuntimeException if the field does not exist in the form.
1509 */
1510 public IHTMLInputElement getFileInputField(String fieldName) {
1511 IHTMLInputElement file = (IHTMLInputElement) getFormElement("input", new String[]{"type", "name"}, new String[]{"file", fieldName});
1512 highlightFormField(file);
1513 return file;
1514 }
1515
1516 /***
1517 * Gets the text area given by it's field name
1518 *
1519 * @param fieldName - the name of the text area
1520 * @return the text area representing the field name.
1521 * @throws RuntimeException if the field does not exist in the form.
1522 */
1523 public IHTMLTextAreaElement getTextArea(String fieldName) {
1524 IHTMLTextAreaElement textArea = null;
1525 if (docDelegate.getWorkingForm() != null) {
1526 textArea = (IHTMLTextAreaElement) getFormElement("textarea", "name", fieldName);
1527 } else {
1528 textArea = (IHTMLTextAreaElement) getIHTMLElement("textarea", "name", fieldName);
1529 }
1530 highlightFormField(textArea);
1531 return textArea;
1532 }
1533
1534 /***
1535 * Checks to see if the current page has the desired block of text
1536 * @param text - the expected text
1537 * @return True if the expected text is found
1538 */
1539 public boolean isTextInPage(String text){
1540 IHTMLDocument2 doc = docDelegate.getDocument();
1541 boolean textInPage = false;
1542 if (doc != null) {
1543 try {
1544 String html = doc.getBody().getParentElement().getOuterHtml();
1545 textInPage = ( html.indexOf(text) >= 0);
1546 } catch (JiffieException je) {
1547 throw new RuntimeException("Couldn't get text on current page", je);
1548 } finally {
1549 release(doc);
1550 }
1551 }
1552 return textInPage;
1553 }
1554
1555 protected void release(IDispatch dis){
1556 if (dis != null) {
1557 dis.release();
1558 }
1559 }
1560
1561 public void highlightElement(IHTMLElement element){
1562 if (docDelegate.highlightActiveElement() &&
1563 element != null &&
1564 !element.isReleased()) {
1565 element.getStyle().setCssText(ELEMENT_CSS);
1566 }
1567 }
1568
1569 public void highlightFormField(IHTMLElement element){
1570 if (docDelegate.highlightActiveElement() &&
1571 element != null &&
1572 !element.isReleased()) {
1573 element.getStyle().setCssText(FORM_FIELD_CSS);
1574 }
1575 }
1576
1577 protected boolean attributeValueMatches(String attributeName, String expectedValue, String actualValue){
1578 boolean matches = false;
1579
1580 if ( (attributeName != null) &&
1581 (attributeName.equalsIgnoreCase("src") ||
1582 attributeName.equalsIgnoreCase("href")) ) {
1583 if (expectedValue != null && actualValue.endsWith(expectedValue)) {
1584 matches = true;
1585 }
1586 } else {
1587 if (expectedValue != null && expectedValue.equals(actualValue)) {
1588 matches = true;
1589 }
1590 }
1591 return matches;
1592 }
1593 }