Source Code Cross Referenced for WicketTester.java in  » J2EE » wicket » wicket » util » tester » 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 » J2EE » wicket » wicket.util.tester 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $Id: WicketTester.java 471275 2006-11-04 22:11:25Z frankbille $
0003:         * $Revision: 471275 $
0004:         * $Date: 2006-11-04 23:11:25 +0100 (Sat, 04 Nov 2006) $
0005:         * 
0006:         * ==============================================================================
0007:         * Licensed under the Apache License, Version 2.0 (the "License"); you may not
0008:         * use this file except in compliance with the License. You may obtain a copy of
0009:         * the License at
0010:         * 
0011:         * http://www.apache.org/licenses/LICENSE-2.0
0012:         * 
0013:         * Unless required by applicable law or agreed to in writing, software
0014:         * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
0015:         * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
0016:         * License for the specific language governing permissions and limitations under
0017:         * the License.
0018:         */
0019:        package wicket.util.tester;
0020:
0021:        import java.lang.reflect.Constructor;
0022:        import java.lang.reflect.Field;
0023:        import java.lang.reflect.InvocationTargetException;
0024:        import java.util.ArrayList;
0025:        import java.util.Arrays;
0026:        import java.util.Iterator;
0027:        import java.util.List;
0028:
0029:        import junit.framework.Assert;
0030:
0031:        import org.apache.commons.logging.Log;
0032:        import org.apache.commons.logging.LogFactory;
0033:
0034:        import wicket.Component;
0035:        import wicket.Page;
0036:        import wicket.PageParameters;
0037:        import wicket.RequestCycle;
0038:        import wicket.WicketRuntimeException;
0039:        import wicket.ajax.AjaxEventBehavior;
0040:        import wicket.ajax.AjaxRequestTarget;
0041:        import wicket.ajax.form.AjaxFormSubmitBehavior;
0042:        import wicket.ajax.markup.html.AjaxFallbackLink;
0043:        import wicket.ajax.markup.html.AjaxLink;
0044:        import wicket.ajax.markup.html.form.AjaxSubmitLink;
0045:        import wicket.behavior.IBehavior;
0046:        import wicket.feedback.FeedbackMessage;
0047:        import wicket.feedback.FeedbackMessages;
0048:        import wicket.feedback.IFeedbackMessageFilter;
0049:        import wicket.markup.html.basic.Label;
0050:        import wicket.markup.html.form.Button;
0051:        import wicket.markup.html.form.CheckGroup;
0052:        import wicket.markup.html.form.Form;
0053:        import wicket.markup.html.form.FormComponent;
0054:        import wicket.markup.html.form.RadioGroup;
0055:        import wicket.markup.html.link.BookmarkablePageLink;
0056:        import wicket.markup.html.link.IPageLink;
0057:        import wicket.markup.html.link.Link;
0058:        import wicket.markup.html.link.PageLink;
0059:        import wicket.markup.html.list.ListView;
0060:        import wicket.markup.html.panel.Panel;
0061:        import wicket.protocol.http.MockWebApplication;
0062:        import wicket.util.lang.Classes;
0063:        import wicket.util.string.Strings;
0064:
0065:        /**
0066:         * A helper to ease unit testing of Wicket applications without the need for a
0067:         * servlet container. To start a test, we can use either startPage() or
0068:         * startPanel():
0069:         * 
0070:         * <pre>
0071:         * // production page  
0072:         * public class MyPage extends WebPage
0073:         * {
0074:         * 	public MyPage()
0075:         * 	{
0076:         * 		add(new Label(&quot;myMessage&quot;, &quot;Hello!&quot;));
0077:         * 		add(new Link(&quot;toYourPage&quot;)
0078:         * 		{
0079:         * 			public void onClick()
0080:         * 			{
0081:         * 				setResponsePage(new YourPage(&quot;Hi!&quot;));
0082:         * 			}
0083:         * 		});
0084:         * 	}
0085:         * }
0086:         * </pre>
0087:         * 
0088:         * <pre>
0089:         * // test code
0090:         * private WicketTester tester;
0091:         * 
0092:         * public void setUp()
0093:         * {
0094:         * 	tester = new WicketTester();
0095:         * }
0096:         * 
0097:         * public void testRenderMyPage()
0098:         * {
0099:         * 	//start and render the test page
0100:         * 	tester.startPage(MyPage.class);
0101:         * 
0102:         * 	//assert rendered page class
0103:         * 	tester.assertRenderedPage(MyPage.class);
0104:         * 
0105:         * 	//assert rendered label component 
0106:         * 	tester.assertLabel(&quot;myMessage&quot;, &quot;Hello!&quot;);
0107:         * }
0108:         * </pre>
0109:         * 
0110:         * Above example is straight forward: start MyPage.class and assert Label it
0111:         * rendered. Next, we try to navigate through link:
0112:         * 
0113:         * <pre>
0114:         * // production page  
0115:         * public class YourPage extends WebPage
0116:         * {
0117:         * 	public YourPage(String message)
0118:         * 	{
0119:         * 		add(new Label(&quot;yourMessage&quot;, message));
0120:         * 		info(&quot;Wicket Rocks ;-)&quot;);
0121:         * 	}
0122:         * }
0123:         * 
0124:         * //test code
0125:         * public void testLinkToYourPage()
0126:         * {
0127:         * 	tester.startPage(MyPage.class);
0128:         * 
0129:         * 	//click link and render
0130:         * 	tester.clickLink(&quot;toYourPage&quot;);
0131:         * 
0132:         * 	tester.assertRenderedPage(YourPage.class);
0133:         * 	tester.assertLabel(&quot;yourMessage&quot;, &quot;Hi!&quot;);
0134:         * }
0135:         * </pre>
0136:         * 
0137:         * <code>tester.clickLink(path);</code> will simulate user click on the
0138:         * component (in this case, it's a <code>Link</code>) and render the response
0139:         * page <code>YourPage</code>. Ok, unit test of <code>MyPage</code> is
0140:         * completed. Now we test <code>YourPage</code> standalone:
0141:         * 
0142:         * <pre>
0143:         * //test code
0144:         * public void testRenderYourPage()
0145:         * {
0146:         * 	// provide page instance source for WicketTester
0147:         * 	tester.startPage(new TestPageSource()
0148:         * 	{
0149:         * 		public Page getTestPage()
0150:         * 		{
0151:         * 			return new YourPage(&quot;mock message&quot;);
0152:         * 		}
0153:         * 	});
0154:         * 
0155:         * 	tester.assertRenderedPage(YourPage.class);
0156:         * 	tester.assertLabel(&quot;yourMessage&quot;, &quot;mock message&quot;);
0157:         * 
0158:         * 	// assert feedback messages in INFO Level 
0159:         * 	tester.assertInfoMessages(new String[] { &quot;Wicket Rocks ;-)&quot; });
0160:         * 
0161:         * }
0162:         * </pre>
0163:         * 
0164:         * Instead of <code>tester.startPage(pageClass)</code>, we define a
0165:         * {@link wicket.util.tester.ITestPageSource} to provide testing page instance
0166:         * for WicketTester. This is necessary because <code>YourPage</code> uses a
0167:         * custom constructor, which is very common for transfering model data, can not
0168:         * be instansiated by reflection. Finally, we use
0169:         * <code>assertInfoMessages</code> to assert there is a feedback message
0170:         * "Wicket Rocks ;-)" in INFO level.
0171:         * 
0172:         * TODO General: Example usage of FormTester
0173:         * 
0174:         * @author Ingram Chen
0175:         * @author Juergen Donnerstag
0176:         * @author Frank Bille
0177:         */
0178:        public class WicketTester extends MockWebApplication {
0179:            /** log. */
0180:            private static final Log log = LogFactory
0181:                    .getLog(WicketTester.class);
0182:
0183:            /**
0184:             * create WicketTester with null path
0185:             * 
0186:             * @see #WicketTester(String)
0187:             */
0188:            public WicketTester() {
0189:                this (null);
0190:            }
0191:
0192:            /**
0193:             * create a WicketTester to help unit testing.
0194:             * 
0195:             * @param path
0196:             *            The absolute path on disk to the web application contents
0197:             *            (e.g. war root) - may be null
0198:             * 
0199:             * @see wicket.protocol.http.MockWebApplication#MockWebApplication(String)
0200:             */
0201:            public WicketTester(final String path) {
0202:                super (path);
0203:            }
0204:
0205:            /**
0206:             * Render a page defined in <code>TestPageSource</code>. This usually
0207:             * used when a page does not have default consturctor. For example, a
0208:             * <code>ViewBook</code> page requires a <code>Book</code> instance:
0209:             * 
0210:             * <pre>
0211:             * tester.startPage(new TestPageSource()
0212:             * {
0213:             * 	public Page getTestPage()
0214:             * 	{
0215:             * 		Book mockBook = new Book(&quot;myBookName&quot;);
0216:             * 		return new ViewBook(mockBook);
0217:             * 	}
0218:             * });
0219:             * </pre>
0220:             * 
0221:             * @param testPageSource
0222:             *            a page factory that creating test page instance
0223:             * @return Page rendered page
0224:             */
0225:            public final Page startPage(ITestPageSource testPageSource) {
0226:                setHomePage(DummyHomePage.class);
0227:                setupRequestAndResponse();
0228:                processRequestCycle();
0229:                DummyHomePage page = (DummyHomePage) getLastRenderedPage();
0230:                page.setTestPageSource(testPageSource);
0231:
0232:                newRequestToComponent(page.getTestPageLink());
0233:                return getLastRenderedPage();
0234:            }
0235:
0236:            /**
0237:             * 
0238:             * @param component
0239:             */
0240:            private void newRequestToComponent(Component component) {
0241:                setupRequestAndResponse();
0242:                getServletRequest().setRequestToComponent(component);
0243:                // getServletRequest().getSession().getPageMap(null);
0244:                processRequestCycle();
0245:            }
0246:
0247:            /**
0248:             * Render the page
0249:             * 
0250:             * @param page
0251:             * @return The page rendered
0252:             */
0253:            public final Page startPage(final Page page) {
0254:                setHomePage(DummyHomePage.class);
0255:                processRequestCycle(page);
0256:
0257:                Page last = getLastRenderedPage();
0258:
0259:                getWicketSession().touch(page);
0260:                if (page != last) {
0261:                    getWicketSession().touch(last);
0262:                }
0263:                return last;
0264:            }
0265:
0266:            /**
0267:             * Render a page from its default constructor.
0268:             * 
0269:             * @param pageClass
0270:             *            a test page class with default constructor
0271:             * @return Page Rendered Page
0272:             */
0273:            public final Page startPage(Class pageClass) {
0274:                setHomePage(pageClass);
0275:                setupRequestAndResponse();
0276:                processRequestCycle();
0277:                return getLastRenderedPage();
0278:            }
0279:
0280:            /**
0281:             * Render a panel defined in <code>TestPanelSource</code>. The usage is
0282:             * similar with {@link #startPage(ITestPageSource)}. Please note that
0283:             * testing panel must use supplied <code>panelId<code> as component id.
0284:             * 
0285:             * <pre>
0286:             * tester.startPanel(new TestPanelSource()
0287:             * {
0288:             * 	public Panel getTestPanel(String panelId)
0289:             * 	{
0290:             * 		MyData mockMyData = new MyData();
0291:             * 		return new MyPanel(panelId, mockMyData);
0292:             * 	}
0293:             * });
0294:             * </pre>
0295:             * 
0296:             * @param testPanelSource
0297:             *            a panel factory that creating test panel instance
0298:             * @return Panel rendered panel
0299:             */
0300:            public final Panel startPanel(final TestPanelSource testPanelSource) {
0301:                return (Panel) startPage(new ITestPageSource() {
0302:                    private static final long serialVersionUID = 1L;
0303:
0304:                    public Page getTestPage() {
0305:                        return new DummyPanelPage(testPanelSource);
0306:                    }
0307:                }).get(DummyPanelPage.TEST_PANEL_ID);
0308:            }
0309:
0310:            /**
0311:             * Render a panel from <code>Panel(String id)</code> constructor.
0312:             * 
0313:             * @param panelClass
0314:             *            a test panel class with <code>Panel(String id)</code>
0315:             *            constructor
0316:             * @return Panel rendered panel
0317:             */
0318:            public final Panel startPanel(final Class panelClass) {
0319:                return (Panel) startPage(new ITestPageSource() {
0320:                    private static final long serialVersionUID = 1L;
0321:
0322:                    public Page getTestPage() {
0323:                        return new DummyPanelPage(new TestPanelSource() {
0324:                            private static final long serialVersionUID = 1L;
0325:
0326:                            public Panel getTestPanel(String panelId) {
0327:                                try {
0328:                                    Constructor c = panelClass
0329:                                            .getConstructor(new Class[] { String.class });
0330:                                    return (Panel) c
0331:                                            .newInstance(new Object[] { panelId });
0332:                                } catch (SecurityException e) {
0333:                                    throw convertoUnexpect(e);
0334:                                } catch (NoSuchMethodException e) {
0335:                                    throw convertoUnexpect(e);
0336:                                } catch (InstantiationException e) {
0337:                                    throw convertoUnexpect(e);
0338:                                } catch (IllegalAccessException e) {
0339:                                    throw convertoUnexpect(e);
0340:                                } catch (InvocationTargetException e) {
0341:                                    throw convertoUnexpect(e);
0342:                                }
0343:                            }
0344:                        });
0345:                    }
0346:                }).get(DummyPanelPage.TEST_PANEL_ID);
0347:            }
0348:
0349:            /**
0350:             * Throw "standard" WicketRuntimeException
0351:             * 
0352:             * @param e
0353:             * @return RuntimeException
0354:             */
0355:            private RuntimeException convertoUnexpect(Exception e) {
0356:                return new WicketRuntimeException("tester: unexpected", e);
0357:            }
0358:
0359:            /**
0360:             * Gets the component with the given path from last rendered page. This
0361:             * method fails in case the component couldn't be found, and it will return
0362:             * null if the component was found, but is not visible.
0363:             * 
0364:             * @param path
0365:             *            Path to component
0366:             * @return The component at the path
0367:             * @see wicket.MarkupContainer#get(String)
0368:             */
0369:            public Component getComponentFromLastRenderedPage(String path) {
0370:                final Component component = getLastRenderedPage().get(path);
0371:                if (component == null) {
0372:                    Assert.fail("path: '"
0373:                            + path
0374:                            + "' does no exist for page: "
0375:                            + Classes.simpleName(getLastRenderedPage()
0376:                                    .getClass()));
0377:                    return component;
0378:                }
0379:                if (component.isVisibleInHierarchy()) {
0380:                    return component;
0381:                }
0382:                return null;
0383:            }
0384:
0385:            /**
0386:             * assert the text of <code>Label</code> component.
0387:             * 
0388:             * @param path
0389:             *            path to <code>Label</code> component
0390:             * @param expectedLabelText
0391:             *            expected label text
0392:             */
0393:            public void assertLabel(String path, String expectedLabelText) {
0394:                Label label = (Label) getComponentFromLastRenderedPage(path);
0395:                Assert.assertEquals(expectedLabelText, label
0396:                        .getModelObjectAsString());
0397:            }
0398:
0399:            /**
0400:             * assert <code>PageLink</code> link to page class.
0401:             * 
0402:             * @param path
0403:             *            path to <code>PageLink</code> component
0404:             * @param expectedPageClass
0405:             *            expected page class to link
0406:             */
0407:            public void assertPageLink(String path, Class expectedPageClass) {
0408:                PageLink pageLink = (PageLink) getComponentFromLastRenderedPage(path);
0409:                try {
0410:                    Field iPageLinkField = pageLink.getClass()
0411:                            .getDeclaredField("pageLink");
0412:                    iPageLinkField.setAccessible(true);
0413:                    IPageLink iPageLink = (IPageLink) iPageLinkField
0414:                            .get(pageLink);
0415:                    Assert.assertEquals(expectedPageClass, iPageLink
0416:                            .getPageIdentity());
0417:                } catch (SecurityException e) {
0418:                    throw convertoUnexpect(e);
0419:                } catch (NoSuchFieldException e) {
0420:                    throw convertoUnexpect(e);
0421:                } catch (IllegalAccessException e) {
0422:                    throw convertoUnexpect(e);
0423:                }
0424:            }
0425:
0426:            /**
0427:             * assert component class
0428:             * 
0429:             * @param path
0430:             *            path to component
0431:             * @param expectedComponentClass
0432:             *            expected component class
0433:             */
0434:            public void assertComponent(String path,
0435:                    Class expectedComponentClass) {
0436:                Component component = getComponentFromLastRenderedPage(path);
0437:                Assert.assertTrue("component '"
0438:                        + Classes.simpleName(component.getClass())
0439:                        + "' is not type:"
0440:                        + Classes.simpleName(expectedComponentClass),
0441:                        expectedComponentClass.isAssignableFrom(component
0442:                                .getClass()));
0443:            }
0444:
0445:            /**
0446:             * assert component visible.
0447:             * 
0448:             * @param path
0449:             *            path to component
0450:             */
0451:            public void assertVisible(String path) {
0452:                Component component = getLastRenderedPage().get(path);
0453:                if (component == null) {
0454:                    Assert.fail("path: '"
0455:                            + path
0456:                            + "' does no exist for page: "
0457:                            + Classes.simpleName(getLastRenderedPage()
0458:                                    .getClass()));
0459:                }
0460:
0461:                Assert.assertTrue("component '" + path + "' is not visible",
0462:                        component.isVisible());
0463:            }
0464:
0465:            /**
0466:             * assert component invisible.
0467:             * 
0468:             * @param path
0469:             *            path to component
0470:             */
0471:            public void assertInvisible(String path) {
0472:                Assert.assertNull("component '" + path + "' is visible",
0473:                        getComponentFromLastRenderedPage(path));
0474:            }
0475:
0476:            /**
0477:             * assert the content of last rendered page contains(matches) regex pattern.
0478:             * 
0479:             * @param pattern
0480:             *            reqex pattern to match
0481:             */
0482:            public void assertContains(String pattern) {
0483:                Assert.assertTrue("pattern '" + pattern + "' not found",
0484:                        getServletResponse().getDocument().matches(
0485:                                "(?s).*" + pattern + ".*"));
0486:            }
0487:
0488:            /**
0489:             * assert the model of {@link ListView} use expectedList
0490:             * 
0491:             * @param path
0492:             *            path to {@link ListView} component
0493:             * @param expectedList
0494:             *            expected list in the model of {@link ListView}
0495:             */
0496:            public void assertListView(String path, List expectedList) {
0497:                ListView listView = (ListView) getComponentFromLastRenderedPage(path);
0498:                WicketTesterHelper.assertEquals(expectedList, listView
0499:                        .getList());
0500:            }
0501:
0502:            /**
0503:             * create a {@link FormTester} for the form at path, and fill all child
0504:             * {@link wicket.markup.html.form.FormComponent}s with blank String
0505:             * initially.
0506:             * 
0507:             * @param path
0508:             *            path to {@link Form} component
0509:             * @return FormTester A FormTester instance for testing form
0510:             * @see #newFormTester(String, boolean)
0511:             */
0512:            public FormTester newFormTester(String path) {
0513:                return newFormTester(path, true);
0514:            }
0515:
0516:            /**
0517:             * create a {@link FormTester} for the form at path.
0518:             * 
0519:             * @param path
0520:             *            path to {@link Form} component
0521:             * @param fillBlankString
0522:             *            specify whether fill all child
0523:             *            {@link wicket.markup.html.form.FormComponent}s with
0524:             *            blankString initially.
0525:             * @return FormTester A FormTester instance for testing form
0526:             * @see FormTester
0527:             */
0528:            public FormTester newFormTester(String path, boolean fillBlankString) {
0529:                return new FormTester(path,
0530:                        (Form) getComponentFromLastRenderedPage(path), this ,
0531:                        fillBlankString);
0532:            }
0533:
0534:            /**
0535:             * Click the {@link Link} in the last rendered Page.
0536:             * <p>
0537:             * Simulate that AJAX is enabled.
0538:             * 
0539:             * @see WicketTester#clickLink(String, boolean)
0540:             * @param path
0541:             *            Click the <code>Link</code> in the last rendered Page.
0542:             */
0543:            public void clickLink(String path) {
0544:                clickLink(path, true);
0545:            }
0546:
0547:            /**
0548:             * Click the {@link Link} in the last rendered Page.
0549:             * <p>
0550:             * This method also works for {@link AjaxLink}, {@link AjaxFallbackLink}
0551:             * and {@link AjaxSubmitLink}.
0552:             * <p>
0553:             * On AjaxLinks and AjaxFallbackLinks the onClick method is invoked with a
0554:             * valid AjaxRequestTarget. In that way you can test the flow of your
0555:             * application when using AJAX.
0556:             * <p>
0557:             * When clicking an AjaxSubmitLink the form, which the AjaxSubmitLink is
0558:             * attached to is first submitted, and then the onSubmit method on
0559:             * AjaxSubmitLink is invoked. If you have changed some values in the form
0560:             * during your test, these will also be submitted. This should not be used
0561:             * as a replacement for the {@link FormTester} to test your forms. It should
0562:             * be used to test that the code in your onSubmit method in AjaxSubmitLink
0563:             * actually works.
0564:             * <p>
0565:             * This method is also able to simulate that AJAX (javascript) is disabled
0566:             * on the client. This is done by setting the isAjax parameter to false. If
0567:             * you have an AjaxFallbackLink you can then check that it doesn't fail when
0568:             * invoked as a normal link.
0569:             * 
0570:             * @param path
0571:             *            path to <code>Link</code> component
0572:             * @param isAjax
0573:             *            Whether to simulate that AJAX (javascript) is enabled or not.
0574:             *            If it's false then AjaxLink and AjaxSubmitLink will fail,
0575:             *            since it wouldn't work in real life. AjaxFallbackLink will be
0576:             *            invoked with null as the AjaxRequestTarget parameter.
0577:             */
0578:            public void clickLink(String path, boolean isAjax) {
0579:                Component linkComponent = getComponentFromLastRenderedPage(path);
0580:
0581:                // if the link is an AjaxLink, we process it differently
0582:                // than a normal link
0583:                if (linkComponent instanceof  AjaxLink) {
0584:                    // If it's not ajax we fail
0585:                    if (isAjax == false) {
0586:                        Assert
0587:                                .fail("Link "
0588:                                        + path
0589:                                        + "is an AjaxLink and will "
0590:                                        + "not be invoked when AJAX (javascript) is disabled.");
0591:                    }
0592:
0593:                    AjaxLink link = (AjaxLink) linkComponent;
0594:
0595:                    setupRequestAndResponse();
0596:                    RequestCycle requestCycle = createRequestCycle();
0597:                    AjaxRequestTarget target = new AjaxRequestTarget();
0598:                    requestCycle.setRequestTarget(target);
0599:
0600:                    link.onClick(target);
0601:
0602:                    // process the request target
0603:                    target.respond(requestCycle);
0604:                }
0605:                // AjaxFallbackLinks is processed like an AjaxLink if isAjax is true
0606:                // If it's not handling of the linkComponent is passed through to the
0607:                // Link.
0608:                else if (linkComponent instanceof  AjaxFallbackLink && isAjax) {
0609:                    AjaxFallbackLink link = (AjaxFallbackLink) linkComponent;
0610:
0611:                    setupRequestAndResponse();
0612:                    RequestCycle requestCycle = createRequestCycle();
0613:                    AjaxRequestTarget target = new AjaxRequestTarget();
0614:                    requestCycle.setRequestTarget(target);
0615:
0616:                    link.onClick(target);
0617:
0618:                    // process the request target
0619:                    target.respond(requestCycle);
0620:                }
0621:                // if the link is an AjaxSubmitLink, we need to find the form
0622:                // from it using reflection so we know what to submit.
0623:                else if (linkComponent instanceof  AjaxSubmitLink) {
0624:                    // If it's not ajax we fail
0625:                    if (isAjax == false) {
0626:                        Assert
0627:                                .fail("Link "
0628:                                        + path
0629:                                        + "is an AjaxSubmitLink and "
0630:                                        + "will not be invoked when AJAX (javascript) is disabled.");
0631:                    }
0632:
0633:                    AjaxSubmitLink link = (AjaxSubmitLink) linkComponent;
0634:
0635:                    // We cycle through the attached behaviors and select the
0636:                    // LAST matching behavior as the one we handle.
0637:                    List behaviors = link.getBehaviors();
0638:                    AjaxFormSubmitBehavior ajaxFormSubmitBehavior = null;
0639:                    for (Iterator iter = behaviors.iterator(); iter.hasNext();) {
0640:                        Object behavior = iter.next();
0641:
0642:                        if (behavior instanceof  AjaxFormSubmitBehavior) {
0643:                            AjaxFormSubmitBehavior submitBehavior = (AjaxFormSubmitBehavior) behavior;
0644:                            ajaxFormSubmitBehavior = submitBehavior;
0645:                        }
0646:                    }
0647:
0648:                    String failMessage = "No form submit behavior found on the submit link. Strange!!";
0649:                    Assert.assertNotNull(failMessage, ajaxFormSubmitBehavior);
0650:
0651:                    setupRequestAndResponse();
0652:                    RequestCycle requestCycle = createRequestCycle();
0653:
0654:                    submitAjaxFormSubmitBehavior(ajaxFormSubmitBehavior);
0655:
0656:                    // Ok, finally we "click" the link
0657:                    ajaxFormSubmitBehavior.onRequest();
0658:
0659:                    // process the request target
0660:                    requestCycle.getRequestTarget().respond(requestCycle);
0661:                }
0662:                // if the link is a normal link
0663:                else if (linkComponent instanceof  Link) {
0664:                    Link link = (Link) linkComponent;
0665:
0666:                    /*
0667:                     * If the link is a bookmarkable link, then we need to transfer the
0668:                     * parameters to the next request.
0669:                     */
0670:                    if (link instanceof  BookmarkablePageLink) {
0671:                        BookmarkablePageLink bookmarkablePageLink = (BookmarkablePageLink) link;
0672:                        try {
0673:                            Field parametersField = BookmarkablePageLink.class
0674:                                    .getDeclaredField("parameters");
0675:                            parametersField.setAccessible(true);
0676:                            PageParameters parameters = (PageParameters) parametersField
0677:                                    .get(bookmarkablePageLink);
0678:                            setParametersForNextRequest(parameters);
0679:                        } catch (Exception e) {
0680:                            Assert
0681:                                    .fail("Internal error in WicketTester. "
0682:                                            + "Please report this in Wickets Issue Tracker.");
0683:                        }
0684:
0685:                    }
0686:
0687:                    newRequestToComponent(link);
0688:                } else {
0689:                    Assert
0690:                            .fail("Link "
0691:                                    + path
0692:                                    + " is not a Link, AjaxLink, AjaxFallbackLink or AjaxSubmitLink");
0693:                }
0694:            }
0695:
0696:            /**
0697:             * submit the <code>Form</code> in the last rendered Page.
0698:             * 
0699:             * @param path
0700:             *            path to <code>Form</code> component
0701:             */
0702:            public void submitForm(String path) {
0703:                Form form = (Form) getComponentFromLastRenderedPage(path);
0704:                newRequestToComponent(form);
0705:            }
0706:
0707:            /**
0708:             * Sets a parameter for the component with the given path to be used with
0709:             * the next request. NOTE: this method only works when a page was rendered
0710:             * first.
0711:             * 
0712:             * @param componentPath
0713:             *            path of the component
0714:             * @param value
0715:             *            the parameter value to set
0716:             */
0717:            public void setParameterForNextRequest(String componentPath,
0718:                    Object value) {
0719:                if (getLastRenderedPage() == null) {
0720:                    Assert
0721:                            .fail("before using this method, at least one page has to be rendered");
0722:                }
0723:
0724:                Component c = getComponentFromLastRenderedPage(componentPath);
0725:                if (c == null) {
0726:                    Assert
0727:                            .fail("component " + componentPath
0728:                                    + " was not found");
0729:                    return;
0730:                }
0731:
0732:                if (c instanceof  FormComponent) {
0733:                    getParametersForNextRequest().put(
0734:                            ((FormComponent) c).getInputName(), value);
0735:                } else {
0736:                    getParametersForNextRequest().put(c.getPath(), value);
0737:                }
0738:
0739:            }
0740:
0741:            /**
0742:             * assert last rendered Page class
0743:             * 
0744:             * @param expectedReneredPageClass
0745:             *            expected class of last renered page
0746:             */
0747:            public void assertRenderedPage(Class expectedReneredPageClass) {
0748:                if (!getLastRenderedPage().getClass().isAssignableFrom(
0749:                        expectedReneredPageClass)) {
0750:                    Assert.assertEquals(Classes
0751:                            .simpleName(expectedReneredPageClass), Classes
0752:                            .simpleName(getLastRenderedPage().getClass()));
0753:                }
0754:            }
0755:
0756:            /**
0757:             * assert no error feedback messages
0758:             */
0759:            public void assertNoErrorMessage() {
0760:                List messages = getMessages(FeedbackMessage.ERROR);
0761:                Assert.assertTrue("expect no error message, but contains\n"
0762:                        + WicketTesterHelper.asLined(messages), messages
0763:                        .isEmpty());
0764:            }
0765:
0766:            /**
0767:             * assert no info feedback messages
0768:             */
0769:            public void assertNoInfoMessage() {
0770:                List messages = getMessages(FeedbackMessage.INFO);
0771:                Assert.assertTrue("expect no info message, but contains\n"
0772:                        + WicketTesterHelper.asLined(messages), messages
0773:                        .isEmpty());
0774:            }
0775:
0776:            /**
0777:             * assert error feedback messages
0778:             * 
0779:             * @param expectedErrorMessages
0780:             *            expected error messages
0781:             */
0782:            public void assertErrorMessages(String[] expectedErrorMessages) {
0783:                List actualMessages = getMessages(FeedbackMessage.ERROR);
0784:                WicketTesterHelper.assertEquals(Arrays
0785:                        .asList(expectedErrorMessages), actualMessages);
0786:            }
0787:
0788:            /**
0789:             * assert info feedback message
0790:             * 
0791:             * @param expectedInfoMessages
0792:             *            expected info messages
0793:             */
0794:            public void assertInfoMessages(String[] expectedInfoMessages) {
0795:                List actualMessages = getMessages(FeedbackMessage.INFO);
0796:                WicketTesterHelper.assertEquals(Arrays
0797:                        .asList(expectedInfoMessages), actualMessages);
0798:            }
0799:
0800:            /**
0801:             * get feedback messages
0802:             * 
0803:             * @param level
0804:             *            level of feedback message, ex.
0805:             *            <code>FeedbackMessage.DEBUG or FeedbackMessage.INFO.. etc</code>
0806:             * @return List list of messages (in String)
0807:             * @see FeedbackMessage
0808:             */
0809:            public List getMessages(final int level) {
0810:                FeedbackMessages feedbackMessages = getLastRenderedPage()
0811:                        .getFeedbackMessages();
0812:                List allMessages = feedbackMessages
0813:                        .messages(new IFeedbackMessageFilter() {
0814:                            private static final long serialVersionUID = 1L;
0815:
0816:                            public boolean accept(FeedbackMessage message) {
0817:                                return message.getLevel() == level;
0818:                            }
0819:                        });
0820:                List actualMessages = new ArrayList();
0821:                for (Iterator iter = allMessages.iterator(); iter.hasNext();) {
0822:                    actualMessages.add(((FeedbackMessage) iter.next())
0823:                            .getMessage());
0824:                }
0825:                return actualMessages;
0826:            }
0827:
0828:            /**
0829:             * assert previous rendered page expired
0830:             * 
0831:             * TODO Post 1.2: General: This test is no longer valid because it depends
0832:             * on an implementation detail that just changed!
0833:             * 
0834:             * public void assertExpirePreviousPage() { PageMap pageMap =
0835:             * getWicketSession().getPageMap(null); Field internalMapCacheField; try {
0836:             * internalMapCacheField = pageMap.getClass().getDeclaredField("pages");
0837:             * internalMapCacheField.setAccessible(true); MostRecentlyUsedMap mru =
0838:             * (MostRecentlyUsedMap)internalMapCacheField.get(pageMap);
0839:             * Assert.assertFalse("Previous Page '" +
0840:             * Classes.name(getPreviousRenderedPage().getClass()) + "' not expire", mru
0841:             * .containsValue(getPreviousRenderedPage())); } catch (SecurityException e) {
0842:             * throw convertoUnexpect(e); } catch (NoSuchFieldException e) { throw
0843:             * convertoUnexpect(e); } catch (IllegalAccessException e) { throw
0844:             * convertoUnexpect(e); } }
0845:             */
0846:
0847:            /**
0848:             * dump the source of last rendered page
0849:             */
0850:            public void dumpPage() {
0851:                log.info(getServletResponse().getDocument());
0852:            }
0853:
0854:            /**
0855:             * dump component tree
0856:             */
0857:            public void debugComponentTrees() {
0858:                debugComponentTrees("");
0859:            }
0860:
0861:            /**
0862:             * Dump the component trees to log.
0863:             * 
0864:             * @param filter
0865:             *            Show only the components, which path contains the
0866:             *            filterstring.
0867:             */
0868:            public void debugComponentTrees(String filter) {
0869:                log
0870:                        .info("debugging ----------------------------------------------");
0871:                for (Iterator iter = WicketTesterHelper.getComponentData(
0872:                        getLastRenderedPage()).iterator(); iter.hasNext();) {
0873:                    WicketTesterHelper.ComponentData obj = (WicketTesterHelper.ComponentData) iter
0874:                            .next();
0875:                    if (obj.path.matches(".*" + filter + ".*")) {
0876:                        log.info("path\t" + obj.path + " \t" + obj.type
0877:                                + " \t[" + obj.value + "]");
0878:                    }
0879:                }
0880:            }
0881:
0882:            /**
0883:             * Test that a component has been added to a AjaxRequestTarget, using
0884:             * {@link AjaxRequestTarget#addComponent(Component)}. This method actually
0885:             * tests that a component is on the AJAX response sent back to the client.
0886:             * <p>
0887:             * PLEASE NOTE! This method doesn't actually insert the component in the
0888:             * client DOM tree, using javascript. But it shouldn't be needed because you
0889:             * have to trust that the Wicket Ajax Javascript just works.
0890:             * 
0891:             * @param component
0892:             *            The component to test whether it's on the response.
0893:             */
0894:            public void assertComponentOnAjaxResponse(Component component) {
0895:                String failMessage = "A component which is null could not have been added to the AJAX response";
0896:                Assert.assertNotNull(failMessage, component);
0897:
0898:                // Get the AJAX response
0899:                String ajaxResponse = getServletResponse().getDocument();
0900:
0901:                // Test that the previous response was actually a AJAX response
0902:                failMessage = "The Previous response was not an AJAX response. "
0903:                        + "You need to execute an AJAX event, using clickLink, before using this assert";
0904:                boolean isAjaxResponse = ajaxResponse
0905:                        .startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?><ajax-response>");
0906:                Assert.assertTrue(failMessage, isAjaxResponse);
0907:
0908:                // See if the component has a markup id
0909:                String markupId = component.getMarkupId();
0910:
0911:                failMessage = "The component doesn't have a markup id, "
0912:                        + "which means that it can't have been added to the AJAX response";
0913:                Assert.assertFalse(failMessage, Strings.isEmpty(markupId));
0914:
0915:                // Look for that the component is on the response, using the markup id
0916:                boolean isComponentInAjaxResponse = ajaxResponse
0917:                        .matches(".*<component id=\"" + markupId + "\" ?>.*");
0918:                failMessage = "Component wasn't found in the AJAX response";
0919:                Assert.assertTrue(failMessage, isComponentInAjaxResponse);
0920:            }
0921:
0922:            /**
0923:             * Simulate that an AJAX event has been fired.
0924:             * 
0925:             * @see #executeAjaxEvent(Component, String)
0926:             * 
0927:             * @since 1.2.3
0928:             * @param componentPath
0929:             *            The component path.
0930:             * @param event
0931:             *            The event which we simulate is fired. If the event is null,
0932:             *            the test will fail.
0933:             */
0934:            public void executeAjaxEvent(String componentPath, String event) {
0935:                Component component = getComponentFromLastRenderedPage(componentPath);
0936:                executeAjaxEvent(component, event);
0937:            }
0938:
0939:            /**
0940:             * Simulate that an AJAX event has been fired. You add an AJAX event to a
0941:             * component by using:
0942:             * 
0943:             * <pre>
0944:             *    ...
0945:             *    component.add(new AjaxEventBehavior(&quot;ondblclick&quot;) {
0946:             *        public void onEvent(AjaxRequestTarget) {
0947:             *            // Do something.
0948:             *        }
0949:             *    });
0950:             *    ...
0951:             * </pre>
0952:             * 
0953:             * You can then test that the code inside onEvent actually does what it's
0954:             * supposed to, using the WicketTester:
0955:             * 
0956:             * <pre>
0957:             *    ...
0958:             *    tester.executeAjaxEvent(component, &quot;ondblclick&quot;);
0959:             *              
0960:             *    // Test that the code inside onEvent is correct.
0961:             *    ...
0962:             * </pre>
0963:             * 
0964:             * This also works with AjaxFormSubmitBehavior, where it will "submit" the
0965:             * form before executing the command.
0966:             * <p>
0967:             * PLEASE NOTE! This method doesn't actually insert the component in the
0968:             * client DOM tree, using javascript.
0969:             * 
0970:             * 
0971:             * @param component
0972:             *            The component which has the AjaxEventBehavior we wan't to
0973:             *            test. If the component is null, the test will fail.
0974:             * @param event
0975:             *            The event which we simulate is fired. If the event is null,
0976:             *            the test will fail.
0977:             */
0978:            public void executeAjaxEvent(Component component, String event) {
0979:                String failMessage = "Can't execute event on a component which is null.";
0980:                Assert.assertNotNull(failMessage, component);
0981:
0982:                failMessage = "event must not be null";
0983:                Assert.assertNotNull(failMessage, event);
0984:
0985:                // Run through all the behavior and select the LAST ADDED behavior which
0986:                // matches the event parameter.
0987:                AjaxEventBehavior ajaxEventBehavior = null;
0988:                List behaviors = component.getBehaviors();
0989:                for (Iterator iter = behaviors.iterator(); iter.hasNext();) {
0990:                    IBehavior behavior = (IBehavior) iter.next();
0991:
0992:                    // AjaxEventBehavior is the one to look for
0993:                    if (behavior instanceof  AjaxEventBehavior) {
0994:                        AjaxEventBehavior tmp = (AjaxEventBehavior) behavior;
0995:
0996:                        if (event.equals(tmp.getEvent())) {
0997:                            ajaxEventBehavior = tmp;
0998:                        }
0999:                    }
1000:                }
1001:
1002:                // If there haven't been found any event behaviors on the component
1003:                // which maches the parameters we fail.
1004:                failMessage = "No AjaxEventBehavior found on component: "
1005:                        + component.getId() + " which matches the event: "
1006:                        + event.toString();
1007:                Assert.assertNotNull(failMessage, ajaxEventBehavior);
1008:
1009:                setupRequestAndResponse();
1010:                RequestCycle requestCycle = createRequestCycle();
1011:
1012:                // If the event is an FormSubmitBehavior then also "submit" the form
1013:                if (ajaxEventBehavior instanceof  AjaxFormSubmitBehavior) {
1014:                    AjaxFormSubmitBehavior ajaxFormSubmitBehavior = (AjaxFormSubmitBehavior) ajaxEventBehavior;
1015:                    submitAjaxFormSubmitBehavior(ajaxFormSubmitBehavior);
1016:                }
1017:
1018:                ajaxEventBehavior.onRequest();
1019:
1020:                // process the request target
1021:                requestCycle.getRequestTarget().respond(requestCycle);
1022:            }
1023:
1024:            /**
1025:             * Get a TagTester based on a wicket:id. If more components exists with the
1026:             * same wicket:id in the markup only the first one is returned.
1027:             * 
1028:             * @param wicketId
1029:             *            The wicket:id to search for.
1030:             * @return The TagTester for the tag which has the given wicket:id.
1031:             */
1032:            public TagTester getTagByWicketId(String wicketId) {
1033:                return TagTester.createTagByAttribute(getServletResponse()
1034:                        .getDocument(), "wicket:id", wicketId);
1035:            }
1036:
1037:            /**
1038:             * Get a TagTester based on an dom id. If more components exists with the
1039:             * same id in the markup only the first one is returned.
1040:             * 
1041:             * @param id
1042:             *            The dom id to search for.
1043:             * @return The TagTester for the tag which has the given dom id.
1044:             */
1045:            public TagTester getTagById(String id) {
1046:                return TagTester.createTagByAttribute(getServletResponse()
1047:                        .getDocument(), "id", id);
1048:            }
1049:
1050:            /**
1051:             * Helper method for all the places where an AjaxCall should submit an
1052:             * associated form.
1053:             * 
1054:             * @param behavior
1055:             *            The AjaxFormSubmitBehavior with the form to "submit"
1056:             */
1057:            private void submitAjaxFormSubmitBehavior(
1058:                    AjaxFormSubmitBehavior behavior) {
1059:                // We need to get the form submitted, using reflection.
1060:                // It needs to be "submitted".
1061:                Form form = null;
1062:                try {
1063:                    Field formField = AjaxFormSubmitBehavior.class
1064:                            .getDeclaredField("form");
1065:                    formField.setAccessible(true);
1066:                    form = (Form) formField.get(behavior);
1067:                } catch (Exception e) {
1068:                    Assert.fail(e.getMessage());
1069:                }
1070:
1071:                String failMessage = "No form attached to the submitlink.";
1072:                Assert.assertNotNull(failMessage, form);
1073:
1074:                form.visitFormComponents(new FormComponent.IVisitor() {
1075:                    public void formComponent(FormComponent formComponent) {
1076:                        if (!(formComponent instanceof  Button)
1077:                                && !(formComponent instanceof  RadioGroup)
1078:                                && !(formComponent instanceof  CheckGroup)) {
1079:                            String name = formComponent.getInputName();
1080:                            String value = formComponent.getValue();
1081:
1082:                            getServletRequest().setParameter(name, value);
1083:                        }
1084:                    }
1085:                });
1086:            }
1087:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.