JSFUnitWithRichFaces

Introduction

RichFaces/Ajax4jsf is the first Ajax component library to be supported by JSFUnit.  Our plan is to make sure that all of the popular JSF libraries work well with JSFUnit.

RichFaces and JSFUnit

Since JSFUnit now uses HtmlUnit, the javascript is executed natively when you tell JSFUnit to "click" something.  So for most things, you can use the JSFClientSession as usual.

 

But for some complex components, you will need to make calls using the HtmlUnit API.  To help with that you can use the RichFacesClient that already knows how the RichFaces components are rendered, and thus knows how to call HtmlUnit to do what you need.  The RichFacesClient lives in a seperate jar.  Click Here to Download.

Using the RichFacesClient API

The RichFacesClient takes a JSFClientSession in its constructor.  After that, you can call any of its methods to help you manipulate RichFaces components.

 

JSFSession jsfSession = new JSFSession("/home.jsf");
JSFClientSession client = jsfSession.getJSFClientSession();
RichFacesClient richClient = new RichFacesClient(client);

New <rich:tree> support in JSFUnit 1.2

There are three new methods for working with <rich:tree>.  These methods will only work if your tree nodes display text.  They use complex xpath expressions to find the HtmlElement you need to manipulate.  Here are the methods.

  • public HtmlElement getTreeHandle(String treeID, String treeNodeID, String nodeText)
  • public boolean isTreeHandleExpanded(String treeID, String treeNodeID, String nodeText)
  • public HtmlElement getTreeNodeByText(String treeID, String componentID, String nodeText)

Note that in getTreeNodeByText(), the second param is componentID rather than treeNodeID.  You should provide the id of whatever JSF component contains the desired text.  See example below.

 

If you are viewing this page before the release of JSFUnit 1.2, you can try out the snapshot attached at the bottom of this page.

 

For each of these methods, you will need the component ID for the tree and the node you are working with.  Then you need to give the text that is displayed with the node. For example, say I have the following tree:

<rich:tree id="ajaxTree" switchType="ajax" value="#{library.data}" var="item">
  <rich:treeNode id="ajaxTreeArtistNode" type="artist" iconLeaf="singer.gif" icon="singer.gif">
    <h:commandLink id="artistLink" value="#{item.name}"/>
  </rich:treeNode>
 

  <rich:treeNode id="ajaxTreeAlbumNode" type="album" iconLeaf="disc.gif" icon="disc.gif">
    <h:commandLink id="albumLink" value="#{item.title}"/>
  </rich:treeNode>

</rich:tree>

To open the artist formerly known as Prince and select his Purple Rain album, I would do this in my test:

JSFSession jsfSession = new JSFSession("/home.jsf");
JSFClientSession client = jsfSession.getJSFClientSession();
RichFacesClient richClient = new RichFacesClient(client);

assertFalse(richClient.isTreeHandleExpanded("ajaxTree", "ajaxTreeArtistNode", "Prince"));
HtmlElement handle = richClient.getTreeHandle("ajaxTree", "ajaxTreeArtistNode", "Prince");
handle.click();
assertTrue(richClient.isTreeHandleExpanded(
"ajaxTree", "ajaxTreeArtistNode", "Prince"));

HtmlElement purpleRainLink =
   richClient.getTreeNodeByText("ajaxTree", "albumLink", "Purple Rain"));
purpleRainLink.click();

Other RichFacesClient methods

Except for the methods used with <rich:tree> all RichFaces methods use a componentID parameter to find the target component to set/click/slide/whatever:

  • public void dragAndDrop(String dragComponentID, String dropComponentID)  // new in JSFUnit 1.3
  • public void setDataFilterSlider(String componentID, String value)
  • public void setCalendarValue(String componentID, String value)
  • public void setInplaceInput( String componentID, String value, String customSaveID )
  • public void setInplaceInput( String componentID, String value )
  • public void clickTreeNodeHandle( String treeNodeKey, String treeNodeId )  // deprecated in JSFUnit 1.2
  • public void clickTab(String tabComponentID)
  • public void setComboBox(String componentID, String value)
  • public void setInputNumberSpinner(String componentID, String value)
  • public void clickInputNumberSpinnerUp(String componentID)
  • public void clickInputNumberSpinnerDown(String componentID)
  • public void setInputNumberSlider(String componentID, String value)

 

Click here for javadoc and further details of the above methods.

 

For manipulating more complex components and for custom behavior, see Using the HtmlUnit API with JSFUnit.