mandag den 8. september 2008

Full JS applications

Recently I asked my network for novel ideas for small web applications or sites.

My accountant mentioned that he had a hard time calculating distance travelled for some of his customers. He needs to calculate the specific distance for any trip made in a private car for a refund from the danish IRS.

For each trip made by an employee in one of the companies he used to go to a GeoCoding site like http://www.maps.google.com. Plot in 1 trip with From and To addresses, take the distance and put it into a spreadsheet. And so his days went. He made sure to mention to me that it is a problem for many smaller companies.

Using Google's public GeoCoding services I managed to put together an application run entirely by javascript. It is available at http://www.kennethhn.dk/map.html, it is in danish, until I bother using JS I18N. To give it a go, I included a demo, click 'tryk her for hjælp og demo', in the appeared box click 'klikke her'. Then at the bottom of the page click 'beregn alle'. This will calculate all the inputs with the rate of DKK/KM.

Then to print the results click 'print'.

The tricky thing here is to transfer all the data. What I did was serialize all the data in JSON and put it as a parameter for the print page.

Aside from some escape issues, this transfer works perfectly. It might aswell have been a server request, but this way, you don't need all that performance reducing Serverside rendering..

torsdag den 6. marts 2008

cross site javascript

This is an ajax widget I wrote, while learning about cross site scripting (xss). Read more about the Webspace wormhole here.

The idea is that on any page on any browser I should be able to embed this script and it will share content. Much like Google maps and a ton of other useful stuff from Yahoo and Google.

On the page itself the script only needs a small amount of information, like the id of the div it will use for the graphics and what 'tag' it will subscribe to.

The transport it uses is not the typical Ajax.Request from the prototype lbirary, because this uses solely XMLHttpRequest, which for security reasons default in browsers is not cross site.

Instead I had to write a transport of my own. The basic work-around is to embed a script element in the dom created by a dynamic page. This way, when the script is loaded it can inject data into the javascript execution, just like a plain script file. I implemented a reusable class for it, thusly:

var Transport = Class.create({
initialize: function(url, jsonCallback) {
this.url = url;
this.jsonCallback = jsonCallback;
},
activate: function() {
this._cleanUpScript(this.url);
var script_object = new Element('script', {src: this.url, type: 'text/javascript'});
var head=document.getElementsByTagName('head')[0] ;
head.appendChild(script_object);
this._xssScriptLoad();
},
_xssScriptLoad: function() {
var _this = this;
if(typeof(wh_xss_result) != 'undefined') {
this.jsonCallback(wh_xss_result);
void(wh_xss_result);
} else {
setTimeout(function(){_this._xssScriptLoad();}, 100);
}
},
_cleanUpScript: function(url) {
$A(document.getElementsByTagName('script')).each(function(el){
if(el.src == url){
el.remove();
};
});
}
});

The only 'gotcha' here is that I have to know the name of the variable that the result is stored in. This could be set on the serverside if I pass it as a parmater if I want the serverside to be more reusable, but for the sake of my little wormhole, I hardcoded the variable on both sides.

Here is an example usage of the transport:

var url = 'http://www.kennethhn.dk/webhole/get.php?tag=science';
var t = Transport(url, function(json){alert("json object = " + json});
t.activate();

In this case, the url is a reference to a php script on my site that returns a url for content submitted for the tag.

The second argument is a callback function, that will be called with the resulting json object.

The result might look like this:

var wh_xss_result = {
message: 'fetched url for tag science',
result: 'http://tbn0.google.com/images?q=tbn:-U28WILXKSXv5M:http://www.familycourtchronicles.com/philosophy/wormhole/wormhole-diagram.jpg'};

The transport class will then embed the result as a script and set a timeout event to repeat until the browser has loaded the script. Loading of the script is determined by the variable wh_xss_result, which will be 'undefined' until executed.

Xss can be very useful, but also very dangerous, just be vary of what scripts you choose to embed.

Update 13/04/2009: removed the WebSpace wormhole from this page.

tirsdag den 26. februar 2008

Full testing with JavaScript

In my efforts to achieve a full and robust test of web applications I have run into several difficulties.
1. simulating different browsers
2. keeping test scripts simple
3. fragile tests

Simulating different browser


Initially I achieved this using the Canoo Webtest. Though powerful, this integration fo different third party frameworks has shown not to be able to handle JavaScript very well. This means that if you have no control over the javascript in an application, the test becomes very fragile.

Instead I concluded that the best way to simulate the different browsers is not to actually simulate them. Instead it is very efficient to inject JavaScript along with your tests into the page that you wish to test and thereby testing on the executed page.

Several issues comes with this. Firstly, the security in the browser won't allow you to execute JS on another page, if they are not from the same domain, so you have to execute the test from the domain itself. For inhouse testing this is not a problem, but involves some more deployment.

keeping test script simple


This is really up to the implementation of the web application. If its based on poor standard, test script become increasingly difficult. If for example id's are duplicated or tags are broken, the traversal of the DOM becomes difficult. The best solution to this is to stick to strict xhtml and keep your styles in CSS while maintaining ids on all divs.

A second worry is that the script becomes complicated with lots of hacks and too much code, but this is really up to the framework being used. The better the framework and web application coexist, the easier and cleaner the scripts become.

fragile tests


With a low sense of 'standards' in a project, the test become very fragile. The team must agree upon how to use divs and lists etc. Once referring to an id of a div or anchor at a specific position, that has moved or is renamed, the script might have to be rewritten. The framework should help avoid too specific referenced. Whenever referencing an element in the DOM, reference it as lenient as possible.

here is an example of how the framework might be implemented

MyTestFramework.clickLink = function(text) {
$$('a').each(function(el){if(el.innerHTML==text){window.location=el.href}});
}

MyTestFramework.clickLink('login');


I'll be working on this and post when I have a functioning framework. I'll proably pull in some JSUNit library and use that for a backbone for TestCase and TestRunner.

torsdag den 7. februar 2008

Making the BEA Weblogic Portal bookmarkable

The issue


The two big Portal servers I know have problems with state. WebSphere and WebLogic.

It seems as though somewhere along the productline, someone concluded that maintaining state in the portal while having clean bookmarkable URLs and back/forth working, was too much of a hassle, so they decided to disregard bookmarkability and browser history.

In any major portal project I have worked, this issue has come up. The customer says it's a 'need to have', and I agree.. but the portals really should handle this internally.. alas they don't.

A Weblogic solution


Through an experienced BEA developer I heard of a URL-rewriter plugin for the WebLogic portal, which might offer a solution. The idea is pretty straightforward, anywhere a URL is compiled, the URL rewriter is called upon to do it's *magic*.
Decompiled from 'com.bea.portlet.GenericURL', it looks like this:

if(urlRewriterPlugin != null)
{
ServletContext servletContext = UIContext.getFromRequest(httpRequest).getServletContext();
String target = path;
if(path != null || contextualPath != null)
{
DefaultUrl defaultUrl = resolveTemplate(removeUnsetParams);
target = defaultUrl.url;
}
if(scopedRequest != null)
val = urlRewriterPlugin.createUrl(target, params, getUrlType(), isStandalone(), scopedRequest, httpResponse, servletContext);
else
val = urlRewriterPlugin.createUrl(target, params, getUrlType(), isStandalone(), httpRequest, httpResponse, servletContext);
if(debug.ON)
debug.out((new StringBuilder()).append("Output from the URL rewriter: ").append(val).toString());
if(urlCompression != null && !suppressUrlCompression && val != null && !val.startsWith("wsrp_rewrite?"))
val = compress(val);
}


As you can see its a typical adapter pattern. What we can also see is that the URL rewriter also has to address the complexity of ScopedRequest, which is probably used for referencing any resources inside the scope of a portlet.

Implementing the rewriter


Firstly it must implement the interface 'com.bea.portlet.GenericURL.UrlRewriterPlugin'.
this interface forces the method:

public String createUrl(String path, Map parameters, String urlType, boolean
isStandAlone, HttpServletRequest request, HttpServletResponse response, ServletContext servletContext);

Now, there's a lot of different parametres here, but we are only/mostly interested in parameters and the request.
Back to the issue of the ScopedRequest; We actually just want to ignore it, any request string coming in, should be the same coming out with the parameters trailing. In order to disregard a ScopedRequest, you can do something like this:

if(request instanceof ScopedRequestImpl) {
ServletRequest sRequest = ((ScopedRequestImpl) request).getRequest();
request = ((ScopedRequestImpl) request).getOuterRequest();
}

Now you have the original request and you may add any parameters you like. Firstly though, be sure to add all parameters from the Map parameters in order to keep any state the framework put there in the first place.

Example use case


One use of this is to have the portlets react to a parameter on the request. Thereby allowing a bookmarkable URL to return to the same page, with the same information. One side effect of this is that back and forth will be working, since the browser history executes via URLs :).
The responsibility of maintaining the parameters is then up to the portlets themselves. I will leave it up to individual projects to implement a backbone for the portlets communication with the URL rewriter. But using session might be the easy way out..

Registering the URL rewriter


The URL rewriter is retrieved from the request by the framework, but we need a way of putting it there in the first place. The simple solution is to use a filter, so we'll do just that:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain
chain) throws IOException, ServletException {
request.setAttribute(UrlRewriterPlugin.URL_REWRITER_PLUGIN, new MyURLRewriter());
}

and then add the appropriate configuration in the web.xml:

<filter>
<filter-name>URLFilter</filter-name>
<filter-class>com.mycompany.URLFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>URLFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>

Prologue


These few tips should be enough for a developer to implement bookmarkability in a WebLogic portal server. But beware of this solution, since it is highly dependant on the BEA implementation. If any issues regarding bad URLs pop-up, I would refer you to the 'com.bea.portlet.GenericURL' class. See what it does if the URLRewriter is not used. I have implemented a great deal of security around the URLRewriter in order to ensure the state of the portlet and portal. The power of the URLRewriter is great though.. use with caution ;)

credit for an example of this goes to Deepak Natarajan

mandag den 21. januar 2008

Interactive javascript environment

Before I really got into Javascript I experienced it as a necessary evil when constructing web applications.

Though recently because of the added pressure of webapps being interactive, I finally took the bullet and gave object oriented javascript a go.

I was amazed, after going through several tutorials on scriptaculous(based on prototype) and JQuery.

But to really get my groove on I needed the ultimate tools, which I found here: Web Development Bookmarklets.

The JavaScript interactive compiler(drag to bookmarks bar), from web development page. You can click this bookmarklet to open a javascript shell for any page and it keeps its scope across new requests.. Excellent!


here's a bookmarklet for loading prototype on the fly, made this myself :), drag to bookmark bar:

load prototype

Then you may write something like this, in the shell, to print the names of all divs:

$$('div').each(function(element){print(element.name);});

Or this to make all divs blink

$$('div').each(function(element){blink(element);});


You can load any script you want, which is particularly easy in the shell with> load(scriptURL). ex.

load('http://wiki.script.aculo.us/javascripts/prototype.js');
//to add more fun load this:
load('http://wiki.script.aculo.us/javascripts/effects.js');
//shake all divs
$$('div').each(function(divElement){Effect.Shake(divElement);});

It boils down to being able to manipulate the dom at will and test Ajax very easily. Enjoy it, I do.

UPDATE:
more powerfull load
load scripts

adds the function shakeDivs(); - try it

søndag den 23. december 2007

High automatic test coverage of web applications

Tests in web applications


Features in a web application reside in one of two locations: On the client or on the server.

A unit test of the feature in the serverside codebase can cover numerous errors. If the application is written in PHP, Python or any other language compiled at runtime, the unit test can cover compiler errors. It can also cover logical errors and the error of not meeting the requirements.

A functional test on the client side can also cover the integration test with browsers if the test framework can execute the tests in multiple browsers, otherwise the lowest denominator might be adequate (think IE 6).

frameworks to use


Almost every decent language has a unit testing framework which provide a standard way of defining, executing and reporting tests. Some, like Django's, also handles the fixtures, like creating and deleting a database for each test run. This is very helpful.

For functional tests in the browser engine, there are numerous frameworks. Some record a macro and repeats it, these tools are to be avoided, since they make maintenance of the tests very cumbersome, which may lead to neglect in the project. Instead of dicussing pro's and con's of various frameworks, like loadrunner, selenium etc. I'm simply going for Canoo's webtest, which aggregates HtmlUnit and several other thirdparty frameworks into one very good framework.

It has the advantage that it is defined in XML, which ought to be readable by most with at least some technical interest. Think testers, new developers and maybe even project managers. It also has a very good reporting tool that is generated in static html files. I'll give an example of a webtest further down.

implementing and maintaining the tests


When developing testdriven, it is a given that at least unit tests are being made. In most IDE's for java developers JUnit tests are we easily made and runnable (though sometimes it can be tricky to setup a full test suite running all tests). In Django you simply write a tests.py module at the root of your application*1. The management tool in Django can then invoke all tests py simple running 'manage.py tests' at the root of the project. In java you have to marshal all the tests in an ANT script or reference all test classes from 1 testsuite, leading to tedious work that puts the tests in jeopardy of being neglected.

A canoo webtest is run by an ANT script. 1 script, which I always use is simply called 'allTests.xml'. Separating tests should not be the norm as with JUnit instead you should have to put some effort into excluding certain tests. The exclusions might be performance tests or some other test that is not a candidate for regression testing.

In webtest you may define several macros and reuse them when you like and it has all the functionality of ANT. In the next section I give an example of a test implementation.

testing upload and file conversion


This feature of my project involves multiple units on the serverside and only 1 clientside. Because most of the features serverside are using almost exclusively the Django framework there is no need to cover it, so I can rely on one simple unit test to test this for me, it takes a file and converts it, which is the only part I have implemented myself:

def test_convert_video(self):
entity = Entity(name="test video")
entity.save()
physical = Physical(content_object=entity)

convert_to_flv(self.avifilename, self.flvfilename, physical)
result = os.path.exists(self.flvfilename)
self.assertTrue(result)
self.assertEqual(self.flvfilename, physical.converted_filename)
os.remove(self.flvfilename)

There are several more features surrounding this one, like test_grab_thumbnail_from_flv, test_invalid_cleanup_convert_video, test_get_default_thumbnail_filename and many more. This part has to have high coverage because it is a core function of the web application, but I will not go into priority vs. coverage in this entry.

The unit under test in the example is the convert_to_flv. When the test executes a fake database is set up and some test doubles are made. The files used in the test are cleaned up afterwards to ensure that the state of the system is not changed as a result of the test.

On the client side I have this webtest:

<target name="test">
<webtest name="add different kinds of content">
<login username="user" password="pass"/>
<addContent name="picture 1" file="../../JOOLLU_webtest/tests/picture1.png"/>
<addContent name="picture 2" file="../../JOOLLU_webtest/tests/babe.jpg"/>
<addContent name="movie 1" file="../../JOOLLU_webtest/tests/plane_lands.avi"/>
<addContent name="movie 2" file="../../JOOLLU_webtest/tests/preview.mov"/>
<addContent name="" file="../../JOOLLU_webtest/tests/preview.mov"/>
<addContent name="plain flv" file="../../JOOLLU_webtest/tests/3.flv"/>
</webtest>

It covers the feature of uploading files. Other tests rely on this being executed which leads to test dependencies, which is totally fine. If it was a requirement not to have test dependencies I would have tests that were hard to maintain since all tests relying on this one would have to upload content themselves, putting the test at risk of being neglected.

Inspect the test. The tag 'addContent' is one macro I have defined as a part of my test project, and it looks like this:

<macrodef name="addContent" description="add some content to the current user profile">
<attribute name="name"/>
<attribute name="file"/>

<sequential>
<clickLink label="add content"/>
<setInputField name="name" value="@{name}"/>
<setFileField name="file" fileName="@{file}"/>
<clickButton htmlId="add_button"/>
</sequential>
</macrodef>

The power of this is that I can encapsulate code that is part of implementing the tests separately and thus make the actual test easier to read and maintain. A tester with no programming background would be able to read the test and change the name of the file and the file itself.
Among other tests that rely on this I have contentValidation.xml, invalidContentValidation.xml, verifyCorrectContent.xml and many others. The nice thing is that each subsequent test can be a direct verification of the feature or requirement. This way I can ensure that no test effort is lost because the implementation on the server has changed.

closing remarks


Testing this way allows for full coverage of a web application. The webtest framework can handle almost all browser functionality even Ajax, ehich is due to the HtmlUit project. It has a couple of bugs, it can for example only drag and drop 1 item for each test. But these are minor issues. If my application did not contain flash as part of the implementation I reckon I could achieve 100% coverage in automatic tests. As it is now I don't have much test of requirements for performance, but I think I'm at 80% coverage in total with unit tests and webtest.

To get the high automatic coverage you need to figure out on which side you have to test your feature, client or server. Then implement the unit tests for serverside and clientside tests in a framework like webtest.. and then you can implement the feature itself, knowing that when the bar in the reporting tool reaches green.. you are finished.

links

canoo webtest

Django testing

footnotes
*1 in Django there are multiple applications per project. An application in Django is the equivalent of a plugin in Eclipse RCP or a Web Application Resource in J2EE.

tirsdag den 4. december 2007

Development with Django and NADB

Python has always intrigued me. Occasionally I have kept revisiting the language to be marbled at the simplicity and ease of use. Until recently I did not have a reason to go further with it.

I started implementing the project Joollu(coming soon joollu).

I decided to use the Django framework. Because a) its done in python and b) I heard it was good for content-driven websites.

And boy it's intuitive, being a novice Python-programmer I felt it astonishing that I could implement my own video blog in less than approx. 10 hours. The documentation is equally astounding.

The Django framework has an object relational-mapper, that handles all your db-management for you, it's a very simple way of making a model layer. You only need to configure the things that are specfic for you, making it very rapid for simple features. I thought it might be a bigger task to implement the NADB, which is only based on interfaces, but then I discovered this notion of Generics implemented in Django.

Generics is used to associate a model object with any other object, without knowing anything about it's implementation. This is exactly what the NADB is all about. Instead of having a Video model class, I implemented a Physical(for storing files), viewable(for attributes like thumbnail, width/height etc.) and firstly an Entity class to represent the actual video, the only attribute here is name and id. None of these models know anything about the other on the DB-layer, instead I have a MediaManager, that can marshal a video from all its referred interfaces. Retrieving a video can be done like so:


>>> from joollu.core.models import *
>>> entity = Entity.objects.get(name="myvideo")
>>> physical = Physical.objects.get(content_object=e)
>>> viewable = Viewable.objects.get(content_object=e)



or more simply with a little wrapping



>>> from joollu.core.managers import MediaManager
>>> entity = Entity.objects.get(name="myvideo")
>>> video = MediaManager().filter_video(name="myvideo")


OR


>>> from joollu.core.managers import MediaManager
>>> entity = Entity.objects.get(name="myvideo")
>>> video = MediaManager().get_media(entity.id)


sadly it kinda impairs the possibilities of filtering and retrieving which is done very easily with Django. Here is an example for physical, if I want particular files:


>>> from joollu.core.models import *
>>> physical_list = Physical.objects.filter(file__endswith=".png")
>>> physical_list
[Physical: /Users/kennethnielsen/pythonspace/joollu/media/content/picture1.png]


Keeping the notions of things like video and images in the business layer increases flexibility. If I were to change attributes I can slap it on one of the exisitng interfaces or make a new one. Like if I want to save who and when something has been published, I can make a new model class Publishable and attach it to all content. This would be regardless of it being a video, image or other. It is up to the business layer to decide if published attributes are needed in specific cases. Comments is another example and so it goes..

There are a ton of other stuff worth mentioning about Django, it all just kinda fits together in this very intuitive framework. You should read up on it, or find the tech talk about it on google tech talks.