diff --git a/apps/portlet/pom.xml b/apps/portlet/pom.xml
index 15ac1486c..2ef93f7e0 100644
--- a/apps/portlet/pom.xml
+++ b/apps/portlet/pom.xml
@@ -40,6 +40,21 @@
http://svn.apache.org/viewcvs.cgi/struts/struts2/trunk/apps/portlet/
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+
+ org/apache/struts2/portlet/test/*
+
+
+
+
+
+
pluto
diff --git a/apps/portlet/src/test/java/org/apache/struts2/portlet/test/BasePortletTest.java b/apps/portlet/src/test/java/org/apache/struts2/portlet/test/BasePortletTest.java
new file mode 100644
index 000000000..1c7e76c44
--- /dev/null
+++ b/apps/portlet/src/test/java/org/apache/struts2/portlet/test/BasePortletTest.java
@@ -0,0 +1,75 @@
+package org.apache.struts2.portlet.test;
+
+import net.sourceforge.jwebunit.junit.WebTestCase;
+
+import org.apache.pluto.core.PortletServlet;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.servlet.ServletHolder;
+import org.mortbay.jetty.webapp.WebAppContext;
+
+public abstract class BasePortletTest extends WebTestCase {
+
+ protected Server server;
+
+ private int port = 9876;
+
+ private String contextPath = "/test";
+
+ public void setUp() throws Exception {
+ System.setProperty("org.apache.pluto.embedded.portletId", getPortletName());
+ server = new Server(port);
+ WebAppContext webapp = new WebAppContext("src/main/webapp", contextPath);
+ webapp.setDefaultsDescriptor("/WEB-INF/jetty-pluto-web-default.xml");
+ ServletHolder portletServlet = new ServletHolder(new PortletServlet());
+ portletServlet.setInitParameter("portlet-name", getPortletName());
+ portletServlet.setInitOrder(1);
+ webapp.addServlet(portletServlet, "/PlutoInvoker/" + getPortletName());
+ server.addHandler(webapp);
+ server.start();
+ getTestContext().setBaseUrl("http://localhost:" + port + contextPath);
+ }
+
+
+ public void tearDown() throws Exception {
+ server.stop();
+ }
+
+ public void minimizeWindow() {
+ clickElementByXPath("//span[@class='minimized']/..");
+ }
+
+ public void maximizeWindow() {
+ clickElementByXPath("//span[@class='minimized']/..");
+ }
+
+ public void restoreWindow() {
+ clickElementByXPath("//span[@class='normal']/..");
+ }
+
+ public void switchEdit() {
+ clickElementByXPath("//span[@class='edit']/..");
+ }
+
+ public void switchView() {
+ clickElementByXPath("//span[@class='view']/..");
+ }
+
+ public void switchHelp() {
+ clickElementByXPath("//span[@class='help']/..");
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ public void setContextPath(String contextPath) {
+ if(!contextPath.startsWith("/")) {
+ this.contextPath = "/" + contextPath;
+ }
+ else {
+ this.contextPath = contextPath;
+ }
+ }
+
+ public abstract String getPortletName();
+}
diff --git a/apps/portlet/src/test/java/org/apache/struts2/portlet/test/Struts2PortletTest.java b/apps/portlet/src/test/java/org/apache/struts2/portlet/test/Struts2PortletTest.java
new file mode 100644
index 000000000..d1e7c8d11
--- /dev/null
+++ b/apps/portlet/src/test/java/org/apache/struts2/portlet/test/Struts2PortletTest.java
@@ -0,0 +1,83 @@
+package org.apache.struts2.portlet.test;
+
+public class Struts2PortletTest extends BasePortletTest {
+
+ private final static String PORTLET_NAME = "StrutsPortlet";
+
+ public void testIndexPage() throws Exception {
+ beginAt("pluto/index.jsp");
+ assertTextPresent("Welcome to the Struts example portlet");
+ assertLinkPresentWithExactText("A simple form");
+ assertLinkPresentWithExactText("Validation");
+ }
+
+ public void testFormExample() throws Exception {
+ beginAt("pluto/index.jsp");
+ clickLinkWithExactText("A simple form");
+ assertFormPresent("processFormExample");
+ assertTextPresent("Input your name");
+ setWorkingForm("processFormExample");
+ setTextField("firstName", "Nils-Helge");
+ setTextField("lastName", "Garli");
+ submit();
+ assertTextPresent("Hello Nils-Helge Garli");
+ }
+
+ public void testValidationExample() throws Exception {
+ beginAt("pluto/index.jsp");
+ clickLinkWithExactText("Validation");
+ assertFormPresent("processValidationExample");
+ assertTextPresent("Input your name");
+ setWorkingForm("processValidationExample");
+ setTextField("firstName", "Nils-Helge");
+ submit();
+ assertTextFieldEquals("firstName", "Nils-Helge");
+ assertTextPresent("You must enter a last name");
+ setTextField("lastName", "Garli");
+ submit();
+ assertTextPresent("Hello Nils-Helge Garli");
+ }
+
+ public void testValidationErrorMessagesStickBetweenWindowStateChanges() throws Exception {
+ beginAt("pluto/index.jsp");
+ clickLinkWithExactText("Validation");
+ assertFormPresent("processValidationExample");
+ assertTextPresent("Input your name");
+ setWorkingForm("processValidationExample");
+ setTextField("firstName", "Nils-Helge");
+ submit();
+ assertTextFieldEquals("firstName", "Nils-Helge");
+ assertTextPresent("You must enter a last name");
+ minimizeWindow();
+ assertTextNotPresent("Input your name");
+ restoreWindow();
+ assertTextPresent("Input your name");
+ assertTextPresent("You must enter a last name");
+ }
+
+ public void testTokenExample() throws Exception {
+ beginAt("pluto/index.jsp");
+ clickLinkWithText("Token");
+ setWorkingForm(0);
+ setTextField("theValue", "something");
+ submit();
+ assertTextPresent("ERROR");
+ setWorkingForm(1);
+ setTextField("theValue", "somethingElse");
+ submit();
+ assertTextPresent("The form was successfully submitted with a valid token");
+ }
+
+ public void testSwitchFromViewToEditShouldGoToDefaultEditPage() throws Exception {
+ beginAt("pluto/index.jsp");
+ assertTextPresent("Welcome to the Struts example portlet");
+ switchEdit();
+ assertTextPresent("Back to view mode");
+ }
+
+ @Override
+ public String getPortletName() {
+ return PORTLET_NAME;
+ }
+
+}