During protocol level recording SilkPerformer captures and records the traffic between client and server  (requests/ responses), and not client-side JavaScript execution. This means that you will not see JavaScript code functions recorded in your bdf script.  SilkPerformer will record the JavaScript code as part of the page content (you can view this via the relevant Truelog Explorer "source" tab), but it will not record the actual JavaScript actions. This is entirely as designed. 

SilkPerformer does not execute client-side JavaScript code on replay at protocol level. Executing JavaScript logic requires a JavaScript engine to be running and on replay at protocol level a browser instance is only simulated.  The majority of JavaScript functions that are used in a web application are used to perform client-side actions such as "mouse over", "on-click" commands, and verification of form input data; in these types of scenarios the fact that the JavaScript code is not executed by SilkPerformer will have no bearing on the network traffic generated.

Regarding SilkPerformers Browser Driven Load Testing module, the browser application does execute client side JavaScript during both record and replay.

Oftentimes there are scenarios where the client side JavaScript logic needs to be executed at protocol level.  This article explores the options.
 

SilkPerformer can execute native JavaScript code in the following ways:  

- Use built-in SilkPerformer functions which incorporate JavaScript functionality
- Rewrite the JavaScript logic in BDL code or Java or .Net code, both of which SilkPerformer can execute
- Java Frameworks approach using ScriptEngineManager class
- Compile the JavaScript into an exe using .Net framework Jscript module and run the exe from within your script when needed using ProcessInitialize functions
- Use Web Browser-Driven (Ajax) module for testing the application
- Partially use the BDLT module for the purposes of executing JavaScript event on a page and returning required values.
- Prepare values in advance for use as input parameters
- Temporarily disable some client side JavaScript logic

Existing functions in SilkPerformer to simulate JavaScript logic.

If the JavaScript code dynamically creates form data, e.g. timestamps it may be the case that an equivalent function already exists within SilkPerformer to incorporate the JavaScript functionality into a script, such as the GetTimestamp function. 

Example:
  CGI_CUST_SUPPORT:
    "time"     := "1358336023026";
  Would become:
  CGI_CUST_SUPPORT:
    "time"     := GetTimeStamp(TIMESTAMP_GMT | TIMESTAMP_IN_MS);

 

An alternative would be to use a recording rule, such as in the attached 6840.TimeStamp.zip, in order to have SilkPerformer recorder automatically replace the Time Stamp, with the GetTimeStamp function. This means that you would not need to manually customize the script, after recording.

Rewrite the JavaScript logic in BDL code

Some JavaScript functionality is simple in nature and if required could be rewritten in SilkPerformer BDL code.
Generating a random string in JavaScript:

function Rstring()
{
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    for( var i=0; i < 20; i++ )
        text += possible.charAt(Math.floor(Math.random() * possible.length));
    return text;
// outputs BWLQAFNEYMHVDVIKHTMC
}

Generating a random string in BDL:
dclrand
  rsletter : RndStr( 10..40);  
dclfunc
    function FMyFunction(size : number) : string
    // takes a number in and returns a string
    var sMainString : string;
    count : number;
    randletter : string ;
   
    begin
      // add 1 character the number of times specified by the size parameter
      for count := 0 to size do
      //assign randomstring into variable
        randletter := rsletter ;
      //concatenate the letter to the current string  
        sMainString := Strcat(sMainString,randletter);
      end;


        FMyFunction := sMainString; writeln ("final =" +sMainString);
        //outputs PFBGJKPNCARAFCKZAZVI
      end FMyFunction;

Java Frameworks approach using ScriptEngineManager class

The ScriptEngineManager class provides a method to load a JavaScript script engine and execute code within it, accepting input parameters and returning output.  Please see the attachments for an example on this.

Compile the JavaScript into an exe using .net framework Jscript module

The .net framework ships with an executable called jsc.exe which can be used to compile JavaScript files into an executable.  This is described in detail here.


To compile the js file do the following:

Locate the jsc.exe on your system:
C:\Windows\Microsoft.NET\Framework\v4.0.30319
Open a command prompt and type the command jsc .js and hit enter.



If no errors occur check the directory of the js file and you should now see a matching executable.


This executable can now be called from within SilkPerformer to execute the JavaScript within and the value passed back to the script.  See ProcessInitialize function in SilkPerformer help files for further details.

Using Web Browser-Driven (Ajax) approach to test the application

Introduction to Browser Driven Load Testing

Using Web Browser-Driven (Ajax) script alongside protocol level scripts

This involves having a script written in the bdlt module and imported into a project which uses protocol module.  The bdlt script only runs to generate the values from the javascript logic and output them to a file.  The protocol level scripts then run and access the file for use as input values where needed.  This method also has memory overhead associated, both with using real browsers and with file access so it should be used with caution.  It is also not useful in scenarios where the JS return value is session related because it won't be available for use in time.  One final caveat with this approach is that a separate connection will be used for each script and so this is not realistic.

Using Web Browser-Driven (Ajax) within protocol level scripts

You can also merge some BDLT logic into your protocol level script by starting a browser and calling the page which executes the JavaScript code.  For this approach to work it should return the output value to the url or to an object of the page where the BDLT functions can access it (like a BrowserGetText for example).  This approach has not been widely tested and has some memory overhead associated so you should use with caution.  As above, a different connection will be used for each of the methods. 

Prepare values in advance for use as input parameters

Where JavaScript must be executed to create data to be used as input parameters (password hashing for example), it might be possible to either always use the same password for all users or encrypt all passwords in a data file in advance for use as parameters during the test so live execution of the JavaScript is not required at runtime. 

Temporarily disable some client side JavaScript logic

In the event that none of the solutions listed helps it is worth considering whether execution of the JavaScript can be disabled or bypassed.  This is obviously not ideal but in situations where the JavaScript does not generate network traffic disabling it might have a negligible impact on your load test when compared with the work involved in executing it.  A good example of this situation is a CAPTCHA.  It would be very difficult to implement the code of a CAPTCHA because by its nature it is designed to prevent robots from submitting data in online forms.  While it is possible sometimes to work around the code of the CAPTCHA it is not worth the effort considering it has little or no impact on network traffic and so will not impact on the validity of your load test results. 

Note on JavaScript escape characters:  it is recommended NOT to use any test data (input values) with characters which must be escaped within JavaScript strings as these will interfere with the SilkPerformer parsing functions including those which take place via recording rules (Siebel, Peoplesoft etc).