Friday, January 25, 2013

JavaScript application testing - Firebug - Part 2

I wrote about how one can use Firebug over here. Today I'll extend that a little by introducing a few of the features I didn't touch upon last time. There's not too many left as I did the bulk last time, but hey..let's complete stuff :)

So the last time, we talked about setting breakpoints inside Javascript to look at code. We'll do 2 things now..firstly we'll actually set those breakpoints and take an actual application and see how these breakpoints help and secondly we'll introduce DOM breakpoints and see how those can be helpful at times.

So here's a client side application. On logging in as an Admin user we can see the first image and while logging in as a normal user, we can see the second image.

The goal here is to try and make those extra links appear for a normal user. Since the purpose of this blog is to just show you what breakpoints can accomplish, I won't dive too deep into how I identified the right place to set the breakpoint. Here I know that the critical place is line 4598.

The application is checking if the current user has a role of 'Edit Articles'. Where is it checking? It's looking into the TM.Gui.CurrentUser.userRoles element. Now how do we know what that contains? Well there's 3 ways. The first way is to look directly at the DOM element in question by navigating to the DOM tab and expanding nodes till you reach that element.

The second way is to do this through the console by typing in the whole path. If that path exists, the values will be displayed. Autocomplete by the way is enabled in the Firebug console...use the arrow keys to complete a word (left/right) or view possibilities (up/down) and hit Enter 2 times when done. If you type the whole thing out you need to hit Enter only once.

The final way is by means of something called a Watch expression. This is something completely new. It was to me too a day or so ago :). Navigate to the Scripts Tab and look at the right pane. Now click on watch and then inside the box which says 'New watch expression' and type in the exact same path you typed in the console. Autocomplete is enabled here as well. You can also right click on any property in the DOM and say 'Add to Watch List'.

NOTE though that the Watch is useful only when a breakpoint is enabled. We'll see why very soon.

Coming back to our example, which we've forgotten completely :).. we want to do something so that those 2 extra links appear for a normal user. Now if you've followed through, you'll know that the normal user does not have the 'EditArticles' role at all. And if she does not have the EditArticles role, she cannot get those 2 extra links. This means that we'll have to somehow edit the DOM and add that role in.

If you look at the Watch tab here before editing you can immediately see the value of the specific property without changing tabs to go to the DOM or the Console. You can stay in the Script tab and do it.

If you'd read Part 1 you'll know that this can easily be achieved by using the Console. If you haven't, and are frantically right clicking inside the DOM without success, don't worry. Here's how you do it again.

If you look at the DOM, using any of the 3 above techniques you'll see an additional role (EditArticles) that's added.

Let's now hit Continue (F8) and see if we get an additional link. We sure do :). The exact same exercise can be repeated by setting a breakpoint on the isAdmin line (4597) and adding the "Admin" role to the DOM. If you'd like to try it out,  grab a copy of TeamMentor from Git.

DOM Breakpoints

All this while we've been setting breakpoints in the JavaScript. It's also possible to set these breakpoints in the DOM instead and alert us when that particular property changes. Let's extend this same example now, shall we.

On clicking logout, there's a high chance that the DOM is going to get flushed and we won't have access to any of these menus any more. Let's see when exactly the 'role emptying' of the DOM happens.

Navigate to the DOM and expand the CurrentUser node. Right click on the currentuserName element and click 'Break on Property Change'. You now have a DOM breakpoint set which are also visible in the Breakpoints menu in the right pane of the Script Tab (You may have to scroll down). Let's now logout and see if this gets triggered.

Yes! The DOM breakpoint is triggered and points us to the exact line of JS code that was editing the property. Click F8 and then go back to the DOM to see if there actually was a change and you'll find that the same property is now "undefined". Which means the DOM breakpoint did work :). This is extremely useful when you can see the exact path of an interesting element in the DOM but don't know where its corresponding JS code is.

 Other useful features:

There's the 'Break on Next' feature which will break on the immediate next script. I want to see what happens as soon as I click login? Click the Break on Next button and then click Login.

As mentioned by a person who read the previous article, you can set XHR breakpoints if you want to break on a specific XHR call; that's the easiest approach to do things...many a time. Break on the XHR and then use all these other techniques. Similarly you can also break inside the HTML tab when an attribute is added or removed. Make sure though that you're clicking on a leaf node...the last node...the attribute. You can't break on a non leaf node. The same logic applies to DOM elements as well.

If you want to look at the entire Call tree. For example: If you've broken on isEditor and want to know where it is called from you can look at the Stack (middle menu - right pane - Script menu). The most recent function is at the top and the first caller right at the bottom.

That apart you can edit HTML, add elements, destroy or modify cookies and possibly many other little things. To know everything this fantastic tool can do go on to its webpage and read the documentation :).

Hope you liked this small series. Again..if you  missed it.. here is Part 1.

No comments: