Bug 1883706: part 3) Implement `createHTML`, `createScript` and `createScriptURL...
[gecko.git] / testing / mochitest / chrome-harness.js
blob7c506a63aa14a46ae3079a8bde2e1b67c7df0f7a
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
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/. */
7 var { NetUtil } = ChromeUtils.importESModule(
8   "resource://gre/modules/NetUtil.sys.mjs"
9 );
11 /* import-globals-from manifestLibrary.js */
13 // Defined in browser-test.js
14 /* global gTestPath */
17  * getChromeURI converts a URL to a URI
18  *
19  * url: string of a URL (http://mochi.test/test.html)
20  * returns: a nsiURI object representing the given URL
21  *
22  */
23 function getChromeURI(url) {
24   return Services.io.newURI(url);
28  * Convert a URL (string) into a nsIURI or NSIJARURI
29  * This is intended for URL's that are on a file system
30  * or in packaged up in an extension .jar file
31  *
32  * url: a string of a url on the local system(http://localhost/blah.html)
33  */
34 function getResolvedURI(url) {
35   var chromeURI = getChromeURI(url);
36   var resolvedURI = Cc["@mozilla.org/chrome/chrome-registry;1"]
37     .getService(Ci.nsIChromeRegistry)
38     .convertChromeURL(chromeURI);
40   try {
41     resolvedURI = resolvedURI.QueryInterface(Ci.nsIJARURI);
42   } catch (ex) {} // not a jar file
44   return resolvedURI;
47 /**
48  *  getChromeDir is intended to be called after getResolvedURI and convert
49  *  the input URI into a nsIFile (actually the directory containing the
50  *  file).  This can be used for copying or referencing the file or extra files
51  *  required by the test.  Usually we need to load a secondary html file or library
52  *  and this will give us file system access to that.
53  *
54  *  resolvedURI: nsIURI (from getResolvedURI) that points to a file:/// url
55  */
56 function getChromeDir(resolvedURI) {
57   var fileHandler = Cc["@mozilla.org/network/protocol;1?name=file"].getService(
58     Ci.nsIFileProtocolHandler
59   );
60   var chromeDir = fileHandler.getFileFromURLSpec(resolvedURI.spec);
61   return chromeDir.parent.QueryInterface(Ci.nsIFile);
64 // used by tests to determine their directory based off window.location.path
65 function getRootDirectory(path, chromeURI) {
66   if (chromeURI === undefined) {
67     chromeURI = getChromeURI(path);
68   }
69   var myURL = chromeURI.QueryInterface(Ci.nsIURL);
70   var mydir = myURL.directory;
72   if (mydir.match("/$") != "/") {
73     mydir += "/";
74   }
76   return chromeURI.prePath + mydir;
79 // used by tests to determine their directory based off window.location.path
80 function getChromePrePath(path, chromeURI) {
81   if (chromeURI === undefined) {
82     chromeURI = getChromeURI(path);
83   }
85   return chromeURI.prePath;
89  * Given a URI, return nsIJARURI or null
90  */
91 function getJar(uri) {
92   var resolvedURI = getResolvedURI(uri);
93   var jar = null;
94   try {
95     if (resolvedURI.JARFile) {
96       jar = resolvedURI;
97     }
98   } catch (ex) {}
99   return jar;
103  * input:
104  *  jar: a nsIJARURI object with the jarfile and jarentry (path in jar file)
106  * output;
107  *  all files and subdirectories inside jarentry will be extracted to TmpD/mochikit.tmp
108  *  we will return the location of /TmpD/mochikit.tmp* so you can reference the files locally
109  */
110 function extractJarToTmp(jar) {
111   var tmpdir = Services.dirsvc.get("ProfD", Ci.nsIFile);
112   tmpdir.append("mochikit.tmp");
113   // parseInt is used because octal escape sequences cause deprecation warnings
114   // in strict mode (which is turned on in debug builds)
115   tmpdir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, parseInt("0777", 8));
117   var zReader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance(
118     Ci.nsIZipReader
119   );
121   var fileHandler = Cc["@mozilla.org/network/protocol;1?name=file"].getService(
122     Ci.nsIFileProtocolHandler
123   );
125   var fileName = fileHandler.getFileFromURLSpec(jar.JARFile.spec);
126   zReader.open(fileName);
128   // filepath represents the path in the jar file without the filename
129   var filepath = "";
130   var parts = jar.JAREntry.split("/");
131   for (var i = 0; i < parts.length - 1; i++) {
132     if (parts[i] != "") {
133       filepath += parts[i] + "/";
134     }
135   }
137   /* Create dir structure first, no guarantee about ordering of directories and
138    * files returned from findEntries.
139    */
140   for (let dir of zReader.findEntries(filepath + "*/")) {
141     var targetDir = buildRelativePath(dir, tmpdir, filepath);
142     // parseInt is used because octal escape sequences cause deprecation warnings
143     // in strict mode (which is turned on in debug builds)
144     if (!targetDir.exists()) {
145       targetDir.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt("0777", 8));
146     }
147   }
149   // now do the files
150   for (var fname of zReader.findEntries(filepath + "*")) {
151     if (fname.substr(-1) != "/") {
152       var targetFile = buildRelativePath(fname, tmpdir, filepath);
153       zReader.extract(fname, targetFile);
154     }
155   }
156   return tmpdir;
160  * Take a relative path from the current mochitest file
161  * and returns the absolute path for the given test data file.
162  */
163 function getTestFilePath(path) {
164   if (path[0] == "/") {
165     throw new Error("getTestFilePath only accepts relative path");
166   }
167   // Get the chrome/jar uri for the current mochitest file
168   // gTestPath being defined by the test harness in browser-chrome tests
169   // or window is being used for mochitest-browser
170   var baseURI = typeof gTestPath == "string" ? gTestPath : window.location.href;
171   var parentURI = getResolvedURI(getRootDirectory(baseURI));
172   var file;
173   if (parentURI.JARFile) {
174     // If it's a jar/zip, we have to extract it first
175     file = extractJarToTmp(parentURI);
176   } else {
177     // Otherwise, we can directly cast it to a file URI
178     var fileHandler = Cc[
179       "@mozilla.org/network/protocol;1?name=file"
180     ].getService(Ci.nsIFileProtocolHandler);
181     file = fileHandler.getFileFromURLSpec(parentURI.spec);
182   }
183   // Then walk by the given relative path
184   path.split("/").forEach(function (p) {
185     if (p == "..") {
186       file = file.parent;
187     } else if (p != ".") {
188       file.append(p);
189     }
190   });
191   return file.path;
195  * Simple utility function to take the directory structure in jarentryname and
196  * translate that to a path of a nsIFile.
197  */
198 function buildRelativePath(jarentryname, destdir, basepath) {
199   var baseParts = basepath.split("/");
200   if (baseParts[baseParts.length - 1] == "") {
201     baseParts.pop();
202   }
204   var parts = jarentryname.split("/");
206   var targetFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
207   targetFile.initWithFile(destdir);
209   for (var i = baseParts.length; i < parts.length; i++) {
210     targetFile.append(parts[i]);
211   }
213   return targetFile;
216 function readConfig(filename) {
217   filename = filename || "testConfig.js";
219   var configFile = Services.dirsvc.get("ProfD", Ci.nsIFile);
220   configFile.append(filename);
222   if (!configFile.exists()) {
223     return {};
224   }
226   var fileInStream = Cc[
227     "@mozilla.org/network/file-input-stream;1"
228   ].createInstance(Ci.nsIFileInputStream);
229   fileInStream.init(configFile, -1, 0, 0);
231   var str = NetUtil.readInputStreamToString(
232     fileInStream,
233     fileInStream.available()
234   );
235   fileInStream.close();
236   return JSON.parse(str);
239 function getTestList(params, callback) {
240   var baseurl = "chrome://mochitests/content";
241   if (window.parseQueryString) {
242     params = window.parseQueryString(location.search.substring(1), true);
243   }
244   if (!params.baseurl) {
245     params.baseurl = baseurl;
246   }
248   var config = readConfig();
249   for (var p in params) {
250     if (params[p] == 1) {
251       config[p] = true;
252     } else if (params[p] == 0) {
253       config[p] = false;
254     } else {
255       config[p] = params[p];
256     }
257   }
258   params = config;
259   getTestManifest(
260     "http://mochi.test:8888/" + params.manifestFile,
261     params,
262     callback
263   );