[Webtest] AJAX Support

uhmm@1234.sk uhmm@1234.sk" <uhmm@1234.sk
Wed, 04 Apr 2007 16:52:57 +0100


Michael,

I'm sending you the relevant parts of code (html, javascript
and XHR response). Sorry for sending it this messy, it's an
old PHP generated code...

There are 3 sections. HTML, Javascript, XmlHttpResponse.
I can clearly see in my logs, that 
/track/xmlhttprequests/offeringtypetosubtype.php is called
when running the web test, so I guess the problem will be
somewhere in reading the response.

If I missed some part, please come back to me, I'll post
them online.

            <tr>
                <td class=3d"body-text-small"
valign=3d"top">Offering Type:</td>
                <td class=3d"body-text-small"
valign=3d"top">
		<select name=3d"fOfferingType" id=3d"fOfferingType"
class=3d"body-text-small "
onchange=3d"offeringTypeClick(this, false)">
			<option value=3d"5">Content Migration</option>
			<option value=3d"2">Web Content Maintenance</option>
		</select>
		</td>
            </tr>
        
            <tr>
                <td class=3d"body-text-small"
valign=3d"top">Subtype:</td>
                <td class=3d"body-text-small"
valign=3d"top">
		<select name=3d"fOfferingSubtype" id=3d"fOfferingSubtype"
class=3d"body-text-small "
onchange=3d"showRelevantCountries();">
		<option value=3d"1">Work Request</option>
		</select>
		</td>
            </tr>

Javascript:
=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d
                function
offeringTypeClick(offeringTypeDropdown, initialbuild,
offtype, offsubtype) 
				{
					// set default values
					if (!offtype) 
						offtype =3d false;
					if (!offsubtype)
						offsubtype =3d false;

					// set the offering type id
					var offeringtypeid =3d offeringTypeDropdown.value;
					if (offtype && offtype > 0) {
						offeringtypeid =3d offtype;
					}

                    requestXMLDocument(
                       
"/track/xmlhttprequests/offeringtypetosubtype.php"
                            + "?id=3d" + offeringtypeid +
"&offsubtype=3d" + offsubtype,
                        processSubtypeXMLHttpResponse
                    );

					if (!initialbuild) {
                    	changeduedate();
					}	
                } // offeringTypeClick

=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d
                function processSubtypeXMLHttpResponse() 
				{
                    var response =3d
getResponseXMLDocument(); 
                    if (response !=3d null) {
                        // Navigate XML response DOM and
modify dropdown accordingly  
                        var dropdown =3d
document.getElementById("fOfferingSubtype");
                        clearDropdown(dropdown);
                        var results =3d
response.getElementsByTagName("result");
                        for (var i =3d 0; i <
results.length; i++) {
                            var id =3d
results[i].getElementsByTagName("id")[0].firstChild.data;
                            var name =3d
results[i].getElementsByTagName("name")[0].firstChild.data;
							var sel =3d
results[i].getElementsByTagName("selected")[0].firstChild.data;
							if (!sel || sel =3d=3d 0)
								sel =3d false;
                            addDropdownEntry(dropdown, i,
name, id, sel);
                        } // for
                       		dropdown.value =3d 0;
                        if (!dropdown.value) {
                            // The current offering subtype
role is not in the dropdowns
                            dropdown.selectedIndex =3d 0;
                        } // if
			dropdown.onchange();                         
                    } // if
                } // processSubtypeXMLHttpResponse

=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d
                function changeduedate(ovrday, ovrmonth,
ovryear) {
					// set default values for parameters
					if (!ovrday || ovrday < 1 || ovrday > 31) 
						ovrday =3d false;
					if (!ovrmonth || ovrmonth < 1 || ovrmonth > 12) 
						ovrmonth =3d false;
					if (!ovryear || ovryear < 1900 || ovryear > 2100) 
						ovryear =3d false;

					var okdatechg =3d true;
					
              		
					// if the user is okay with changing the date
					if (okdatechg) {
						var offeringTypeEditable =3d true;
        				var priorityIndex =3d
document.aform.fPriority.selectedIndex;
        				var offeringTypeIndex =3d 0;
        				//get the index of the selected offering type
(only if we are permitted to select offering types)
        				if (offeringTypeEditable) {
        					offeringTypeIndex =3d
document.aform.fOfferingType.selectedIndex;
        				}

						if (ovrday =3d=3d false) {
                 
			document.aform.fDueDay.options[day[offeringTypeIndex][priorityIndex]
- 1].selected =3d true;
						} else {
							document.aform.fDueDay.options[ovrday - 1].selected
=3d true;
						}
						if (ovrmonth =3d=3d false) {
                  
			document.aform.fDueMonth.options[month[offeringTypeIndex][priorityIndex]
- 1].selected =3d true;
						} else {
							document.aform.fDueMonth.options[ovrmonth -
1].selected =3d true;
						}
						if (ovryear =3d=3d false) {
                  
			document.aform.fDueYear.options[year[offeringTypeIndex][priorityIndex]
- 2007].selected =3d true;
						} else {
							for (i in document.aform.fDueYear.options){
								if (ovryear =3d=3d
document.aform.fDueYear.options[i]) {
									document.aform.fDueYear.options[i].selected =3d
true;
								}
							}
						}
					}                   		
                }

=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d
function clearDropdown(dropdown) 
{
    while (dropdown.options.length > 0) {
        dropdown.remove(0);
    } // while
} // clearDropdown

=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d
function addDropdownEntry(dropdown, position, text, value,
selected) 
{	selected =3d selected || false;	// defaults to false

    var opt =3d document.createElement('option');
    opt.text =3d text;
    opt.value =3d value;
    opt.defaultSelected =3d selected;
    opt.selected =3d opt.defaultSelected;
    try {
        // standards compliant; doesn't work in IE
        dropdown.add(opt, dropdown.options[position]);
    } catch(ex) {
        // IE only
        dropdown.add(opt, position);
    } // try
} // addDropdownEntry

=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d
=3d				var countriesSection =3d
document.getElementById("countries");
				countriesSection.style.display=3d"none";
=3d				
				function showRelevantCountries()
				{
					
			if (offSubtype.value =3d=3d 2 || offSubtype.value =3d=3d
56 || 	false) {				
				countriesSection.style.display=3d"";
				countriesSection.style.fontSize=3d"11px";
			} else {
				countriesSection.style.display=3d"none";
			}
		
				}

=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d
requestQueue =3d new Array();		// queue of requests
noRequests =3d true;				// binary semaphore

// Add an XMLHttpRequest to the queue.  Please use this
rather than loadXMLDoc directly.
// (Unless you want weird behaviour where your requests get
mixed up.)
function requestXMLDocument(url, func) 
{
	requestQueue.push({url: url, func: func});
	
	// Check to see if you're the first to arrive, and the
waiting room is empty.
	if (noRequests) {
		var request =3d requestQueue.pop();
		loadXMLDoc(request.url, request.func);
	} // if
} // requestXMLDocument


// Make an XMLHttpRequest call if possible (depends on the
browser).
function loadXMLDoc(url, func) 
{
	noRequests =3d false;
	
	// To prevent IE from cacheing the XML document returned
from this, append
	// a timestamp to the URL to ensure that it is unique.  The
page itself doesn't
	// actually use the time for anything.
	var d =3d new Date();
	var timestamp =3d "&ts=3d"
		+ "." + d.getDate() 
		+ "." + d.getHours() 
		+ "." + d.getMinutes()
		+ "." + d.getSeconds();
	var newurl =3d url + timestamp;
	
	/********************************************************************/
	// probably the best thing you can do to debug is uncomment
this line
	// and plug the URL into your browser to see if the XML is
being
	// generated properly
//    alert(newurl);
	/********************************************************************/	
	
    if (window.XMLHttpRequest) {
        // branch for native XMLHttpRequest object
        req =3d new XMLHttpRequest();
        req.onreadystatechange =3d func;
        req.open("GET", newurl, true);
        req.send(null);
    } else if (window.ActiveXObject) {
        // branch for IE/Windows ActiveX version
        req =3d new ActiveXObject("Microsoft.XMLHTTP");
        if (req) {
            req.onreadystatechange =3d func;
            req.open("GET", newurl, true);
            req.send();
        } // if
    } // if
} // loadXMLDoc


// Return the XMLHttpRequest response.  Returns null if it
is not yet ready
// or if there is an error in the request/response.
function getResponseXMLDocument() 
{
	if (req.readyState =3d=3d 4) {
		// Ensures that we return this request rather than some
other one
		// that slips through the semaphore between the semaphore
release
		// and the return (basically returning the same request
twice and
		// skipping this one).
		var tempRequest =3d req;
		if (requestQueue.length > 0) {
			var request =3d requestQueue.pop();
			loadXMLDoc(request.url, request.func);
		} else {
			noRequests =3d true;
		} // if
		if (tempRequest.status && tempRequest.status =3d=3d 200) {
			return tempRequest.responseXML.documentElement;
		}
		return null;
	} // if
	return null;
} // getResponseXMLDocument


=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d=3d
XHR Response:
<?xml version=3d"1.0" encoding=3d"UTF-8"
standalone=3d"yes"?>
<response>
	<result><id>8</id><name>Administration - User or
Database</name><selected>0</selected></result>
	<result><id>39</id><name>Other</name><selected>0</selected></result>
	<result><id>6</id><name>Problem
Report</name><selected>0</selected></result>
	<result><id>7</id><name>Sizing/New Functionality or
Requirement (s)</name><selected>0</selected></result>
</response>




----- Original Message -----
From: Michael Habbert <Michael.Habbert@netpioneer.de>
To: webtest@lists.canoo.com
Subject: Re: [Webtest] AJAX Support
Date: Wed, 04 Apr 2007 14:44:50 +0200

> Hi uhmm,
> 
> as far as I can see it the error occurs in sht
> setSelectField step as you can see:
> 
>  > Step: setSelectField "Select offering type" (13/15)
> 
> and at the bottom you can see:
> 
> Message was: No
> option found
> matching criteria in select HtmlSelect[<select
> name=3d"fOfferingSubtype"
> id=3d"fOfferingSubtype" class=3d"body-text-small "
> onchange=3d"showRelevantCountries();">]
> 
> for further help it would be helpfull if you post your
> html-code.
> 
> Michael
> 
> uhmm@1234.sk wrote:
> > Hey there,
> > I've been looking around internet for ajax support in
> > webtest, but
> > haven't found anything what would help me. Hope people
> > here can...
> > 
> > I have school example of ajax usage. 2 dropdowns, first
> > one is
> > changed, second one is updated. How shall I create test
> > steps?
> > 
> > Easy it may seem, but it's not. Here is my try:
> > 
> > <setSelectField
> >        description=3d"Select offering type"
> >        htmlid=3d"fOfferingType"
> >        text=3d"Application Support"
> > />
> > <sleep description=3d"12s pause" seconds=3d"12" />
> > <setSelectField
> >        description=3d"Select offering subtype"
> >        htmlid=3d"fOfferingSubtype"
> >        value=3d"Other"
> > />
> > 
> > Errors I'm getting:
> > [setSelectField]  INFO (com.canoo.webtest.steps.Step) -
> > >>>> Start
> > Step: setSelectField "Select offering type" (13/15)
> >    [sleep] java.lang.NullPointerException
> >    [sleep]     at
> >
> com.gargoylesoftware.htmlunit.javascript.OptionsArray.get(
> >    OptionsArray.java:102) [sleep]     at
> >
> org.mozilla.javascript.ScriptableObject.getProperty(Script
> >    ableObject.java:1343) [sleep]     at
> >
> org.mozilla.javascript.ScriptRuntime.getObjectElem(ScriptR
> >    untime.java:1304) [sleep]     at
> >
> org.mozilla.javascript.ScriptRuntime.getObjectElem(ScriptR
> untime.java:1288) [...]
> HtmlSelect[<select
> name=3d"fOfferingSubtype" id=3d"fOfferingSubtype"
> class=3d"body-text-small "
> onchange=3d"showRelevantCountries();">]
>   INFO (com.canoo.webtest.steps.Step) - Running with:
> Canoo Webtest: R_1537.
>   INFO (com.canoo.webtest.steps.Step) - Exception thrown
> from this
> class: com.canoo.webtest.engine.StepFailedException
>   INFO (com.canoo.webtest.steps.Step) - Message was: No
> option found
> matching criteria in select HtmlSelect[<select
> name=3d"fOfferingSubtype"
> id=3d"fOfferingSubtype" class=3d"body-text-small "
> onchange=3d"showRelevantCountries();">]
> [...]
> 
> 
> -- 
> Mit freundlichen Gr=fc=dfen
> ----------------------------------------------------------
> -------------- Michael Habbert
> _______________________________________________
> WebTest mailing list
> WebTest@lists.canoo.com
> http://lists.canoo.com/mailman/listinfo/webtest