[Webtest] Displaying pages modified by Javascript in Webtest results

Dan T Dan T" <olafkolzig@gmail.com
Thu, 14 Dec 2006 14:30:51 -0500


------=_Part_107709_9126870.1166124651029
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Hi,

I had previously pursued this in HTMLUnit but found it wasn't an issue
there, but rather with Webtest. Generally speaking, when javascript modifies
the content of a page but does not reload or submit it, the results won't be
saved (which is the way it was intended, since the current response will not
have changed - only the content of it will have done so). This makes it
rather difficult to test pages with Javascript/JScript/whatever validation,
because if the validation fails there's no way to tell what exactly
happened.

I've made a minimal page that can be used as an example of this here:
http://ca.geocities.com/olafkolzig@rogers.com/test.html  . The javascript is
rather messy (this was generated by a framework, if you're wondering) but it
checks the input field on the page to make sure it's not empty or all spaces
before submitting. If it is, it modifies the content of a previously empty
div with an error message; otherwise it submits to Google (I didn't plan on
that form submission actually doing anything useful). If you run a webtest
on this to load the page and click the continue button, the clickButton step
on the continue button will not have a saved response. I'm not sure if I can
just randomly embed xml here, but the steps would be something like:
invoke url="/olafkolzig@rogers.com/test.html"
clickButton label="Continue"
I tried to keep that page W3C compliant so that only the javascript bits
fail validation, along with the junk Yahoo inserts at the end. Other than
that, I don't think there's a problem with the HTML as the onclick function
works in Firefox, IE and Opera.

The relevant code for saving responses to html is found in
AbstractBrowserAction.notifyCompleted() (possibly other places, but I've
basically take the minimal effort to prove that a solution to this problem
is possible). For starters, it may perhaps be useful to have an option
similar to saveResponse for saving html in different scenarios -
saveResponseIfContentChanged or alwaysSaveResponse to save responses if the
content has changed but the response objects are equal, or to simply save
the response on every step regardless of whether the content has changed or
not. At the least I would find the first option useful... the second one I'm
not sure about. I imagine it would take more effort to have steps like
setInputField or setSelectField show up in the saved response as I'm not
sure how those steps work.

However, even with removing the check to see if the responses has changed
and just saving the current response to html on every Webtest step, the
results of those steps don't show up in the source. After some more mucking
around with the code I found Context.saveCurrentResponseToFile essentially
saves the contents of fCurrentResponse.getPage(), which doesn't seem to
necessarily be the source of the page returned by HTMLUnit after running
javascript. By using
((HtmlPage)fCurrentResponse.getPage().getEnclosingWindow().getEnclosedPage()).asXml(),
however, I did get the content I was looking for - the page as modified by
javascript. I can include a patch set with the source changes necessary to
at least show an example of this working as I'd like, but it's is rather
ugly. The chain of method calls and the HtmlPage cast are rather ridiculous,
so I'm sure there's a better way of doing this but I'm not familiar enough
with HTMLUnit to know what methods I should be using.

Anyhow, I think a feature like this would help even more generally than with
the limited example I've included. HTMLUnit conveniently evaluates
Javascript with the Mozilla engine, so it should be able to return pages
with more or less the same content as Firefox would. And as for IE, well...
eh, hope for the best.

------=_Part_107709_9126870.1166124651029
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Hi,<br><br>I had previously pursued this in HTMLUnit but found it wasn't an issue there, but rather with Webtest. Generally speaking, when javascript modifies the content of a page but does not reload or submit it, the results won't be saved (which is the way it was intended, since the current response will not have changed - only the content of it will have done so). This makes it rather difficult to test pages with Javascript/JScript/whatever validation, because if the validation fails there's no way to tell what exactly happened. 
<br><br>I've made a minimal page that can be used as an example of this here: <a href="http://ca.geocities.com/olafkolzig@rogers.com/test.html">http://ca.geocities.com/olafkolzig@rogers.com/test.html</a>&nbsp; . The javascript is rather messy (this was generated by a framework, if you're wondering) but it checks the input field on the page to make sure it's not empty or all spaces before submitting. If it is, it modifies the content of a previously empty div with an error message; otherwise it submits to Google (I didn't plan on that form submission actually doing anything useful). If you run a webtest on this to load the page and click the continue button, the clickButton step on the continue button will not have a saved response. I'm not sure if I can just randomly embed xml here, but the steps would be something like:
<br>invoke url=&quot;/olafkolzig@<a href="http://rogers.com/test.html">rogers.com/test.html</a>&quot;<br>clickButton label=&quot;Continue&quot;<br>I tried to keep that page W3C compliant so that only the javascript bits fail validation, along with the junk Yahoo inserts at the end. Other than that, I don't think there's a problem with the HTML as the onclick function works in Firefox, IE and Opera.
<br><br>The relevant code for saving responses to html is found in AbstractBrowserAction.notifyCompleted() (possibly other places, but I've basically take the minimal effort to prove that a solution to this problem is possible). For starters, it may perhaps be useful to have an option similar to saveResponse for saving html in different scenarios - saveResponseIfContentChanged or alwaysSaveResponse to save responses if the content has changed but the response objects are equal, or to simply save the response on every step regardless of whether the content has changed or not. At the least I would find the first option useful... the second one I'm not sure about. I imagine it would take more effort to have steps like setInputField or setSelectField show up in the saved response as I'm not sure how those steps work.
<br><br>However, even with removing the check to see if the responses has changed and just saving the current response to html on every Webtest step, the results of those steps don't show up in the source. After some more mucking around with the code I found 
Context.saveCurrentResponseToFile essentially saves the contents of fCurrentResponse.getPage(), which doesn't seem to necessarily be the source of the page returned by HTMLUnit after running javascript. By using ((HtmlPage)fCurrentResponse.getPage().getEnclosingWindow().getEnclosedPage()).asXml(), however, I did get the content I was looking for - the page as modified by javascript. I can include a patch set with the source changes necessary to at least show an example of this working as I'd like, but it's is rather ugly. The chain of method calls and the HtmlPage cast are rather ridiculous, so I'm sure there's a better way of doing this but I'm not familiar enough with HTMLUnit to know what methods I should be using.
<br><br>Anyhow, I think a feature like this would help even more generally than with the limited example I've included. HTMLUnit conveniently evaluates Javascript with the Mozilla engine, so it should be able to return pages with more or less the same content as Firefox would. And as for IE, well... eh, hope for the best.
<br> 

------=_Part_107709_9126870.1166124651029--