5 Replies Latest reply on Jun 13, 2008 10:46 AM by Stan Silvert

    also problems with myfaces/tomahawk command links in datatab

    L Kr Newbie

      Hi,

      after reading this post http://www.jboss.com/index.html?module=bb&op=viewtopic&t=136815 I've used the current sources from svn to click a myfaces/tomahawk command link in a datatable. What makes me wonder, that jsfunit seems to find the right component but I can't click it. Here's a simple example:

      <html
       xmlns="http://www.w3.org/1999/xhtml"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:t="http://myfaces.apache.org/tomahawk">
      
      <t:dataTable
       ...
       <t:column> <t:commandLink forceId="true" forceIdIndex="true" id="plantName_1" rendered="true"/></t:column>
       <t:column> <t:commandLink forceId="true" forceIdIndex="true" id="plantName_2" rendered="false"/></t:column>
       ...
      </t:dataTable
      


      The html output looks like:
      <a href="#" onclick="return oamSubmitForm('f','plantName_2[0]');" id="plantName_2[0]">1017394342537</a>
      <a href="#" onclick="return oamSubmitForm('f','plantName_2[1]');" id="plantName_2[1]">1017395465464</a>
      


      My test looks like :
      jsfSession = new JSFSession("/faces/presentation/login.xhtml");
      client = jsfSession.getJSFClientSession();
      server = jsfSession.getJSFServerSession();
      ...
      doLogin();
      ..
      assertEquals("/presentation/plant_selection.xhtml", server.getCurrentViewID());
      UIComponent component1 = server.findComponent("plantName_2[0]");
      assertNotNull(component1);
      assertTrue(component1 instanceof HtmlCommandLink);
      assertTrue(component1.isRendered());
      HtmlCommandLink link1 = (HtmlCommandLink)component1;
      client.click(link1.getId());
      


      This causes the following exception:
      org.jboss.jsfunit.jsfsession.ComponentIDNotFoundException: No component ID was found for plantName_2
      org.jboss.jsfunit.jsfsession.ClientIDs.findClientID(ClientIDs.java:172)
      org.jboss.jsfunit.jsfsession.JSFClientSession.getElement(JSFClientSession.java:197)
      org.jboss.jsfunit.jsfsession.JSFClientSession.click(JSFClientSession.java:153)
      


      But
      assertTrue(component1.getId().equals("plantName_2[0]"));
      returns false, because component1.getId() returns "plantName_2".

      If I don't use forceId or change t:commandLink to h:commandLink the html output looks like
      <a href="#" onclick="return oamSubmitForm('f','f:plant_selection_data:0:j_id94');" id="f:plant_selection_data:0:j_id94">1017394342537
      <a href="#" onclick="return oamSubmitForm('f','f:plant_selection_data:1:j_id94');" id="f:plant_selection_data:1:j_id94">1017395465464
      


      But now I'm having another problem: server.findComponent() returns a value (not null) but getId() returns j_id94 instead of f:plant_selection_data:0:j_id94.
      Without "validating the id with assert I'm getting this exception:
      org.jboss.jsfunit.jsfsession.DuplicateClientIDException: j_id94 matches more than one JSF component ID. Use a more specific ID suffix. Suffix matches: f:plant_selection_data:0:j_id94 ..
      org.jboss.jsfunit.jsfsession.ClientIDs.findClientID(ClientIDs.java:174)
      org.jboss.jsfunit.jsfsession.JSFClientSession.getElement(JSFClientSession.java:197)
      org.jboss.jsfunit.jsfsession.JSFClientSession.click(JSFClientSession.java:153)
      com.conergy.sunreader.web.PlantDataJSFTest.testPlantDataChangeExtended(PlantDataJSFTest.java:43)
      



      I'm also using the latest httpunit and htmlunit versions. So what's wrong here ?

      Thanks, Lothar

        • 1. Re: also problems with myfaces/tomahawk command links in dat
          Stan Silvert Master

          ID handling gets a little tricky with DataTables. It's unusual to try to get at the ID from the server side, but if you do that you need to use UIComponent.getClientID() instead of UIComponent.getID(). The JSFClientSession always matches based on a suffix of the client ID. Doing this with a DataTable makes it tougher because you usually need to set the row index before getClientID() will return the correct value.

          I'm not familiar with how Tomahawk renders its ID's, but it looks like you might need to add an ID in your markup somewhere for this to be generated

          id="f:plant_selection_data:0:j_id94"

          Whatever component gave you "j_id94" should get an id attribute so that JSF doesn't assign one for you. That way, you wouldn't need to look at the server side and you could just call something like:
          client.click("plant_selection_data:0:foo");

          Of course, if Tomahawk won't let you give it a proper ID then shame on Tomahawk!

          Stan

          • 2. Re: also problems with myfaces/tomahawk command links in dat
            L Kr Newbie

            Hi Stan,

            I previously tried to assign an id by myself. But I can't get it work ;(
            The id in the facelets view looks like "plantName_2" and because of the datatable in the generated html code the id would be "plantName_2[0]" or "plantName_2[1]" and so on. What I don't understand is that the call of server.findComponent("plantName_2[0]") returns a value but the call of client.click("plantName_2[0]")) causes a NullPointer :

            java.lang.NullPointerException
            org.jboss.jsfunit.jsfsession.JSFClientSession.click(JSFClientSession.java:154)
            com.conergy.sunreader.web.PlantDataJSFTest.testPlantDataChangeExtended(PlantDataJSFTest.java:44)
            


            And the call of client.click(component1.getClientId(server.getFacesContext()))) causes another exception:
            org.jboss.jsfunit.jsfsession.ComponentIDNotFoundException: No component ID was found for plantName_2
            org.jboss.jsfunit.jsfsession.ClientIDs.findClientID(ClientIDs.java:172)
            org.jboss.jsfunit.jsfsession.JSFClientSession.getElement(JSFClientSession.java:197)
            org.jboss.jsfunit.jsfsession.JSFClientSession.click(JSFClientSession.java:153)
            com.conergy.sunreader.web.PlantDataJSFTest.testPlantDataChangeExtended(PlantDataJSFTest.java:44)
            

            That's right because the index "[0]" at the end is missing. Without assigning an id by myself the id looks like "f:plant_selection_data:0:j_id94" but getClientID() returns "f:plant_selection_data:j_id94" (or "plantName_2"). For me it looks like that the index is always missing.

            Of course if there is a better way to click a link in datatable I really would like to hear it.

            Thanks, Lothar

            • 3. Re: also problems with myfaces/tomahawk command links in dat
              Stan Silvert Master

              The id looks more "normal" when you don't use forceId. This is the first time I've seen an ID that has "[0]" in it. It's more normal to have something like "foo:0:bar".

              The issue here is whether or not JSFUnit found the ID of your component and if you are passing a unique suffix of that ID to JSFClientSession.click().

              The id's are gathered on the server side. You can dump all of the id's that JSFUnit found by saying:

              JSFServerSession.getClientIDs().dumpAllIDs()

              That will just dump all the IDs that JSFUnit found to standard out. Then you can see if JSFUnit found the IDs that actually end up on your page.

              Again, there is the problem of the "j_id94". We need to find out where that came from. Tomahawk should give you a way to set your own ID for that instead of the auto-generated "j_id94".

              Stan

              • 4. Re: also problems with myfaces/tomahawk command links in dat
                L Kr Newbie

                Hi Stan,

                When I don't use forceId and set an id by hand (what I did already before) "getClient().click(id)" works now for me ;)

                But because we use forceId very often it would be nice if it will works sometimes in the future. It was not clear to me that the id I've set in the source will be used even without forceId.

                Lothar

                • 5. Re: also problems with myfaces/tomahawk command links in dat
                  Stan Silvert Master

                  OK. I've created a jira task to track this issue:
                  http://jira.jboss.com/jira/browse/JSFUNIT-98

                  You can attach sample code to the jira if needed. Any help such as that and/or patches would be greatly appreciated. Since this only affects Tomahawk components with forceId, it's something that I won't be able to spend much time on for awhile.

                  Stan