Tuesday, February 24, 2009

cross browser key events in javascript

this is a pure JS solution that lets you get the key code from an event, it works for all browser:

Monday, February 23, 2009

Functional Testing with Tellurium

I have recently discovered a new toolset for functional testing. Its called Tellurium and it runs on top of Selenium. Tellurium brings some cutting edge technologies to the table:
  • It's built fully in Groovy and takes advantage of DSLs, closures and other syntax sugar, while letting you code in java if you prefer.
  • It supports JUnit and TestNG unit testing frameworks
  • Instead of relying on xpath to describe the UI, it uses a UI mapping DSL
  • Comes with a firefox plugin for generating UI modules called TrUMP
Even though Tellurium is a fairly young project, it has very good support on the project forums. I have requested a few bug fixes and patches, and had the fixes committed within days. Anyway, the biggest advantage in using Tellurium vs Selenium is the UI mapping. Let's look at what a simple Selenium script would look like versus that same script written for Tellurium.

In this simple script we will click around the Tellurium project page. This is the Selenium version:

And now, the same test in Tellurium. Tellurium uses UI modules to describe the UI in a class that is separate from the test. Here is the UI module DSL:

And this is the Tellurium TestNG test case that uses the above module:

As you can see, the code looks very different. You will notice that the Selenium test is much shorter, but does not re-use UI elements like the Tellurium test does. Tellurium's UI mapping maps UI elements to very short element ids, which support hierarchical nesting, which can greatly simplify large tests.
Another big and obvious advantage to UI mapping is that if your underlying html changes, you would only need to modify the UI mapping DSL, and not need to worry about the actual tests. This is where Tellurium really shines for me.
Modifing the UI maps is really simple using the TrUMP Firefox plugin. TrUMP lets you point and click on the page, and builds out the nested UI module DSL for you.

What you will need in order to use Tellurium for your project
Useful resources for working with Tellurium and TrUMP firefox plugin
The best place to go to find support is the tellurium user group. Questions are answered very fast, and it is the main reason I was able to integrate Tellurium into my functional testing strategy at work.

Also, the Tellurium team has created two videos to help you get started with the project:
Tellurium Demo Video Part I: Tellurium project and TrUMP IDE
Tellurium Demo Video Part II: Create Tellurium Test cases

Tuesday, February 17, 2009

Building fast jQuery plugins

There are 3 million articles out there about making jQuery plugins, but most of them seem to focus on the basics. That is all well and good, but none of those articles will help you if you want to write a fast, responsive plugin that wont peg the CPU.

I will outline some techniques that have worked for me in building good jQuery plugins.

  • Cache your selectors. Not caching can be a real performance killer, once you select an element, cache it, if you plan to use it again. Even ID selectors should be cached. it will always be faster to reuse a cached selector than to ask the DOM for it. When it comes to plugins, you can hide the cached selectors in the main closure, and reuse them in the methods of the plugin.
  • Cache your state. It will always be faster to check if a boolean is true, than to check if a DOM element is visible. Forget about the DOM. Cache everything you will need access to, cache your modifications. DOM access is slow. I will exchange a few bytes of memory for a few ms of execution any day.
  • Use closures. If you dont know how to use closures, you must learn now. You wont be able to write a good plugin if you dont know when and how to use these. You should use the closure to hide all your config data, your cached selectors etc.
  • Dont use $.fn. if it doesnt make sense. Sometimes it makes sense to return something other then the jQuery object from your plugin. You can always pass in the 'this' the old school way as an argument. Sometimes it may be better to return an object that makes some methods from the closure 'public' and exposes some members. This kind of an object can be useful when writing unit tests, or if you want to provide a rich API without bastardizing $.fn.
  • Use functional inheritance. Use this and you will be get private/public members. This is important if you would like to have a clean API. I am talking about the functional inheritance from 'javascript: the good parts' book. See example of what i mean here.
  • Break things up into responsibilties. Let each method inside your plugin handle one thing. Do we need to recalucate something on window resize? Do we need to reload some event handlers after AJAX calls? Dont make one giant 'reload' method when you can have more specific methods that will save time.
  • Time and profile. I wish i had started doing this earlier. Use firebug's timing and profiling to see which portions of your code are slow, and optimize them.
  • Unit test. QUnit is jQuery's testrunner. Use it.
  • Test on a Pentium 3, in IE 6. This is my golden standard. If its fast here, you have nothing to worry about.

Sunday, February 08, 2009

Using jQuery with NYT JSON API

New York Times recently made public a great API that lets you search all of their articles from 1981 to present, and get the data back in JSON format.
I decided to use this API to add some relevant news stories to a site i have been working on. I was going to use jQuery to pull the data using $.getJSON() and shove it into some divs on my site.

I quickly ran into a problem. NYT is retuning plain JSON, not JSONP. JSONP is needed to do cross-domain JSON calls. jQuery will make a jsonp call if you add the following to the request url:
In the background, what happens is that jQuery replaces the ? with a function is creates, for example jsonp1229009. jQuery is expecting a response of:

but new york times is returning:

When jQuery pulls that response into a script tag, and executes in, i get the following error in firefox: "Invalid Label".

What i needed was a JSONP wrapper. Luckly, i have a friend who knows perl =) I asked him to write a service that will take 2 params: url and callback. Where URL is an encoded URL i am requesting, and callback is the param to wrap the response in. It worked out nicely, i can now use ANY JSON API and get JSONP back. This is the perl source:

Here is my crude and incomplete jQuery plugin that gets me a couple of articles with predefined fields and displays them on my site:

i call it like this:

Tuesday, February 03, 2009

Architect - Belgian Connection Lyrics

Lyrics of Belgian Connection from the 2004 album 'I Went Out Shopping To Get Some Noise' by Architect:

You wait and see if I'm not right.
Forty-eight hours and we'll have them aloft.
Then whoosh, up, over and whammo.
Forty-eight hours and we'll have them aloft.
Then whoosh.
There goes the enemy.
Obliterated, finished.
But what are they doing in the meantime?
What do you mean what are they doing?
Probably retaliating the best way they can.
It's a big waste of time, let me tell you.
We get the first licks so they can't do much.

You wait and see if I'm not right.
Forty-eight hours and we'll have them aloft.
Then whoosh whoooosh whooooosh
There goes the enemy.
Forty-eight hours and we'll have them aloft.
Then whoosh
There goes the enemy.
Obliterated, finished.
But what are they doing in the meantime?
What do you mean what are they doing?
Probably retaliating the best way they can.
It's a big waste of time.