test-runner.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. <html>
  2. <script src="jsdifflib.js"></script>
  3. <script src="utilities.js"></script>
  4. <script src="DOMExtension.js"></script>
  5. <script src="treeoutline.js"></script>
  6. <link rel="stylesheet" type="text/css" href="inspector.css">
  7. <style>
  8. :focus {
  9. outline: none;
  10. }
  11. .failed {
  12. color: red;
  13. }
  14. .timeout {
  15. color: brown;
  16. }
  17. iframe {
  18. width: 0;
  19. height: 0;
  20. opacity: 0;
  21. }
  22. </style>
  23. <script>
  24. var layoutTestsServer = "http://localhost:8002/";
  25. var scannerServer = "http://localhost:8002/";
  26. var remoteDebuggingServer = "http://localhost:9222/";
  27. var tests = [];
  28. var skipList = [
  29. // HALT
  30. "inspector/console/console-api-on-call-frame.html",
  31. // FAILED
  32. "inspector/console/console-dir-global.html",
  33. "inspector/console/console-log-toString-object.html",
  34. "inspector/console/console-uncaught-exception-in-eval.html",
  35. "inspector/elements/edit-dom-actions.html",
  36. "inspector/elements/highlight-node-scaled.html",
  37. "inspector/elements/highlight-node-scroll.html",
  38. "inspector/elements/highlight-node.html",
  39. "inspector/elements/highlight-svg-root.html",
  40. "inspector/network-status-non-http.html",
  41. "inspector/storage-panel-dom-storage-update.html",
  42. "inspector/styles/inject-stylesheet.html",
  43. "inspector/styles/protocol-css-regions-commands.html",
  44. "inspector/styles/region-style-crash.html",
  45. "inspector/styles/styles-disable-then-enable-overriden-ua.html",
  46. "inspector/styles/styles-url-linkify.html",
  47. "inspector/styles/vendor-prefixes.html",
  48. "inspector/timeline/timeline-event-dispatch.html",
  49. "inspector/timeline/timeline-frames.html",
  50. "inspector/timeline/timeline-network-resource.html",
  51. "inspector/timeline/timeline-paint.html",
  52. "inspector/timeline/timeline-receive-response-event.html",
  53. // TIMEOUT
  54. "inspector/profiler/cpu-profiler-profiling-without-inspector.html",
  55. "inspector/profiler/heap-snapshot-inspect-dom-wrapper.html",
  56. "inspector/timeline/timeline-network-received-data.html",
  57. ];
  58. var treeOutline = null;
  59. function run(debug)
  60. {
  61. if (window.runner && debug) {
  62. window.runner.continueDebugging();
  63. return;
  64. }
  65. if (window.testScannerIframe)
  66. document.body.removeChild(window.testScannerIframe);
  67. if (window.runner)
  68. window.runner.cleanup();
  69. window.testScannerIframe = document.createElement("iframe");
  70. window.testScannerIframe.src = scannerServer + "LayoutTests/http/tests/inspector/resources/test-scanner.html";
  71. document.body.appendChild(window.testScannerIframe);
  72. window.debug = debug;
  73. }
  74. function runTests()
  75. {
  76. document.getElementById("outline").removeChildren();
  77. treeOutline = new TreeOutline(document.getElementById("outline"));
  78. document.getElementById("pass").textContent = 0;
  79. document.getElementById("skip").textContent = 0;
  80. document.getElementById("fail").textContent = 0;
  81. document.getElementById("timeout").textContent = 0;
  82. document.getElementById("remaining").textContent = tests.length;
  83. runNextTest();
  84. }
  85. function interrupt()
  86. {
  87. tests = [];
  88. }
  89. function runNextTest(lastResult)
  90. {
  91. if (lastResult) {
  92. var element = document.getElementById(lastResult);
  93. element.textContent = parseInt(element.textContent) + 1;
  94. element = document.getElementById("remaining");
  95. element.textContent = parseInt(element.textContent) - 1;
  96. if (window.debug) {
  97. document.getElementById("debug").textContent = "Debug";
  98. return;
  99. }
  100. }
  101. var test;
  102. var filter = document.getElementById("filter").value;
  103. while (test = tests.shift()) {
  104. if (!filter || test[0].match(filter)) {
  105. new StandaloneTestRunner(layoutTestsServer + test[0], test[1], runNextTest.bind(null));
  106. return;
  107. }
  108. }
  109. }
  110. function StandaloneTestRunner(testPath, expected, next)
  111. {
  112. this._testPath = testPath;
  113. this._next = next;
  114. this._expected = expected;
  115. this._pendingMessages = [];
  116. this._treeElement = new TreeElement(testPath);
  117. treeOutline.appendChild(this._treeElement);
  118. for (var i = 0; !window.debug && i < skipList.length; ++i) {
  119. if (testPath.indexOf(skipList[i]) !== -1) {
  120. this._treeElement.title = testPath + ": SKIPPED";
  121. this._next("skip");
  122. return;
  123. }
  124. }
  125. window.runner = this;
  126. this._testPage = window.open("about:blank", "inspected", "width=800,height=600");
  127. window.remoteDebuggingHandshake = this._remoteDebuggingHandshake.bind(this);
  128. var script = document.createElement("script");
  129. script.src = remoteDebuggingServer + "json?jsonp=remoteDebuggingHandshake";
  130. document.head.appendChild(script);
  131. }
  132. StandaloneTestRunner.FrontendLocation = "inspector.html";
  133. StandaloneTestRunner.prototype = {
  134. _remoteDebuggingHandshake: function(data)
  135. {
  136. for (var i = 0; i < data.length; ++i) {
  137. if (data[i].url !== "about:blank")
  138. continue;
  139. this._debuggerURL = data[i].webSocketDebuggerUrl.replace("://", "=");
  140. this._navigateTestPage();
  141. break;
  142. }
  143. },
  144. _navigateTestPage: function()
  145. {
  146. this._testPage.location.href = this._testPath;
  147. var width = localStorage.getItem('inspectorWidth') || 600;
  148. var height = localStorage.getItem('inspectorHeight') || 400;
  149. var features = "width=" + Math.max(width , 600) + ",height=" + Math.max(height, 400);
  150. this._inspectorWindowLoading = window.open(StandaloneTestRunner.FrontendLocation + "?" + this._debuggerURL, "inspector", features);
  151. this._inspectorWindowLoading.dispatchStandaloneTestRunnerMessages = true;
  152. window.addEventListener('unload', this.cleanup.bind(this));
  153. if (!window.debug)
  154. this._watchDog = setTimeout(this._timeout.bind(this), 10000);
  155. },
  156. loadCompleted: function()
  157. {
  158. if (!window.debug) {
  159. this._loadCompleted(this);
  160. return;
  161. }
  162. document.getElementById("debug").textContent = "Continue";
  163. },
  164. continueDebugging: function()
  165. {
  166. this._loadCompleted();
  167. },
  168. _loadCompleted: function()
  169. {
  170. this._inspectorWindow = this._inspectorWindowLoading;
  171. for (var i = 0; i < this._pendingMessages.length; ++i)
  172. this._inspectorWindow.postMessage(this._pendingMessages[i], "*");
  173. this._pendingMessages = [];
  174. },
  175. closeWebInspector: function()
  176. {
  177. if (!window.debug)
  178. this._inspectorWindow.close();
  179. },
  180. notifyDone: function(actual)
  181. {
  182. if (this._done)
  183. return;
  184. this._done = true;
  185. if (!window.debug)
  186. this.cleanup()
  187. clearTimeout(this._watchDog);
  188. this._treeElement.onselect = this.onTreeElementSelect.bind(this);
  189. // TODO pavel is the RHS || condition wanted?
  190. if (actual === this._expected || actual === this._expected + "\n") {
  191. this._treeElement.title = this._testPath + ": SUCCESS";
  192. this._next("pass");
  193. return;
  194. }
  195. this._treeElement.title = this._testPath + ": FAILED";
  196. this._treeElement.listItemElement.addStyleClass("failed");
  197. var baseLines = difflib.stringAsLines(this._expected);
  198. var newLines = difflib.stringAsLines(actual);
  199. var sm = new difflib.SequenceMatcher(baseLines, newLines);
  200. var opcodes = sm.get_opcodes();
  201. var lastWasSeparator = false;
  202. for (var idx = 0; idx < opcodes.length; idx++) {
  203. var code = opcodes[idx];
  204. var change = code[0];
  205. var b = code[1];
  206. var be = code[2];
  207. var n = code[3];
  208. var ne = code[4];
  209. var rowCount = Math.max(be - b, ne - n);
  210. var topRows = [];
  211. var bottomRows = [];
  212. for (var i = 0; i < rowCount; i++) {
  213. if (change === "delete" || (change === "replace" && b < be)) {
  214. var lineNumber = b++;
  215. this._treeElement.appendChild(new TreeElement("- [" + lineNumber + "] " + baseLines[lineNumber]));
  216. }
  217. if (change === "insert" || (change === "replace" && n < ne)) {
  218. var lineNumber = n++;
  219. this._treeElement.appendChild(new TreeElement("+ [" + lineNumber + "] " + newLines[lineNumber]));
  220. }
  221. if (change === "equal") {
  222. b++;
  223. n++;
  224. }
  225. }
  226. }
  227. this._next("fail");
  228. },
  229. evaluateInWebInspector: function(callId, script)
  230. {
  231. if (this._inspectorWindow)
  232. this._inspectorWindow.postMessage(["evaluateForTest", callId, script], "*");
  233. else
  234. this._pendingMessages.push(["evaluateForTest", callId, script]);
  235. },
  236. _timeout: function()
  237. {
  238. this._treeElement.title = this._testPath + ": TIMEOUT";
  239. this._treeElement.listItemElement.addStyleClass("timeout");
  240. this._done = true;
  241. this.cleanup();
  242. this._next("timeout");
  243. },
  244. cleanup: function ()
  245. {
  246. localStorage.setItem('inspectorWidth', this._inspectorWindowLoading.outerWidth);
  247. localStorage.setItem('inspectorHeight', this._inspectorWindowLoading.outerHeight);
  248. this._inspectorWindowLoading.close();
  249. this._testPage.close();
  250. delete window.runner;
  251. },
  252. onTreeElementSelect: function ()
  253. {
  254. var baseEndSentinel = '/inspector/';
  255. var baseChars = this._testPath.indexOf(baseEndSentinel) + baseEndSentinel.length;
  256. if (baseChars > 0)
  257. document.getElementById("filter").value = this._testPath.substr(baseChars);
  258. },
  259. display: function() { }
  260. }
  261. function onMessageFromTestPage(event)
  262. {
  263. var signature = event.data;
  264. var method = signature.shift();
  265. if (method === "tests") {
  266. tests = signature[0];
  267. runTests();
  268. return;
  269. }
  270. if (window.runner)
  271. window.runner[method].apply(window.runner, signature);
  272. }
  273. function onload()
  274. {
  275. var queryParamsObject = {};
  276. var queryParams = window.location.search;
  277. if (!queryParams)
  278. return;
  279. var params = queryParams.substring(1).split("&");
  280. for (var i = 0; i < params.length; ++i) {
  281. var pair = params[i].split("=");
  282. queryParamsObject[pair[0]] = pair[1];
  283. }
  284. if ("filter" in queryParamsObject)
  285. document.getElementById("filter").value = queryParamsObject["filter"];
  286. }
  287. window.addEventListener("message", onMessageFromTestPage, true);
  288. </script>
  289. <body onload="onload()">
  290. This is a standalone test suite for inspector front-end. Here is how you run it:
  291. <ul>
  292. <li>Check out WebKit source tree: git clone http://git.chromium.org/external/Webkit.git</li>
  293. <li>Run "Tools/Scripts/new-run-webkit-httpd --root=. --port=8002 --server=start"</li>
  294. <li>Run Chrome Canary (ToT Chromium) with following flags: "--remote-debugging-port=9222 --user-data-dir=testProfile http://localhost:8002/Source/devtools/front_end/test-runner.html"</li>
  295. </ul>
  296. <button onclick="run()">Run</button>
  297. <button id="debug" onclick="run(true)">Debug</button>
  298. <button onclick="interrupt()">Interrupt</button>
  299. Filter: <input id="filter" type="text" size="40"></input><small><i>Click on results to load filter</i></small><br>
  300. <span>Passed: <span id="pass">0</span></span>
  301. <span>Failed: <span id="fail">0</span></span>
  302. <span>Timeout: <span id="timeout">0</span></span>
  303. <span>Skipped: <span id="skip">0</span></span>
  304. <span>Remaining: <span id="remaining">0</span><br>
  305. <ol id="outline" style="font-size: 12px !important" class="source-code outline-disclosure"></ol>
  306. </body>
  307. </html>