source: Dev/trunk/src/client/util/doh/_browserRunner.js

Last change on this file was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 26.4 KB
Line 
1define([
2        "dojo/dom", "dojo/dom-geometry", "dojo/dom-style",
3        "dojo/_base/fx", "dojo/_base/lang", "dojo/query", "dojo/domReady", "dojo/sniff", "dojo/window",
4        "doh/runner"
5], function(dom, domGeom, domStyle, baseFx, lang, query, domReady, has, win, doh){
6        doh.isBrowser= true;
7        var topdog;
8        try{
9                topdog = (window.parent == window) || !Boolean(window.parent.doh);
10        }catch(e){
11                //can't access window.parent.doh, then consider ourselves as topdog
12                topdog=true;
13        }
14        if(topdog){
15                // we're the top-dog window.
16
17                // borrowed from Dojo, etc.
18                var byId = function(id){
19                        return document.getElementById(id);
20                };
21
22                var _addOnEvt = function( type,         // string
23                                                                        refOrName,      // function or string
24                                                                        scope){         // object, defaults is window
25
26                        if(!scope){ scope = window; }
27
28                        var funcRef = refOrName;
29                        if(typeof refOrName == "string"){
30                                funcRef = scope[refOrName];
31                        }
32                        var enclosedFunc = function(){ return funcRef.apply(scope, arguments); };
33
34                        if(domReady && type == "load"){
35                                domReady(enclosedFunc);
36                        }else{
37                                if(window["attachEvent"]){
38                                        window.attachEvent("on"+type, enclosedFunc);
39                                }else if(window["addEventListener"]){
40                                        window.addEventListener(type, enclosedFunc, false);
41                                }else if(document["addEventListener"]){
42                                        document.addEventListener(type, enclosedFunc, false);
43                                }
44                        }
45                };
46
47                //
48                // Over-ride or implement base runner.js-provided methods
49                //
50                var escapeXml = function(str){
51                        // summary:
52                        //              Adds escape sequences for special characters in XML: &<>"'
53                        //              Optionally skips escapes for single quotes
54                        return str.replace(/&/gm, "&amp;").replace(/</gm, "&lt;").replace(/>/gm, "&gt;").replace(/"/gm, "&quot;"); // string
55                };
56
57                var formatTime = function(n){
58                        switch(true){
59                                case n<1000: //<1s
60                                        return n+"ms";
61                                case n<60000: //<1m
62                                        return Math.round(n/100)/10+"s";
63                                case n<3600000: //<1h
64                                        return Math.round(n/6000)/10+"m";
65                                default: //>1h
66                                        return Math.round(n/360000)/10+"h";
67                        }
68                };
69
70                var _logBacklog = [], _loggedMsgLen = 0;
71                var sendToLogPane = function(args, skip){
72                        var msg = "";
73                        for(var x = 0; x < args.length; x++){
74                                msg += " " + args[x];
75                        }
76
77                        msg = escapeXml(msg);
78
79                        // workarounds for IE. Wheeee!!!
80                        msg = msg.replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;")
81                                .replace(" ", "&nbsp;")
82                                .replace("\n", "<br>&nbsp;");
83                        if(!byId("logBody")){
84                                _logBacklog.push(msg);
85                                return;
86                        }else if(_logBacklog.length && !skip){
87                                var tm;
88                                while((tm = _logBacklog.shift())){
89                                        sendToLogPane(tm, true);
90                                }
91                        }
92                        var logBody = byId("logBody");
93                        var tn = document.createElement("div");
94                        tn.innerHTML = msg;
95                        //tn.id="logmsg_"+logBody.childNodes.length;
96                        logBody.appendChild(tn);
97                        _loggedMsgLen++;
98                };
99
100                var findTarget = function(n){
101                        while(n && !n.getAttribute('_target')){
102                                n = n.parentNode;
103                                if(!n.getAttribute){
104                                        n = null;
105                                }
106                        }
107                        return n;
108                };
109
110                doh._jumpToLog = function(e){
111                        //console.log(e);
112
113                        var node = findTarget(e?e.target:window.event.srcElement);
114                        if(!node){
115                                return;
116                        }
117                        var _t = Number(node.getAttribute('_target'));
118                        var lb = byId("logBody");
119                        if(_t>=lb.childNodes.length){
120                                return;
121                        }
122                        var t = lb.childNodes[_t];
123                        t.scrollIntoView();
124                        if(domStyle && baseFx){
125                                //t.parentNode.parentNode is <div class="tabBody">, only it has a explicitly set background-color,
126                                //all children of it are transparent
127                                var bgColor = domStyle.get(t.parentNode.parentNode,'backgroundColor');
128                                //node.parentNode is the tr which has background-color set explicitly
129                                var hicolor = domStyle.get(node.parentNode,'backgroundColor');
130                                var unhilight = baseFx.animateProperty({
131                                        node: t,
132                                        duration: 500,
133                                        properties:
134                                        {
135                                                backgroundColor: { start: hicolor, end: bgColor }
136                                        },
137                                        onEnd: function(){
138                                                t.style.backgroundColor="";
139                                        }
140                                });
141                                var hilight = baseFx.animateProperty({
142                                        node: t,
143                                        duration: 500,
144                                        properties:
145                                        {
146                                                backgroundColor: { start: bgColor, end: hicolor }
147                                        },
148                                        onEnd: function(){
149                                                unhilight.play();
150                                        }
151                                });
152                                hilight.play();
153                        }
154                };
155
156                doh._jumpToSuite = function(e){
157                        var node = findTarget(e ? e.target : window.event.srcElement);
158                        if(!node){
159                                return;
160                        }
161                        var _g = node.getAttribute('_target');
162                        var gn = getGroupNode(_g);
163                        if(!gn){
164                                return;
165                        }
166                        gn.scrollIntoView();
167                };
168
169                doh._init = (function(oi){
170                        return function(){
171                                var lb = byId("logBody");
172                                if(lb){
173                                        // clear the console before each run
174                                        while(lb.firstChild){
175                                                lb.removeChild(lb.firstChild);
176                                        }
177                                        _loggedMsgLen = 0;
178                                }
179                                this._totalTime = 0;
180                                this._suiteCount = 0;
181                                oi.apply(doh, arguments);
182                        }
183                })(doh._init);
184
185                doh._setupGroupForRun = (function(os){
186                        //overload _setupGroupForRun to record which log line to jump to when a suite is clicked
187                        return function(groupName){
188                                var tg = doh._groups[groupName];
189                                doh._curTestCount = tg.length;
190                                doh._curGroupCount = 1;
191                                var gn = getGroupNode(groupName);
192                                if(gn){
193                                        //two lines will be added, scroll the second line into view
194                                        gn.getElementsByTagName("td")[2].setAttribute('_target',_loggedMsgLen+1);
195                                }
196                                os.apply(doh,arguments);
197                        }
198                })(doh._setupGroupForRun);
199
200                var originalDohReport= doh._report;
201                doh._report = function(){
202                        var tb = byId("testList");
203                        if(tb){
204                                var tfoots=tb.getElementsByTagName('tfoot');
205                                if(tfoots.length){
206                                        tb.removeChild(tfoots[0]);
207                                }
208                                var foot = tb.createTFoot();
209                                var row = foot.insertRow(-1);
210                                row.className = 'inProgress';
211                                var cell=row.insertCell(-1);
212                                cell.colSpan=2;
213                                cell.innerHTML="Result";
214                                cell = row.insertCell(-1);
215                                cell.innerHTML=this._testCount+" tests in "+this._groupCount+" groups /<span class='failure'>"+this._errorCount+"</span> errors, <span class='failure'>"+this._failureCount+"</span> failures";
216                                cell.setAttribute('_target',_loggedMsgLen+1);
217                                row.insertCell(-1).innerHTML=formatTime(doh._totalTime);
218                        }
219
220                        //This location can do the final performance rendering for the results
221                        //of any performance tests.
222
223                        if(doh.perfTestResults){
224                                require(["dojox/math/stats", "dojox/charting/DataChart", "dojox/charting/plot2d/Scatter", "dojox/charting/plot2d/Lines", "dojo/data/ItemFileReadStore"],
225                                                function(stats, DataChart, Scatter, Lines, ItemFileReadStore){
226                                        lang.mixin(doh, stats);
227
228                                        var plotResults = function(div, name, dataArray) {
229                                                // Performance report generating functions!
230                                                var median = doh.median(dataArray);
231                                                var medarray = [];
232
233                                                var i;
234                                                for(i = 0; i < dataArray.length; i++){
235                                                        medarray.push(median);
236                                                }
237
238                                                var data = {
239                                                        label: "name",
240                                                        items: [
241                                                                {name: name, trials: dataArray},
242                                                                {name: "Median", trials: medarray}
243                                                        ]
244                                                };
245                                                var ifs = new ItemFileReadStore({data: data});
246
247                                                var min = Math.floor(doh.min(dataArray));
248                                                var max = Math.ceil(doh.max(dataArray));
249                                                var step = (max - min)/10;
250
251                                                //Lets try to pad out the bottom and top a bit
252                                                //Then recalc the step.
253                                                if(min > 0){
254                                                        min = min - step;
255                                                        if(min < 0){
256                                                                min = 0;
257                                                        }
258                                                        min = Math.floor(min);
259                                                }
260                                                if(max > 0){
261                                                        max = max + step;
262                                                        max = Math.ceil(max);
263                                                }
264                                                step = (max - min)/10;
265
266                                                var chart = new DataChart(div, {
267                                                        type: Lines,
268                                                        displayRange: dataArray.length,
269                                                        xaxis: {min: 1, max: dataArray.length, majorTickStep: Math.ceil((dataArray.length - 1)/10), htmlLabels: false},
270                                                        yaxis: {min: min, max: max, majorTickStep: step, vertical: true, htmlLabels: false}
271                                                });
272                                                chart.setStore(ifs, {name:"*"}, "trials");
273                                        };
274
275                                        try{
276                                                var g;
277                                                var pBody = byId("perfTestsBody");
278                                                var chartsToRender = [];
279                                                // store analytics for reading later
280                                                // keyed on test group name, each value is in turn an object keyed on test name
281                                                doh.perfTestAnalytics={};
282                                                doh.showPerfTestsPage();
283                                                for(g in doh.perfTestResults){
284                                                        doh.perfTestAnalytics[g] = {};
285                                                        var grp = doh.perfTestResults[g];
286                                                        var hdr = document.createElement("h1");
287                                                        hdr.appendChild(document.createTextNode("Group: " + g));
288                                                        pBody.appendChild(hdr);
289                                                        var ind = document.createElement("blockquote");
290                                                        pBody.appendChild(ind);
291                                                        var f;
292                                                        for(f in grp){
293                                                                var fResults = grp[f];
294                                                                if(!fResults){ continue; }
295                                                                var fhdr = document.createElement("h3");
296                                                                fhdr.appendChild(document.createTextNode("TEST: " + f));
297                                                                fhdr.style.textDecoration = "underline";
298                                                                ind.appendChild(fhdr);
299                                                                var div = document.createElement("div");
300                                                                ind.appendChild(div);
301
302                                                                //Figure out the basic info
303                                                                var results = "<b>TRIAL SIZE: </b>"      + fResults.trials[0].testIterations + " iterations<br>" +
304                                                                        "<b>NUMBER OF TRIALS: </b>" + fResults.trials.length + "<br>";
305
306                                                                //Figure out the average test pass cost.
307                                                                var i;
308                                                                var iAvgArray = [];
309                                                                var tAvgArray = [];
310                                                                for(i = 0; i < fResults.trials.length; i++){
311                                                                        iAvgArray.push(fResults.trials[i].average);
312                                                                        tAvgArray.push(fResults.trials[i].executionTime);
313                                                                }
314                                                                var analytics = doh.perfTestAnalytics[g][f] = {
315                                                                        averageTrialExecutionTime: doh.mean(tAvgArray),
316                                                                        maxTestIterationTime: doh.max(iAvgArray),
317                                                                        minTestIterationTime: doh.min(iAvgArray),
318                                                                        averageTestIterationTime: doh.mean(iAvgArray),
319                                                                        medianTestIterationTime: doh.median(iAvgArray),
320                                                                        varianceTestIterationTime: doh.variance(iAvgArray),
321                                                                        standardDeviationTestIterationTime: doh.sd(iAvgArray)
322                                                                };
323                                                                results += "<b>AVERAGE TRIAL EXECUTION TIME: </b>" + analytics.averageTrialExecutionTime.toFixed(10) + "ms.<br>";
324                                                                results += "<b>MAXIMUM TEST ITERATION TIME: </b>" + analytics.maxTestIterationTime.toFixed(10) + "ms.<br>";
325                                                                results += "<b>MINIMUM TEST ITERATION TIME: </b>" + analytics.minTestIterationTime.toFixed(10) + "ms.<br>";
326                                                                results += "<b>AVERAGE TEST ITERATION TIME: </b>" + analytics.averageTestIterationTime.toFixed(10) + "ms.<br>";
327                                                                results += "<b>MEDIAN TEST ITERATION TIME: </b>" + analytics.medianTestIterationTime.toFixed(10) + "ms.<br>";
328                                                                results += "<b>VARIANCE TEST ITERATION TIME: </b>" + analytics.varianceTestIterationTime.toFixed(10) + "ms.<br>";
329                                                                results += "<b>STANDARD DEVIATION ON TEST ITERATION TIME: </b>" +analytics.standardDeviationTestIterationTime.toFixed(10) + "ms.<br>";
330
331                                                                //Okay, attach it all in.
332                                                                div.innerHTML = results;
333
334                                                                div = document.createElement("div");
335                                                                div.innerHTML = "<h3>Average Test Execution Time (in milliseconds, with median line)</h3>";
336                                                                ind.appendChild(div);
337                                                                div = document.createElement("div");
338                                                                domStyle.set(div, "width", "600px");
339                                                                domStyle.set(div, "height", "250px");
340                                                                ind.appendChild(div);
341                                                                chartsToRender.push({
342                                                                        div: div,
343                                                                        title: "Average Test Execution Time",
344                                                                        data: iAvgArray
345                                                                });
346
347                                                                div = document.createElement("div");
348                                                                div.innerHTML = "<h3>Average Trial Execution Time (in milliseconds, with median line)</h3>";
349                                                                ind.appendChild(div);
350                                                                div = document.createElement("div");
351                                                                domStyle.set(div, "width", "600px");
352                                                                domStyle.set(div, "height", "250px");
353                                                                ind.appendChild(div);
354                                                                chartsToRender.push({
355                                                                        div: div,
356                                                                        title: "Average Trial Execution Time",
357                                                                        data: tAvgArray
358                                                                });
359                                                        }
360                                                }
361
362                                                //Lazy-render these to give the browser time and not appear locked.
363                                                var delayedRenders = function() {
364                                                        if(chartsToRender.length){
365                                                                var chartData = chartsToRender.shift();
366                                                                plotResults(chartData.div, chartData.title, chartData.data);
367                                                        }
368                                                        setTimeout(delayedRenders, 50);
369                                                };
370                                                setTimeout(delayedRenders, 150);
371                                        }catch(e){
372                                                doh.debug(e);
373                                        }
374                                });
375                        }
376                        originalDohReport.apply(doh,arguments);
377                };
378
379
380                doh.error = undefined;
381                if(this["opera"] && opera.postError){
382                        doh.debug = function(){
383                                var msg = "";
384                                for(var x=0; x<arguments.length; x++){
385                                        msg += " "+arguments[x];
386                                }
387                                sendToLogPane([msg]);
388                                opera.postError("DEBUG:"+msg);
389                        }
390                }else if(window["console"]){
391                        if(console.error){
392                                doh.error = function(){
393                                        sendToLogPane.call(window, arguments);
394                                        console.error(Array.prototype.join.call(arguments, " "))
395                                };
396                        }
397                        if(console.debug){
398                                doh.debug = function(){
399                                        sendToLogPane.call(window, arguments);
400                                        console.debug(Array.prototype.join.call(arguments, " "))
401                                };
402                        }else if(console.info){
403                                doh.debug = function(){
404                                        sendToLogPane.call(window, arguments);
405                                        console.info(Array.prototype.join.call(arguments, " "))
406                                };
407                        }else{
408                                doh.debug = function(){
409                                        sendToLogPane.call(window, arguments);
410                                        console.log("DEBUG:"+ Array.prototype.join.call(arguments, " "));
411                                };
412                        }
413                }else{
414                        doh.debug = function(){
415                                sendToLogPane.call(window, arguments);
416                        }
417                }
418                doh.error = doh.error || doh.debug;
419                var loaded = false;
420                var groupTemplate = null;
421                var testTemplate = null;
422
423                var groupNodes = {};
424
425                var _groupTogglers = {};
426
427                var _getGroupToggler = function(group, toggle){
428                        if(_groupTogglers[group]){ return _groupTogglers[group]; }
429                        var rolledUp = true;
430                        return (_groupTogglers[group] = function(evt, forceOpen){
431                                var nodes = groupNodes[group].__items;
432                                var x;
433                                if(rolledUp||forceOpen){
434                                        rolledUp = false;
435                                        for(x=0; x<nodes.length; x++){
436                                                nodes[x].style.display = "";
437                                        }
438                                        toggle.innerHTML = "&#9660;";
439                                }else{
440                                        rolledUp = true;
441                                        for(x=0; x<nodes.length; x++){
442                                                nodes[x].style.display = "none";
443                                        }
444                                        toggle.innerHTML = "&#9658;";
445                                }
446                        });
447                };
448
449                var addGroupToList = function(group){
450                        if(!byId("testList")){
451                                return;
452                        }
453                        var tb = byId("testList").tBodies[0];
454                        var tg = groupTemplate.cloneNode(true);
455                        var tds = tg.getElementsByTagName("td");
456                        var toggle = tds[0];
457                        toggle.onclick = _getGroupToggler(group, toggle);
458                        var cb = tds[1].getElementsByTagName("input")[0];
459                        cb.group = group;
460                        cb.onclick = function(){
461                                doh._groups[group].skip = (!this.checked);
462                        };
463                        tds[2].innerHTML = "<div class='testGroupName'>" + group + "</div><div style='width:0;'>&nbsp;</div>";
464                        tds[3].innerHTML = "";
465
466                        tb.appendChild(tg);
467                        return tg;
468                };
469
470                var addFixtureToList = function(group, fixture){
471                        if(!testTemplate){
472                                return;
473                        }
474                        var cgn = groupNodes[group];
475                        if(!cgn["__items"]){
476                                cgn.__items = [];
477                        }
478                        var tn = testTemplate.cloneNode(true);
479                        var tds = tn.getElementsByTagName("td");
480
481                        tds[2].innerHTML = fixture.name;
482                        tds[3].innerHTML = "";
483
484                        var nn = (cgn.__lastFixture || cgn.__groupNode).nextSibling;
485                        if(nn){
486                                nn.parentNode.insertBefore(tn, nn);
487                        }else{
488                                cgn.__groupNode.parentNode.appendChild(tn);
489                        }
490                        // FIXME: need to make group display toggleable!!
491                        tn.style.display = "none";
492                        cgn.__items.push(tn);
493                        return (cgn.__lastFixture = tn);
494                };
495
496                var getFixtureNode = function(group, fixture){
497                        if(groupNodes[group]){
498                                return groupNodes[group][fixture.name];
499                        }
500                        return null;
501                };
502
503                var getGroupNode = function(group){
504                        if(groupNodes[group]){
505                                return groupNodes[group].__groupNode;
506                        }
507                        return null;
508                };
509
510                var updateBacklog = [];
511                doh._updateTestList = function(group, fixture, unwindingBacklog){
512                        if(!loaded){
513                                if(group && fixture){
514                                        updateBacklog.push([group, fixture]);
515                                }
516                                return;
517                        }else if(updateBacklog.length && !unwindingBacklog){
518                                var tr;
519                                while((tr = updateBacklog.shift())){
520                                        doh._updateTestList(tr[0], tr[1], true);
521                                }
522                        }
523                        if(group && fixture){
524                                if(!groupNodes[group]){
525                                        groupNodes[group] = {
526                                                "__groupNode": addGroupToList(group)
527                                        };
528                                }
529                                if(!groupNodes[group][fixture.name]){
530                                        groupNodes[group][fixture.name] = addFixtureToList(group, fixture)
531                                }
532                        }
533                };
534
535                doh._testRegistered = doh._updateTestList;
536
537                doh._groupStarted = function(group){
538                        if(this._suiteCount == 0){
539                                this._runedSuite = 0;
540                                this._currentGlobalProgressBarWidth = 0;
541                                this._suiteCount = this._testCount;
542                        }
543                        // console.debug("_groupStarted", group);
544                        if(doh._inGroup != group){
545                                doh._groupTotalTime = 0;
546                                doh._runed = 0;
547                                doh._inGroup = group;
548                                this._runedSuite++;
549                        }
550                        var gn = getGroupNode(group);
551                        if(gn){
552                                gn.className = "inProgress";
553                        }
554                };
555
556                doh._groupFinished = function(group, success){
557                        // console.debug("_groupFinished", group);
558                        var gn = getGroupNode(group);
559                        if(gn && doh._inGroup == group){
560                                doh._totalTime += doh._groupTotalTime;
561                                gn.getElementsByTagName("td")[3].innerHTML = formatTime(doh._groupTotalTime);
562                                gn.getElementsByTagName("td")[2].lastChild.className = "";
563                                doh._inGroup = null;
564                                //doh._runedSuite++;
565                                var failure = doh._updateGlobalProgressBar(this._runedSuite / this._groupCount, success, group);
566                                gn.className = failure ? "failure" : "success";
567                                //doh._runedSuite--;
568                                doh._currentGlobalProgressBarWidth = parseInt(this._runedSuite / this._groupCount * 10000) / 100;
569                                //byId("progressOuter").style.width = parseInt(this._runedSuite/this._suiteCount*100)+"%";
570                        }
571                        if(doh._inGroup == group){
572                                this.debug("Total time for GROUP \"", group, "\" is ", formatTime(doh._groupTotalTime));
573                        }
574                };
575
576                doh._testStarted = function(group, fixture){
577                        // console.debug("_testStarted", group, fixture.name);
578                        var fn = getFixtureNode(group, fixture);
579                        if(fn){
580                                fn.className = "inProgress";
581                        }
582                };
583
584                var _nameTimes = {};
585                var _playSound = function(name){
586                        if(byId("hiddenAudio") && byId("audio") && byId("audio").checked){
587                                // console.debug("playing:", name);
588                                var nt = _nameTimes[name];
589                                // only play sounds once every second or so
590                                if((!nt) || (((new Date) - nt) > 700)){
591                                        _nameTimes[name] = new Date();
592                                        var tc = document.createElement("span");
593                                        byId("hiddenAudio").appendChild(tc);
594                                        tc.innerHTML = '<embed src="_sounds/' + name + '.wav" autostart="true" loop="false" hidden="true" width="1" height="1"></embed>';
595                                }
596                        }
597                };
598
599                doh._updateGlobalProgressBar = function(p, success, group){
600                        var outerContainer = byId("progressOuter");
601
602                        var gdiv = outerContainer.childNodes[doh._runedSuite - 1];
603                        if(!gdiv){
604                                gdiv = document.createElement('div');
605                                outerContainer.appendChild(gdiv);
606                                gdiv.className = 'success';
607                                gdiv.setAttribute('_target', group);
608                        }
609                        if(!success && !gdiv._failure){
610                                gdiv._failure = true;
611                                gdiv.className = 'failure';
612                                if(group){
613                                        gdiv.setAttribute('title', 'failed group ' + group);
614                                }
615                        }
616                        var tp = parseInt(p * 10000) / 100;
617                        gdiv.style.width = (tp - doh._currentGlobalProgressBarWidth) + "%";
618                        return gdiv._failure;
619                };
620                doh._testFinished = function(group, fixture, success){
621                        var fn = getFixtureNode(group, fixture);
622                        var elapsed = fixture.endTime-fixture.startTime;
623                        var gn;
624                        if(fn){
625                                fn.getElementsByTagName("td")[3].innerHTML = formatTime(elapsed);
626                                fn.className = (success) ? "success" : "failure";
627                                fn.getElementsByTagName("td")[2].setAttribute('_target', _loggedMsgLen);
628                                if(!success){
629                                        _playSound("doh");
630                                        gn = getGroupNode(group);
631                                        if(gn){
632                                                gn.className = "failure";
633                                                _getGroupToggler(group)(null, true);
634                                        }
635                                }
636                        }
637                        if(doh._inGroup == group){
638                                gn = getGroupNode(group);
639                                doh._runed++;
640                                if(gn && doh._curTestCount){
641                                        var p = doh._runed/doh._curTestCount;
642                                        var groupfail = this._updateGlobalProgressBar((doh._runedSuite+p-1)/doh._groupCount,success,group);
643
644                                        var pbar = gn.getElementsByTagName("td")[2].lastChild;
645                                        pbar.className = groupfail?"failure":"success";
646                                        pbar.style.width = parseInt(p*100)+"%";
647                                        gn.getElementsByTagName("td")[3].innerHTML = parseInt(p*10000)/100+"%";
648                                }
649                        }
650                        this._groupTotalTime += elapsed;
651                        this.debug((success ? "PASSED" : "FAILED"), "test:", fixture.name, elapsed, 'ms');
652                };
653
654                doh._registerUrl = function(group, url, timeout, type, dohArgs){
655                        group= group || url;
656                        this._registerTest(group, {
657                                name: url,
658                                setUp: function(){
659                                        doh.currentGroupName = group;
660                                        doh.currentGroup = this;
661                                        doh.currentUrl = url;
662                                        doh.dohArgs = dohArgs;
663                                        this.d = new doh.Deferred();
664                                        doh.currentTestDeferred = this.d;
665                                        doh.showTestPage();
666                                        byId("testBody").src = url;
667                                },
668                                timeout: timeout||10000, // 10s
669                                // timeout: timeout||1000, // 10s
670                                runTest: function(){
671                                        // FIXME: implement calling into the url's groups here!!
672                                        return this.d;
673                                },
674                                tearDown: function(){
675                                        doh.currentGroupName = null;
676                                        doh.currentGroup = null;
677                                        doh.currentTestDeferred = null;
678                                        doh.currentUrl = null;
679                                        // this.d.errback(false);
680                                        // byId("testBody").src = "about:blank";
681                                        doh.showLogPage();
682                                }
683                        }, type);
684                };
685
686                //
687                // Utility code for runner.html
688                //
689                // var isSafari = navigator.appVersion.indexOf("Safari") >= 0;
690                var tabzidx = 1;
691                var _showTab = function(toShow, toHide){
692                        // FIXME: I don't like hiding things this way.
693                        var i;
694                        for(i = 0; i < toHide.length; i++){
695                                var node = byId(toHide[i]);
696                                if(node){
697                                        node.style.display = "none";
698                                }
699                        }
700                        toShow = byId(toShow);
701                        if(toShow){
702                                toShow.style.display = "";
703                                toShow.style.zIndex = ++tabzidx;
704                        }
705                };
706
707                doh.showTestPage = function(){
708                        _showTab("testBody", ["logBody", "perfTestsBody"]);
709                };
710
711                doh.showLogPage = function(){
712                        _showTab("logBody", ["testBody", "perfTestsBody"]);
713                };
714
715                doh.showPerfTestsPage = function(){
716                        _showTab("perfTestsBody", ["testBody", "logBody"]);
717                };
718
719                var runAll = true;
720                doh.toggleRunAll = function(){
721                        // would be easier w/ query...sigh
722                        runAll = !runAll;
723                        if(!byId("testList")){
724                                return;
725                        }
726                        var tb = byId("testList").tBodies[0];
727                        var inputs = tb.getElementsByTagName("input");
728                        var x = 0;
729                        var tn;
730                        while((tn = inputs[x++])){
731                                tn.checked = runAll;
732                                doh._groups[tn.group].skip = (!runAll);
733                        }
734                };
735
736                var listHeightTimer = null;
737                var setListHeight = function(){
738                        if(listHeightTimer){
739                                clearTimeout(listHeightTimer);
740                        }
741                        var tl = byId("testList");
742                        if(!tl){
743                                return;
744                        }
745                        listHeightTimer = setTimeout(function(){
746                                tl.style.display = "none";
747                                tl.style.display = "";
748
749                        }, 10);
750                };
751
752                _addOnEvt("resize", setListHeight);
753                _addOnEvt("load", setListHeight);
754                _addOnEvt("load", function(){
755                        if(loaded){ return; }
756                        loaded = true;
757                        groupTemplate = byId("groupTemplate");
758                        if(!groupTemplate){
759                                // make sure we've got an amenable DOM structure
760                                return;
761                        }
762                        groupTemplate.parentNode.removeChild(groupTemplate);
763                        groupTemplate.style.display = "";
764                        testTemplate = byId("testTemplate");
765                        testTemplate.parentNode.removeChild(testTemplate);
766                        testTemplate.style.display = "";
767                        doh._updateTestList();
768                });
769
770                _addOnEvt("load",
771                        function(){
772                                // let robot code run if it gets to this first
773                                var __onEnd = doh._onEnd;
774                                doh._onEnd = function(){
775                                        __onEnd.apply(doh, arguments);
776                                        if(doh._failureCount == 0){
777                                                doh.debug("WOOHOO!!");
778                                                _playSound("woohoo");
779                                        }else{
780                                                console.debug("doh._failureCount:", doh._failureCount);
781                                        }
782                                        if(byId("play")){
783                                                toggleRunning();
784                                        }
785                                };
786                                if(!byId("play")){
787                                        // make sure we've got an amenable DOM structure
788                                        return;
789                                }
790                                var isRunning = false;
791                                var toggleRunning = function(){
792                                        // ugg, this would be so much better w/ dojo.query()
793                                        if(isRunning){
794                                                byId("play").style.display = byId("pausedMsg").style.display = "";
795                                                byId("playingMsg").style.display = byId("pause").style.display = "none";
796                                                isRunning = false;
797                                        }else{
798                                                byId("play").style.display = byId("pausedMsg").style.display = "none";
799                                                byId("playingMsg").style.display = byId("pause").style.display = "";
800                                                isRunning = true;
801                                        }
802                                };
803                                doh.run = (function(oldRun){
804                                        return function(){
805                                                if(!doh._currentGroup){
806                                                        toggleRunning();
807                                                }
808                                                return oldRun.apply(doh, arguments);
809                                        }
810                                })(doh.run);
811                                var btns = byId("toggleButtons").getElementsByTagName("span");
812                                var node; var idx=0;
813                                while((node=btns[idx++])){
814                                        node.onclick = toggleRunning;
815                                }
816                        }
817                );
818        }else{
819                // we're in an iframe environment. Time to mix it up a bit.
820
821                var _doh = window.parent.doh;
822                var _thisGroup = _doh.currentGroupName;
823                var _thisUrl = _doh.currentUrl;
824                if(_thisGroup){
825                        doh._onEnd = function(){
826                                _doh._errorCount += doh._errorCount;
827                                _doh._failureCount += doh._failureCount;
828                                _doh._testCount += doh._testCount;
829                                // should we be really adding raw group counts?
830                                //_doh._groupCount += doh._groupCount;
831                                _doh.currentTestDeferred.callback(true);
832                        };
833                        doh._testRegistered = function(group, fixture){
834                                fixture.name = _thisUrl+"::"+arguments[0]+"::"+fixture.name;
835                                _doh._updateTestList(_thisGroup, fixture);
836                        };
837                        doh.debug = lang.hitch(_doh, "debug");
838                        doh.error = lang.hitch(_doh, "error");
839                        doh.registerUrl = lang.hitch(_doh, "registerUrl");
840                        doh._testStarted = function(group, fixture){
841                                _doh._testStarted(_thisGroup, fixture);
842                        };
843                        doh._testFinished = function(g, f, s){
844                                _doh._testFinished(_thisGroup, f, s);
845
846                                //Okay, there may be performance info we need to filter back
847                                //to the parent, so do that here.
848                                if(doh.perfTestResults){
849                                        try{
850                                                var gName = g.toString();
851                                                var localFName = f.name;
852                                                while(localFName.indexOf("::") >= 0){
853                                                        localFName = localFName.substring(localFName.indexOf("::") + 2, localFName.length);
854                                                }
855                                                if(!_doh.perfTestResults){
856                                                        _doh.perfTestResults = {};
857                                                }
858                                                if(!_doh.perfTestResults[gName]){
859                                                        _doh.perfTestResults[gName] = {};
860                                                }
861                                                _doh.perfTestResults[gName][f.name] = doh.perfTestResults[gName][localFName];
862                                        }catch (e){
863                                                doh.debug(e);
864                                        }
865                                }
866                        };
867                        doh._groupStarted = function(){
868                                if(!this._setParent){
869                                        _doh._curTestCount = this._testCount;
870                                        _doh._curGroupCount = this._groupCount;
871                                        this._setParent = true;
872                                }
873                        };
874                        doh._report = function(){
875                        };
876                }
877        }
878
879        var fixHeight = doh._fixHeight = function(){
880                // IE9 doesn't give test iframe height because no nodes have an explicit pixel height!
881                // Give outer table a pixel height.
882                if(has("ie")){
883                        var headerHeight = 0;
884                        var rows = query('#testLayout > tbody > tr');
885                        for(var i = 0; i < rows.length-1; i++){
886                                headerHeight += domGeom.position(rows[i]).h;
887                        }
888                        try{
889                                // we subtract the headerHeight from the window height because the table row containing the tests is height:100% so they will stretch the table to the intended height.
890                                dom.byId('testLayout').style.height = (win.getBox().h - headerHeight)+"px";
891                        }catch(e){
892                                // An obscure race condition when you load the runner in IE from the command line causes the window reported height to be 0.
893                                // Try to recover after the window finishes rendering.
894                                setTimeout(function(){ fixHeight(); },0);
895                        }
896                }
897        };
898
899        return doh;
900});
Note: See TracBrowser for help on using the repository browser.