5 Replies Latest reply on Sep 24, 2010 2:24 PM by martinkurz

    old page in jsfClientSession

    martinkurz

      Hi,

       

      when running a jsfUnit testsuite we are occasionally facing the problem, that some ComponentIDs aren't found in jsfClientSession when trying to set some value or click a button.

       

      After some debugging and adding a RequestListener, we found out that jsfClientSession.getPageAsString() and the last servers response saved with RequestListener are different. The page in the jsfClientSession is the page before the last click (the application under test has tab navigation, test cases are switching between tabs), the page recorded with RequestListener has the expected content.

       

      Is there any way forcing the client to actualize the page or waiting for the client until the page is loaded?

       

      The application is deployed on tomcat 6 with mojarra 2.0.2 and jsfunit 1.2 (tests with jsfunit 1.3 failed also occasionally).

       

      best regards,

       

      martin

        • 1. Re: old page in jsfClientSession
          martinkurz

          For clearification of the problem: We are doing some site changes with client.click(ID) in our testcases. Sometimes, tests fail because expected elements in the page aren't found. The situation in these cases is:

           

          • client.click(ID_PAGE_1)
          • client.click(ID_PAGE_2)
          • client.click(ID_PAGE_3)
          • when assertions fail:
            • client.getContentPage().getWebResponse().getRequestSettings().getUrl() returns URL of PAGE_2 instead of expected URL of PAGE_3
            • client.getPageAsText() also shows PAGE_2 instead of PAGE3
            • our attached RequestListener records last request URL and response and shows URL and page content of PAGE_3 (as expected)

           

          We couldn't find any reproducable conditions for this to happen.

          • 2. Re: old page in jsfClientSession
            ssilvert

            Can you post an example of your JSFUnit test code?  If you have some simple markup that goes along with it, post that as well.

             

            Stan

            • 3. Re: old page in jsfClientSession
              martinkurz

              Hi Stan,

               

              thanks for your fast reply. I can't provide the original files, but the simplified setup is like the following:

               

              page one:

               

              <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
              <html xmlns="http://www.w3.org/1999/xhtml"
                  xmlns:h="http://java.sun.com/jsf/html"
                  xmlns:f="http://java.sun.com/jsf/core"
                  xmlns:ui="http://java.sun.com/jsf/facelets">
              <ui:composition template="/WEB-INF/templates/common.xhtml">
                  <ui:define name="pageTitle">Index</ui:define>
                  <ui:define name="body">
                  <h1>Hello index world</h1>
                  <p>Loem ipsum...</p>
                  <h:inputText id="textIndex"/>
                  <h:button id="saveIndex" value="saveIndex" outcome="view1"/>
                  <h:commandLink action="view1" id="view1Link">to view1</h:commandLink>
                  <h:commandLink action="view2" id="view2Link">to view2</h:commandLink>
                  </ui:define>
              </ui:composition>
              </html>

               

              page two:

               

              <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
              <html xmlns="http://www.w3.org/1999/xhtml"
                  xmlns:h="http://java.sun.com/jsf/html"
                  xmlns:f="http://java.sun.com/jsf/core"
                  xmlns:ui="http://java.sun.com/jsf/facelets">
              <ui:composition template="/WEB-INF/templates/common.xhtml">
                  <ui:define name="pageTitle">View1</ui:define>
                  <ui:define name="body">
                  <h1>Hello view1 world</h1>
                  <p>Loem ipsum...</p>
                  <h:inputText id="textView1"/>
                  <h:button id="saveView1" value="saveView1" outcome="view2"/>
                  <h:commandLink action="index" id="indexLink">to index</h:commandLink>
                  <h:commandLink action="view2" id="view2Link">to view2</h:commandLink>
                  </ui:define>
              </ui:composition>
              </html>

               

              and some more pages, linked with commandLinks.

               

              Testclass:

               

              public class JsfUnitTest extends ServletTestCase {
                  private JSFSession             jsfSession;
                  private JSFClientSession       client;
                  private JsfUnitRequestListener jsfUnitRequestListener;

                  @Override

                  public void setUp() throws IOException {
                      WebClientSpec wcSpec = new WebClientSpec("/index.xhtml");
                      WebClient webClient = wcSpec.getWebClient();
                      webClient.setRefreshHandler(new ThreadedRefreshHandler());
                      jsfUnitRequestListener = new JsfUnitRequestListener();
                      ((JSFUnitWebConnection) webClient.getWebConnection()).addListener(jsfUnitRequestListener);
                      jsfSession = new JSFSession(wcSpec);
                      client = jsfSession.getJSFClientSession();
                  }

                  public void testWrongPage() throws IOException {

                      click("form:view1Link");
                      getElement("form:saveView1");
                      click("form:view2Link");
                      getElement("form:saveView2");
                      click("form:indexLink");
                      getElement("form:saveIndex");
                  }     private Element getElement(String id) throws IOException {
                      if (id == null) {
                          return null;
                      }
                      StringBuilder debug = new StringBuilder("getElement with id '");
                      debug.append(id);
                      debug.append("' failed");
                      insertDebug(debug);
                      Element e = client.getElement(id);
                      assertNotNull(debug.toString(), e);
                      return e;
                  }

                  private void click(String id) throws IOException {

                      if (id == null) {
                          return;
                      }
                      StringBuilder debug = new StringBuilder("click on '");
                      debug.append(id);
                      debug.append("' failed");
                      insertDebug(debug);
                      assertNotNull(debug.toString(), client.getElement(id));
                      client.click(id);
                  }

                  private void insertDebug(StringBuilder debug) {

                      if (debug != null) {
                          debug.append("\n\n--- client.getContentPage().getWebResponse().getRequestSettings().getUrl() ---\n");
                          try {
                              debug.append(client.getContentPage().getWebResponse().getRequestSettings().getUrl());
                          } catch (Exception e) {
                              debug.append(e.getMessage());
                          }
                          debug.append("\n\n--- client.getPageAsText() ---\n");
                          try {
                              debug.append(client.getPageAsText());
                          } catch (Exception e) {
                              debug.append(e.getMessage());
                          }
                          debug.append("\n\n--- jsfUnitRequestListener.getUrl() ---\n");
                          try {
                              debug.append(jsfUnitRequestListener.getUrl());
                          } catch (Exception e) {
                              debug.append(e.getMessage());
                          }
                          debug.append("\n\n--- jsfUnitRequestListener.getContent() ---\n");
                          try {
                              debug.append(jsfUnitRequestListener.getContent());
                          } catch (Exception e) {
                              debug.append(e.getMessage());
                          }
                          debug.append("\n");
                      }
                  }

                  public static Test suite() {

                      return new TestSuite(JsfUnitTest.class);
                  }
              }

               

              So in the real test classes, we occasionally have failing assertions on some elements, that must be in the page after click. So I added a requestListener:

               

              public class JsfUnitRequestListener implements RequestListener {
                  private String content = null;
                  private String url     = null;

                  @Override

                  public void afterRequest(WebResponse webResponse) {
                      content = webResponse.getContentAsString();
                  }

                  @Override

                  public void beforeRequest(WebRequestSettings webRequestSettings) {
                      url = webRequestSettings.getUrl().toString();
                  }     public String getContent() {
                      return content;
                  }
                  public String getUrl() {
                      return url;
                  } }

               

              Occassionally (without any reproducable change or cirumstance), executing click or getElement (or setValue not implemented in this reduced test case) fail because no component with given id is found. And with all these noisy debug output from insertDebug(), we can see that ie after clicking the commandLink to view2 on view1, client.getContentPage().getWebResponse().getRequestSettings().getUrl() gives URL to view1, client.getPageAsText() gets content of view1, jsfUnitRequestListener.getUrl() shows URL to view2 and jsfUnitRequestListener.getContent() shows content of view2. The biggest problem is, that we can't force the tests to fail, it seems totally unpredictable.

               

              Sincerely,

               

              martin

              • 4. Re: old page in jsfClientSession
                ssilvert

                Why are you setting the ThreadedRefreshHandler?

                • 5. Re: old page in jsfClientSession
                  martinkurz

                  I found that in http://community.jboss.org/message/71308#71308 and simply tried ThreadedRefreshHandler, originally we simple did

                   

                  jsfSession = new JSFSession("/index.xhtml");

                   

                  but that failed occassionaly too. Seems not to be an allready known behaviour.