9 Replies Latest reply on Apr 9, 2008 5:16 PM by Stan Silvert

    Mix JSFClientSessionAPI and WebResponse does not work

    Alexander Jesse Newbie

      I have the need to navigate to a certain page using the WebResponse.getLinkWith().click() method and when a certain page is reached I must use the JSFClientSessionAPI-methods.

      I start setting up the JSFClientSession starting on a valid JSF-page. From that I fetch the WebResponse and navigate to the target page. So far this works ok. But when I then try to use the JSFClientSessionAPI again to continue my usecase I find it is out of sync...

      JSFClientSession jsfClientSession = new JSFClientSession("/pages/index.jsf");
      JSFServerSession jsfServerSession = new JSFServerSession(jsfClientSession);
      WebResponse webResponse = jsfClientSession.getWebResponse();
      webResponse = webResponse.getLinkWith("USECASES").click();
      webResponse = webResponse.getLinkWith("SearchListDetail").click();
      webResponse = webResponse.getLinkWith("List All CDs").click();
      webResponse = webResponse.getLinkWith("USECASES").click();
      // --- so far it works. Now I have a table with some records and would like to click on a commandlink:
      jsfClientSession.clickCommandLink("searchlistdetailListForm:cdList:0:details");
      // doing this in a browser works... but the jsfClientSession does not find the existing link...
      


      sample link "USECASES":
      <a href="/csJsfSample/usecases/cancel/cancelForm.jsf?nav=npl&nav-id=usecases&javax.faces.ViewState=j_id13:j_id14" title="CsJsf Usecase Examples">USECASES</a>
      This is rendered by some navigation-component and analyzed by a phaselistener...
      


      Is this supposed to work and maybe a bug that it doesn't? Or is it a user-error because it is not supposed to work? Are there work-arounds?

        • 1. Re: Mix JSFClientSessionAPI and WebResponse does not work
          Stan Silvert Master

          Instead of this:

          webResponse = webResponse.getLinkWith("USECASES").click();
          webResponse = webResponse.getLinkWith("SearchListDetail").click();


          Try this:

          jsfClientSession.doWebRequest(webResponse.getLinkWith("USECASES").getRequest());
          jsfClientSession.doWebRequest(webResponse.getLinkWith("SearchListDetail").getRequest());
          .
          .
          .
          


          That should keep things in sync.

          Does the response to getLinkWith("USECASES") contain a JSF-rendered comand link with id="searchlistdetailListForm:cdList:0:details"? If so I think it will work.

          Stan

          • 2. Re: Mix JSFClientSessionAPI and WebResponse does not work
            Alexander Jesse Newbie

             

            "stan.silvert@jboss.com" wrote:
            Instead of this:
            webResponse = webResponse.getLinkWith("USECASES").click();
            webResponse = webResponse.getLinkWith("SearchListDetail").click();


            Try this:

            jsfClientSession.doWebRequest(webResponse.getLinkWith("USECASES").getRequest());
            jsfClientSession.doWebRequest(webResponse.getLinkWith("SearchListDetail").getRequest());
            .
            .
            .
            


            That should keep things in sync.

            That's the way the "doWebRequest" works... I will try and report back.

            "stan.silvert@jboss.com" wrote:
            Does the response to getLinkWith("USECASES") contain a JSF-rendered comand link with id="searchlistdetailListForm:cdList:0:details"? If so I think it will work.

            It is a link that has to be processed through JSF, but is not rendered like a commandLink or outputLink... long story of a navigation-component that works in a perfect world (== without Javascript)

            • 3. Re: Mix JSFClientSessionAPI and WebResponse does not work
              Stan Silvert Master

               

              "AleJesse" wrote:


              "stan.silvert@jboss.com" wrote:
              Does the response to getLinkWith("USECASES") contain a JSF-rendered comand link with id="searchlistdetailListForm:cdList:0:details"? If so I think it will work.

              It is a link that has to be processed through JSF, but is not rendered like a commandLink or outputLink... long story of a navigation-component that works in a perfect world (== without Javascript)


              In that case, you might have to write your own special processor for it. All you have to do is create the proper WebRequest object and pass it to JSFClientSession.doWebRequest().

              Stan

              • 4. Re: Mix JSFClientSessionAPI and WebResponse does not work
                Alexander Jesse Newbie

                Stan the last hint works... I now have my BaseTestCase which has a method myNavigation(String navigationId).

                BUT... (seems there is always a but,...)
                I had to copy&paste a private method from a JSFUnit-class, which, being a refactoring freak, calls for a nifty little new JSFUnit-class, or an addition to an existing utility- or helper-class.

                package some.package;
                
                import com.meterware.httpunit.PostMethodWebRequest;
                import com.meterware.httpunit.WebResponse;
                
                import org.jboss.jsfunit.facade.JSFClientSession;
                
                public class JsfUnitUtilities {
                 /**
                 * <p>Construct the basics of a post-request from an action-url.</p>
                 * <p>This method is copied from org.jboss.jsfunit.facade.WebRequestFactory < br />
                 * A request should be made to extract that method into a utility-class.</p>
                 * @param actionURL
                 * @return
                 *
                 */
                 static public PostMethodWebRequest makePostRequest(JSFClientSession jsfClientSession, String actionURL) {
                 WebResponse latestResponse = jsfClientSession.getWebResponse();
                 String protocol = latestResponse.getURL().getProtocol();
                 String host = latestResponse.getURL().getHost();
                 String port = Integer.toString(latestResponse.getURL().getPort());
                 return new PostMethodWebRequest(protocol + "://" + host + ":" + port + actionURL);
                 }
                }
                

                Is that a good idea?
                well there may be other methods to pack into there... (eg. makeGetRequest)

                • 5. Re: Mix JSFClientSessionAPI and WebResponse does not work
                  Stan Silvert Master

                  Can't you just create your own instance of WebRequestFactory and call one of its public methods?

                  Granted, this part of the API could use some work to make it more usable.

                  Stan

                  • 6. Re: Mix JSFClientSessionAPI and WebResponse does not work
                    Alexander Jesse Newbie

                    No, I tried... but the nav-fw we use is using something in between the normal JSF-commandlink and a normal html-link.

                    - does not put the links into the component tree
                    - is not within a form. The form is at some remote angle of the page
                    - it renders differently in case Javascript is enabled or disabled

                    So my method just checks all methods... and selects the one that fits... in one case it will create a POST-request (with some of the parameters within the form and others passed as link-parms...) in another one it will just submit the html-link and it tries to submit it as JSF-link...

                    • 7. Re: Mix JSFClientSessionAPI and WebResponse does not work
                      Stan Silvert Master

                      I see. So what if I just make WebRequestFactory.makePostRequest() a public method? Would that be worthwhile?

                      Stan

                      • 8. Re: Mix JSFClientSessionAPI and WebResponse does not work
                        Alexander Jesse Newbie

                        Sure, then I would call that. The final decision is up to you.
                        I just wonder whether such a utility-class might not make sense anyway...