How I may help
LinkedIn Profile Email me!

Reload this page AJax Scripting in LoadRunner

This is a tutorial on emulating users of AJAX scripts, using LoadRunner and other tools.

 

RSS XML feed for load testers RSS preview for load testers Site Map List all pages on this site 
About this site About this site 
Go to first topic Go to Bottom of this page


Set screen AJAX vs. Others

Set screen AJAX Libraries

Set screen Recording Using LoadRunner

  1. Before recording, write down the manual steps as you perform them.

    If you get certificate errors, save the SSL certificate. Otherwise, you end up having VuGen record/generate this:

    	web_text_link("Continue to this website (not recomm", 
    		"Snapshot=t1.inf", 
    		DESCRIPTION, 
    		"Text=Continue to this website (not recommended).", 
    		ACTION, 
    		"UserAction=Click", 
    		LAST);
    
    If you end up with this, comment it out in your script.
  2. Set Recording Options by pulling down the Tools menu.
  3. Invoke VuGen to create a new script of protocol "Web (Click and Script)" (available in LoadRunner v8.1 FP4 and later). This activates technology from the HP QuickTestPro (QTP) product which recognizes and replays Javascript just as the browser would.

  4. Click Start Record. Select "Internet Application" and type in the URL of the AJAX-enabled page you want to script. Sample AJAX sites at Blinklist include these:
  5. When the brower appears with the screen expected, type "x" in the text box to the right of "Type the Text:".
  6. Wait for what you typed in to appear to the right of "Text in the AJAX Response:",
  7. Stop the recording. VuGen then generate LoadRunner script code.
  8. If you had recorded with option ___ set at __, when VuGen encounters a page with no title, it erroneousy generates this line: web_reg_find("Text=Untitled", LAST);

    To avoid a playback error, comment it out (with //).

  9. Press F4 to set Runtime Settings Log to display everything all the time: Advanced and all boxes checked.
  10. In Runtime Settings Internet Protocol Advanced Options scroll to Step Download Timeout and set its value to 9999 (rather than the default 120).
  11. In Tools > General, set Display
  12. Replay the recording.
  13. Save the script using a file name that distinguishes it among all your other recordings.
  14. Zip up the script folder immediately after a recording. This preserves the Generation Log.
  15. Analyze. Click the "Generation Log" tab for the detailed sequence of (header and body) requests and responses.

    Unlike static HTML web pages, one cannot "View Source" at the client browser to look for text to correlate. With AJAX sites, one must look at the dynamic exchange of data VuGen captures in its Generation Log and in VuGen's new Tree view.

    VuGen captures the traffic between client and server much like HTTP Proxy client utilities such as Fiddler.

  16. In the Generation Log, the first GET request is for the URL specified to obtain the response. "HTTP/1.1 200 OK" is the normal expected valid response, as agreed in the HTTP 1.1 spec. In the Response Header, notice the
    Set-Cookie: JSESSIONID=89B629853850438A28F07F366FD57F4A; Path=/a4j-simpleRepeator

  17. The first Response Body for that Request Header in the Generation Log is below, indented with line breaks:

    <HTML>

    </HTML>

    The remaining HTML is not shown here.

  18. The first "Add Event" is the LoadRunner script generated from the first GET request.
  19. Scroll down through the second set of requests for the "AjaxScript" file requested in the <script tag:
    http://livedemo.exadel.com/a4j-simpleRepeator/org.ajax4jsf.resource/org.ajax4jsf.framework.ajax.AjaxScript

    If the script was recorded with "Recording Options" set to "HTML", then the script would not have a separate request for the AjaxScript because the "mode=HTML" in the VuGen script tells LoadRunner to automatically retrieve resources (such as script, css, img, and other files) mentioned in the HTML.

    The "jsessionid=" appended to the end of the URL to retrieve the AjaxScript means that the file will be downloaded again at the start of every session, which developers want if the file changes dynamically.

    If the script file is not expected to change, users would not need to wait for the file to be downloaded if there was not a "jsessionid=" in the URL, since the browser will automatically reuse what remains in the cache. That is unless the browser has been set by the user to "refresh with every page" or the expiration date on the file has passed.

    When normally static file changes, developers rename the file name to ensure that all active clients get the new file rather than reusing the old file in their cache.

    The AjaxScript file can be examined at the location where browsers download resources (cookies, CSS files, etc.). On IE browsers, pull down "Tools", "Internet Options", click "Settings" within the "Temporary Internet files" section, then "View Files...". This opens up a Windows Explorer. Scroll right or expand the width of the window to click "Last Accessed" once or twice to sort the list.

    Save the file by right clicking on it, select "Copy", then paste it into another Windows Explorer window.
    At that new location, right click on it, select "Properties" to note its size (e.g., 50,798 bytes).

  20. Use Wordpad to edit the file because it contains UNIX style line breaks which Notepad ignores.

    For faster download, "production" websites would have the content of static compressed (stripped of whitespace such as blank spaces and tabs). If that is the case, for human readability we would need to reverse the compression by saving the code in a file and sending it through a code formatter utility to indent the statements.
    The SlickEdit editor can reformat code.

  21. BTW, at the top of the file, notice the comment "Sarissa is an ECMAScript library acting as a cross-browser wrapper for native XML APIs."
    Scroll down to see that this particular library uses logging functions extensively.

  22. Change the Recording Mode to "URL" and re-record the script again.

    Notice that "RecContentType=text/javascript" appears even when the file name is suffixed with ".AjaxScript" rather than ".js". "AjaxScript" is really JavaScript.

  23. The next request is a "POST" which was triggered by onkeyup=, that browsers recognize as an event that should fire when certain keys are pressed and released. This Microsoft webpage notes that

    Other websites code the onKeyPress= event instead because it represents the entire keystroke and can be canceled.

    The event specified to fire is the A4J.AJAX.Submit function defined in a JavaScript/AjaxScript library on the client. Other libraries may use another function name.

    Unlike other attributes, "onkeyup=" does not require the user to click on another area of the screen before it gets to work.

    Search for this in the ActionScript file. We see that it accepts 3 parameters (separated by commas within the parentheses):

    A4J.AJAX.Submit =  function( containerId, form, obj , options ) {
    

    This function in turn calls A4J.AJAX.SubmitRequest (which has the same parameters) at last invokes form.onsubmit that sends a request out to the server "/a4j-simpleRepeator/demo.jsf", Java Server Faces file. specified "<form action=" HTML.
    The request body shown in the Generation Log, such as:

    are formatted in the "Add Event" script presented under "ITEMDATA" in VuGen scripts, presented in this table with a correspondence to the source of parameters in HTML code through AjaxScript functions:

    HTML onkeyup= A4J.AJAX.Submit parameter parameter in Javascript function VuGen script generated within web_submit_data
    <form action=... '/a4j-simpleRepeator/demo.jsf' form "Action=http://livedemo.exadel.com/a4j-simpleRepeator/demo.jsf;jsessionid={JSESSIONID2}",
    - '_viewRoot' containerId "Name=AJAXREQUEST", "Value=_viewRoot",
    <input type="text" name="_id0:_id3" this obj "Name=_id0:_id3", "Value=x",
    - {'parameters':{'_id0:_id4':'_id0:_id4'}} options "Name=_id0:_id4", "Value=_id0:_id4",
    <input type="hidden" name="_id0" value="_id0"> - - "Name=_id0", "Value=_id0",
    <form ... enctype="application/x-www-form-urlencoded" - - "RecContentType=text/xml"

    Within the Javascript, note that "this" refers to the text object itself, which contains a text value "x".

    The enctype="application/x-www-form-urlencoded" in the HTML form requests the browser to send (asynchronously) what the HTTP spec calls an XMLHttpRequest by specifying Content-Type: application/x-www-form-urlencoded;charset=UTF-8 in the Request Header.
    "RecContentType=text/xml" appears with the web_submit_data instead of
    "RecContentType=text/html" for regular HTML requests. Internally, this results in VuGen sending out a "HTTPXMLrequest".

  24. Going back to the Generation Log, notice that the second and subsequent Request Header do not contain a "Set-Cookie" as in the first Request.

    The second and subsequent Response Header do not contain a "Cookie: JSESSIONID=" that browers and LoadRunner automatically resend back to the server to help maintain the same session.

  25. To see what comes back from a request, scroll down to the "Response Body For Transaction" under the request above.

    Note that the response body begins with <?xml version="1.0" encoding="iso-8859-1"?>, which IE does not display.
    During playback, the Run-Time Viewer would display an error for pages beginning with this (if in "Tools", "General Options", "Display" tab, "Show browser during replay" is checked).

    A JavaScript listener function in the AjaxScript reads the rest of the response body. For example:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head><title>ajax4jsf. Simple Repeator Demo</title>
    </head>
    <body><hr />
    <span id="_id0:repeater">x</span>
    <span id="ajax-update-ids" style="display: none" title="_id0:repeater">
    <input type="hidden" name="jsf_sequence" value="1" />
    </span> 
    <div style="font-size:9px;height:150px;width:800px; 
        border: 1px solid darkblue;padding: 5px 5px 5px 5px; overflow: auto;" 
        id="logConsole">
    </div>
    </body></html>
    

    Notice that this response does not contain some of the HTML of the first Response Body (why AJAX is preferred over traditional whole-page exchangees).

  26. The response from the server to the request sent to the server is received by the AjaxScript. We trace through the AjaxScript code to learn that in the incoming XML:

    <span id="ajax-update-ids" style="display: none" title="_id0:repeater">

    id="ajax-update-ids" triggers an update of the innerHTML text in the object named in title="_id0:repeater", which is defined in the first HTML above by <span id="_id0:repeater">.

    An AjaxScript "callback" function update displays the text "x" between <span id="_id0:repeater"> and </span>.

    So to verify the response, add to the VuGenscript a LoadRunner web_reg_save_param() call to capture the text between those two markers.

    	web_reg_save_param("pRetText","Search=Body", "ORD=ALL",
    		"LB=<span id=\"_id0:repeater\">",
    		"RB=</span>", "Notfound=warning",
    		LAST);
    

    Note that back slashes are added to quote characters being searched.

  27. The first parameter in the "web_submit_data(" displayed in Add Events and in the VuGen script generated for the "POST" is often edited by performance engineers to avoid confusion because the session code there is what was captured during recorded and will change with every session.
  28. Click on the VuGen script window.

    Add logic to perform the VuGen script command to capture the JSESSIONID value AGAIN if cookies are cleared or if the application user logs off.
    Add logic to NOT perform the VuGen script command to capture the JSESSIONID value during the same continuous session.

    This can be done by declaring an integer (binary) flag in the vuser_init section:

    int intHaveJSessionID = 0; // 0 = NO.
    

    The Action section would have:

    if( intHaveJSessionID == 0 ){
    	web_reg_save_param("JSESSIONID2", 
    		"LB/IC=jsessionid=", 
    		"RB/IC=\"", 
    		"Ord=1", 
    		"Search=header", 
    		"RelFrameId=1", 
    		LAST);
    	intHaveJSessionID = 1; // 1 = YES
    }
    ...
    	web_cleanup_cookies(); 
    	intHaveJSessionID = 0;
    

    Simply adding "Notfound=warning", to the generated web_reg_save_param command does not work because that would cause the JESSIONID2 parameter to be unusable when the value is not there to find.

    Because the Response Header is usually smaller than the Response Body, you can save a little script execution time by changing
    "Search=body" to
    "Search=header"

  29. Pull down the "Tools" menu for Recording Options. Mouse over to the "GUI-based script" and note that the description reads: "Generate a step for each user action, for a concise, intuitive script. JavaScript is evaluated during replay."
  30. During VuGen script development, you may also want to set Run-Time Settings to ignore think times.
  31. Record another sample URL: http://livedemo.exadel.com/fruits-selector.

    Instead of a traditional web_submit_data command, VuGen may records this out-going XML requests as web_custom_request() commands containing a Body such as:

    "Body=AJAXREQUEST=_viewRoot&_id1%3AtextArea=This%20text%20area%20should%20not%20be%20updated&_id1%3A_id18=any&_id1%3A_id21=yellow&_id1%3A_id24=any&_id1=_id1&_id1%3A_id22=_id1%3A_id22&",

    Other examples from Exadel, the sponsor of AJAX4JSP, require hidden type fields such as com.sun.faces.VIEW to be captured within VuGen scripts.

    The Get Author webapp described here

  32. A very popular Ajax library is Yahoo's BSD-Licensed User Interface Library (YUI). Record the Calendar functional example. An analysis of the files downloaded:

    Requested by/as File Downloadload Bytes Notes
    user solution.html 2,067
    - .../fonts.css 634
      .../reset.css 441
      .../yahoo.js 4,548 global object used by YUI Library.
      .../event.js 60,717
      .../dom.js 34,659
      .../calendar.js 132,161
      .../calendar.css 1,928
    EXTRARES ...bc_1.7.3.js 3,211
    EXTRARES
    calendar.css
    ...callt.gif 94
    ...calrt.gif 94
    Total: ?.?

    YAHOO.namespace("example.calendar"); invokes a function in the yahoo.js library which invokes the function YAHOO.widget.Calendar.

    function init()" in the calendar.js library knows to replace
    <div id="cal1Container"></div> with HTML code that it generates based on the current date.
    Such generated HTML can only be seen if "Full Source" or a special Microsoft DLL is installed.

    In that generated HTML, each clickable field is defined with a class and an id that are also generated internally by JavaScript.

    YAHOO.util.Event.addListener(window, "load", init); establishes a listener for responses from the server.

Set screen JSON Coming Back

Set screen Resources:

Portions ©Copyright 1996-2009 Wilson Mar. All rights reserved. | Privacy Policy |

Related Topics:
another page on this site Performance Testing 
another page on this site NT Perfmon / UNIX rstatd Counters 
another page on this site Mercury LoadRunner 
another page on this site Mercury Virtual Table Server (VTS) 
another page on this site Mercury WinRunner 
another page on this site Rational Robot 
another page on this site Free Training! 
another page on this site Tech Support 


How I may help

Send a message with your email client program


Your rating of this page:
Low High




Your first name:

Your family name:

Your location (city, country):

Your Email address: 



  Top of Page Go to top of page

Thank you!