Debugging, Javascript

Faster 3rd party widget debugging using DOM breakpoints


Imagine the following scenario:
You got a requirement to implement a multi select dropdown with icons near each option and filtering capabilities. Assuming your first course of action won’t be writing it from scratch, you google around to find a library which meets those needs. You found exactly what you needed, it even has a lot of stars in github, seems safe to use. Jackpot.
You implement this dropdown and everything works fine.

After 2 weeks you get a call from the good guys at QA saying that sometimes, when filtering random strings, the icons of the filtering results are disappearing. How would you handle it? I assume that you’ll google the problem to see if this is a familiar issue with this library. But what if you won’t find anything, then what?

DOM Breakpoints to the Rescue

In order to understand what causes the problem, we’ll need to know exactly which code removes the DOM in our library and follow it’s call stack. We can do this by using DOM breakpoint on the removed element. Let’s see some code:

index.html

<!DOCTYPE html>
<html>
  <head>
    <script data-require="jquery@3.0.0" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
    <script src="3rdPartyLib.js"></script>
  </head>

  <body>
    <i id="myIcon">ICON</i>
  </body>
</html>

3rdPartyLib.js

// Assume this is a 3rd party library you are using.

var iconRemover = function() {

	/*
	   ...........
	   Imagine we have much code here
	   ...........
	*/
		
        setTimeout(firstInStack,10000);
        
	/*
	   ...........
	   Imagine we have much code here
	   ...........
	*/
		
        function firstInStack() {
          setTimeout(secondInStack,500);
        }
		
	/*
	   ...........
	   Imagine we have much code here
	   ...........
	*/
        
        function secondInStack() {
          setTimeout(thirdInStack,500);
        }
        
	/*
	   ...........
	   Imagine we have much code here
	   ...........
	*/
		
        function thirdInStack() {
          $("#myIcon").remove();
        }
        
}();

In order to understand what causes the icon element to be removed, inspect the element and then click on ‘break on’ and select ‘Node removal’ (we’ll cover the other options later):

availble-breakpoints

Now we’ll wait 10 seconds until the first timeout of our 3rd party library will kick in and the debugger will open with the following screen:

stack-trace-icon-rem-1

As you can see, the breakpoint stopped at jQuery’s removeChild function. But if you look at the call stack you’ll able the to see the call stack that eventually invoked jQuery’s remove. You’ll be able to see that firstInStack called secondInStack which called thirdInStack which removed the icon by id. It gives us a crystal clear picture of what’s going on, which makes debugging much easier. You can click on any function in the stack to examine it’s contents, if we click on thirdInStack we’ll see:

stack-trace-icon-rem-2

One thing you need to make sure is that you checked the Async option in the debugger (I’ve marked it in the previous screen shot). This instructs the debugger to show asynchronous functions in the call stack.

Type of breakpoints

As you can see there are 3 types of breakpoints:

  • Subtree Modifications – Addition, removal or modification of any child element
  • Attributes Modifications – Any change in the attributes of the element under inspection
  • Node Removal – Removal of the element under inspection

That’s it, pretty simple yet efficient.

One thought on “Faster 3rd party widget debugging using DOM breakpoints

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s