~clinton-collins/familyproject/trunk

« back to all changes in this revision

Viewing changes to ZendFramework/externals/dojo/util/doh/_browserRunner.js

  • Committer: Clinton Collins
  • Date: 2009-06-26 19:54:58 UTC
  • Revision ID: clinton.collins@gmail.com-20090626195458-5ebba0qcvo15xlpy
Initial Import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
if(window["dojo"]){
 
2
        dojo.provide("doh._browserRunner");
 
3
}
 
4
 
 
5
// FIXME: need to add prompting for monkey-do testing
 
6
// FIXME: need to implement progress bar
 
7
// FIXME: need to implement errors in progress bar
 
8
 
 
9
(function(){
 
10
        if(window.parent == window){
 
11
                // we're the top-dog window.
 
12
 
 
13
                // borrowed from Dojo, etc.
 
14
                var byId = function(id){
 
15
                        return document.getElementById(id);
 
16
                };
 
17
 
 
18
                var _addOnEvt = function(       type,           // string
 
19
                                                                        refOrName,      // function or string
 
20
                                                                        scope){         // object, defaults is window
 
21
 
 
22
                        if(!scope){ scope = window; }
 
23
 
 
24
                        var funcRef = refOrName;
 
25
                        if(typeof refOrName == "string"){
 
26
                                funcRef = scope[refOrName];
 
27
                        }
 
28
                        var enclosedFunc = function(){ return funcRef.apply(scope, arguments); };
 
29
 
 
30
                        if((window["dojo"])&&(type == "load")){
 
31
                                dojo.addOnLoad(enclosedFunc);
 
32
                        }else{
 
33
                                if(window["attachEvent"]){
 
34
                                        window.attachEvent("on"+type, enclosedFunc);
 
35
                                }else if(window["addEventListener"]){
 
36
                                        window.addEventListener(type, enclosedFunc, false);
 
37
                                }else if(document["addEventListener"]){
 
38
                                        document.addEventListener(type, enclosedFunc, false);
 
39
                                }
 
40
                        }
 
41
                };
 
42
 
 
43
                //
 
44
                // Over-ride or implement base runner.js-provided methods
 
45
                //
 
46
                var escapeXml = function(str){
 
47
                        //summary:
 
48
                        //              Adds escape sequences for special characters in XML: &<>"'
 
49
                        //              Optionally skips escapes for single quotes
 
50
                        return str.replace(/&/gm, "&amp;").replace(/</gm, "&lt;").replace(/>/gm, "&gt;").replace(/"/gm, "&quot;"); // string
 
51
                };
 
52
 
 
53
                var _logBacklog = [], _loggedMsgLen = 0;
 
54
                var sendToLogPane = function(args, skip){
 
55
                        var msg = "";
 
56
                        for(var x=0; x<args.length; x++){
 
57
                                msg += " "+args[x];
 
58
                        }
 
59
 
 
60
                        msg = escapeXml(msg);
 
61
 
 
62
                        // workarounds for IE. Wheeee!!!
 
63
                        msg = msg.replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;")
 
64
                                .replace(" ", "&nbsp;")
 
65
                                .replace("\n", "<br>&nbsp;");
 
66
                        if(!byId("logBody")){
 
67
                                _logBacklog.push(msg);
 
68
                                return;
 
69
                        }else if(_logBacklog.length && !skip){
 
70
                                var tm;
 
71
                                while((tm=_logBacklog.shift())){
 
72
                                        sendToLogPane(tm, true);
 
73
                                }
 
74
                        }
 
75
                        var logBody=byId("logBody");
 
76
                        var tn = document.createElement("div");
 
77
                        tn.innerHTML = msg;
 
78
                        //tn.id="logmsg_"+logBody.childNodes.length;
 
79
                        logBody.appendChild(tn);
 
80
                        _loggedMsgLen++;
 
81
                }
 
82
 
 
83
                var findTarget = function(n){
 
84
                        while(n && !n.getAttribute('_target')){
 
85
                                n=n.parentNode;
 
86
                                if(!n.getAttribute){
 
87
                                        n=null;
 
88
                                }
 
89
                        }
 
90
                        return n;
 
91
                }
 
92
                
 
93
                doh._jumpToLog = function(e){
 
94
                        //console.log(e);
 
95
                        
 
96
                        var node = findTarget(e?e.target:window.event.srcElement);
 
97
                        if(!node){
 
98
                                return;
 
99
                        }
 
100
                        var _t = Number(node.getAttribute('_target'));
 
101
                        var lb = byId("logBody");
 
102
                        if(_t>=lb.childNodes.length){
 
103
                                return;
 
104
                        }
 
105
                        var t = lb.childNodes[_t];
 
106
                        t.scrollIntoView();
 
107
                        if(window.dojo){
 
108
                                //t.parentNode.parentNode is <div class="tabBody">, only it has a explicitly set background-color,
 
109
                                //all children of it are transparent
 
110
                                var bgColor = dojo.style(t.parentNode.parentNode,'backgroundColor');
 
111
                                //node.parentNode is the tr which has background-color set explicitly
 
112
                                var hicolor = dojo.style(node.parentNode,'backgroundColor');
 
113
                                var unhilight = dojo.animateProperty({
 
114
                                        node: t,
 
115
                                        duration: 500,
 
116
                                        properties:
 
117
                                        {
 
118
                                                backgroundColor: { start:hicolor, end: bgColor }
 
119
                                        },
 
120
                                        onEnd: function(){
 
121
                                                t.style.backgroundColor="";
 
122
                                        }
 
123
                                });
 
124
                                var hilight = dojo.animateProperty({
 
125
                                        node: t,
 
126
                                        duration: 500,
 
127
                                        properties:
 
128
                                        {
 
129
                                                backgroundColor: { start:bgColor, end: hicolor }
 
130
                                        },
 
131
                                        onEnd: function(){
 
132
                                                unhilight.play();
 
133
                                        }
 
134
                                });
 
135
                                hilight.play();
 
136
                        }
 
137
                };
 
138
 
 
139
                doh._jumpToSuite = function(e){
 
140
                        var node = findTarget(e ? e.target : window.event.srcElement);
 
141
                        if(!node){
 
142
                                return;
 
143
                        }
 
144
                        var _g = node.getAttribute('_target');
 
145
                        var gn = getGroupNode(_g);
 
146
                        if(!gn){
 
147
                                return;
 
148
                        }
 
149
                        gn.scrollIntoView();
 
150
                };
 
151
 
 
152
                doh._init = (function(oi){
 
153
                        return function(){
 
154
                                var lb = byId("logBody");
 
155
                                if(lb){
 
156
                                        // clear the console before each run
 
157
                                        while(lb.firstChild){
 
158
                                                lb.removeChild(lb.firstChild);
 
159
                                        }
 
160
                                        _loggedMsgLen = 0;
 
161
                                }
 
162
                                this._totalTime = 0;
 
163
                                this._suiteCount = 0;
 
164
                                oi.apply(doh, arguments);
 
165
                        }
 
166
                })(doh._init);
 
167
 
 
168
                doh._setupGroupForRun = (function(os){
 
169
                        //overload _setupGroupForRun to record which log line to jump to when a suite is clicked
 
170
                        return function(groupName){
 
171
                                var tg = doh._groups[groupName];
 
172
                                doh._curTestCount = tg.length;
 
173
                                doh._curGroupCount = 1;
 
174
                                var gn = getGroupNode(groupName);
 
175
                                if(gn){
 
176
                                        //two lines will be added, scroll the second line into view
 
177
                                        gn.getElementsByTagName("td")[2].setAttribute('_target',_loggedMsgLen+1);
 
178
                                }
 
179
                                os.apply(doh,arguments);
 
180
                        }
 
181
                })(doh._setupGroupForRun);
 
182
                
 
183
                doh._report = (function(or){
 
184
                        //overload _report to insert a tfoot
 
185
                        return function(){
 
186
                                var tb = byId("testList");
 
187
                                if(tb){
 
188
                                        var tfoots=tb.getElementsByTagName('tfoot');
 
189
                                        if(tfoots.length){
 
190
                                                tb.removeChild(tfoots[0]);
 
191
                                        }
 
192
                                        var foot = tb.createTFoot();
 
193
                                        var row = foot.insertRow(-1);
 
194
                                        row.className = 'inProgress';
 
195
                                        var cell=row.insertCell(-1);
 
196
                                        cell.colSpan=2;
 
197
                                        cell.innerHTML="Result";
 
198
                                        cell = row.insertCell(-1);
 
199
                                        cell.innerHTML=this._testCount+" tests in "+this._groupCount+" groups /<span class='failure'>"+this._errorCount+"</span> errors, <span class='failure'>"+this._failureCount+"</span> failures";
 
200
                                        cell.setAttribute('_target',_loggedMsgLen+1);
 
201
                                        row.insertCell(-1).innerHTML=doh._totalTime+"ms";
 
202
                                }
 
203
                                or.apply(doh,arguments);
 
204
                        }
 
205
                })(doh._report);
 
206
                
 
207
                if(this["opera"] && opera.postError){
 
208
                        doh.debug = function(){
 
209
                                var msg = "";
 
210
                                for(var x=0; x<arguments.length; x++){
 
211
                                        msg += " "+arguments[x];
 
212
                                }
 
213
                                sendToLogPane([msg]);
 
214
                                opera.postError("DEBUG:"+msg);
 
215
                        }
 
216
                }else if(window["console"]){
 
217
                        if(console.debug){
 
218
                                doh.debug = function(){
 
219
                                        sendToLogPane.call(window, arguments);
 
220
                                        console.debug.apply(console, arguments);
 
221
                                };
 
222
                        }else if(console.info){
 
223
                                doh.debug = function(){
 
224
                                        sendToLogPane.call(window, arguments);
 
225
                                        console.info.apply(console, arguments);
 
226
                                };
 
227
                        }else{
 
228
                                doh.debug = function(){
 
229
                                        var msg = "";
 
230
                                        for(var x=0; x<arguments.length; x++){
 
231
                                                msg += " "+arguments[x];
 
232
                                        }
 
233
                                        sendToLogPane([msg]);
 
234
                                        console.log("DEBUG:"+msg);
 
235
                                };
 
236
                        }
 
237
                }else{
 
238
                        doh.debug = function(){
 
239
                                sendToLogPane.call(window, arguments);
 
240
                        }
 
241
                }
 
242
 
 
243
                var loaded = false;
 
244
                var groupTemplate = null;
 
245
                var testTemplate = null;
 
246
 
 
247
                var groupNodes = {};
 
248
 
 
249
                var _groupTogglers = {};
 
250
 
 
251
                var _getGroupToggler = function(group, toggle){
 
252
                        if(_groupTogglers[group]){ return _groupTogglers[group]; }
 
253
                        var rolledUp = true;
 
254
                        return (_groupTogglers[group] = function(evt, forceOpen){
 
255
                                var nodes = groupNodes[group].__items;
 
256
                                var x;
 
257
                                if(rolledUp||forceOpen){
 
258
                                        rolledUp = false;
 
259
                                        for(x=0; x<nodes.length; x++){
 
260
                                                nodes[x].style.display = "";
 
261
                                        }
 
262
                                        toggle.innerHTML = "&#9660;";
 
263
                                }else{
 
264
                                        rolledUp = true;
 
265
                                        for(x=0; x<nodes.length; x++){
 
266
                                                nodes[x].style.display = "none";
 
267
                                        }
 
268
                                        toggle.innerHTML = "&#9658;";
 
269
                                }
 
270
                        });
 
271
                };
 
272
 
 
273
                var addGroupToList = function(group){
 
274
                        if(!byId("testList")){ return; }
 
275
                        var tb = byId("testList").tBodies[0];
 
276
                        var tg = groupTemplate.cloneNode(true);
 
277
                        var tds = tg.getElementsByTagName("td");
 
278
                        var toggle = tds[0];
 
279
                        toggle.onclick = _getGroupToggler(group, toggle);
 
280
                        var cb = tds[1].getElementsByTagName("input")[0];
 
281
                        cb.group = group;
 
282
                        cb.onclick = function(evt){
 
283
                                doh._groups[group].skip = (!this.checked);
 
284
                        }
 
285
                        tds[2].innerHTML = "<div class='testGroupName'>"+group+"</div><div style='width:0;'>&nbsp;</div>";
 
286
                        tds[3].innerHTML = "";
 
287
 
 
288
                        tb.appendChild(tg);
 
289
                        return tg;
 
290
                }
 
291
 
 
292
                var addFixtureToList = function(group, fixture){
 
293
                        if(!testTemplate){ return; }
 
294
                        var cgn = groupNodes[group];
 
295
                        if(!cgn["__items"]){ cgn.__items = []; }
 
296
                        var tn = testTemplate.cloneNode(true);
 
297
                        var tds = tn.getElementsByTagName("td");
 
298
 
 
299
                        tds[2].innerHTML = fixture.name;
 
300
                        tds[3].innerHTML = "";
 
301
 
 
302
                        var nn = (cgn.__lastFixture||cgn.__groupNode).nextSibling;
 
303
                        if(nn){
 
304
                                nn.parentNode.insertBefore(tn, nn);
 
305
                        }else{
 
306
                                cgn.__groupNode.parentNode.appendChild(tn);
 
307
                        }
 
308
                        // FIXME: need to make group display toggleable!!
 
309
                        tn.style.display = "none";
 
310
                        cgn.__items.push(tn);
 
311
                        return (cgn.__lastFixture = tn);
 
312
                }
 
313
 
 
314
                var getFixtureNode = function(group, fixture){
 
315
                        if(groupNodes[group]){
 
316
                                return groupNodes[group][fixture.name];
 
317
                        }
 
318
                        return null;
 
319
                }
 
320
 
 
321
                var getGroupNode = function(group){
 
322
                        if(groupNodes[group]){
 
323
                                return groupNodes[group].__groupNode;
 
324
                        }
 
325
                        return null;
 
326
                }
 
327
 
 
328
                var updateBacklog = [];
 
329
                doh._updateTestList = function(group, fixture, unwindingBacklog){
 
330
                        if(!loaded){
 
331
                                if(group && fixture){
 
332
                                        updateBacklog.push([group, fixture]);
 
333
                                }
 
334
                                return;
 
335
                        }else if(updateBacklog.length && !unwindingBacklog){
 
336
                                var tr;
 
337
                                while((tr=updateBacklog.shift())){
 
338
                                        doh._updateTestList(tr[0], tr[1], true);
 
339
                                }
 
340
                        }
 
341
                        if(group && fixture){
 
342
                                if(!groupNodes[group]){
 
343
                                        groupNodes[group] = {
 
344
                                                "__groupNode": addGroupToList(group)
 
345
                                        };
 
346
                                }
 
347
                                if(!groupNodes[group][fixture.name]){
 
348
                                        groupNodes[group][fixture.name] = addFixtureToList(group, fixture)
 
349
                                }
 
350
                        }
 
351
                }
 
352
 
 
353
                doh._testRegistered = doh._updateTestList;
 
354
 
 
355
                doh._groupStarted = function(group){
 
356
                        if(this._suiteCount == 0){
 
357
                                this._runedSuite = 0;
 
358
                                this._currentGlobalProgressBarWidth = 0;
 
359
                                this._suiteCount = this._testCount;
 
360
                        }
 
361
                        // console.debug("_groupStarted", group);
 
362
                        if(doh._inGroup != group){
 
363
                                doh._groupTotalTime = 0;
 
364
                                doh._runed = 0;
 
365
                                doh._inGroup = group;
 
366
                                this._runedSuite++;
 
367
                        }
 
368
                        var gn = getGroupNode(group);
 
369
                        if(gn){
 
370
                                gn.className = "inProgress";
 
371
                        }
 
372
                }
 
373
 
 
374
                doh._groupFinished = function(group, success){
 
375
                        // console.debug("_groupFinished", group);
 
376
                        var gn = getGroupNode(group);
 
377
                        if(gn && doh._inGroup == group){
 
378
                                doh._totalTime += doh._groupTotalTime;
 
379
                                gn.getElementsByTagName("td")[3].innerHTML = doh._groupTotalTime+"ms";
 
380
                                gn.getElementsByTagName("td")[2].lastChild.className = "";
 
381
                                doh._inGroup = null;
 
382
                                //doh._runedSuite++;
 
383
                                var failure = doh._updateGlobalProgressBar(this._runedSuite/this._groupCount,success,group);
 
384
                                gn.className = failure ? "failure" : "success";
 
385
                                //doh._runedSuite--;
 
386
                                doh._currentGlobalProgressBarWidth = parseInt(this._runedSuite/this._groupCount*10000)/100;
 
387
                                //byId("progressOuter").style.width = parseInt(this._runedSuite/this._suiteCount*100)+"%";
 
388
                        }
 
389
                        if(doh._inGroup == group){
 
390
                                this.debug("Total time for GROUP \"",group,"\" is ",doh._groupTotalTime,"ms");
 
391
                        }
 
392
                }
 
393
 
 
394
                doh._testStarted = function(group, fixture){
 
395
                        // console.debug("_testStarted", group, fixture.name);
 
396
                        var fn = getFixtureNode(group, fixture);
 
397
                        if(fn){
 
398
                                fn.className = "inProgress";
 
399
                        }
 
400
                }
 
401
 
 
402
                var _nameTimes = {};
 
403
                var _playSound = function(name){
 
404
                        if(byId("hiddenAudio") && byId("audio") && byId("audio").checked){
 
405
                                // console.debug("playing:", name);
 
406
                                var nt = _nameTimes[name];
 
407
                                // only play sounds once every second or so
 
408
                                if((!nt)||(((new Date)-nt) > 700)){
 
409
                                        _nameTimes[name] = new Date();
 
410
                                        var tc = document.createElement("span");
 
411
                                        byId("hiddenAudio").appendChild(tc);
 
412
                                        tc.innerHTML = '<embed src="_sounds/'+name+'.wav" autostart="true" loop="false" hidden="true" width="1" height="1"></embed>';
 
413
                                }
 
414
                        }
 
415
                }
 
416
 
 
417
                doh._updateGlobalProgressBar = function(p,success,group){
 
418
                        var outerContainer=byId("progressOuter");
 
419
                                        
 
420
                        var gdiv=outerContainer.childNodes[doh._runedSuite-1];
 
421
                        if(!gdiv){
 
422
                                gdiv=document.createElement('div');
 
423
                                outerContainer.appendChild(gdiv);
 
424
                                gdiv.className='success';
 
425
                                gdiv.setAttribute('_target',group);
 
426
                        }
 
427
                        if(!success && !gdiv._failure){
 
428
                                gdiv._failure=true;
 
429
                                gdiv.className='failure';
 
430
                                if(group){
 
431
                                        gdiv.setAttribute('title','failed group '+group);
 
432
                                }
 
433
                        }
 
434
                        var tp=parseInt(p*10000)/100;
 
435
                        gdiv.style.width = (tp-doh._currentGlobalProgressBarWidth)+"%";
 
436
                        return gdiv._failure;
 
437
                }
 
438
                doh._testFinished = function(group, fixture, success){
 
439
                        var fn = getFixtureNode(group, fixture);
 
440
                        var elapsed = fixture.endTime-fixture.startTime;
 
441
                        if(fn){
 
442
                                fn.getElementsByTagName("td")[3].innerHTML = elapsed+"ms";
 
443
                                fn.className = (success) ? "success" : "failure";
 
444
                                fn.getElementsByTagName("td")[2].setAttribute('_target', _loggedMsgLen);
 
445
                                if(!success){
 
446
                                        _playSound("doh");
 
447
                                        var gn = getGroupNode(group);
 
448
                                        if(gn){
 
449
                                                gn.className = "failure";
 
450
                                                _getGroupToggler(group)(null, true);
 
451
                                        }
 
452
                                }
 
453
                        }
 
454
                        if(doh._inGroup == group){
 
455
                                var gn = getGroupNode(group);
 
456
                                doh._runed++;
 
457
                                if(gn && doh._curTestCount){
 
458
                                        var p = doh._runed/doh._curTestCount;
 
459
                                        var groupfail = this._updateGlobalProgressBar((doh._runedSuite+p-1)/doh._groupCount,success,group);
 
460
                                        
 
461
                                        var pbar = gn.getElementsByTagName("td")[2].lastChild;
 
462
                                        pbar.className = groupfail?"failure":"success";
 
463
                                        pbar.style.width = parseInt(p*100)+"%";
 
464
                                        gn.getElementsByTagName("td")[3].innerHTML = parseInt(p*10000)/100+"%";
 
465
                                }
 
466
                        }
 
467
                        this._groupTotalTime += elapsed;
 
468
                        this.debug((success ? "PASSED" : "FAILED"), "test:", fixture.name, elapsed, 'ms');
 
469
                }
 
470
 
 
471
                // FIXME: move implementation to _browserRunner?
 
472
                doh.registerUrl = function(     /*String*/ group, 
 
473
                                                                                /*String*/ url, 
 
474
                                                                                /*Integer*/ timeout){
 
475
                        var tg = new String(group);
 
476
                        this.register(group, {
 
477
                                name: url,
 
478
                                setUp: function(){
 
479
                                        doh.currentGroupName = tg;
 
480
                                        doh.currentGroup = this;
 
481
                                        doh.currentUrl = url;
 
482
                                        this.d = new doh.Deferred();
 
483
                                        doh.currentTestDeferred = this.d;
 
484
                                        doh.showTestPage();
 
485
                                        byId("testBody").src = url;
 
486
                                },
 
487
                                timeout: timeout||10000, // 10s
 
488
                                // timeout: timeout||1000, // 10s
 
489
                                runTest: function(){
 
490
                                        // FIXME: implement calling into the url's groups here!!
 
491
                                        return this.d;
 
492
                                },
 
493
                                tearDown: function(){
 
494
                                        doh.currentGroupName = null;
 
495
                                        doh.currentGroup = null;
 
496
                                        doh.currentTestDeferred = null;
 
497
                                        doh.currentUrl = null;
 
498
                                        // this.d.errback(false);
 
499
                                        // byId("testBody").src = "about:blank";
 
500
                                        doh.showLogPage();
 
501
                                }
 
502
                        });
 
503
                }
 
504
 
 
505
                // 
 
506
                // Utility code for runner.html
 
507
                //
 
508
                // var isSafari = navigator.appVersion.indexOf("Safari") >= 0;
 
509
                var tabzidx = 1;
 
510
                var _showTab = function(toShow, toHide){
 
511
                        // FIXME: I don't like hiding things this way.
 
512
                        byId(toHide).style.display = "none";
 
513
                        with(byId(toShow).style){
 
514
                                display = "";
 
515
                                zIndex = ++tabzidx;
 
516
                        }
 
517
                }
 
518
 
 
519
                doh.showTestPage = function(){
 
520
                        _showTab("testBody", "logBody");
 
521
                }
 
522
 
 
523
                doh.showLogPage = function(){
 
524
                        _showTab("logBody", "testBody");
 
525
                }
 
526
 
 
527
                var runAll = true;
 
528
                doh.toggleRunAll = function(){
 
529
                        // would be easier w/ query...sigh
 
530
                        runAll = !runAll;
 
531
                        if(!byId("testList")){ return; }
 
532
                        var tb = byId("testList").tBodies[0];
 
533
                        var inputs = tb.getElementsByTagName("input");
 
534
                        var x=0; var tn;
 
535
                        while((tn=inputs[x++])){
 
536
                                tn.checked = runAll;
 
537
                                doh._groups[tn.group].skip = (!runAll);
 
538
                        }
 
539
                }
 
540
 
 
541
                var listHeightTimer = null;
 
542
                var setListHeight = function(){
 
543
                        if(listHeightTimer){
 
544
                                clearTimeout(listHeightTimer);
 
545
                        }
 
546
                        var tl = byId("testList");
 
547
                        if(!tl){ return; }
 
548
                        listHeightTimer = setTimeout(function(){
 
549
                                tl.style.display = "none";
 
550
                                tl.style.display = "";
 
551
 
 
552
                        }, 10);
 
553
                }
 
554
 
 
555
                _addOnEvt("resize", setListHeight);
 
556
                _addOnEvt("load", setListHeight);
 
557
                _addOnEvt("load", function(){
 
558
                        if(loaded){ return; }
 
559
                        loaded = true;
 
560
                        groupTemplate = byId("groupTemplate");
 
561
                        if(!groupTemplate){ 
 
562
                                // make sure we've got an ammenable DOM structure
 
563
                                return;
 
564
                        }
 
565
                        groupTemplate.parentNode.removeChild(groupTemplate);
 
566
                        groupTemplate.style.display = "";
 
567
                        testTemplate = byId("testTemplate");
 
568
                        testTemplate.parentNode.removeChild(testTemplate);
 
569
                        testTemplate.style.display = "";
 
570
                        doh._updateTestList();
 
571
                });
 
572
 
 
573
                _addOnEvt("load", 
 
574
                        function(){
 
575
                                // let robot code run if it gets to this first
 
576
                                var __onEnd = doh._onEnd;
 
577
                                doh._onEnd = function(){
 
578
                                        __onEnd.apply(doh, arguments);
 
579
                                        if(doh._failureCount == 0){
 
580
                                                doh.debug("WOOHOO!!");
 
581
                                                _playSound("woohoo");
 
582
                                        }else{
 
583
                                                console.debug("doh._failureCount:", doh._failureCount);
 
584
                                        }
 
585
                                        if(byId("play")){
 
586
                                                toggleRunning();
 
587
                                        }
 
588
                                }
 
589
                                if(!byId("play")){ 
 
590
                                        // make sure we've got an amenable DOM structure
 
591
                                        return;
 
592
                                }
 
593
                                var isRunning = false;
 
594
                                var toggleRunning = function(){
 
595
                                        // ugg, this would be so much better w/ dojo.query()
 
596
                                        if(isRunning){
 
597
                                                byId("play").style.display = byId("pausedMsg").style.display = "";
 
598
                                                byId("playingMsg").style.display = byId("pause").style.display = "none";
 
599
                                                isRunning = false;
 
600
                                        }else{
 
601
                                                byId("play").style.display = byId("pausedMsg").style.display = "none";
 
602
                                                byId("playingMsg").style.display = byId("pause").style.display = "";
 
603
                                                isRunning = true;
 
604
                                        }
 
605
                                }
 
606
                                doh.run = (function(oldRun){
 
607
                                        return function(){
 
608
                                                if(!doh._currentGroup){
 
609
                                                        toggleRunning();
 
610
                                                }
 
611
                                                return oldRun.apply(doh, arguments);
 
612
                                        }
 
613
                                })(doh.run);
 
614
                                var btns = byId("toggleButtons").getElementsByTagName("span");
 
615
                                var node; var idx=0;
 
616
                                while((node=btns[idx++])){
 
617
                                        node.onclick = toggleRunning;
 
618
                                }
 
619
                        }
 
620
                );
 
621
        }else{
 
622
                // we're in an iframe environment. Time to mix it up a bit.
 
623
 
 
624
                _doh = window.parent.doh;
 
625
                var _thisGroup = _doh.currentGroupName;
 
626
                var _thisUrl = _doh.currentUrl;
 
627
                if(_thisGroup){
 
628
                        doh._testRegistered = function(group, tObj){
 
629
                                _doh._updateTestList(_thisGroup, tObj);
 
630
                        }
 
631
                        doh._onEnd = function(){
 
632
                                _doh._errorCount += doh._errorCount;
 
633
                                _doh._failureCount += doh._failureCount;
 
634
                                _doh._testCount += doh._testCount;
 
635
                                // should we be really adding raw group counts?
 
636
                                //_doh._groupCount += doh._groupCount;
 
637
                                _doh.currentTestDeferred.callback(true);
 
638
                        }
 
639
                        var otr = doh._getTestObj;
 
640
                        doh._getTestObj = function(){
 
641
                                var tObj = otr.apply(doh, arguments);
 
642
                                tObj.name = _thisUrl+"::"+arguments[0]+"::"+tObj.name;
 
643
                                return tObj;
 
644
                        }
 
645
                        doh.debug = doh.hitch(_doh, "debug");
 
646
                        doh.registerUrl = doh.hitch(_doh, "registerUrl");
 
647
                        doh._testStarted = function(group, fixture){
 
648
                                _doh._testStarted(_thisGroup, fixture);
 
649
                        }
 
650
                        doh._testFinished = function(g, f, s){
 
651
                                _doh._testFinished(_thisGroup, f, s);
 
652
                        }
 
653
                        doh._groupStarted = function(g){
 
654
                                if(!this._setParent){
 
655
                                        _doh._curTestCount = this._testCount;
 
656
                                        _doh._curGroupCount = this._groupCount;
 
657
                                        this._setParent = true;
 
658
                                }
 
659
                        }
 
660
                        doh._report = function(){};
 
661
                }
 
662
        }
 
663
 
 
664
})();