0001: // Copyright 2006, 2007 The Apache Software Foundation
0002: //
0003: // Licensed under the Apache License, Version 2.0 (the "License");
0004: // you may not use this file except in compliance with the License.
0005: // You may obtain a copy of the License at
0006: //
0007: // http://www.apache.org/licenses/LICENSE-2.0
0008: //
0009: // Unless required by applicable law or agreed to in writing, software
0010: // distributed under the License is distributed on an "AS IS" BASIS,
0011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012: // See the License for the specific language governing permissions and
0013: // limitations under the License.
0014:
0015: package org.apache.tapestry.integration;
0016:
0017: import java.io.BufferedInputStream;
0018: import java.io.ByteArrayOutputStream;
0019: import java.io.InputStream;
0020: import java.net.URL;
0021:
0022: import org.apache.tapestry.corelib.mixins.RenderDisabled;
0023: import org.apache.tapestry.internal.services.InjectComponentWorker;
0024: import org.apache.tapestry.ioc.Resource;
0025: import org.apache.tapestry.ioc.internal.util.ClasspathResource;
0026: import org.apache.tapestry.test.AbstractIntegrationTestSuite;
0027: import org.testng.annotations.Test;
0028:
0029: /**
0030: * Note: If these tests fail with BindException when starting Jetty, it could be Skype. At least on
0031: * my system, Skype is listening on localhost:80.
0032: */
0033: @Test(timeOut=50000,sequential=true,groups={"integration"})
0034: public class IntegrationTests extends AbstractIntegrationTestSuite {
0035: public IntegrationTests() {
0036: super ("src/test/app1");
0037: }
0038:
0039: @Test
0040: public void assets() throws Exception {
0041: open(BASE_URL);
0042: clickAndWait("link=AssetDemo");
0043:
0044: assertText("//img[@id='icon']/@src",
0045: "/images/tapestry_banner.gif");
0046:
0047: // This doesn't prove that the image shows up in the client browser (it does, but
0048: // it could just as easily be a broken image). Haven't figured out how Selenium
0049: // allows this to be verified. Note that the path below represents some aliasing
0050: // of the raw classpath resource path.
0051:
0052: assertText("//img[@id='button']/@src",
0053: "/assets/app1/pages/tapestry-button.png");
0054:
0055: // Read the byte stream for the asset and compare to the real copy.
0056:
0057: URL url = new URL("http", "localhost", JETTY_PORT,
0058: "/assets/app1/pages/tapestry-button.png");
0059:
0060: byte[] downloaded = readContent(url);
0061:
0062: Resource classpathResource = new ClasspathResource(
0063: "org/apache/tapestry/integration/app1/pages/tapestry-button.png");
0064:
0065: byte[] actual = readContent(classpathResource.toURL());
0066:
0067: assertEquals(downloaded, actual);
0068: }
0069:
0070: @Test
0071: public void basic_parameters() throws Exception {
0072:
0073: // OK ... this could be a separate test, but for efficiency, we'll mix it in here.
0074: // It takes a while to start up Selenium RC (and a Firefox browser).
0075:
0076: open(BASE_URL);
0077:
0078: clickAndWait("link=Count Page");
0079:
0080: assertTextPresent("Ho! Ho! Ho!");
0081: }
0082:
0083: /**
0084: * Tests the ability to inject a Block, and the ability to use the block to control rendering.
0085: */
0086: @Test
0087: public void block_rendering() throws Exception {
0088: open(BASE_URL);
0089: clickAndWait("link=BlockDemo");
0090:
0091: assertTextPresent("[]");
0092:
0093: select("//select[@id='blockName']", "fred");
0094: waitForPageToLoad(PAGE_LOAD_TIMEOUT);
0095:
0096: assertTextPresent("[Block fred.]");
0097:
0098: select("//select[@id='blockName']", "barney");
0099: waitForPageToLoad(PAGE_LOAD_TIMEOUT);
0100:
0101: assertTextPresent("[Block barney.]");
0102:
0103: // TAPESETRY-1583
0104:
0105: assertTextPresent("before it is defined: [Block wilma].");
0106: }
0107:
0108: @Test
0109: public void component_parameter_default_from_method()
0110: throws Exception {
0111: open(BASE_URL);
0112: clickAndWait("link=ParameterDefault");
0113:
0114: assertTextPresent("Echo component default: [ParameterDefault:echo]");
0115: }
0116:
0117: @Test
0118: public void embedded_components() {
0119: open(BASE_URL);
0120:
0121: clickAndWait("link=Countdown Page");
0122:
0123: assertTextPresent("regexp:\\s+5\\s+4\\s+3\\s+2\\s+1\\s+");
0124:
0125: assertTextPresent("Brought to you by the org.apache.tapestry.integration.app1.components.Count");
0126: }
0127:
0128: @Test
0129: public void encoded_loop_inside_a_form() {
0130: test_loop_inside_form("ToDo List");
0131: }
0132:
0133: @Test
0134: public void environmental() {
0135: open(BASE_URL);
0136:
0137: clickAndWait("link=Environmental Annotation Useage");
0138:
0139: assertSourcePresent("[<strong>A message provided by the RenderableProvider component.</strong>]");
0140: }
0141:
0142: @Test
0143: public void exception_report() {
0144: open(BASE_URL);
0145:
0146: clickAndWait("link=BadTemplate Page");
0147:
0148: assertTextPresent(
0149: "org.apache.tapestry.ioc.internal.util.TapestryException",
0150: "Failure parsing template classpath:org/apache/tapestry/integration/app1/pages/BadTemplate.html, line 7, column 15",
0151: "<t:foobar>content from template</t:foobar>",
0152: "Element <t:foobar> is in the Tapestry namespace, but is not a recognized Tapestry template element.");
0153: }
0154:
0155: @Test
0156: public void expansion() {
0157: open(BASE_URL);
0158:
0159: clickAndWait("link=Expansion Page");
0160:
0161: assertTextPresent("[value provided by a template expansion]");
0162: }
0163:
0164: /**
0165: * {@link InjectComponentWorker} is largely tested by the forms tests ({@link RenderDisabled}
0166: * is built on it). This test is for the failure case, where a mixin class is used with the
0167: * wrong type of component.
0168: */
0169: @Test
0170: public void inject_component_failure() throws Exception {
0171: open(BASE_URL);
0172: clickAndWait("link=InjectComponentMismatch");
0173:
0174: // And exception message:
0175:
0176: assertTextPresent("Component InjectComponentMismatch is not assignable to field org.apache.tapestry.corelib.mixins.RenderDisabled._field (of type org.apache.tapestry.Field).");
0177: }
0178:
0179: @Test
0180: public void injection() throws Exception {
0181: open(BASE_URL);
0182:
0183: clickAndWait("link=Inject Demo");
0184:
0185: // This is a test for a named @Inject:
0186: assertTextPresent("<Proxy for Request(org.apache.tapestry.services.Request)>");
0187:
0188: // This is a test for an anonymous @Inject and ComponentResourcesInjectionProvider
0189: assertTextPresent("ComponentResources[InjectDemo]");
0190:
0191: // Another test, DefaultInjectionProvider
0192: assertTextPresent("<Proxy for BindingSource(org.apache.tapestry.services.BindingSource)>");
0193: }
0194:
0195: @Test
0196: public void instance_mixin() {
0197: open(BASE_URL);
0198:
0199: final String[] dates = { "Jun 13, 1999", "Jul 15, 2001",
0200: "Dec 4, 2005" };
0201:
0202: clickAndWait("link=InstanceMixin");
0203:
0204: for (String date : dates) {
0205: String snippet = String.format("[%s]", date);
0206:
0207: assertSourcePresent(snippet);
0208: }
0209:
0210: clickAndWait("link=Toggle emphasis");
0211:
0212: for (String date : dates) {
0213: String snippet = String.format("[<em>%s</em>]", date);
0214: assertSourcePresent(snippet);
0215: }
0216: }
0217:
0218: @Test
0219: public void localization() {
0220: open(BASE_URL);
0221: clickAndWait("link=Localization");
0222:
0223: assertTextPresent("Via injected Messages property: [Accessed via injected Messages]");
0224: assertTextPresent("Via message: binding prefix: [Accessed via message: binding prefix]");
0225: assertTextPresent("From Application Message Catalog: [Application Catalog Working]");
0226: assertTextPresent("Page locale: [en]");
0227: clickAndWait("link=French");
0228: assertTextPresent("Page locale: [fr]");
0229: clickAndWait("link=English");
0230: assertTextPresent("Page locale: [en]");
0231: }
0232:
0233: @Test
0234: public void page_injection() throws Exception {
0235: open(BASE_URL);
0236:
0237: clickAndWait("link=Inject Demo");
0238:
0239: clickAndWait("link=Fred");
0240:
0241: assertTextPresent("You clicked Fred.");
0242:
0243: clickAndWait("link=Back");
0244: clickAndWait("link=Barney");
0245:
0246: assertTextPresent("You clicked Barney.");
0247:
0248: clickAndWait("link=Back");
0249: clickAndWait("link=Wilma");
0250: assertTextPresent("You clicked Wilma.");
0251: }
0252:
0253: @Test
0254: public void passivate_activate() throws Exception {
0255: open(BASE_URL);
0256: clickAndWait("link=NumberSelect");
0257: clickAndWait("link=5");
0258: assertTextPresent("You chose 5.");
0259: }
0260:
0261: @Test
0262: public void password_field() {
0263: open(BASE_URL);
0264:
0265: clickAndWait("link=PasswordFieldDemo");
0266:
0267: type("userName", "howard");
0268: type("password", "wrong-password");
0269:
0270: clickAndWait("//input[@type='submit']");
0271:
0272: assertFieldValue("userName", "howard");
0273: // Verify that password fields do not render a non-blank password, even when it is known.
0274: assertFieldValue("password", "");
0275:
0276: assertTextPresent("[howard]");
0277: assertTextPresent("[wrong-password]");
0278:
0279: type("password", "tapestry");
0280:
0281: clickAndWait("//input[@type='submit']");
0282:
0283: assertTextPresent("You have provided the correct user name and password.");
0284: }
0285:
0286: @Test
0287: public void render_phase_method_returns_a_component()
0288: throws Exception {
0289: open(BASE_URL);
0290: clickAndWait("link=RenderComponentDemo");
0291:
0292: assertText("//span[@id='container']", "[]");
0293:
0294: // Sneak in a little test for If and parameter else:
0295:
0296: assertTextPresent("Should be blank:");
0297:
0298: clickAndWait("enabled");
0299:
0300: // After clicking the link (which submits the form), the page re-renders and shows us
0301: // the optional component from inside the NeverRender, resurrected to render on the page
0302: // after all.
0303:
0304: assertText("//span[@id='container']/span", "Optional Text");
0305:
0306: assertTextPresent("Should now show up:");
0307: }
0308:
0309: @Test
0310: public void render_phase_order() {
0311: open(BASE_URL);
0312:
0313: clickAndWait("link=RenderPhaseOrder");
0314:
0315: assertTextPresent("[BEGIN-TRACER-MIXIN BEGIN-ABSTRACT-TRACER BEGIN-TRACER BODY AFTER-TRACER AFTER-ABSTRACT-TRACER AFTER-TRACER-MIXIN]");
0316: }
0317:
0318: @Test
0319: public void server_side_validation_for_textfield_and_textarea()
0320: throws Exception {
0321: open(BASE_URL);
0322: clickAndWait("link=ValidForm");
0323: clickAndWait("//input[@type='submit']");
0324: assertTextPresent("You must provide a value for Email.");
0325: // This is an overrdden validation error message:
0326: assertTextPresent("Please provide a detailed description of the incident.");
0327:
0328: // Check on decorations via the default validation decorator:
0329:
0330: assertText("//label[1]/@class", "t-error");
0331: assertText("//label[2]/@class", "t-error");
0332: assertText("//input[@id='email']/@class", "t-error");
0333: assertText("//textarea[@id='message']/@class", "t-error");
0334:
0335: type("email", "foo@bar.baz");
0336: type("message", "Show me the money!");
0337: type("hours", "foo");
0338:
0339: clickAndWait("//input[@type='submit']");
0340:
0341: assertTextPresent("[false]");
0342: assertTextPresent("The input value 'foo' is not parseable as an integer value.");
0343:
0344: assertText("//input[@id='hours']/@value", "foo");
0345:
0346: type("hours", " 19 ");
0347: click("//input[@id='urgent']");
0348: clickAndWait("//input[@type='submit']");
0349:
0350: // Make sure the decoration went away.
0351:
0352: // Sorry, not sure how to do that, since the attributes don't exist, we get xpath errors.
0353:
0354: // assertText("//label[1]/@class", "");
0355: // assertText("//label[2]/@class", "");
0356: // assertText("//input[@id='email']/@class", "");
0357: // assertText("//textarea[@id='message']/@class", "");
0358:
0359: assertTextPresent("[foo@bar.baz]");
0360: assertTextPresent("[Show me the money!]");
0361: assertTextPresent("[true]");
0362: assertTextPresent("[19]");
0363: }
0364:
0365: @Test
0366: public void simple_component_event() {
0367: final String YOU_CHOSE = "You chose: ";
0368:
0369: open(BASE_URL);
0370:
0371: clickAndWait("link=Action Page");
0372:
0373: assertFalse(isTextPresent(YOU_CHOSE));
0374:
0375: for (int i = 2; i < 5; i++) {
0376: clickAndWait("link=" + i);
0377:
0378: assertTextPresent(YOU_CHOSE + i);
0379: }
0380: }
0381:
0382: /**
0383: * Tests for forms and form submissions and basic form control components. This also tests a few
0384: * other things, such as computed default bindings and invisible instrumentation.
0385: */
0386: @Test
0387: public void simple_form() {
0388: open(BASE_URL);
0389:
0390: clickAndWait("link=SimpleForm");
0391:
0392: assertText("//label[@id='disabled:label']", "Disabled");
0393: assertText("//label[@id='email:label']", "Email");
0394: assertText("//label[@id='message:label']", "Incident Message");
0395: assertText("//label[@id='operatingSystem:label']",
0396: "Operating System");
0397: assertText("//label[@id='department:label']", "Department");
0398: assertText("//label[@id='urgent:label']",
0399: "Urgent Processing Requested");
0400:
0401: assertFieldValue("email", "");
0402: assertFieldValue("message", "");
0403: assertFieldValue("operatingSystem", "osx");
0404: assertFieldValue("department", "ACCOUNTING");
0405: assertFieldValue("urgent", "on");
0406:
0407: type("email", "foo@bar.baz");
0408: type("message", "Message for you, sir!");
0409: select("operatingSystem", "Windows NT");
0410: select("department", "R&D");
0411: click("urgent");
0412:
0413: clickAndWait("//input[@type='submit']");
0414:
0415: assertFieldValue("email", "foo@bar.baz");
0416: assertFieldValue("message", "Message for you, sir!");
0417: assertFieldValue("urgent", "off");
0418:
0419: // Tried to use "email:" and "exact:email:" but Selenium 0.8.1 doesn't seem to accept that.
0420:
0421: assertTextPresent("[foo@bar.baz]", "[Message for you, sir!]",
0422: "[false]", "[winnt]", "[RESEARCH_AND_DESIGN]");
0423:
0424: // Haven't figured out how to get selenium to check that fields are disabled.
0425: }
0426:
0427: @Test
0428: public void subclass_inherits_parent_template() {
0429: open(BASE_URL);
0430:
0431: clickAndWait("link=ExpansionSubclass");
0432:
0433: assertTextPresent("[value provided, in the subclass, via a template expansion]");
0434: }
0435:
0436: @Test
0437: public void template_overridden() {
0438: open(BASE_URL);
0439:
0440: clickAndWait("link=Template Overriden by Class Page");
0441:
0442: assertTextPresent("Output: ClassValue");
0443: }
0444:
0445: @Test
0446: public void volatile_loop_inside_a_form() {
0447: test_loop_inside_form("ToDo List (Volatile)");
0448: }
0449:
0450: /** This also verifies the use of meta data to set the default strategy. */
0451: @Test
0452: public void flash_persistence() {
0453: open(BASE_URL);
0454:
0455: clickAndWait("link=FlashDemo");
0456:
0457: assertTextPresent("[]");
0458:
0459: clickAndWait("show");
0460:
0461: assertTextPresent("[You clicked the link!]");
0462:
0463: clickAndWait("refresh");
0464:
0465: assertTextPresent("[]");
0466: }
0467:
0468: private byte[] readContent(URL url) throws Exception {
0469: InputStream is = new BufferedInputStream(url.openStream());
0470:
0471: ByteArrayOutputStream os = new ByteArrayOutputStream();
0472:
0473: byte[] buffer = new byte[10000];
0474:
0475: while (true) {
0476: int length = is.read(buffer);
0477:
0478: if (length < 0)
0479: break;
0480:
0481: os.write(buffer, 0, length);
0482: }
0483:
0484: os.close();
0485: is.close();
0486:
0487: return os.toByteArray();
0488: }
0489:
0490: private void test_loop_inside_form(String linkLabel) {
0491: open(BASE_URL);
0492:
0493: clickAndWait("link=" + linkLabel);
0494: clickAndWait("reset");
0495:
0496: assertFieldValue("title", "End World Hunger");
0497: assertFieldValue("title_0", "Develop Faster-Than-Light Travel");
0498: assertFieldValue("title_1", "Cure Common Cold");
0499:
0500: type("title", "End World Hunger - today");
0501: type("title_0",
0502: "Develop Faster-Than-Light Travel - immediately");
0503: type("title_1", "Cure Common Cold - post haste");
0504:
0505: clickAndWait("//input[@value='Update ToDos']");
0506:
0507: assertFieldValue("title", "End World Hunger - today");
0508: assertFieldValue("title_0",
0509: "Develop Faster-Than-Light Travel - immediately");
0510: assertFieldValue("title_1", "Cure Common Cold - post haste");
0511:
0512: clickAndWait("addNew");
0513:
0514: type("title_2", "Conquer World");
0515:
0516: clickAndWait("//input[@value='Update ToDos']");
0517:
0518: assertFieldValue("title", "End World Hunger - today");
0519: assertFieldValue("title_0",
0520: "Develop Faster-Than-Light Travel - immediately");
0521: assertFieldValue("title_1", "Cure Common Cold - post haste");
0522: assertFieldValue("title_2", "Conquer World");
0523: }
0524:
0525: /**
0526: * Tests the bean editor. Along the way, tests a bunch about validation, loops, blocks, and
0527: * application state objects.
0528: */
0529: @Test
0530: public void bean_editor() {
0531: String submitButton = "//input[@type='submit']";
0532:
0533: open(BASE_URL);
0534: clickAndWait("link=BeanEditor Demo");
0535: clickAndWait("link=Clear Data");
0536: clickAndWait(submitButton);
0537:
0538: assertTextPresent("(First Name is Required)",
0539: "You must provide a value for First Name.",
0540: "Everyone has to have a last name!",
0541: "Year of Birth requires a value of at least 1900.");
0542:
0543: // Part of the override for the firstName property
0544:
0545: assertText("//input[@id='firstName']/@size", "40");
0546:
0547: // Check override of the submit label
0548:
0549: assertText("//input[@type='submit']/@value", "Register");
0550:
0551: type("firstName", "a");
0552: type("lastName", "b");
0553: type("birthYear", "");
0554: select("sex", "label=Martian");
0555: click("citizen");
0556:
0557: clickAndWait(submitButton);
0558:
0559: assertTextPresent(
0560: "You must provide at least 3 characters for First Name.",
0561: "You must provide at least 5 characters for Last Name.",
0562: "You must provide a value for Year of Birth.");
0563:
0564: type("firstName", "Howard");
0565: type("lastName", "Lewis Ship");
0566: type("birthYear", "1966");
0567:
0568: clickAndWait(submitButton);
0569:
0570: assertTextPresent("[Howard]", "[Lewis Ship]", "[1966]",
0571: "[MARTIAN]", "[true]");
0572: }
0573:
0574: @Test
0575: public void pageloaded_lifecycle_method_invoked() {
0576: open(BASE_URL);
0577: clickAndWait("link=PageLoaded Demo");
0578:
0579: assertTextPresent("[pageLoaded() was invoked.]");
0580: }
0581:
0582: /**
0583: * Basic Grid rendering, with a column render override. Also tests sorting.
0584: */
0585: @Test
0586: public void basic_grid() {
0587: open(BASE_URL);
0588: clickAndWait("link=Grid Demo");
0589:
0590: assertTextSeries("//th[%d]", 1, "Title", "Album", "Artist",
0591: "Genre", "Play Count", "Rating");
0592:
0593: // Strange: I thought tr[1] was the header row ???
0594:
0595: assertTextSeries("//tr[1]/td[%d]", 1, "Bug Juice",
0596: "Late Lounge (2 of 2)", "45 Dip", "Electronica", "4",
0597: "-");
0598:
0599: // Here were checking that the page splits are correct
0600:
0601: clickAndWait("link=3");
0602:
0603: // Last on page 3:
0604: assertText("//tr[25]/td[1]", "Blood Red River");
0605:
0606: clickAndWait("link=4");
0607: assertText("//tr[1]/td[1]", "Devil Song");
0608:
0609: clickAndWait("link=7");
0610: clickAndWait("link=10");
0611:
0612: // Here's one with a customized rating cell
0613:
0614: assertTextSeries("//tr[25]/td[%d]", 1, "Smoked",
0615: "London (Original Motion Picture Soundtrack)",
0616: "The Crystal Method", "Soundtrack", "30", "****");
0617:
0618: clickAndWait("link=69");
0619:
0620: assertText("//tr[22]/td[1]", "radioioAmbient");
0621:
0622: // Sort ascending (and we're on the last page, with the highest ratings).
0623:
0624: clickAndWait("link=Rating");
0625:
0626: assertText("//img[@id='rating:sort']/@src",
0627: "/assets/tapestry/corelib/components/sort-asc.png");
0628: assertText("//img[@id='rating:sort']/@alt", "[Asc]");
0629:
0630: assertTextSeries("//tr[22]/td[%d]", 1, "Mona Lisa Overdrive",
0631: "Labyrinth", "Juno Reactor", "Dance", "31", "*****");
0632:
0633: // Toggle to sort descending
0634:
0635: clickAndWait("link=Rating");
0636:
0637: assertText("//img[@id='rating:sort']/@src",
0638: "/assets/tapestry/corelib/components/sort-desc.png");
0639: assertText("//img[@id='rating:sort']/@alt", "[Desc]");
0640:
0641: assertTextSeries("//tr[1]/td[%d]", 1, "Hey Blondie",
0642: "Out from Out Where");
0643:
0644: clickAndWait("link=Title");
0645:
0646: assertText("//img[@id='title:sort']/@src",
0647: "/assets/tapestry/corelib/components/sort-asc.png");
0648: assertText("//img[@id='title:sort']/@alt", "[Asc]");
0649:
0650: clickAndWait("link=1");
0651:
0652: assertText("//tr[1]/td[1]", "(untitled hidden track)");
0653: }
0654:
0655: @Test
0656: public void grid_from_explicit_interface_model() {
0657: open(BASE_URL);
0658: clickAndWait("link=SimpleTrack Grid Demo");
0659:
0660: assertTextSeries("//th[%d]", 1, "Title", "Album", "Rating");
0661:
0662: assertTextSeries("//tr[1]/td[%d]", 1, "Bug Juice",
0663: "Late Lounge (2 of 2)", "-");
0664: }
0665:
0666: @Test
0667: public void grid_enum_display() {
0668: open(BASE_URL);
0669: clickAndWait("link=Grid Enum Demo");
0670: clickAndWait("link=reset");
0671:
0672: assertTextSeries("//tr[1]/td[%d]", 2, "End World Hunger",
0673: "Medium");
0674: assertTextSeries("//tr[2]/td[%d]", 2,
0675: "Develop Faster-Than-Light Travel", "High");
0676: assertTextSeries("//tr[3]/td[%d]", 2, "Cure Common Cold", "Low");
0677: }
0678:
0679: @Test
0680: public void null_grid() throws Exception {
0681: open(BASE_URL);
0682:
0683: clickAndWait("link=Null Grid");
0684:
0685: assertTextPresent("There is no data to display.");
0686: }
0687:
0688: @Test
0689: public void navigation_response_from_page_activate()
0690: throws Exception {
0691: open(BASE_URL);
0692:
0693: clickAndWait("link=Protected Page");
0694:
0695: assertText("//h1", "Security Alert");
0696:
0697: // The message is set by Protected, but is rendered by SecurityAlert.
0698:
0699: assertTextPresent("Access to Protected page is denied");
0700: }
0701:
0702: @Test
0703: public void mixed_page_activation_context_and_component_context() {
0704: open(BASE_URL);
0705:
0706: clickAndWait("link=Kicker");
0707:
0708: clickAndWait("actionlink");
0709:
0710: assertTextSeries("//li[%d]", 1, "betty", "wilma");
0711: assertTextPresent("No component context.");
0712:
0713: clickAndWait("link=go");
0714:
0715: assertTextSeries("//li[%d]", 1, "betty", "wilma");
0716: assertTextSeries("//ul[2]/li[%d]", 1, "fred", "barney",
0717: "clark kent");
0718: }
0719:
0720: @Test
0721: public void page_link_with_explicit_empty_context() {
0722: open(BASE_URL);
0723:
0724: clickAndWait("link=Kicker");
0725:
0726: clickAndWait("actionlink");
0727:
0728: assertTextSeries("//li[%d]", 1, "betty", "wilma");
0729:
0730: clickAndWait("nocontext");
0731:
0732: assertTextPresent("No activation context.");
0733: }
0734:
0735: @Test
0736: public void page_link_with_explicit_activation_context() {
0737: open(BASE_URL);
0738:
0739: clickAndWait("link=PageLink Context Demo");
0740:
0741: clickAndWait("link=no context");
0742:
0743: assertTextPresent("No activation context.");
0744:
0745: clickAndWait("link=PageLink Context Demo");
0746:
0747: clickAndWait("link=literal context");
0748:
0749: assertText("//li[1]", "literal context");
0750:
0751: clickAndWait("link=PageLink Context Demo");
0752:
0753: clickAndWait("link=computed context");
0754:
0755: assertTextSeries("//li[%d]", 1, "fred", "7", "true");
0756: }
0757:
0758: @Test
0759: public void client_side_validation() {
0760: open(BASE_URL);
0761:
0762: clickAndWait("link=Client Validation Demo");
0763:
0764: assertTextSeries("//script[%d]/@src", 1,
0765: "/assets/scriptaculous/prototype.js",
0766: "/assets/scriptaculous/scriptaculous.js");
0767:
0768: clickAndWait("link=Clear Data");
0769:
0770: // Notice: click, not click and wait.
0771:
0772: click("//input[@type='submit']");
0773:
0774: assertTextSeries("//li[%d]", 1,
0775: "You must provide a value for First Name.",
0776: "Everyone has to have a last name!",
0777: "Year of Birth requires a value of at least 1900.");
0778:
0779: type("firstName", "Howard");
0780: type("lastName", "Lewis Ship");
0781: type("birthYear", "1000");
0782: click("//input[@type='submit']");
0783:
0784: assertText("//li",
0785: "Year of Birth requires a value of at least 1900.");
0786:
0787: type("birthYear", "1966");
0788: click("citizen");
0789:
0790: clickAndWait("//input[@type='submit']");
0791:
0792: assertTextPresent("First Name: [Howard]");
0793: }
0794:
0795: @Test
0796: public void recursive_components_are_identified_as_errors() {
0797: open(BASE_URL);
0798: clickAndWait("link=Recursive Demo");
0799:
0800: assertTextPresent(
0801: "An unexpected application exception has occurred.",
0802: "The template for component org.apache.tapestry.integration.app1.components.Recursive is recursive (contains another direct or indirect reference to component org.apache.tapestry.integration.app1.components.Recursive). This is not supported (components may not contain themselves).",
0803: "This component is <t:recursive>recursive</t:recursive>, so we\'ll see a failure.");
0804: }
0805:
0806: @Test
0807: public void render_phase_method_may_return_renderable() {
0808: open(BASE_URL);
0809: clickAndWait("link=Renderable Demo");
0810:
0811: assertTextPresent("Renderable Demo", "[This proves it works.]");
0812: }
0813:
0814: @Test
0815: public void verify_event_handler_invocation_order_and_circumstance() {
0816: String clear = "link=clear";
0817:
0818: open(BASE_URL);
0819: clickAndWait("link=EventHandler Demo");
0820: clickAndWait(clear);
0821:
0822: clickAndWait("wilma");
0823: assertTextPresent("[parent.eventHandlerZero(), parent.onAction(), child.eventHandlerZeroChild(), child.onAction()]");
0824:
0825: clickAndWait(clear);
0826: clickAndWait("barney");
0827:
0828: assertTextPresent("[parent.eventHandlerOne(String), parent.eventHandlerZero(), parent.onAction(), parent.onAction(String), child.eventHandlerOneChild(), child.eventHandlerZeroChild(), child.onAction(), child.onAction(String)]");
0829:
0830: clickAndWait(clear);
0831: clickAndWait("betty");
0832: assertTextPresent("[parent.eventHandlerOne(String), parent.eventHandlerZero(), parent.onAction(), parent.onAction(String), child.eventHandlerOneChild(), child.eventHandlerZeroChild(), child.onAction(), child.onAction(String)]");
0833:
0834: clickAndWait(clear);
0835: clickAndWait("fred");
0836:
0837: assertTextPresent("[parent.eventHandlerOne(String), parent.eventHandlerZero(), parent.onAction(), parent.onAction(String), child.eventHandlerForFred(), child.eventHandlerOneChild(), child.eventHandlerZeroChild(), child.onAction(), child.onAction(String), child.onActionFromFred(), child.onActionFromFred(String), child.onAnyEventFromFred(), child.onAnyEventFromFred(String)]");
0838: }
0839:
0840: @Test
0841: public void inherited_bindings() {
0842: open(BASE_URL);
0843: clickAndWait("link=Inherited Bindings Demo");
0844:
0845: assertTextPresent(
0846: "Bound: [ value: the-bound-value, bound: true ]",
0847: "Unbound: [ value: null, bound: false ]");
0848: }
0849:
0850: @Test
0851: public void client_persistence() {
0852: open(BASE_URL);
0853: clickAndWait("link=Client Persistence Demo");
0854:
0855: assertTextPresent("Persisted value: []", "Session: [false]");
0856:
0857: clickAndWait("link=store string");
0858:
0859: assertTextPresent("Persisted value: [A String]",
0860: "Session: [false]");
0861: }
0862:
0863: @Test
0864: public void attribute_expansions() {
0865: open(BASE_URL);
0866: clickAndWait("link=Attribute Expansions Demo");
0867:
0868: assertText("//div[@id='mixed-expansion']/@style",
0869: "color: blue;");
0870: assertText("//div[@id='single']/@class", "red");
0871: assertText("//div[@id='consecutive']/@class", "goober-red");
0872: assertText("//div[@id='trailer']/@class", "goober-green");
0873: assertText("//div[@id='formal']/text()",
0874: "ALERT-expansions work inside formal component parameters as well");
0875:
0876: // An unrelated test, but fills in a bunch of minor gaps.
0877:
0878: assertSourcePresent("<!-- A comment! -->");
0879: }
0880:
0881: @Test
0882: public void palette_component() {
0883: open(BASE_URL);
0884: clickAndWait("link=Palette Demo");
0885: clickAndWait("link=reset");
0886:
0887: addSelection("languages:avail", "label=Haskell");
0888: addSelection("languages:avail", "label=Javascript");
0889: click("languages:select");
0890:
0891: clickAndWait("//input[@type='submit']");
0892: assertTextPresent("Selected Languages: [HASKELL, JAVASCRIPT]");
0893:
0894: addSelection("languages", "label=Javascript");
0895: click("languages:deselect");
0896:
0897: addSelection("languages:avail", "label=Perl");
0898: removeSelection("languages:avail", "label=Javascript");
0899: addSelection("languages:avail", "label=Erlang");
0900: addSelection("languages:avail", "label=Java");
0901: addSelection("languages:avail", "label=Lisp");
0902: addSelection("languages:avail", "label=Ml");
0903: addSelection("languages:avail", "label=Python");
0904: addSelection("languages:avail", "label=Ruby");
0905:
0906: click("languages:select");
0907:
0908: clickAndWait("//input[@type='submit']");
0909:
0910: assertTextPresent("[ERLANG, HASKELL, JAVA, LISP, ML, PERL, PYTHON, RUBY]");
0911:
0912: check("reorder");
0913: clickAndWait("//input[@type='submit']");
0914:
0915: addSelection("languages", "label=Ruby");
0916:
0917: for (int i = 0; i < 6; i++)
0918: click("languages:up");
0919:
0920: removeSelection("languages", "label=Ruby");
0921: addSelection("languages", "label=Perl");
0922:
0923: click("languages:down");
0924:
0925: clickAndWait("//input[@type='submit']");
0926:
0927: assertTextPresent("[ERLANG, RUBY, HASKELL, JAVA, LISP, ML, PYTHON, PERL]");
0928: }
0929:
0930: @Test
0931: public void event_handler_return_types() {
0932:
0933: open(BASE_URL);
0934: assertTextPresent("Tapestry 5 Integration Application 1");
0935:
0936: clickAndWait("link=Return Types");
0937: assertTextPresent("Return Type Tests");
0938:
0939: clickAndWait("link=null");
0940: assertTextPresent("Return Type Tests");
0941:
0942: clickAndWait("link=string");
0943: assertTextPresent("Tapestry 5 Integration Application 1");
0944: goBack();
0945: waitForPageToLoad();
0946:
0947: clickAndWait("link=class");
0948: assertTextPresent("Tapestry 5 Integration Application 1");
0949: goBack();
0950: waitForPageToLoad();
0951:
0952: clickAndWait("link=page");
0953: assertTextPresent("Tapestry 5 Integration Application 1");
0954: goBack();
0955: waitForPageToLoad();
0956:
0957: clickAndWait("link=link");
0958: assertTextPresent("Tapestry 5 Integration Application 1");
0959: goBack();
0960: waitForPageToLoad();
0961:
0962: clickAndWait("link=stream");
0963: assertTextPresent("Success!");
0964: goBack();
0965: waitForPageToLoad();
0966:
0967: clickAndWait("link=bad");
0968: assertTextPresent(
0969: "An unexpected application exception has occurred.",
0970: "An event handler for component org.apache.tapestry.integration.app1.pages.Start returned the value 20 (from method org.apache.tapestry.integration.app1.pages.Start.onActionFromBadReturnType() (at Start.java:34)). Return type java.lang.Integer can not be handled.");
0971:
0972: }
0973:
0974: @Test
0975: public void access_to_page_name() {
0976: open(BASE_URL);
0977:
0978: assertTextPresent("Currently on page: Start");
0979:
0980: clickAndWait("link=Grid Demo");
0981:
0982: assertTextPresent("Currently on page: GridDemo");
0983: }
0984:
0985: @Test
0986: public void form_encoding_type() {
0987: open(BASE_URL);
0988:
0989: clickAndWait("link=Form Encoding Type");
0990:
0991: assertText("//form/@enctype", "x-override");
0992: }
0993:
0994: @Test
0995: public void radio_button_and_group() {
0996: open(BASE_URL);
0997:
0998: clickAndWait("link=RadioDemo");
0999:
1000: String update = "//input[@type='submit']";
1001:
1002: click("//label[.='Accounting']");
1003:
1004: clickAndWait(update);
1005:
1006: assertTextPresent("Selected department: ACCOUNTING");
1007:
1008: click("//label[.='Sales And Marketing']");
1009:
1010: clickAndWait(update);
1011:
1012: assertTextPresent("Selected department: SALES_AND_MARKETING");
1013: }
1014:
1015: @Test
1016: public void regexp_validator() {
1017: open(BASE_URL);
1018:
1019: clickAndWait("link=Regexp Demo");
1020:
1021: String update = "//input[@type='submit']";
1022:
1023: type("zipCode", "abc");
1024:
1025: click(update); // but don't wait
1026:
1027: assertTextPresent("A zip code consists of five or nine digits, eg: 02134 or 90125-4472.");
1028:
1029: type("zipCode", "12345");
1030:
1031: clickAndWait(update);
1032:
1033: assertTextPresent("Zip code: [12345]");
1034:
1035: type("zipCode", "12345-9876");
1036:
1037: clickAndWait(update);
1038:
1039: assertTextPresent("Zip code: [12345-9876]");
1040: }
1041: }
|