NightwatchJS – re-perform a client.execute() function on fail

Posted on Posted in Web Development

A snippet to perform a certain action again, if it fails

In my current job, I also write NightwatchJS tests in order to automatically run tests for a software. During development, our team realized that sometimes you cannot know whether or not an event handler has already attached to a certain dynamically created DOM object – for example, a modal window.

For this reason, I developed a semi-recursive function that lets you try a certain client.execute() function several times before failing.

The first thing it does it that it makes the client.execute()¬†function synchronous (rather than asynchronous) by using client.perform(). Otherwise all tries would be started at once and therefore it wouldn’t really give us any benefit.

Then, we create a logic that appends the function to our iteration-function so that we know when to let the test fail. Finally, the client.execute() function is invoked.

For any problems, questions or suggestions, feel free to leave a comment below.

      /**
      * This function tries a certain operation (using clien.execute()) several times
      * @param {Object} client The client (or browser) object.
      * @param {Function} executeFunction The function that should be executed in the remote DOM
      * @param {Array} parameters The parameters that will be passed to the executeFunction. If no arguments are necessary, pass an empty array []
      * @param {function(result)} callbackFunction The callback function that gets the result parameter after the executeFunction is finished. In this callback function, you need to return false of the test failed and true of the test succeeded
      * @param {Number} maxTries The maximum amount of trials
      */
     function try(client, executeFunction, parameters, callbackFunction, maxTries) {
       // we wrap it in a client.perform() so that the client.execute() is asynchronous
       client.perform(function() {
        //this is a tricky one - we experience during tests that sometimes we need to click several times on the first header in
        //order to get the input field working. For this case, we developed a self invoking function that tries up to {maxTries} times to
        //get into the input field to change the header. After maxTries times, it will fail
          var doItAgain = function(iteration) {
            //let's wait a bit - maybe it works now
            client.pause(100);
              if(typeof iteration === "undefined") {
                // check the iteration - the first call doesn't have this parameter attached, so it has to be 0
                iteration = 0;
              }
              iteration++;
              if(iteration > maxTries) {
                // this lets the tests fail, so we know it didn't work
                client.assert.equal(true, false, 'Tried doing X for ' + maxTries + ' times and it still failed.');
                //after trying maxTries times, let it be
                return;
              }
              //this appends the callback to the doItAgain function
              var joinedFunctions = function(result) {
                  if(!callbackFunction(result)) {
                    doItAgain(iteration);
                  }
              };
              // invoke the client.execute() function with our joinedFunctions
              client.execute(executeFunction, parameters, joinedFunctions);
            };
          // after declaring the function, invoke it once
          doItAgain();
        });
     }

Please feel free to use this function wherever you might need it.

If you are new to NightwatchJS, here is the link:

http://nightwatchjs.org/

Happy coding!

Leave a Reply

Your email address will not be published. Required fields are marked *