Source Code Cross Referenced for ClickButton.java in  » Testing » webtest » com » canoo » webtest » steps » request » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Testing » webtest » com.canoo.webtest.steps.request 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // Copyright © 2002-2007 Canoo Engineering AG, Switzerland.
002:        package com.canoo.webtest.steps.request;
003:
004:        import com.canoo.webtest.engine.StepFailedException;
005:        import com.canoo.webtest.util.ConversionUtil;
006:        import com.canoo.webtest.util.HtmlConstants;
007:        import com.gargoylesoftware.htmlunit.Page;
008:        import com.gargoylesoftware.htmlunit.html.ClickableElement;
009:        import com.gargoylesoftware.htmlunit.html.HtmlButton;
010:        import com.gargoylesoftware.htmlunit.html.HtmlElement;
011:        import com.gargoylesoftware.htmlunit.html.HtmlForm;
012:        import com.gargoylesoftware.htmlunit.html.HtmlImageInput;
013:        import com.gargoylesoftware.htmlunit.html.HtmlInput;
014:        import com.gargoylesoftware.htmlunit.html.HtmlPage;
015:        import org.apache.commons.lang.StringUtils;
016:        import org.apache.log4j.Logger;
017:        import org.jaxen.JaxenException;
018:        import org.xml.sax.SAXException;
019:
020:        import java.io.IOException;
021:        import java.util.ArrayList;
022:        import java.util.Collection;
023:        import java.util.HashSet;
024:        import java.util.Iterator;
025:        import java.util.List;
026:        import java.util.Set;
027:
028:        /**
029:         * Provides the ability to click on a submit button.
030:         *
031:         * @author unknown
032:         * @author Marc Guillemot
033:         * @author Paul King
034:         * @author Denis N. Antonioli
035:         * @webtest.step category="Core"
036:         * name="clickButton"
037:         * alias="clickbutton"
038:         * description="This step is used to locate a form button and then click it."
039:         */
040:        public class ClickButton extends AbstractIdOrLabelTarget {
041:            private static final Logger LOG = Logger
042:                    .getLogger(ClickButton.class);
043:            private static final Set INPUT_BUTTONS_TYPES = new HashSet();
044:            private String fName;
045:            private String fFieldIndex;
046:            private String fX;
047:            private String fY;
048:
049:            static {
050:                INPUT_BUTTONS_TYPES.add(HtmlConstants.SUBMIT);
051:                INPUT_BUTTONS_TYPES.add(HtmlConstants.IMAGE);
052:                INPUT_BUTTONS_TYPES.add(HtmlConstants.BUTTON);
053:                INPUT_BUTTONS_TYPES.add(HtmlConstants.RESET);
054:            }
055:
056:            /**
057:             * @webtest.parameter required="yes/no"
058:             * description="The NAME attribute for the button of interest.
059:             * One of 'label', 'name', 'htmlid' or 'xpath' must be set.
060:             * Name has lower precedence than <em>htmlId</em>."
061:             */
062:            public void setName(String name) {
063:                fName = name;
064:            }
065:
066:            public String getName() {
067:                return fName;
068:            }
069:
070:            /**
071:             * Sets the index of the button to click (starting with 0) within the buttons
072:             * identified with the other criteria.
073:             *
074:             * @param index the new value
075:             * @webtest.parameter required="no"
076:             * default="0"
077:             * description="The index (starting with 0) of the button to click within the buttons having the specified label and/or name. Useful for instance to distinguish two buttons having the same name."
078:             */
079:            public void setFieldIndex(final String index) {
080:                fFieldIndex = index;
081:            }
082:
083:            public String getFieldIndex() {
084:                return fFieldIndex;
085:            }
086:
087:            /**
088:             * @webtest.parameter required="no"
089:             * description="Optional X coordinate of click within an image button. If set, Y coordinate must also be set."
090:             */
091:            public void setX(String clickPositionX) {
092:                fX = clickPositionX;
093:            }
094:
095:            public String getX() {
096:                return fX;
097:            }
098:
099:            /**
100:             * @webtest.parameter required="no"
101:             * description="Optional Y coordinate of click within an image button. If set, X coordinate must also be set."
102:             */
103:            public void setY(String clickPositionY) {
104:                fY = clickPositionY;
105:            }
106:
107:            public String getY() {
108:                return fY;
109:            }
110:
111:            /**
112:             * @deprecated use setFieldIndex instead
113:             */
114:
115:            public void setIndex(final int index) {
116:                LOG.warn("setIndex is deprecated - use setFieldIndex instead");
117:                setFieldIndex(Integer.toString(index));
118:            }
119:
120:            /**
121:             * Finds the button in the page according to the properties set on this step
122:             *
123:             * @param page the page to search in
124:             * @return the button, <code>null</code> if not found
125:             */
126:            protected ClickableElement findClickableElementByAttribute(
127:                    final HtmlPage page) {
128:                ClickableElement button = null;
129:                // look for the button in the current form
130:                if (getContext().getCurrentForm() != null) {
131:                    LOG.debug("Looking for button in current form");
132:                    button = findButton(getContext().getCurrentForm());
133:                }
134:                // if not found look at the other forms
135:                if (button == null) {
136:                    button = findButtonAllForms(page);
137:                }
138:                return button;
139:            }
140:
141:            protected Page findTarget() throws JaxenException, IOException,
142:                    SAXException {
143:                final ClickableElement button = findClickableElement(getContext()
144:                        .getCurrentHtmlResponse(this ));
145:                if (button == null) {
146:                    throw buildNoButtonFoundException();
147:                }
148:
149:                LOG.info("-> findTarget(by " + button.getTagName() + "): name="
150:                        + button.getAttributeValue("name") + " value="
151:                        + button.getAttributeValue("value"));
152:
153:                if (isImageButton()) {
154:                    LOG.info("-> findTarget(by " + button.getTagName()
155:                            + "): name=" + button.getAttributeValue("name")
156:                            + " value=" + button.getAttributeValue("value"));
157:                    return ((HtmlInput) button).click(Integer.parseInt(getX()),
158:                            Integer.parseInt(getY()));
159:                }
160:                return button.click();
161:            }
162:
163:            /**
164:             * Builds an exception with helpfull information
165:             * @return the exception
166:             */
167:            private StepFailedException buildNoButtonFoundException() {
168:                final StepFailedException e = new StepFailedException(
169:                        "No button found", this );
170:
171:                final HtmlForm currentForm = getContext().getCurrentForm();
172:                final StringBuffer msg = new StringBuffer();
173:                if (currentForm != null) {
174:                    msg.append("In current form:\n");
175:                    msg.append(getButtonsDescription(currentForm));
176:                }
177:
178:                final Iterator formsIterator = getContext()
179:                        .getCurrentHtmlResponse(this ).getForms().iterator();
180:                while (formsIterator.hasNext()) {
181:                    final HtmlForm form = (HtmlForm) formsIterator.next();
182:                    if (form != currentForm) {
183:                        if (msg.length() != 0)
184:                            msg.append("\n\n");
185:                        msg.append("In " + form + ":\n");
186:                        msg.append(getButtonsDescription(form));
187:                    }
188:                }
189:
190:                e.addDetail("available buttons", msg.toString());
191:                return e;
192:            }
193:
194:            private String getButtonsDescription(final HtmlForm _form) {
195:                final List buttons = new ArrayList();
196:                for (final Iterator iter = _form.getAllHtmlChildElements(); iter
197:                        .hasNext();) {
198:                    final HtmlElement element = (HtmlElement) iter.next();
199:                    if ((element instanceof  HtmlInput)
200:                            && isInputButtonType((HtmlInput) element)) {
201:                        buttons.add(element);
202:                    } else if (element instanceof  HtmlButton) {
203:                        buttons.add(element);
204:                    }
205:                }
206:
207:                if (buttons.isEmpty())
208:                    return "none";
209:                else
210:                    return buttons.toString();
211:            }
212:
213:            protected String getLogMessageForTarget() {
214:                return "by clickButton with name: " + getName();
215:            }
216:
217:            protected void verifyParameters() {
218:                super .verifyParameters();
219:                nullResponseCheck();
220:
221:                paramCheck((StringUtils.isEmpty(getX()) && !StringUtils
222:                        .isEmpty(getY()))
223:                        || (!StringUtils.isEmpty(getX()) && StringUtils
224:                                .isEmpty(getY())),
225:                        "X and Y values must be set for click button support!");
226:                paramCheck(getLabel() == null && fName == null
227:                        && getHtmlId() == null && getXpath() == null,
228:                        "Required parameter 'label', 'name', 'htmlid' or 'xpath' must be set!");
229:
230:                optionalIntegerParamCheck(getFieldIndex(), "fieldIndex", true);
231:                optionalIntegerParamCheck(getX(), "x", false);
232:                optionalIntegerParamCheck(getY(), "y", false);
233:            }
234:
235:            /**
236:             * Checks that the element is of the desired html type and has the right name and label (if needed)
237:             *
238:             * @param elt the button to check
239:             * @return the button if ok, <code>null</code> otherwise
240:             */
241:            ClickableElement checkFoundElement(final HtmlElement elt)
242:                    throws StepFailedException {
243:                // check that it is a "button"
244:                if (!isButton(elt)) {
245:                    throw new StepFailedException("Selected element is a "
246:                            + elt.getTagName() + " tag and not a button", this );
247:                }
248:
249:                if (hasMatchingNameOrDontCare(elt)
250:                        && hasMatchingLabelOrDontCare(elt)) {
251:                    LOG.debug("Button passes test with label and name");
252:                    return (ClickableElement) elt;
253:                }
254:                LOG.debug("Test with name and label fails for html button: "
255:                        + elt);
256:                return null;
257:            }
258:
259:            /**
260:             * Looks for the first button (that may be an input of type submit, image or button or a "normal" button)
261:             * in the given form corresponding to the criterias
262:             *
263:             * @param form the form in which the button should be searched
264:             * @return the button, <code>null</code> if not found
265:             */
266:            ClickableElement findButton(final HtmlForm form) {
267:                LOG
268:                        .debug("Looking for inputs of type submit, image or button in "
269:                                + form);
270:                ClickableElement button = findInputButton(form);
271:                if (button != null) {
272:                    return button;
273:                }
274:                LOG.debug("Looking for \"normal\" button in " + form);
275:                return findNormalButton(form);
276:            }
277:
278:            private ClickableElement findButtonAllForms(
279:                    final HtmlPage currentResp) {
280:                LOG
281:                        .debug("Looking for button in all forms contained in the document");
282:                List forms = currentResp.getForms();
283:                if (forms.size() == 0) {
284:                    LOG
285:                            .warn("No forms found - page probably non-compliant - searching page anyway");
286:                    return searchButton(currentResp);
287:                }
288:                for (final Iterator iter = forms.iterator(); iter.hasNext();) {
289:                    ClickableElement button = findButton((HtmlForm) iter.next());
290:                    if (button != null) {
291:                        return button;
292:                    }
293:                }
294:                return null;
295:            }
296:
297:            private static boolean isButton(HtmlElement elt) {
298:                if (elt instanceof  HtmlButton) {
299:                    LOG.debug("It's a button, that's ok");
300:                    return true;
301:                }
302:                if (elt instanceof  HtmlInput
303:                        && isInputButtonType((HtmlInput) elt)) {
304:                    LOG.debug("It's an "
305:                            + elt.getAttributeValue(HtmlConstants.TYPE)
306:                            + " input, that's ok");
307:                    return true;
308:                }
309:                LOG.debug("Html element is not a button");
310:                return false;
311:            }
312:
313:            private static boolean isInputButtonType(final HtmlInput input) {
314:                return INPUT_BUTTONS_TYPES.contains(input.getTypeAttribute()
315:                        .toLowerCase());
316:            }
317:
318:            private ClickableElement findInputButton(final HtmlForm form) {
319:                final Collection inputButtons = form
320:                        .getHtmlElementsByTagName(HtmlConstants.INPUT);
321:                return findInputButton(inputButtons.iterator());
322:            }
323:
324:            private ClickableElement searchButton(final HtmlPage page) {
325:                final Collection buttons = new ArrayList();
326:                final Iterator childElements = page.getAllHtmlChildElements();
327:                while (childElements.hasNext()) {
328:                    final HtmlElement elt = (HtmlElement) childElements.next();
329:                    if (isButton(elt)) {
330:                        buttons.add(elt);
331:                    }
332:                }
333:                ClickableElement button = findInputButton(buttons.iterator());
334:                if (button == null) {
335:                    button = findNormalButton(buttons.iterator());
336:                }
337:                return button;
338:            }
339:
340:            private ClickableElement findInputButton(
341:                    final Iterator candidateIterator) {
342:                int indexFound = 0; // should index be across both button types? currently not
343:                while (candidateIterator.hasNext()) {
344:                    final HtmlElement curElement = (HtmlElement) candidateIterator
345:                            .next();
346:                    if (!(curElement instanceof  HtmlInput)) {
347:                        continue;
348:                    }
349:                    final HtmlInput curInput = (HtmlInput) curElement;
350:                    if (!isInputButtonType(curInput)) {
351:                        continue; // not a "button"
352:                    }
353:                    LOG.debug("Examining button: " + curInput);
354:                    if (hasMatchingNameOrDontCare(curInput)
355:                            && hasMatchingLabelOrDontCare(curInput)) {
356:                        if (indexFound == ConversionUtil.convertToInt(
357:                                getFieldIndex(), 0)) {
358:                            LOG.debug(curInput.getTypeAttribute()
359:                                    + " button found: " + curInput);
360:                            return curInput;
361:                        }
362:                        ++indexFound;
363:                    }
364:                }
365:                return null;
366:            }
367:
368:            private ClickableElement findNormalButton(final HtmlForm form) {
369:                return findNormalButton(form.getAllHtmlChildElements());
370:            }
371:
372:            private ClickableElement findNormalButton(
373:                    final Iterator candidateIterator) {
374:                int indexFound = 0; // should index be across both button types? currently not
375:                while (candidateIterator.hasNext()) {
376:                    final HtmlElement curElement = (HtmlElement) candidateIterator
377:                            .next();
378:                    if (!(curElement instanceof  HtmlButton)) {
379:                        continue;
380:                    }
381:                    final HtmlButton curButton = (HtmlButton) curElement;
382:                    LOG.debug("Examining button: " + curButton);
383:                    if (hasMatchingNameOrDontCare(curButton)
384:                            && hasMatchingLabelOrDontCare(curButton)) {
385:                        if (indexFound == ConversionUtil.convertToInt(
386:                                getFieldIndex(), 0)) {
387:                            LOG.debug("Normal button found: " + curButton);
388:                            return curButton;
389:                        }
390:                        ++indexFound;
391:                    }
392:                }
393:                return null;
394:            }
395:
396:            private boolean hasMatchingNameOrDontCare(
397:                    final HtmlElement curButton) {
398:                if (curButton instanceof  HtmlInput) {
399:                    return hasMatchingNameOrDontCare((HtmlInput) curButton);
400:                }
401:                if (curButton instanceof  HtmlButton) {
402:                    return hasMatchingNameOrDontCare((HtmlButton) curButton);
403:                }
404:                throw new IllegalArgumentException(
405:                        "Button is neither a HtmlInput nor a HtmlButton: "
406:                                + curButton);
407:            }
408:
409:            private boolean hasMatchingNameOrDontCare(final HtmlInput curButton) {
410:                return getName() == null
411:                        || getName().equals(curButton.getNameAttribute());
412:            }
413:
414:            private boolean hasMatchingNameOrDontCare(final HtmlButton curButton) {
415:                return getName() == null
416:                        || getName().equals(curButton.getNameAttribute());
417:            }
418:
419:            private boolean hasMatchingLabelOrDontCare(
420:                    final HtmlElement curButton) {
421:                if (getLabel() == null)
422:                    return true;
423:                else if (curButton instanceof  HtmlImageInput) {
424:                    return getLabel().equals(
425:                            ((HtmlImageInput) curButton).getAltAttribute());
426:                } else {
427:                    return getLabel().equals(curButton.asText());
428:                }
429:            }
430:
431:            protected boolean isImageButton() {
432:                return !StringUtils.isEmpty(getX())
433:                        && !StringUtils.isEmpty(getY());
434:            }
435:
436:            /**
437:             * Called by Ant to set the text nested between opening and closing tags.
438:             * @param text the text to set
439:             * @webtest.nested.parameter
440:             *    required="no"
441:             *    description="Alternative way to set the 'label' attribute."
442:             */
443:            public void addText(final String text) {
444:                setLabel(getProject().replaceProperties(text));
445:            }
446:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.