[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