001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019
020 package org.tynamo.test;
021
022 import com.gargoylesoftware.htmlunit.ElementNotFoundException;
023 import com.gargoylesoftware.htmlunit.WebClient;
024 import com.gargoylesoftware.htmlunit.html.HtmlForm;
025 import com.gargoylesoftware.htmlunit.html.HtmlInput;
026 import com.gargoylesoftware.htmlunit.html.HtmlPage;
027 import org.mortbay.jetty.Connector;
028 import org.mortbay.jetty.Handler;
029 import org.mortbay.jetty.Server;
030 import org.mortbay.jetty.handler.DefaultHandler;
031 import org.mortbay.jetty.handler.HandlerCollection;
032 import org.mortbay.jetty.nio.SelectChannelConnector;
033 import org.mortbay.jetty.webapp.WebAppContext;
034 import org.mortbay.resource.ResourceCollection;
035 import org.testng.annotations.BeforeClass;
036 import org.testng.annotations.BeforeTest;
037
038 import java.io.IOException;
039 import java.util.List;
040
041 import static com.gargoylesoftware.htmlunit.WebAssert.assertTextNotPresent;
042 import static com.gargoylesoftware.htmlunit.WebAssert.assertTextPresent;
043 import static org.testng.Assert.*;
044
045 public abstract class AbstractContainerTest
046 {
047 protected static PauseableServer server;
048
049 protected static final int port = 8180;
050
051 protected static final String BASEURI = "http://localhost:" + port + "/";
052
053 protected final WebClient webClient = new WebClient();
054
055 static String errorText = "You must correct the following errors before you may continue";
056
057 @BeforeClass
058 public void startContainer() throws Exception
059 {
060 if (server == null)
061 {
062 server = new PauseableServer();
063 Connector connector = new SelectChannelConnector();
064 connector.setPort(port);
065 server.setConnectors(new Connector[]{connector});
066
067 HandlerCollection handlers = new HandlerCollection();
068 handlers.setHandlers(new Handler[]{buildContext(), new DefaultHandler()});
069 server.setHandler(handlers);
070 server.start();
071 assertTrue(server.isStarted());
072 }
073 }
074
075 /**
076 * Non-abstract hook method (with a default implementation) to allow subclasses to provide their own WebAppContext instance.
077 * @return a WebAppContext
078 */
079 public WebAppContext buildContext()
080 {
081 WebAppContext context = new WebAppContext("src/main/webapp", "/");
082 ResourceCollection resourceCollection = new ResourceCollection(new String[]{"src/main/webapp", "src/test/webapp"});
083 context.setBaseResource(resourceCollection);
084
085 /**
086 * like -Dorg.mortbay.jetty.webapp.parentLoaderPriority=true
087 * Sets the classloading model for the context to avoid an strange "ClassNotFoundException: org.slf4j.Logger"
088 */
089 context.setParentLoaderPriority(true);
090 return context;
091 }
092
093 /**
094 * Hook method which is called during setup phase, before the first request.
095 * It allows subclasses to modify the webClient, such as for disabling javascript
096 */
097 @BeforeTest
098 public void configureWebClient()
099 {
100 webClient.setThrowExceptionOnFailingStatusCode(true);
101 }
102
103 public void pauseServer(boolean paused)
104 {
105 if (server != null) server.pause(paused);
106 }
107
108 public static class PauseableServer extends Server
109 {
110 public synchronized void pause(boolean paused)
111 {
112 try
113 {
114 if (paused) for (Connector connector : getConnectors())
115 connector.stop();
116 else for (Connector connector : getConnectors())
117 connector.start();
118 } catch (Exception e)
119 {
120 }
121 }
122 }
123
124 /**
125 * Verifies that the specified xpath is somewhere on the page.
126 *
127 * @param page
128 * @param xpath
129 */
130 protected void assertXPathPresent(HtmlPage page, String xpath)
131 {
132 String message = "XPath not present: " + xpath;
133 List list = page.getByXPath(xpath);
134 if (list.isEmpty()) fail(message);
135 assertNotNull(list.get(0), message);
136 }
137
138 /**
139 * Verifies that the specified xpath does NOT appear anywhere on the page.
140 *
141 * @param page
142 * @param xpath
143 */
144 protected void assertXPathNotPresent(HtmlPage page, String xpath)
145 {
146 if (!page.getByXPath(xpath).isEmpty()) fail("XPath IS present: " + xpath);
147 }
148
149
150 protected HtmlPage clickLink(HtmlPage page, String linkText)
151 {
152 try
153 {
154 return (HtmlPage) page.getFirstAnchorByText(linkText).click();
155 } catch (ElementNotFoundException e)
156 {
157 fail("Couldn't find a link with text '" + linkText + "' on page " + page);
158 } catch (IOException e)
159 {
160 fail("Clicking on link '" + linkText + "' on page " + page + " failed because of: ", e);
161 }
162 return null;
163 }
164
165 protected HtmlPage clickButton(HtmlPage page, String buttonId) throws IOException
166 {
167 return page.getElementById(buttonId).click();
168 }
169
170 protected HtmlPage clickButton(HtmlForm form, String buttonValue) throws IOException
171 {
172 try
173 {
174 return form.<HtmlInput>getInputByValue(buttonValue).click();
175 } catch (ElementNotFoundException e)
176 {
177 try
178 {
179 return form.getButtonByName(buttonValue).click();
180 } catch (ElementNotFoundException e1)
181 {
182 fail("Couldn't find a button with text/name '" + buttonValue + "' on form '" + form.getNameAttribute() +
183 "'");
184 }
185 }
186 return null;
187 }
188
189 protected void assertErrorTextPresent(HtmlPage page)
190 {
191 assertTextPresent(page, errorText);
192 }
193
194 protected void assertErrorTextNotPresent(HtmlPage page)
195 {
196 assertTextNotPresent(page, errorText);
197 }
198
199 }