Testing rich:fileUpload with HtmlUnit
freemarket Dec 5, 2008 2:59 PMI have the following test:
/* * based on jboss tests */ package org.jboss.jsfunit.test.richfaces; import com.gargoylesoftware.htmlunit.html.HtmlFileInput; import com.gargoylesoftware.htmlunit.html.HtmlForm; import com.gargoylesoftware.htmlunit.javascript.host.Element; import java.io.File; import java.io.IOException; import java.util.ArrayList; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.cactus.ServletTestCase; 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.jsfunit.richclient.RichFacesClient; /** * Peform JSFUnit tests on RichFaces demo application. * * @author Stan Silvert */ public class RichFileUploadTest extends ServletTestCase { private JSFSession jsfSession; private JSFClientSession client; private RichFacesClient ajaxClient; private JSFServerSession server; public void setUp() throws IOException { this.jsfSession = new JSFSession("/richfaces/fileUpload.jsf"); this.client = jsfSession.getJSFClientSession(); this.ajaxClient = new RichFacesClient(this.client); this.server = jsfSession.getJSFServerSession(); } public void tearDown() throws Exception { this.jsfSession = null; this.client = null; this.ajaxClient = null; this.server = null; } public void testFilePresent() throws IOException { final String filename = "D:\\Notes-hkatz\\images\\support_desk.png"; ArrayList<File> uploadedFiles = setFileParameter(filename); assertEquals(1, uploadedFiles.size()); for (File upf : uploadedFiles) { System.out.println("file: " + upf.getAbsolutePath() + ", size: " + upf.length()); } } public static Test suite() { return new TestSuite( RichFileUploadTest.class ); } private ArrayList<File> setFileParameter(String filename) { final String uploadForm = "uploadform"; final String uploadBtn = "uploadform:upload:upload1"; final String uploadTextInput = "uploadform:upload:file"; File f = new File(filename); if (!f.exists()) { System.out.println("Page.setFileParameter: file does not exist: " + f.toString()); return null; } assertNotNull(client.getElement(uploadForm)); // assertNull(client.getElement(uploadBtn)); // false assumption that upload button not rendered // stuff filename into widget HtmlFileInput inputWidget = (HtmlFileInput)client.getElement(uploadTextInput); try { inputWidget.type(filename); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } assertNotNull(client.getElement(uploadBtn)); try { client.click(uploadBtn); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return (ArrayList<File>)server.getManagedBeanValue("#{fileUploadBean.files}"); } }
which runs against the following facelet (straight from the Richfaces demo for 3.2.2):
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich"> <style> .top { vertical-align: top; } .info { height: 202px; overflow: auto; } </style> <h:form id="uploadform"> <h:panelGrid columns="2" columnClasses="top,top"> <rich:fileUpload fileUploadListener="#{fileUploadBean.listener}" maxFilesQuantity="#{fileUploadBean.uploadsAvailable}" reRender="table" id="upload" immediateUpload="#{fileUploadBean.autoUpload}" acceptedTypes="jpg, gif, png, bmp" allowFlash="#{fileUploadBean.useFlash}"> <a4j:support event="onuploadcomplete" reRender="info" /> </rich:fileUpload> <h:panelGroup id="info"> <rich:panel bodyClass="info"> <f:facet name="header"> <h:outputText value="Uploaded Files Info" /> </f:facet> <h:outputText value="No files currently uploaded" rendered="#{fileUploadBean.size==0}" /> <rich:dataGrid columns="1" value="#{fileUploadBean.files}" var="file" rowKeyVar="row"> <rich:panel bodyClass="rich-laguna-panel-no-header"> <h:panelGrid columns="2"> <a4j:mediaOutput element="img" mimeType="#{file.mime}" createContent="#{fileUploadBean.paint}" value="#{row}" style="width:100px; height:100px;" cacheable="false"> <f:param value="#{fileUploadBean.timeStamp}" name="time"/> </a4j:mediaOutput> <h:panelGrid columns="2"> <h:outputText value="File Name:" /> <h:outputText value="#{file.name}" /> <h:outputText value="File Length(bytes):" /> <h:outputText value="#{file.length}" /> </h:panelGrid> </h:panelGrid> </rich:panel> </rich:dataGrid> </rich:panel> <rich:spacer height="3"/> <br /> <a4j:commandButton id="uploadBtn" action="#{fileUploadBean.clearUploadData}" reRender="info, upload" value="Clear Uploaded Data" rendered="#{fileUploadBean.size>0}" /> </h:panelGroup> </h:panelGrid> </h:form> </ui:composition>
The apparent attempts to stuff a filename into the HtmlInput widget (type=file) which is a HtmlFileInput object under HtmlUnit is unsuccessful as determined during a debug session in the JBDS 1.1.0 GA ide as the managed bean has not detected anything. Nor is clicking on the apparent DIV html structure which has the proper JS callbacks (according to firebug) invoking the loading of the image file.
The prior poster has a HttpUnit variant which I chose not to repeat as this is deprecated. Is my inspection of the generated HTML/javascript incorrect and if so how do I simulate the selection of a file from the file browser and subsequent clicking of the "ADD" button to upload this file via this rich:fileUpload widget?
Thanks,
Henry