|
1 /* -*- js-indent-level: 2; tab-width: 2; indent-tabs-mode: nil -*- */ |
|
2 /* vim:set ts=2 sw=2 sts=2 et: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 TestRunner.logEnabled = true; |
|
8 TestRunner.logger = LogController; |
|
9 |
|
10 /* Helper function */ |
|
11 parseQueryString = function(encodedString, useArrays) { |
|
12 // strip a leading '?' from the encoded string |
|
13 var qstr = (encodedString[0] == "?") ? encodedString.substring(1) : |
|
14 encodedString; |
|
15 var pairs = qstr.replace(/\+/g, "%20").split(/(\&\;|\&\#38\;|\&|\&)/); |
|
16 var o = {}; |
|
17 var decode; |
|
18 if (typeof(decodeURIComponent) != "undefined") { |
|
19 decode = decodeURIComponent; |
|
20 } else { |
|
21 decode = unescape; |
|
22 } |
|
23 if (useArrays) { |
|
24 for (var i = 0; i < pairs.length; i++) { |
|
25 var pair = pairs[i].split("="); |
|
26 if (pair.length !== 2) { |
|
27 continue; |
|
28 } |
|
29 var name = decode(pair[0]); |
|
30 var arr = o[name]; |
|
31 if (!(arr instanceof Array)) { |
|
32 arr = []; |
|
33 o[name] = arr; |
|
34 } |
|
35 arr.push(decode(pair[1])); |
|
36 } |
|
37 } else { |
|
38 for (i = 0; i < pairs.length; i++) { |
|
39 pair = pairs[i].split("="); |
|
40 if (pair.length !== 2) { |
|
41 continue; |
|
42 } |
|
43 o[decode(pair[0])] = decode(pair[1]); |
|
44 } |
|
45 } |
|
46 return o; |
|
47 }; |
|
48 |
|
49 // Check the query string for arguments |
|
50 var params = parseQueryString(location.search.substring(1), true); |
|
51 |
|
52 var config = {}; |
|
53 if (window.readConfig) { |
|
54 config = readConfig(); |
|
55 } |
|
56 |
|
57 if (config.testRoot == "chrome" || config.testRoot == "a11y") { |
|
58 for (p in params) { |
|
59 if (params[p] == 1) { |
|
60 config[p] = true; |
|
61 } else if (params[p] == 0) { |
|
62 config[p] = false; |
|
63 } else { |
|
64 config[p] = params[p]; |
|
65 } |
|
66 } |
|
67 params = config; |
|
68 params.baseurl = "chrome://mochitests/content"; |
|
69 } else { |
|
70 params.baseurl = ""; |
|
71 } |
|
72 |
|
73 if (params.testRoot == "browser") { |
|
74 params.testPrefix = "chrome://mochitests/content/browser/"; |
|
75 } else if (params.testRoot == "chrome") { |
|
76 params.testPrefix = "chrome://mochitests/content/chrome/"; |
|
77 } else if (params.testRoot == "a11y") { |
|
78 params.testPrefix = "chrome://mochitests/content/a11y/"; |
|
79 } else { |
|
80 params.testPrefix = "/tests/"; |
|
81 } |
|
82 |
|
83 // set the per-test timeout if specified in the query string |
|
84 if (params.timeout) { |
|
85 TestRunner.timeout = parseInt(params.timeout) * 1000; |
|
86 } |
|
87 |
|
88 // log levels for console and logfile |
|
89 var fileLevel = params.fileLevel || null; |
|
90 var consoleLevel = params.consoleLevel || null; |
|
91 |
|
92 // repeat tells us how many times to repeat the tests |
|
93 if (params.repeat) { |
|
94 TestRunner.repeat = params.repeat; |
|
95 } |
|
96 |
|
97 if (params.runUntilFailure) { |
|
98 TestRunner.runUntilFailure = true; |
|
99 } |
|
100 |
|
101 // closeWhenDone tells us to close the browser when complete |
|
102 if (params.closeWhenDone) { |
|
103 TestRunner.onComplete = SpecialPowers.quit; |
|
104 } |
|
105 |
|
106 if (params.failureFile) { |
|
107 TestRunner.setFailureFile(params.failureFile); |
|
108 } |
|
109 |
|
110 // Breaks execution and enters the JS debugger on a test failure |
|
111 if (params.debugOnFailure) { |
|
112 TestRunner.debugOnFailure = true; |
|
113 } |
|
114 |
|
115 // logFile to write our results |
|
116 if (params.logFile) { |
|
117 var spl = new SpecialPowersLogger(params.logFile); |
|
118 TestRunner.logger.addListener("mozLogger", fileLevel + "", spl.getLogCallback()); |
|
119 } |
|
120 |
|
121 // A temporary hack for android 4.0 where Fennec utilizes the pandaboard so much it reboots |
|
122 if (params.runSlower) { |
|
123 TestRunner.runSlower = true; |
|
124 } |
|
125 |
|
126 if (params.dumpOutputDirectory) { |
|
127 TestRunner.dumpOutputDirectory = params.dumpOutputDirectory; |
|
128 } |
|
129 |
|
130 if (params.dumpAboutMemoryAfterTest) { |
|
131 TestRunner.dumpAboutMemoryAfterTest = true; |
|
132 } |
|
133 |
|
134 if (params.dumpDMDAfterTest) { |
|
135 TestRunner.dumpDMDAfterTest = true; |
|
136 } |
|
137 |
|
138 if (params.quiet) { |
|
139 TestRunner.quiet = true; |
|
140 } |
|
141 |
|
142 // Log things to the console if appropriate. |
|
143 TestRunner.logger.addListener("dumpListener", consoleLevel + "", function(msg) { |
|
144 dump(msg.num + " " + msg.level + " " + msg.info.join(' ') + "\n"); |
|
145 }); |
|
146 |
|
147 var gTestList = []; |
|
148 var RunSet = {} |
|
149 RunSet.runall = function(e) { |
|
150 // Filter tests to include|exclude tests based on data in params.filter. |
|
151 // This allows for including or excluding tests from the gTestList |
|
152 if (params.testManifest) { |
|
153 getTestManifest("http://mochi.test:8888/" + params.testManifest, params, function(filter) { gTestList = filterTests(filter, gTestList, params.runOnly); RunSet.runtests(); }); |
|
154 } else { |
|
155 RunSet.runtests(); |
|
156 } |
|
157 } |
|
158 |
|
159 RunSet.runtests = function(e) { |
|
160 // Which tests we're going to run |
|
161 var my_tests = gTestList; |
|
162 |
|
163 if (params.startAt || params.endAt) { |
|
164 my_tests = skipTests(my_tests, params.startAt, params.endAt); |
|
165 } |
|
166 |
|
167 if (params.totalChunks && params.thisChunk) { |
|
168 my_tests = chunkifyTests(my_tests, params.totalChunks, params.thisChunk, params.chunkByDir, TestRunner.logger); |
|
169 } |
|
170 |
|
171 if (params.shuffle) { |
|
172 for (var i = my_tests.length-1; i > 0; --i) { |
|
173 var j = Math.floor(Math.random() * i); |
|
174 var tmp = my_tests[j]; |
|
175 my_tests[j] = my_tests[i]; |
|
176 my_tests[i] = tmp; |
|
177 } |
|
178 } |
|
179 TestRunner.runTests(my_tests); |
|
180 } |
|
181 |
|
182 RunSet.reloadAndRunAll = function(e) { |
|
183 e.preventDefault(); |
|
184 //window.location.hash = ""; |
|
185 var addParam = ""; |
|
186 if (params.autorun) { |
|
187 window.location.search += ""; |
|
188 window.location.href = window.location.href; |
|
189 } else if (window.location.search) { |
|
190 window.location.href += "&autorun=1"; |
|
191 } else { |
|
192 window.location.href += "?autorun=1"; |
|
193 } |
|
194 }; |
|
195 |
|
196 // UI Stuff |
|
197 function toggleVisible(elem) { |
|
198 toggleElementClass("invisible", elem); |
|
199 } |
|
200 |
|
201 function makeVisible(elem) { |
|
202 removeElementClass(elem, "invisible"); |
|
203 } |
|
204 |
|
205 function makeInvisible(elem) { |
|
206 addElementClass(elem, "invisible"); |
|
207 } |
|
208 |
|
209 function isVisible(elem) { |
|
210 // you may also want to check for |
|
211 // getElement(elem).style.display == "none" |
|
212 return !hasElementClass(elem, "invisible"); |
|
213 }; |
|
214 |
|
215 function toggleNonTests (e) { |
|
216 e.preventDefault(); |
|
217 var elems = document.getElementsByClassName("non-test"); |
|
218 for (var i="0"; i<elems.length; i++) { |
|
219 toggleVisible(elems[i]); |
|
220 } |
|
221 if (isVisible(elems[0])) { |
|
222 $("toggleNonTests").innerHTML = "Hide Non-Tests"; |
|
223 } else { |
|
224 $("toggleNonTests").innerHTML = "Show Non-Tests"; |
|
225 } |
|
226 } |
|
227 |
|
228 // hook up our buttons |
|
229 function hookup() { |
|
230 if (params.manifestFile) { |
|
231 getTestManifest("http://mochi.test:8888/" + params.manifestFile, params, hookupTests); |
|
232 } else { |
|
233 hookupTests(gTestList); |
|
234 } |
|
235 } |
|
236 |
|
237 function hookupTests(testList) { |
|
238 if (testList.length > 0) { |
|
239 gTestList = testList; |
|
240 } else { |
|
241 gTestList = []; |
|
242 for (var obj in testList) { |
|
243 gTestList.push(obj); |
|
244 } |
|
245 } |
|
246 |
|
247 document.getElementById('runtests').onclick = RunSet.reloadAndRunAll; |
|
248 document.getElementById('toggleNonTests').onclick = toggleNonTests; |
|
249 // run automatically if autorun specified |
|
250 if (params.autorun) { |
|
251 RunSet.runall(); |
|
252 } |
|
253 } |