f7f7f354a38f316396244f62119ed8e5202b966d.svn-base 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. if (window["dojo"]) {
  2. dojo.provide("doh._browserRunner");
  3. }
  4. // FIXME: need to add prompting for monkey-do testing
  5. // FIXME: need to implement progress bar
  6. // FIXME: need to implement errors in progress bar
  7. (function() {
  8. if (window.parent == window) {
  9. // we're the top-dog window.
  10. // borrowed from Dojo, etc.
  11. var byId = function(id) {
  12. return document.getElementById(id);
  13. }
  14. var _addOnEvt = function(type, // string
  15. refOrName, // function or string
  16. scope) { // object, defaults is window
  17. if (!scope) {
  18. scope = window;
  19. }
  20. var funcRef = refOrName;
  21. if (typeof refOrName == "string") {
  22. funcRef = scope[refOrName];
  23. }
  24. var enclosedFunc = function() {
  25. return funcRef.apply(scope, arguments);
  26. };
  27. if ((window["dojo"]) && (type == "load")) {
  28. dojo.addOnLoad(enclosedFunc);
  29. } else {
  30. if (window["attachEvent"]) {
  31. window.attachEvent("on" + type, enclosedFunc);
  32. } else if (window["addEventListener"]) {
  33. window.addEventListener(type, enclosedFunc, false);
  34. } else if (document["addEventListener"]) {
  35. document.addEventListener(type, enclosedFunc, false);
  36. }
  37. }
  38. };
  39. //
  40. // Over-ride or implement base runner.js-provided methods
  41. //
  42. var _logBacklog = [];
  43. var sendToLogPane = function(args, skip) {
  44. var msg = "";
  45. for (var x = 0; x < args.length; x++) {
  46. msg += " " + args[x];
  47. }
  48. // workarounds for IE. Wheeee!!!
  49. msg = msg.replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
  50. msg = msg.replace(" ", "&nbsp;");
  51. msg = msg.replace("\n", "<br>&nbsp;");
  52. if (!byId("logBody")) {
  53. _logBacklog.push(msg);
  54. return;
  55. } else if ((_logBacklog.length) && (!skip)) {
  56. var tm;
  57. while (tm = _logBacklog.shift()) {
  58. sendToLogPane(tm, true);
  59. }
  60. }
  61. var tn = document.createElement("div");
  62. tn.innerHTML = msg;
  63. byId("logBody").appendChild(tn);
  64. }
  65. doh._init = (function(oi) {
  66. return function() {
  67. var lb = byId("logBody");
  68. if (lb) {
  69. // clear the console before each run
  70. while (lb.firstChild) {
  71. lb.removeChild(lb.firstChild);
  72. }
  73. }
  74. oi.apply(doh, arguments);
  75. }
  76. })(doh._init);
  77. if (this["opera"] && opera.postError) {
  78. doh.debug = function() {
  79. var msg = "";
  80. for (var x = 0; x < arguments.length; x++) {
  81. msg += " " + arguments[x];
  82. }
  83. sendToLogPane([msg]);
  84. opera.postError("DEBUG:" + msg);
  85. }
  86. } else if (window["console"]) {
  87. if (console.info) {
  88. doh.debug = function() {
  89. sendToLogPane.call(window, arguments);
  90. console.debug.apply(console, arguments);
  91. }
  92. } else {
  93. doh.debug = function() {
  94. var msg = "";
  95. for (var x = 0; x < arguments.length; x++) {
  96. msg += " " + arguments[x];
  97. }
  98. sendToLogPane([msg]);
  99. console.log("DEBUG:" + msg);
  100. }
  101. }
  102. } else {
  103. doh.debug = function() {
  104. sendToLogPane.call(window, arguments);
  105. }
  106. }
  107. var loaded = false;
  108. var groupTemplate = null;
  109. var testTemplate = null;
  110. var groupNodes = {};
  111. var _groupTogglers = {};
  112. var _getGroupToggler = function(group, toggle) {
  113. if (_groupTogglers[group]) {
  114. return _groupTogglers[group];
  115. }
  116. var rolledUp = true;
  117. return _groupTogglers[group] = function(evt, forceOpen) {
  118. var nodes = groupNodes[group].__items;
  119. if (rolledUp || forceOpen) {
  120. rolledUp = false;
  121. for (var x = 0; x < nodes.length; x++) {
  122. nodes[x].style.display = "";
  123. }
  124. toggle.innerHTML = "&#054;";
  125. } else {
  126. rolledUp = true;
  127. for (var x = 0; x < nodes.length; x++) {
  128. nodes[x].style.display = "none";
  129. }
  130. toggle.innerHTML = "&#052;";
  131. }
  132. };
  133. }
  134. var addGroupToList = function(group) {
  135. if (!byId("testList")) {
  136. return;
  137. }
  138. var tb = byId("testList").tBodies[0];
  139. var tg = groupTemplate.cloneNode(true);
  140. var tds = tg.getElementsByTagName("td");
  141. var toggle = tds[0];
  142. toggle.onclick = _getGroupToggler(group, toggle);
  143. var cb = tds[1].getElementsByTagName("input")[0];
  144. cb.group = group;
  145. cb.onclick = function(evt) {
  146. doh._groups[group].skip = (!this.checked);
  147. }
  148. tds[2].innerHTML = group;
  149. tds[3].innerHTML = "";
  150. tb.appendChild(tg);
  151. return tg;
  152. }
  153. var addFixtureToList = function(group, fixture) {
  154. if (!testTemplate) {
  155. return;
  156. }
  157. var cgn = groupNodes[group];
  158. if (!cgn["__items"]) {
  159. cgn.__items = [];
  160. }
  161. var tn = testTemplate.cloneNode(true);
  162. var tds = tn.getElementsByTagName("td");
  163. tds[2].innerHTML = fixture.name;
  164. tds[3].innerHTML = "";
  165. var nn = (cgn.__lastFixture || cgn.__groupNode).nextSibling;
  166. if (nn) {
  167. nn.parentNode.insertBefore(tn, nn);
  168. } else {
  169. cgn.__groupNode.parentNode.appendChild(tn);
  170. }
  171. // FIXME: need to make group display toggleable!!
  172. tn.style.display = "none";
  173. cgn.__items.push(tn);
  174. return cgn.__lastFixture = tn;
  175. }
  176. var getFixtureNode = function(group, fixture) {
  177. if (groupNodes[group]) {
  178. return groupNodes[group][fixture.name];
  179. }
  180. return null;
  181. }
  182. var getGroupNode = function(group) {
  183. if (groupNodes[group]) {
  184. return groupNodes[group].__groupNode;
  185. }
  186. return null;
  187. }
  188. var updateBacklog = [];
  189. doh._updateTestList = function(group, fixture, unwindingBacklog) {
  190. if (!loaded) {
  191. if (group && fixture) {
  192. updateBacklog.push([group, fixture]);
  193. }
  194. return;
  195. } else if ((updateBacklog.length) && (!unwindingBacklog)) {
  196. var tr;
  197. while (tr = updateBacklog.shift()) {
  198. doh._updateTestList(tr[0], tr[1], true);
  199. }
  200. }
  201. if (group && fixture) {
  202. if (!groupNodes[group]) {
  203. groupNodes[group] = {
  204. "__groupNode" : addGroupToList(group)
  205. };
  206. }
  207. if (!groupNodes[group][fixture.name]) {
  208. groupNodes[group][fixture.name] = addFixtureToList(group,
  209. fixture)
  210. }
  211. }
  212. }
  213. doh._testRegistered = doh._updateTestList;
  214. doh._groupStarted = function(group) {
  215. // console.debug("_groupStarted", group);
  216. var gn = getGroupNode(group);
  217. if (gn) {
  218. gn.className = "inProgress";
  219. }
  220. }
  221. doh._groupFinished = function(group, success) {
  222. // console.debug("_groupFinished", group);
  223. var gn = getGroupNode(group);
  224. if (gn) {
  225. gn.className = (success) ? "success" : "failure";
  226. }
  227. }
  228. doh._testStarted = function(group, fixture) {
  229. // console.debug("_testStarted", group, fixture.name);
  230. var fn = getFixtureNode(group, fixture);
  231. if (fn) {
  232. fn.className = "inProgress";
  233. }
  234. }
  235. var _nameTimes = {};
  236. var _playSound = function(name) {
  237. if (byId("hiddenAudio") && byId("audio") && byId("audio").checked) {
  238. // console.debug("playing:", name);
  239. var nt = _nameTimes[name];
  240. // only play sounds once every second or so
  241. if ((!nt) || (((new Date) - nt) > 700)) {
  242. _nameTimes[name] = allGetServerTime();
  243. var tc = document.createElement("span");
  244. byId("hiddenAudio").appendChild(tc);
  245. tc.innerHTML = '<embed src="_sounds/'
  246. + name
  247. + '.wav" autostart="true" loop="false" hidden="true" width="1" height="1"></embed>';
  248. }
  249. }
  250. }
  251. doh._testFinished = function(group, fixture, success) {
  252. var fn = getFixtureNode(group, fixture);
  253. if (fn) {
  254. fn.getElementsByTagName("td")[3].innerHTML = (fixture.endTime - fixture.startTime)
  255. + "ms";
  256. fn.className = (success) ? "success" : "failure";
  257. if (!success) {
  258. _playSound("doh");
  259. var gn = getGroupNode(group);
  260. if (gn) {
  261. gn.className = "failure";
  262. _getGroupToggler(group)(null, true);
  263. }
  264. }
  265. }
  266. this
  267. .debug(((success) ? "PASSED" : "FAILED"), "test:",
  268. fixture.name);
  269. }
  270. // FIXME: move implementation to _browserRunner?
  271. doh.registerUrl = function( /* String */group,
  272. /* String */url,
  273. /* Integer */timeout) {
  274. var tg = new String(group);
  275. this.register(group, {
  276. name : url,
  277. setUp : function() {
  278. doh.currentGroupName = tg;
  279. doh.currentGroup = this;
  280. doh.currentUrl = url;
  281. this.d = new doh.Deferred();
  282. doh.currentTestDeferred = this.d;
  283. showTestPage();
  284. byId("testBody").src = url;
  285. },
  286. timeout : timeout || 10000, // 10s
  287. // timeout: timeout||1000, // 10s
  288. runTest : function() {
  289. // FIXME: implement calling into the url's groups
  290. // here!!
  291. return this.d;
  292. },
  293. tearDown : function() {
  294. doh.currentGroupName = null;
  295. doh.currentGroup = null;
  296. doh.currentTestDeferred = null;
  297. doh.currentUrl = null;
  298. // this.d.errback(false);
  299. // byId("testBody").src = "about:blank";
  300. showLogPage();
  301. }
  302. });
  303. }
  304. //
  305. // Utility code for runner.html
  306. //
  307. // var isSafari = navigator.appVersion.indexOf("Safari") >= 0;
  308. var tabzidx = 1;
  309. var _showTab = function(toShow, toHide) {
  310. // FIXME: I don't like hiding things this way.
  311. byId(toHide).style.display = "none";
  312. with (byId(toShow).style) {
  313. display = "";
  314. zIndex = ++tabzidx;
  315. }
  316. }
  317. showTestPage = function() {
  318. _showTab("testBody", "logBody");
  319. }
  320. showLogPage = function() {
  321. _showTab("logBody", "testBody");
  322. }
  323. var runAll = true;
  324. toggleRunAll = function() {
  325. // would be easier w/ query...sigh
  326. runAll = (!runAll);
  327. if (!byId("testList")) {
  328. return;
  329. }
  330. var tb = byId("testList").tBodies[0];
  331. var inputs = tb.getElementsByTagName("input");
  332. var x = 0;
  333. var tn;
  334. while (tn = inputs[x++]) {
  335. tn.checked = runAll;
  336. doh._groups[tn.group].skip = (!runAll);
  337. }
  338. }
  339. var listHeightTimer = null;
  340. var setListHeight = function() {
  341. if (listHeightTimer) {
  342. clearTimeout(listHeightTimer);
  343. }
  344. var tl = byId("testList");
  345. if (!tl) {
  346. return;
  347. }
  348. listHeightTimer = setTimeout(function() {
  349. tl.style.display = "none";
  350. tl.style.display = "";
  351. }, 10);
  352. }
  353. _addOnEvt("resize", setListHeight);
  354. _addOnEvt("load", setListHeight);
  355. _addOnEvt("load", function() {
  356. if (loaded) {
  357. return;
  358. }
  359. loaded = true;
  360. groupTemplate = byId("groupTemplate");
  361. if (!groupTemplate) {
  362. // make sure we've got an ammenable DOM structure
  363. return;
  364. }
  365. groupTemplate.parentNode.removeChild(groupTemplate);
  366. groupTemplate.style.display = "";
  367. testTemplate = byId("testTemplate");
  368. testTemplate.parentNode.removeChild(testTemplate);
  369. testTemplate.style.display = "";
  370. doh._updateTestList();
  371. });
  372. _addOnEvt("load", function() {
  373. doh._onEnd = function() {
  374. if (doh._failureCount == 0) {
  375. doh.debug("WOOHOO!!");
  376. _playSound("woohoo");
  377. } else {
  378. console.debug("doh._failureCount:", doh._failureCount);
  379. }
  380. if (byId("play")) {
  381. toggleRunning();
  382. }
  383. }
  384. if (!byId("play")) {
  385. // make sure we've got an ammenable DOM structure
  386. return;
  387. }
  388. var isRunning = false;
  389. var toggleRunning = function() {
  390. // ugg, this would be so much better w/ dojo.query()
  391. if (isRunning) {
  392. byId("play").style.display = byId("pausedMsg").style.display = "";
  393. byId("playingMsg").style.display = byId("pause").style.display = "none";
  394. isRunning = false;
  395. } else {
  396. byId("play").style.display = byId("pausedMsg").style.display = "none";
  397. byId("playingMsg").style.display = byId("pause").style.display = "";
  398. isRunning = true;
  399. }
  400. }
  401. doh.run = (function(oldRun) {
  402. return function() {
  403. if (!doh._currentGroup) {
  404. toggleRunning();
  405. }
  406. return oldRun.apply(doh, arguments);
  407. }
  408. })(doh.run);
  409. var btns = byId("toggleButtons").getElementsByTagName("span");
  410. var node;
  411. var idx = 0;
  412. while (node = btns[idx++]) {
  413. node.onclick = toggleRunning;
  414. }
  415. });
  416. } else {
  417. // we're in an iframe environment. Time to mix it up a bit.
  418. _doh = window.parent.doh;
  419. var _thisGroup = _doh.currentGroupName;
  420. var _thisUrl = _doh.currentUrl;
  421. if (_thisGroup) {
  422. doh._testRegistered = function(group, tObj) {
  423. _doh._updateTestList(_thisGroup, tObj);
  424. }
  425. doh._onEnd = function() {
  426. _doh._errorCount += doh._errorCount;
  427. _doh._failureCount += doh._failureCount;
  428. _doh._testCount += doh._testCount;
  429. // should we be really adding raw group counts?
  430. _doh._groupCount += doh._groupCount;
  431. _doh.currentTestDeferred.callback(true);
  432. }
  433. var otr = doh._getTestObj;
  434. doh._getTestObj = function() {
  435. var tObj = otr.apply(doh, arguments);
  436. tObj.name = _thisUrl + "::" + arguments[0] + "::" + tObj.name;
  437. return tObj;
  438. }
  439. doh.debug = doh.hitch(_doh, "debug");
  440. doh.registerUrl = doh.hitch(_doh, "registerUrl");
  441. doh._testStarted = function(group, fixture) {
  442. _doh._testStarted(_thisGroup, fixture);
  443. }
  444. doh._testFinished = function(g, f, s) {
  445. _doh._testFinished(_thisGroup, f, s);
  446. }
  447. doh._report = function() {
  448. };
  449. }
  450. }
  451. })();