_browserRunner.js 24 KB

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