Pivot Jonathan and I were recently working on support for Google Chrome in Pivotal Tracker. Tracker’s extensive JsUnit test suite made this a lot easier.
Here’s some quick notes I took on the issues we ran into.
Don’t try to directly mock the ‘reset’ method on a Form Element
This was the original mocking code in one of our JsUnit tests:
var resetCalled = false;
widget._uploadForm.reset = function() { resetCalled = true; };
This permanently blew away the “reset” method, so it was undefined when called in a subsequent. To fix it, we did this in our form builder method:
var element = Element.create("form");
element.nativeReset = element.reset;
element.reset = function() { element.nativeReset() };
Hash keys sort differently
We had a testHash.keys() being compared to a hardcoded array. Chrome sorted the keys differently (apparently non-deterministically, so we had to do an explicit sort:
assertArrayEquals(['10001', '10002', '10003', 'endOfList'].sort(), $H(itemListWidget.draggables).keys().sort());
It wasn’t good to depend on the keys order in the first place, but it worked under IE, Firefox, and Safari.
The same hash sorting bug bit us in a much more obscure way. There was some threading test code that simulated timeouts/concurrency using a mock clock. Previously, the test code was dependent on the order in which the functions were added to a hash the mock “clock”. This broke with a different hash sorting order. We had to simulate some additional “ticks” to make the test pass.
Mozilla, but not Gecko
The browser string returned for Chrome by one of our utility functions, BrowserDetect.browser(), is “Mozilla”. However, for some of our simulated keypress events in tests, the “Gecko” version did not work.
Specifically, we had to use “KeyboardEvent” instead of “KeyEvents”, and “initKeyboardEvent” instead of “initKeyEvent”. See the table in this mozilla doc page.
Here’s the code we used to handle both cases:
evt = document.createEvent('KeyboardEvent');
if (typeof(evt.initKeyboardEvent) != 'undefined') {
evt.initKeyboardEvent(eventName, true, true, window, false, false, false, false, options.keyCode, options.keyCode);
} else {
evt.initKeyEvent(eventName, true, true, window, false, false, false, false, options.keyCode, options.keyCode);
}
The UserAgent (request.user_agent) returns
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/0.3.154.9 Safari/525.19
The ‘sort’ function does not preserve order of equivalent elements
The following page outputs ‘ACBD’ under Chrome:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<body>
<a href="#" onclick="alert(doSort()); return false;">Sort</a>
<script type="text/javascript">
function doSort() {
var myArray = [
{id: "A", sortVal: 0},
{id: "B", sortVal: 1},
{id: "C", sortVal: 1},
{id: "D", sortVal: 2}
];
var sorted = myArray.sort(function(a,b) {return a.sortVal - b.sortVal});
return sorted[0].id + sorted[1].id + sorted[2].id + sorted[3].id;
}
</script>
</body>
</html>
About the Author