Customizing Test Script

AppPerfect Load Test stores the recorded test in javascript format. A separate javascript function is created for each node/task visible in the Editor UI. One can edit a task either in UI or in the script editor. UI and the script are always in sync with each other i.e. a change made in UI is reflected back in the script and vice-versa.

Following topics are covered in this chapter :

Editing in Script Editor

You can view and edit the script in script editor provided in the Load Test. It can be invoked in any of the following way:
    a. Selecting the Script editor toolbar button.
    b. Selecting Project -> Script Editor.. menu option
    c. Right click on the Editor Tree and select Script Editor...

You have an option of saving and compiling the script in the editor. These options are available in toolbar and menu bar. Once the test is saved and the editor is closed, the UI is synchronized as per the changes in the script.

Adding Custom Code to Test Script

You can reuse the code in your custom classes in AppPerfect Test Script. You can add your own custom code to the test script. To use any custom classes in the script you should first configure the classpath of those custom classes at Tools -> Options -> Custom Script Settings. You can provide the path for either the zip/jar file or can provide the path for the folder containing the custom classes. Please ensure that the custom class is compiled using the same JRE version with which AppPerfect Load Test is running. By default AppPerfect Load Test runs with the JRE present at $LoadTest_Home/jre.

Once you are done configuring the classpath, you can add package of your class at top of the script as importPackage(Packages.yourPackage);. Once package is added you can access your java class from script code and call methods on those java classes.

For ex. lets say there is a custom class com.appperfect.sample.utils.UtilityFunction and you need to use its function getCurrentTime() in the script. To do this you will need to add following script code :

     importPackage(Packages.com.appperfect.sample.utils);
     var utilityObj = new UtilityFunction();
     var currentTime = utilityObj.getCurrentTime();
     log('currentTime :' + currentTime);

Adding Custom validation

In case you need to perform any custom validation on Web Page you can do so using scripting. We support custom scripting apis, using which you can parse the response and fetch appropriate fields from the response page and validate it against the required value. You can also use scripting apis to fire any database query and perform the required validation by fetching the required data using the result set. Find below few examples to add custom validations :

Adding Custom Task Validation

You can parse the response and fetch appropriate data from the response page and validate it against the required value. Select the concerned URL task in the Editor tree for which you need to add validation for. Now select Project -> Script Editor... It will open the script editor with the code scrolled to that of the javascript function for the selected URL task. Refer to the code snipped below parsing the web response to find the product Table and validating if the product table has "Load Test" listed in it :

function executeTask_1() // script function for Task1 [/]
{
     var request = engine.createGetRequest(1,'Task1','http','www.appperfect.com',80,'/');
      request.setIgnored(false);
      request.addThinkTime(100.0, 0, 5, 0, 0);
      request.setTimeout(300);
      request.addHeader('Accept-Encoding', 'gzip, deflate', '', true);
      request.addHeader('Accept-Language', 'en-US', '', true);
      request.addHeader('Connection', 'keep-alive', '', true);
      request.setExpectedResponseCode(200);
      request.setRecordedFileName('recorded/2009_3_21_1_40_52_37/ActionGroup1/Task1.html');
      var successful = engine.execute(request);
      if(! successful)
      {
         log('Task failed, reason for failure: ' + request.getReasonForFailure());
      }
      else
      {
         //Validations may be added here.
         //Custom Validation code starts here
         var validationSuccess = false;
         var htmlPage = request.getWebResponse(); // this will return instance for com.gargoylesoftware.htmlunit.html.HtmlPage
         var tableElement = htmlPage.getHtmlElementById("productTable"); //here we are querying the product Table
         if(tableElement)
         {
              //Now we will get all the rows in the table.
              var rowList = tableElement.getRows();
              for(var i = 0; i < rowList.size(); i++)
              {
                  var tableRow = rowList.get(i);
                  var cellList = tableRow.getCells();
                  for(var j = 0; j < cellList.size(); j++)
                  {
                      var tableCell = cellList.get(j);
                      var cellData = tableCell.getNodeValue();
                      log('cell data ' + cellData);
                      if(cellData == 'Load Test')
                      {
                          validationSuccess = true;
                          break;
                      }
                  }
              }
         }
         if(!validationSuccess)
         {
              request.setTaskSuccessful(false);
              request.setReasonForFailure("Table data validation failed, could not find Load Test product in table.");
         }
         //Custom Validation code Ends here
      }

      engine.release(request);
}

Adding Custom Database validation

You can fire SQL queries and validate the values fetched using result set. Lets say you have "Products" table in Database and you need to validate if there is product with name "AppPerfect Load Test" present in the table. To add such validation you edit script code as follows :

function executeTask_1() // script function for Task1 [/]
{
     var request = engine.createGetRequest(1,'Task1','http','www.appperfect.com',80,'/');
      request.setIgnored(false);
      request.addThinkTime(100.0, 0, 5, 0, 0);
      request.setTimeout(300);
      request.addHeader('Accept-Encoding', 'gzip, deflate', '', true);
      request.addHeader('Accept-Language', 'en-US', '', true);
      request.addHeader('Connection', 'keep-alive', '', true);
      request.setExpectedResponseCode(200);
      request.setRecordedFileName('recorded/2009_3_21_1_40_52_37/ActionGroup1/Task1.html');
      var successful = engine.execute(request);
      if(! successful)
      {
         log('Task failed, reason for failure: ' + request.getReasonForFailure());
      }
      else
      {
         //Validations may be added here.
         //Custom Validation code starts here
         var validationSuccess = false;
         // DatabaseId used in following API is the database id configured at Tools -> Options -> Browsers, JDKs & DBs
         var resultset = engine.executeSelectQuery("DatabaseId", "select productname from Products");
          // process the result set here
          while(resultset.next())
          {
              var productName = resultset.getString(1);
              if(productName == "Load Test")
             {
                 validationSuccess = true;
                 break;
             }
          }
          engine.closeResultSet(resultset);
         if(!validationSuccess)
         {
              request.setTaskSuccessful(false);
              request.setReasonForFailure("Custom validation Failed: Product Load Test not present in database.");
         }
         //Custom Validation code Ends here
      }

      engine.release(request);
}

Fetching value from response and passing it to Event argument

Lets say you have a form in the Web page which has a input text field. Now you need to fill this input text field with the value retrieved from a table in the web page and then submit the request. So what you need to do is parse the previous task response and fetch the required value and pass it to request parameter of next task. The following code demonstrates passing the value fetched from table in Task1 response to the GET parameter of next request Task2:

We will first declare a global variable 'parameterValue' at top of the script code in which we will be storing the value we get after parsing previous response.

var parameterValue;


Now we will parse the Task1 and initialise parameterValue with the value we need to pass to the next request's parameter.

function executeTask_1() // script function for Task1 [/]
{
     var request = engine.createGetRequest(1,'Task1','http','www.appperfect.com',80,'/');
      request.setIgnored(false);
      request.addThinkTime(100.0, 0, 5, 0, 0);
      request.setTimeout(300);
      request.addHeader('Accept-Encoding', 'gzip, deflate', '', true);
      request.addHeader('Accept-Language', 'en-US', '', true);
      request.addHeader('Connection', 'keep-alive', '', true);
      request.setExpectedResponseCode(200);
      request.setRecordedFileName('recorded/2009_3_21_1_40_52_37/ActionGroup1/Task1.html');
      var successful = engine.execute(request);
      if(! successful)
      {
         log('Task failed, reason for failure: ' + request.getReasonForFailure());
      }
      else
      {
         //Validations may be added here.
         //Function to parse the response starts here
         var htmlPage = request.getWebResponse(); // this will return instance for com.gargoylesoftware.htmlunit.html.HtmlPage
         var tableElement = htmlPage.getHtmlElementById("productTable"); //here we are querying the product Table
         if(tableElement)
         {
              //Now we will get the data from the required cell in the table
              var cellElement = tableElement.getCellAt(1, 2);
              //Intialising the parameterValue with the value we need to pass to the next request's parameter
              parameterValue = cellElement.getNodeValue();
         }
         //Function to parse the response Ends here
      }
      engine.release(request);
}


We have parsed the response and have initialised the global variable parameterValue with required value. Now we will pass this value to Task2 parameter.

function executeTask_2() // script function for Task2 [/queryProduct]
{
     var request = engine.createGetRequest(2,'Task2','http','www.appperfect.com',80,'/queryProduct');
      request.setIgnored(false);
      request.addThinkTime(100.0, 0, 5, 0, 0);
      request.setTimeout(300);
      request.addHeader('Accept-Encoding', 'gzip, deflate', '', true);
      request.addHeader('Accept-Language', 'en-US', '', true);
      request.addHeader('Connection', 'keep-alive', '', true);
     //Passing parameterValue to the task's parameter
      request.addParameter('productName', parameterValue, '', true, false);
      request.setExpectedResponseCode(200);
      request.setRecordedFileName('recorded/2009_3_21_1_40_52_37/ActionGroup1/Task1.html');
      var successful = engine.execute(request);
      if(! successful)
      {
         log('Task failed, reason for failure: ' + request.getReasonForFailure());
      }
      else
      {
         //Validations may be added here.
      }
      engine.release(request);
}

Script documentation

Refer to Scripting documentation for more details on scripting apis supported. While editing the script in script editor, you can open the API documentation using Help -> Java Documentation...as well