/*
* JBoss, Home of Professional Open Source.
* Copyright 2010, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.jsfunit.example.hellojsf;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.component.html.HtmlSelectManyListbox;
import javax.faces.context.FacesContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;
import junit.framework.Assert;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.spi.RemoteLoadableExtension;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.spi.TestEnricher;
import org.jboss.jsfunit.api.Browser;
import org.jboss.jsfunit.api.BrowserVersion;
import org.jboss.jsfunit.api.Cookies;
import org.jboss.jsfunit.api.InitialPage;
import org.jboss.jsfunit.api.InitialRequest;
import org.jboss.jsfunit.api.JSFUnitResource;
import org.jboss.jsfunit.api.Proxy;
import org.jboss.jsfunit.arquillian.container.JSFUnitCleanupTestTreadFilter;
import org.jboss.jsfunit.arquillian.container.JSFUnitRemoteExtension;
import org.jboss.jsfunit.arquillian.container.JSFUnitTestEnricher;
import org.jboss.jsfunit.jsfsession.ComponentIDNotFoundException;
import org.jboss.jsfunit.jsfsession.JSFClientSession;
import org.jboss.jsfunit.jsfsession.JSFServerSession;
import org.jboss.jsfunit.jsfsession.JSFSession;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.gargoylesoftware.htmlunit.html.HtmlSelect;
/**
* Version of the FacadeAPITest that uses Arquillian
*
* @author Stan Silvert
*/
@RunWith(Arquillian.class)
@InitialPage("/index.faces")
public class FacadeAPITest {
@JSFUnitResource
private JSFClientSession client;
@JSFUnitResource
private JSFServerSession server;
@Deployment
public static WebArchive createDeployment() {
WebArchive war = Deployments.createDeployment();
war.addClass(JSFUnitCleanupTestTreadFilter.class)
.addPackages(
true,
org.jboss.arquillian.container.spi.client.protocol.metadata.HTTPContext.class.getPackage(),
org.jboss.arquillian.protocol.servlet.Processor.class.getPackage(),
org.jboss.jsfunit.jsfsession.JSFSession.class.getPackage(),
org.jboss.jsfunit.framework.WebClientSpec.class.getPackage(),
org.jboss.jsfunit.context.JSFUnitFacesContext.class.getPackage(),
org.jboss.jsfunit.seam.SeamUtil.class.getPackage(),
org.jboss.jsfunit.api.JSFUnitResource.class.getPackage(), // Arquillian JSFunit API
org.jboss.jsfunit.arquillian.container.JSFUnitTestEnricher.class.getPackage(), // Support package for
// incontainer enrichment
org.apache.http.HttpEntity.class.getPackage(), // HTTPClient
org.apache.james.mime4j.MimeException.class.getPackage(), // Apache Mime4j, used by HTTP client
com.gargoylesoftware.htmlunit.BrowserVersion.class.getPackage(),
org.apache.commons.codec.Decoder.class.getPackage(), org.apache.commons.io.IOUtils.class.getPackage(),
org.apache.commons.lang.StringUtils.class.getPackage(),
net.sourceforge.htmlunit.corejs.javascript.EvaluatorException.class.getPackage(),
org.w3c.css.sac.CSSException.class.getPackage(),
com.steadystate.css.dom.CSSOMObject.class.getPackage(),
com.steadystate.css.parser.CSSOMParser.class.getPackage(),
com.steadystate.css.sac.TestCSSParseException.class.getPackage(),
com.steadystate.css.userdata.UserDataConstants.class.getPackage(),
org.apache.commons.logging.LogFactory.class.getPackage(),
org.apache.xerces.xni.XNIException.class.getPackage(),
org.apache.commons.collections.Transformer.class.getPackage(),
org.apache.xerces.dom.AttrImpl.class.getPackage(), org.apache.xerces.impl.Constants.class.getPackage(),
org.apache.xerces.jaxp.DocumentBuilderFactoryImpl.class.getPackage(),
org.apache.xerces.parsers.AbstractDOMParser.class.getPackage(),
org.apache.xerces.util.AttributesProxy.class.getPackage(),
org.apache.xerces.xinclude.MultipleScopeNamespaceSupport.class.getPackage(),
org.apache.xerces.xpointer.XPointerHandler.class.getPackage(),
org.apache.xerces.xs.AttributePSVI.class.getPackage(),
org.apache.xml.dtm.Axis.class.getPackage(), org.apache.xml.res.XMLErrorResources.class.getPackage(),
org.apache.xml.utils.AttList.class.getPackage(), org.apache.xpath.XPath.class.getPackage(),
org.apache.xalan.Version.class.getPackage(),
org.cyberneko.html.HTMLComponent.class.getPackage(), org.cyberneko.html.HTMLEntities.class.getPackage())
.addAsResource("com/gargoylesoftware/htmlunit/javascript/configuration/FF2.properties")
.addAsResource("com/gargoylesoftware/htmlunit/javascript/configuration/FF3.properties")
.addAsResource("com/gargoylesoftware/htmlunit/javascript/configuration/FF3.6.properties")
.addAsResource("com/gargoylesoftware/htmlunit/javascript/configuration/IE6.properties")
.addAsResource("com/gargoylesoftware/htmlunit/javascript/configuration/IE7.properties")
.addAsResource("com/gargoylesoftware/htmlunit/javascript/configuration/IE8.properties")
.addAsResource("com/gargoylesoftware/htmlunit/javascript/configuration/JavaScriptConfiguration.xml")
.addAsResource("com/gargoylesoftware/htmlunit/javascript/configuration/JavaScriptConfiguration.xsd")
.addAsResource("net/sourceforge/htmlunit/corejs/javascript/resources/Messages.properties")
.addAsResource("net/sourceforge/htmlunit/corejs/javascript/resources/Messages_fr.properties")
.addAsResource("org/cyberneko/html/res/HTMLlat1.properties")
.addAsResource("org/cyberneko/html/res/HTMLspecial.properties")
.addAsResource("org/cyberneko/html/res/HTMLsymbol.properties")
.addAsResource("org/cyberneko/html/res/XMLbuiltin.properties")
.addAsResource("com/steadystate/css/parser/SACParserMessages.properties")
.addAsResource("com/steadystate/css/parser/SACParserMessages_en.properties")
.addAsResource("com/steadystate/css/parser/SACParserMessages_de.properties")
/**
* TODO use faces-config and web-fragment from jsfunit jar. for now it's not possible because shrinkwrap could
* get a different META-INF/faces-config .addAsManifestResource(this.jsfunitFacesConfigXml(),
* "faces-config.xml")
*/
.addAsServiceProvider(TestEnricher.class, JSFUnitTestEnricher.class)
.addAsServiceProvider(RemoteLoadableExtension.class, JSFUnitRemoteExtension.class);
return war;
}
@Test
@InitialPage("/index.faces")
@BrowserVersion(Browser.INTERNET_EXPLORER_6)
@Proxy(host = "localhost", port = 8080)
public void testCustomBrowserVersion(JSFSession jsfSession) throws IOException {
Assert.assertEquals(com.gargoylesoftware.htmlunit.BrowserVersion.INTERNET_EXPLORER_6, jsfSession.getWebClient()
.getBrowserVersion());
Assert.assertEquals("localhost", jsfSession.getWebClient().getProxyConfig().getProxyHost());
Assert.assertEquals(8080, jsfSession.getWebClient().getProxyConfig().getProxyPort());
}
/**
*/
@Test
@InitialPage("/index.faces")
public void testGetCurrentViewId(JSFServerSession server) throws IOException {
// Test navigation to initial viewID
assertViewId("/index", server.getCurrentViewID());
Assert.assertEquals(server.getCurrentViewID(), server.getFacesContext().getViewRoot().getViewId());
}
@Test
@InitialPage("/index.faces")
@InitialRequest(SetSocketTimeoutRequestStrategy.class)
public void testInitialRequestAnnotation(JSFSession jsfSession, JSFServerSession server) {
// Test navigation to initial viewID
assertViewId("/index", server.getCurrentViewID());
Assert.assertEquals(server.getCurrentViewID(), server.getFacesContext().getViewRoot().getViewId());
// timeout set to 10001 in SetSocketTimeoutRequestStrategy
Assert.assertEquals(10001, jsfSession.getWebClient().getTimeout());
}
@Test
@InitialPage("/index.faces")
@Cookies(names = { "cookie1", "cookie2" }, values = { "value1", "value2" })
public void testCustomCookies(JSFClientSession client, JSFServerSession server) throws IOException {
Assert.assertEquals("value1", this.getCookieValue(server, "cookie1"));
Assert.assertEquals("value2", this.getCookieValue(server, "cookie2"));
// verify that cookies survive for the whole session
client.click("submit_button");
Assert.assertEquals("value1", this.getCookieValue(server, "cookie1"));
Assert.assertEquals("value2", this.getCookieValue(server, "cookie2"));
}
private String getCookieValue(JSFServerSession server, String cookieName) {
Object cookie = server.getFacesContext().getExternalContext().getRequestCookieMap().get(cookieName);
if (cookie != null) {
return ((Cookie) cookie).getValue();
}
return null;
}
@Test
public void testSetCheckbox() throws IOException {
client.setValue("input_foo_text", "Stan");
client.click("funcheck"); // uncheck it
client.click("submit_button");
Assert.assertFalse((Boolean) server.getManagedBeanValue("#{checkbox.funCheck}"));
client.setValue("input_foo_text", "Stan");
client.click("funcheck"); // make it checked again
client.click("submit_button");
Assert.assertTrue((Boolean) server.getManagedBeanValue("#{checkbox.funCheck}"));
}
@Test
public void testClickCommandLink() throws IOException {
Assume.assumeTrue(!Deployments.IS_JSF_1_2);
client.setValue("input_foo_text", "Stan");
client.click("goodbye_button");
client.click("go_back_link");
// test that we are back on the first page
assertViewId("/index", server.getCurrentViewID());
}
@Test
public void testCommandLinkWithoutViewChange() throws IOException {
Assume.assumeTrue(!Deployments.IS_JSF_1_2);
client.setValue("input_foo_text", "Stan");
client.click("goodbye_button");
client.click("stay_here_link");
// test that we are still on the same page
assertViewId("/finalgreeting", server.getCurrentViewID());
}
@Test
public void testCommandLinkWithFParam() throws IOException {
Assume.assumeTrue(!Deployments.IS_JSF_1_2);
client.setValue("input_foo_text", "Stan");
client.click("goodbye_button");
client.click("stay_here_link");
// link includes <f:param id="name" name="name" value="#{foo.text}"/>
String name = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("name");
Assert.assertEquals("Stan", name);
}
/*
* Bug in Mojarra causes this to fail. See http://java.net/jira/browse/JAVASERVERFACES-1527 SEVERE
* [javax.enterprise.resource.webcontainer.jsf.application] JSF1007: Duplicate component ID form1:marathonSelect found in
* view.
*
* @Test public void testCommandLinkWithParamFromLoopVariable() throws IOException { // test should not run for JSF 1.1 - it
* uses a loop variable from <c:forEach> if ((Environment.getJSFMajorVersion() == 1) && (Environment.getJSFMinorVersion() <
* 2)) return;
*
* JSFSession jsfSession = new JSFSession("/marathons.faces"); JSFClientSession client = jsfSession.getJSFClientSession();
*
* client.click("marathonSelect");
* Assert.assertTrue(client.getPageAsText().contains("Selected Marathon: BAA Boston Marathon"));
*
* client.click("marathonSelectj_id_3");
* Assert.assertTrue(client.getPageAsText().contains("Selected Marathon: Flora London Marathon"));
*
* client.click("marathonSelectj_id_5");
* Assert.assertTrue(client.getPageAsText().contains("Selected Marathon: Olympic Marathon")); }
*/
@Test
public void testCommandLinkWithParamFromDatatableVariable() throws IOException {
JSFSession jsfSession = new JSFSession("/marathons_datatable.faces");
JSFClientSession client = jsfSession.getJSFClientSession();
client.click("0:marathonSelect");
Assert.assertTrue(client.getPageAsText().contains("Selected Marathon: BAA Boston Marathon"));
client.click("3:marathonSelect");
Assert.assertTrue(client.getPageAsText().contains("Selected Marathon: Flora London Marathon"));
client.click("5:marathonSelect");
Assert.assertTrue(client.getPageAsText().contains("Selected Marathon: Olympic Marathon"));
}
@Test
public void testInvalidateSession() throws IOException {
JSFSession jsfSession = new JSFSession("/marathons_datatable.faces");
JSFClientSession client = jsfSession.getJSFClientSession();
JSFServerSession server = jsfSession.getJSFServerSession();
client.click("0:marathonSelect");
Assert.assertTrue(client.getPageAsText().contains("Selected Marathon: BAA Boston Marathon"));
Assert.assertEquals("BAA Boston Marathon", server.getManagedBeanValue("#{marathons.selectedMarathon}"));
client.click("invalidateSession");
client.click("0:marathonSelect");
Assert.assertTrue(client.getPageAsText().contains("Selected Marathon: BAA Boston Marathon"));
Assert.assertEquals("BAA Boston Marathon", server.getManagedBeanValue("#{marathons.selectedMarathon}"));
}
@Test
public void testFacesMessages() throws IOException {
client.setValue("input_foo_text", "A"); // input too short - validation error
client.click("submit_button");
// Test that I was returned to the initial view because of input error
assertViewId("/index", server.getCurrentViewID());
// Should be only one FacesMessge generated for the page.
Iterator<FacesMessage> allMessages = server.getFacesMessages();
allMessages.next();
Assert.assertFalse(allMessages.hasNext());
Iterator<FacesMessage> checkboxMessages = server.getFacesMessages("funcheck");
Assert.assertFalse(checkboxMessages.hasNext());
Iterator<FacesMessage> fooTextMessages = server.getFacesMessages("input_foo_text");
FacesMessage message = fooTextMessages.next();
Assert.assertTrue(message.getDetail().contains("input_foo_text"));
}
@Test
@InitialPage("/indexWithExtraComponents.faces")
public void testTextArea(JSFClientSession client, JSFServerSession server) throws IOException {
client.setValue("input_foo_text", "Stan");
Assert.assertEquals("Initial Value", server.getManagedBeanValue("#{foo2.text}"));
client.setValue("MyTextArea", "New Value");
client.click("submit_button");
Assert.assertEquals("New Value", server.getManagedBeanValue("#{foo2.text}"));
}
@Test
@InitialPage("/indexWithExtraComponents.faces")
public void testSelectOneRadio(JSFClientSession client, JSFServerSession server) throws IOException {
client.setValue("input_foo_text", "Stan");
Assert.assertEquals("Blue", server.getManagedBeanValue("#{foo3.text}"));
client.click("selectGreen");
client.click("submit_button");
Assert.assertEquals("Green", server.getManagedBeanValue("#{foo3.text}"));
}
@Test
@InitialPage("/indexWithExtraComponents.faces")
public void testSelectManyListbox(JSFClientSession client, JSFServerSession server) throws IOException {
// JSFUNIT-268
Assume.assumeTrue(!(Deployments.IS_JETTY || Deployments.IS_TOMCAT));
client.setValue("input_foo_text", "Stan");
client.click("selectMonday");
client.click("selectWednesday");
client.click("selectFriday");
client.click("submit_button");
// using dumpAllIDs, you can see that indexWithExtraComponents is not the
// InitialPage in Jetty
// server.getClientIDs().dumpAllIDs();
HtmlSelectManyListbox listBox = (HtmlSelectManyListbox) server.findComponent("Weekdays");
Object[] selectedValues = listBox.getSelectedValues();
Assert.assertEquals(3, selectedValues.length);
List<Object> listOfValues = Arrays.asList(selectedValues);
Assert.assertTrue(listOfValues.contains("Monday"));
Assert.assertFalse(listOfValues.contains("Tuesday"));
Assert.assertTrue(listOfValues.contains("Wednesday"));
Assert.assertFalse(listOfValues.contains("Thursday"));
Assert.assertTrue(listOfValues.contains("Friday"));
}
@Test
@InitialPage("/indexWithExtraComponents.faces")
public void testSelectManyListboxWithItemList(JSFClientSession client, JSFServerSession server) throws IOException {
// JSFUNIT-268
Assume.assumeTrue(!(Deployments.IS_JETTY || Deployments.IS_TOMCAT));
HtmlSelect select = (HtmlSelect) client.getElement("WeekdaysUsingItemList");
client.setValue("input_foo_text", "Stan");
select.getOptionByValue("Monday").setSelected(true);
select.getOptionByValue("Tuesday").setSelected(false);
select.getOptionByValue("Wednesday").setSelected(true);
select.getOptionByValue("Thursday").setSelected(true);
select.getOptionByValue("Friday").setSelected(false);
client.click("submit_button");
HtmlSelectManyListbox listBox = (HtmlSelectManyListbox) server.findComponent("WeekdaysUsingItemList");
Object[] selectedValues = listBox.getSelectedValues();
Assert.assertEquals(3, selectedValues.length);
List<Object> listOfValues = Arrays.asList(selectedValues);
Assert.assertTrue(listOfValues.contains("Monday"));
Assert.assertFalse(listOfValues.contains("Tuesday"));
Assert.assertTrue(listOfValues.contains("Wednesday"));
Assert.assertTrue(listOfValues.contains("Thursday"));
Assert.assertFalse(listOfValues.contains("Friday"));
}
@Test
public void testNoCreationOfBeanDuringELExpressionReference() throws IOException {
HttpSession session = (HttpSession) server.getFacesContext().getExternalContext().getSession(true);
Assert.assertNull(session.getAttribute("unreferencedsessionbean"));
MyBean bean = (MyBean) server.getManagedBeanValue("#{unreferencedsessionbean}");
Assert.assertNull(bean); // <--------- JSFUNIT-164
bean = (MyBean) server.getManagedBeanValue("#{unreferencedrequestbean}");
Assert.assertNull(bean); // <--------- JSFUNIT-164
bean = (MyBean) server.getManagedBeanValue("#{unreferencedapplicationbean}");
Assert.assertNull(bean); // <--------- JSFUNIT-164
}
@Test
@InitialPage("/indexWithExtraComponents.faces")
public void testReferencedBeans(JSFServerSession server, JSFClientSession client) throws IOException {
String html = client.getPageAsText();
Assert.assertTrue(html.contains("request bean scope string = request"));
Assert.assertTrue(html.contains("session bean scope string = session"));
Assert.assertTrue(html.contains("application bean scope string = application"));
HttpSession session = (HttpSession) server.getFacesContext().getExternalContext().getSession(true);
Assert.assertNotNull(session.getAttribute("referencedsessionbean"));
MyBean bean = (MyBean) server.getManagedBeanValue("#{referencedsessionbean}");
Assert.assertNotNull(bean);
Assert.assertEquals(1, bean.myValue);
bean = (MyBean) server.getManagedBeanValue("#{referencedrequestbean}");
Assert.assertNotNull(bean);
Assert.assertEquals(1, bean.myValue);
bean = (MyBean) server.getManagedBeanValue("#{referencedapplicationbean}");
Assert.assertNotNull(bean);
Assert.assertEquals(1, bean.myValue);
}
@Test
public void testClickThrowsComponentNotFound() throws IOException {
try {
client.click("thiselementisnotthere");
Assert.fail("Expected ComponentIDNotFoundException");
} catch (ComponentIDNotFoundException e) {
// OK
}
}
@Test
public void testSetValueThrowsComponentNotFound() throws IOException {
try {
client.setValue("thiselementisnotthere", "bogusvalue");
Assert.fail("Expected ComponentIDNotFoundException");
} catch (ComponentIDNotFoundException e) {
// OK
}
}
@Test
public void testTypeThrowsComponentNotFound() throws IOException {
try {
client.type("thiselementisnotthere", 'b');
Assert.fail("Expected ComponentIDNotFoundException");
} catch (ComponentIDNotFoundException e) {
// OK
}
}
static void assertViewId(String expected, String actual) {
Assert.assertNotNull(expected);
Assert.assertNotNull(actual, "ViewID is null");
if (actual.endsWith(".xhtml")) {
Assert.assertEquals(expected + ".xhtml", actual);
} else if (actual.endsWith(".jsp")) {
Assert.assertEquals(expected + ".jsp", actual);
} else {
Assert.fail("Unknown ViewID ending, " + actual);
}
}
}