IE – Disable JavaScript execution from console

In last post, I mentioned how to disable JavaScript execution from Chrome Developer Tools and now we’ll have a close look on how to achieve it for IE Developer toolbar.

Before getting into how to disable, let’s understand what goes under the hood when you type in JS code in console (or how it is understood by console and executed in the web application environment). Let’s assume that you are trying to execute the following code snippet in console

	var z = parseInt( '123', 10 );

How IE’ console shows it

IE - Console Messages
IE - Console Messages

When you type-in the above statement in IE’s console, it translate it into a full blown script statements and execute it as

document.__IE_DEVTOOLBAR_CONSOLE_EVAL_RESULT = undefined;
document.__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR = false;
try{
    document.__IE_DEVTOOLBAR_CONSOLE_EVAL_RESULT = eval( "var z = parseInt( '123', 10 );" );
}
catch(__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR){
    document.__IE_DEVTOOLBAR_CONSOLE_EVAL_RESULT =__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR.message;
    document.__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR = true;
}

Notice line no 4 where the code which typed in is exactly being passed to parameter to eval function in web application environment.

At this point, you could say – Aha, let me override eval function and discard any string which is being passed from console. Simple, isn’t it? But wait, you could do so if you are sure that eval is not being used in your application code. If it is, how would you differentiate when it is being executed from console or from the application code? (Phew, don’t remind of argument.callee and all!) that is exactly we are going to solve now.

Now, let’s revisit the code snippet generated by IE’s console. Notice that it sets a property “__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR” in document object as false before executing script and resets to true if there are any exception .

With the above knowledge, what we can do

• Create a watch property on “__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR” to understand when the value is being set to true/false.

• Set the watch property to true when the “__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR” property is set to false indicating that the next call to eval is definitely from console.

• Override eval function. Check whether the watched property is true and if so, throw exception which will be catched by code injected from console. Catch handler would reset “__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR” and accordingly our watch property. With this, we now are sure that if there are any call to eval from our application code would definitely be honored.

Now is the time to see the real code which I added to have the same functionality

(function(){
    var  _eval       = eval,
          evalError  = document.__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR,
          flag       = false;
        
    Object.defineProperty( document, "__IE_DEVTOOLBAR_CONSOLE_EVAL_ERROR", {
	get : function(){
		return evalError;
	},
	set : function(v){
		flag = !v;
                evalError = v;
	}
    });
        
    eval = function(){
	if( flag ){
		throw "";
        }
        return _eval.apply( this, arguments );
    };
})();

After adding the code, let’s see what IE’s console does –

IE - Console Disabled
IE - Console Disabled

Stay tuned for next post where I am going to describe how to handle it for Firebug console in Firefox. Don’t forget to leave comments if you have any.

Selecting ExtJS Grid Row using Watir

Grid is the most powerful widget in ExtJS and it becomes tricky at times to write test cases using Watir. One of the instance which I faced was selection of any row in grid with watir script.

From the script, I tried to find the DIV element of grid for the row using the class tag and fired the click event

$browser.div( :class => "x-grid3-row", :index => 10 ).click 

The script immediatley highlighted 10th row in grid but did not get selected (Normally Grid row changes appearance when it gets selected). I tried the other way (firing mousedown event, thinking it would work ) as

$browser.div( :class => "x-grid3-row", 
                   :index => 10 ).fire_event( "onmousedown" )

Still no luck! It looked like as if grid is not responding to the events.

On debugging the issue, I found that whenever “mousedown” or “click” events are being fired from watir scripts, they were cascading “rowmousedown” or “rowclick” event appropriately to the Grid. But the function which changes the css class of row to be selected was not getting called. Again Why?

Stepping further, found the statement in RowSelectionModel class from where the event is simply ignored (as if nothing had happened)

Class - RowSelectionModel
handleMouseDown : function(g, rowIndex, e){
   if(e.button !== 0 || this.isLocked()){
      return;
   };

It seems that value of button property was not equal to ZERO when fired from watir script. However when I use mouse, button value is ZERO.

Why ExtJS has this comparison check for button property of Event? My guess is that ExtJS developer wanted to handle only those event which are being generated by clicking mouse. If the event was generated from Mouse, property button of event will definitely have the value as per the W3C standard or Microsoft standard ( which is obviously not the case with the events generated from watir scripts).

The question now, how do we generate mouse event using our watir scripts? Cause from watir library, there is no way to fire mouse event directly.

Solution to the above problem is to add the module as mentioned in Watir Wiki . Include the module in your script and modify your test statement as

$browser.div( :class => "x-grid3-row", :index => 10 ).left_click

It works perfectly!!!

for me, this is definitely elegant as I was trying to execute javascript code from watir script to select the row as

$browser.document.parentWindow.eval( 
      "Ext.getCmp( 'gridId' ).getSelectionModel().selectRow( 10 ) ")

On a side note, I have not heard of many instance where folks are praising Microsoft for implementing feature which is not according to the standard and still makes sense (specially true with Internet Explorer). Read the “Miscellaneous Properties” section in W3C Dom Events page for details of Event’s Button property. From the page

The Microsoft implementation is the only one that makes sense.