History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: SEL-226
Type: Improvement Improvement
Status: Open Open
Priority: Major Major
Assignee: Matthew Purland
Reporter: Tac_Evaworcim
Votes: 3
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
Selenium

JavaScript Memory Leak Fix

Created: 04/May/06 02:37 PM   Updated: 08/Jun/07 04:56 PM
Component/s: Performance/Stability
Affects Version/s: 0.6
Fix Version/s: None

Original Estimate: Unknown Remaining Estimate: Unknown Time Spent: Unknown
Environment: Windows 2000 Server, IE6, FF 1.5.0.3


 Description  « Hide
Problem: when running long selenium scripts, browser process eats memory like a hungry boa.
Cause: selenium does not release events attached to tested app objects.
Solution: register attached events and release them on page unloads. Idea was found at http://novemberborn.net/javascript/event-cache
Patch:
You need to add eventcache.js (http://novemberborn.net/javascript/event-cache.js , also provided here) to your selenium directory and patch some selenium files:
--------------------------------------- eventcache.js (add) start ---------------------------------------

/* EventCache Version 1.0
    Copyright 2005 Mark Wubben

Provides a way for automagically removing events from nodes and thus preventing memory leakage.
    See <http://novemberborn.net/javascript/event-cache> for more information.
    
This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/>
*/

//window.alert ("Event_Cache.js!");

/* Implement array.push for browsers which don't support it natively.
    Please remove this if it's already in other code */

if(Array.prototype.push == null){
    Array.prototype.push = function(){
        for(var i = 0; i < arguments.length; i++){
            this[this.length] = arguments[i];
        };
        return this.length;
    };
};

/* Event Cache uses an anonymous function to create a hidden scope chain.
    This is to prevent scoping issues. */
var EventCache = function(){
    var listEvents = [];
    
return {
        listEvents : listEvents,
    
add : function(node, sEventName, fHandler, bCapture){
            listEvents.push(arguments);
        },
    
flush : function(){
            var i, item;
            for(i = listEvents.length - 1; i >= 0; i = i - 1){
                item = listEvents[i];
                
if(item[0].removeEventListener){
                    item[0].removeEventListener(item[1], item[2], item[3]);
                };
                
/* From this point on we need the event names to be prefixed with 'on" */
                if(item[1].substring(0, 2) != "on"){
                    item[1] = "on" + item[1];
                };
                
if(item[0].detachEvent){
                    item[0].detachEvent(item[1], item[2]);
                };
                
item[0][item[1]] = null;
            };
        }
    };
}();
--------------------------------------- eventcache.js (add) end ---------------------------------------

--------------------------------------- selenium-browserbot.js (edit) start ---------------------------------------
// line 228
   BrowserBot.prototype.callOnWindowPageTransition = function(loadFunction, windowObject) {
       var attachLoadListener = function() {
           if (windowObject && !windowObject.closed) {
               addLoadListener(windowObject, loadFunction);
           }
       };
   
var unloadFunction = function() {
           window.setTimeout(attachLoadListener, 0);
       };
       addUnloadListener(windowObject, unloadFunction);
// patch start
       addEvent(windowObject, "unload", EventCache.flush);
// patch end
   };

//.....................................//
// line 715 (inside MozillaPageBot.prototype.clickElement() )
    if (geckoVersion) {
        element.addEventListener("click", function(evt) {preventDefault = evt.getPreventDefault();}, false);
// patch start
        EventCache.add(node, "propertychange", onPropertyChangeEventHandler);
// patch end
    }

--------------------------------------- selenium-browserbot.js (edit) end ---------------------------------------

--------------------------------------- html-xpath-patched.js (edit) start ---------------------------------------
// line 593 ( near end of function loadNode(dom, domParentNode, node, helper) )
                   node.attachEvent("onpropertychange", onPropertyChangeEventHandler);
// patch start
                 EventCache.add(node, "propertychange", onPropertyChangeEventHandler);
// patch end
               }
           }
--------------------------------------- html-xpath-patched.js (edit) end ---------------------------------------

--------------------------------------- htmlutils.js (edit) start ---------------------------------------
// line 103
function addLoadListener(element, command) {
    if (window.addEventListener)
        element.addEventListener("load",command, true);
    else if (window.attachEvent)
        element.attachEvent("onload",command);
// patch start
    EventCache.add(element, "load",command, true);
// patch end
}

function addUnloadListener(element, command) {
    if (window.addEventListener)
        element.addEventListener("unload",command, true);
    else if (window.attachEvent)
        element.attachEvent("onunload",command);
// patch start
    EventCache.add(element, "unload",command, true);
// patch end
}
--------------------------------------- htmlutils.js (edit) end ---------------------------------------

--------------------------------------- TestRunner.html (edit) start ---------------------------------------
<!-- line 29 -->
<!-- patch start -->
<script language="JavaScript" type="text/javascript" src="event-cache.js"></script>
<!-- patch end -->
--------------------------------------- TestRunner.html (edit) end ---------------------------------------

 All   Comments   Work Log   Change History      Sort Order:
There are no comments yet on this issue.