Issue Details (XML | Word | Printable)

Key: SEL-226
Type: Improvement Improvement
Status: Open Open
Priority: Major Major
Assignee: Matthew Purland
Reporter: Tac_Evaworcim
Votes: 8
Watchers: 5
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: 23/Mar/09 01:38 PM
Component/s: Performance/Stability
Affects Version/s: 0.6
Fix Version/s: None

Environment: Windows 2000 Server, IE6, FF 1.5.0.3
Issue Links:
Relationship
 


 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 ---------------------------------------



Sort Order: Ascending order - Click to sort in descending order
Dennis Winter added a comment - 20/Jan/09 03:38 AM

I guess this is out of date. I tried to apply this patch on 1.0.Beta.2
I have some problems finding the first patch.

1.
— selenium-browserbot.js —
// 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
};

2.
html-xpath-patched.js does not exist.

3. Unloadlistener doesn't exist in htmlutils.js


Shawn added a comment - 23/Mar/09 01:38 PM

I have the same problems as Dennis, I cannot find the applicable files/functions to apply patch (also 1.0 Beta 2). Are there variations for applying it to said release?