Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Cypress integration

    SNAPSHOT_v13.1d_2023-09-21/Enterprise Deployment

    Hello, I'm trying Cypress, and I just noticed that I've got to remove the inclusion from loginSuccessMarker.html from my index.jsp, otherwise the global variable isc will be null (I'm using portal mode).

    Is it expected or it's possible to make it work with the loginSuccessMarker.html?

    #2
    Hi Claudio,

    Not sure if you've seen the latest doc updates, but we are in the midst of creating Cypress support:

    https://smartclient.com/smartclient-...tClientCypress

    If you email us at support@isomorphic.com we can loop you in on the work we're doing - in particular we have a .js file that has a bunch of custom Cypress commands.

    As a customer with support, you are welcome to join in on refining our Cypress support as a beta tester.

    As to your specific question - what's going on with the loginSuccessMarker? It doesn't assign anything to window.isc, indeed, it should not have side effects at all. What specifically are you seeing?

    Comment


      #3
      SmartClient Version: SNAPSHOT_v13.1d_2023-09-27/Enterprise Deployment (built 2023-09-21)

      Hello, sorry, I forgot to specify that I started trying Cypress right after I saw the documentation (which now you linked me to).
      I'm actually already using the file tools/cypress/commands.js and have managed to set up some simple tests in my application.
      However, I had to remove the inclusion of the loginSuccessMarker.html file.
      I tried to add some logs in it, at the end of the script:
      Code:
      console.log("isc: " + isc)
      var isc = window.parent ? window.parent.isc : null;
      console.log("isc: " + isc)
      if (!isc) isc = top.isc ? top.isc : window.opener ? window.opener.isc : null;
      console.log("isc: " + isc)
      if (isc && isc.RPCManager) isc.RPCManager.delayCall("handleLoginSuccess", [window]);
      and this is what I see in the console. I assume it has to do with the iframe that Cypress creates to run the application?
      Code:
      isc: [object Object]
      isc: undefined
      isc: null
      about emailing at support@isomorphic.com, do you mean having access to something before even it gets included it the latest 13.1 ?

      Comment


        #4
        Hi Claudio, if you're grabbing the latest 13.1d builds, you're already on the bleeding edge, but we would recommend pulling new builds frequently, as this is a very active area of development. Contacting us via email just means we could loop you in on proposed changes before they even land in the build. It's totally fine to just continue on the forums and have you just pulling development builds as you already are.

        Regarding the loginSuccessMarker, we're having trouble understanding what's going wrong here. The Cypress commands.js file doesn't include the loginSuccessMarker, so presumably, you mean you've got a post-login response with that marker included.

        However, the loginSuccessMarker has logic to avoid clobbering window.isc. Is it possible that you have an older version of it that isn't as careful? Please check it against the latest version.

        Comment


          #5
          Hello, I've got the loginSuccessMarker included in my index.jsp page, it's the version included with the build:

          Code:
          <SCRIPT>//'"]]>>isc_loginSuccess
          //
          // When doing relogin with a webserver-based authenticator, protect this page with it and
          // target your login attempts at this page such that when the login succeeds, this page is
          // returned.
          //
          // If you are integrating with a web service that returns a fault, paste this entire script
          // block VERBATIM into the fault text.
          //=======
          
          
          
          if (!window.isc && (window.opener != null || window.parent != window)
              && document.domain && document.domain.indexOf(".") != -1
              && !(new RegExp("^(\\d{1,3}\\.){3}\\d{1,3}$").test(document.domain)))
          {
          
              var set = false;
              while (document.domain.indexOf(".") != -1) {
                  try {
          
                      if (window.parent && window.parent.isc) break;
                      if (window.opener && window.opener.isc) break;
                      if (window.top.isc) break;
          
                      if (!set) { document.domain = document.domain; set = true; }
                      else { document.domain = document.domain.replace(/.*?\./, ''); }
                  } catch (e) {
                      try {
                          if (!set) { document.domain = document.domain; set = true }
                          else { document.domain = document.domain.replace(/.*?\./, ''); }
                      } catch (ee) {
                          break;
                      }
                  }
              }
          }
          
          var isc = window.parent ? window.parent.isc : null;
          if (!isc) isc = top.isc ? top.isc : window.opener ? window.opener.isc : null;
          if (isc && isc.RPCManager) isc.RPCManager.delayCall("handleLoginSuccess", [window]);
          </SCRIPT>
          this time I've added more useful (I hope) logs, ie I've modified the last 3 lines like this:
          Code:
          console.log('window.parent.isc:'+window.parent.isc)
          var isc = window.parent ? window.parent.isc : null;
          console.log('isc:'+isc)
          console.log('top.isc:'+top.isc)
          console.log('window.opener:'+window.opener)
          if (!isc) isc = top.isc ? top.isc : window.opener ? window.opener.isc : null;
          if (isc && isc.RPCManager) isc.RPCManager.delayCall("handleLoginSuccess", [window]);
          </SCRIPT>
          and these are the logs:
          Code:
          window.parent.isc:undefined
          isc:undefined 
          top.isc:undefined 
          window.opener:null

          Comment


            #6
            If the loginSuccessMarker is at the top of your index.jsp, before SmartClient is loaded, then those logs would be expected and are normal.

            The loginSuccessMarker is only meant to actually do anything when your index.jsp is loaded as the result of a background request at the end of the relogin process, in which case that code is meant to navigate out of an iframe or satellite window, find SmartClient, and notify it of login success.

            When the loginSuccessMarker executes in index.jsp when index.jsp is in the top-level window, it is meant to no-op, and your logs seem to show that it does so correctly.

            As far as Cypress being unable to handle this, two things:

            1) is the loginSuccessMarker embedded before or after the loading of SmartClient? If after, try placing it before instead

            2) what specifically happens when the marker is present? Are you saying that it appears to wipe out the "isc" variable somehow, such that later use of SmartClient (e.g. "isc.ListGrid.create({ ..." ) crashes?

            Comment


              #7
              Hello, actually placing the loginSuccessMarker before loading SmartClient did the trick, thanks.

              Now it seems that there's some problem with the Notify system. I've got a non-dismissable Notify, default duration of 5000ms. After it's shown, my test opens a modal Window, and uses getSC() to try typing in the filter editor of a grid contained in the window.
              But the test fails after 4000ms of timeout .
              The test is successful if I remove the Notify, or if I reduce its duration to 1000ms.

              Also note that adding a timeout:
              Code:
              cy.getSC(locator, {timeout: 10*1000})
              doesn't help, it fails anyway after 4000ms, so it seems that the timeout isn't working?

              Comment


                #8
                If you are trying to do something in the satellite window, that should not, in any way, be affected by a Notify in the main window. Notifies aren't even blocking.

                Our guess would be that your attempt to drive the satellite window is not working - you are still in the main window. In particular, cy.getSC() is not going to automatically navigate to an element in a satellite window.

                So the test is probably actually trying to interact with something in the main window. It's probably using extreme fallback strategies, and ending up finding just about anything on the screen it can type into.

                Comment


                  #9
                  Hello, it seems that I could reproduce the problem with this test case:

                  Code:
                  describe('isc test case', () => {
                      beforeEach(() => {
                          cy.visit('https://www-demos.smartclient.com/smartclient-latest/showcase/?id=notifications&skin=Twilight')
                      });
                      it('problem with Notify', () => {
                          cy.getSC("//testRoot[]/child[Class=VLayout||index=0||length=1||classIndex=0||classLength=1]/member[Class=Button||index=1||length=2||classIndex=0||classLength=1||roleIndex=0||roleLength=1||title=Send||scRole=button]/").click()
                          cy.getSC("//testRoot[]/child[Class=VLayout||index=0||length=1||classIndex=0||classLength=1]/member[Class=DynamicForm||index=0||length=2||classIndex=0||classLength=1]/item[name=text||title=Message||value=Download%20complete||index=1||Class=TextItem]/element")
                      });
                  });
                  this simple test fails for me. Also note that adding {timeout:10*1000} as a second argument of the 2nd (and last) getSC command doesn't help, as it seems to have no effect.

                  Comment


                    #10
                    Thanks for the test case Claudio - we see what's going on here and will have a fix for it in the next nightly build (Oct 5 or above)
                    Regards
                    Isomorphic Software

                    Comment


                      #11
                      For context, our Cypress support has a system of automatic waits, where it waits for the whole system to quiesce (all pending redraws done, all RPCs complete) and then proceeds. This allows you to set aggressive timeout and get quick feedback when lots of tests are failing, because you basically know that if all pending actions are done, but your element isn't there, that's a failure.

                      We had neglected to mark the timer for auto-dismissing Notifies as something we don't need to automatically wait for. Hence the behavior with the Notifies.

                      Comment


                        #12
                        SmartClient Version: SNAPSHOT_v13.1d_2023-10-05/Enterprise Deployment (built 2023-10-05)

                        I can confirm that now it's working, thank you very much!

                        BTW, what about the timeout for the getSC method, is it true that has no effect?

                        Comment


                          #13
                          Hi Claudio
                          There is more than one type of timeout at play here.

                          The custom getSC() command we provide makes use of cy.window().then(....) to actually resolve the locator to the element.

                          In the version of getSC() you have, this "then()" command from Cypress will timeout based on the Cypress defaultCommandTimeout which is 4000ms, and that's the timeout that was causing the above problem.

                          In addition to that, the actual SmartClient "waitForElement()" command has a timeout which determines how long it will wait for the SmartClient application to quiesce and make the element available, which defaults to 30 seconds, but can be overridden via the options.timeout passed to getSC().

                          So another solution to the issue you faced would be to increase the cypress defaultCommandTimeout so it exceeded the 5 second wait for the Notify message to hide.


                          However - we realize that this is confusing so we're making a couple of changes to the getSC definition in the sample command.js file to make this area work more intuitively.
                          If you check out the new version (available in the next nightly build), we've modified things so the "then()" command will be derived from the timeout specified as part of the getSC() options argument, and we've also made it possible to specify a system wide default timeout for getSC commands directly in Cypress' config.js file.
                          (This will be covered in the updated Cypress overview docs)


                          Regards
                          Isomorphic Software

                          Comment


                            #14
                            Hello, I've got another question.

                            Would it be feasible to have a custom command to make tests fail if a DSResponse has status < 0 ?

                            Do you think it could make sense for situations where the response does not update the UI ?

                            Comment


                              #15
                              Surely it has some ultimate impact on the UI, otherwise, you wouldn't make the request :)

                              However, you could take the approach of having your test code add a transformResponse handler who's only actual impact is to manually fail the test if it sees a DSResponse with a status code indicating failure.

                              Comment

                              Working...
                              X