chrome-harness.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  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/. */
  6. Components.utils.import("resource://gre/modules/NetUtil.jsm");
  7. /*
  8. * getChromeURI converts a URL to a URI
  9. *
  10. * url: string of a URL (http://mochi.test/test.html)
  11. * returns: a nsiURI object representing the given URL
  12. *
  13. */
  14. function getChromeURI(url) {
  15. var ios = Components.classes["@mozilla.org/network/io-service;1"].
  16. getService(Components.interfaces.nsIIOService);
  17. return ios.newURI(url, null, null);
  18. }
  19. /*
  20. * Convert a URL (string) into a nsIURI or NSIJARURI
  21. * This is intended for URL's that are on a file system
  22. * or in packaged up in an extension .jar file
  23. *
  24. * url: a string of a url on the local system(http://localhost/blah.html)
  25. */
  26. function getResolvedURI(url) {
  27. var chromeURI = getChromeURI(url);
  28. var resolvedURI = Components.classes["@mozilla.org/chrome/chrome-registry;1"].
  29. getService(Components.interfaces.nsIChromeRegistry).
  30. convertChromeURL(chromeURI);
  31. try {
  32. resolvedURI = resolvedURI.QueryInterface(Components.interfaces.nsIJARURI);
  33. } catch (ex) {} //not a jar file
  34. return resolvedURI;
  35. }
  36. /**
  37. * getChromeDir is intended to be called after getResolvedURI and convert
  38. * the input URI into a nsILocalFile (actually the directory containing the
  39. * file). This can be used for copying or referencing the file or extra files
  40. * required by the test. Usually we need to load a secondary html file or library
  41. * and this will give us file system access to that.
  42. *
  43. * resolvedURI: nsIURI (from getResolvedURI) that points to a file:/// url
  44. */
  45. function getChromeDir(resolvedURI) {
  46. var fileHandler = Components.classes["@mozilla.org/network/protocol;1?name=file"].
  47. getService(Components.interfaces.nsIFileProtocolHandler);
  48. var chromeDir = fileHandler.getFileFromURLSpec(resolvedURI.spec);
  49. return chromeDir.parent.QueryInterface(Components.interfaces.nsILocalFile);
  50. }
  51. //used by tests to determine their directory based off window.location.path
  52. function getRootDirectory(path, chromeURI) {
  53. if (chromeURI === undefined)
  54. {
  55. chromeURI = getChromeURI(path);
  56. }
  57. var myURL = chromeURI.QueryInterface(Components.interfaces.nsIURL);
  58. var mydir = myURL.directory;
  59. if (mydir.match('/$') != '/')
  60. {
  61. mydir += '/';
  62. }
  63. return chromeURI.prePath + mydir;
  64. }
  65. //used by tests to determine their directory based off window.location.path
  66. function getChromePrePath(path, chromeURI) {
  67. if (chromeURI === undefined) {
  68. chromeURI = getChromeURI(path);
  69. }
  70. return chromeURI.prePath;
  71. }
  72. /*
  73. * Given a URI, return nsIJARURI or null
  74. */
  75. function getJar(uri) {
  76. var resolvedURI = getResolvedURI(uri);
  77. var jar = null;
  78. try {
  79. if (resolvedURI.JARFile) {
  80. jar = resolvedURI;
  81. }
  82. } catch (ex) {}
  83. return jar;
  84. }
  85. /*
  86. * input:
  87. * jar: a nsIJARURI object with the jarfile and jarentry (path in jar file)
  88. *
  89. * output;
  90. * all files and subdirectories inside jarentry will be extracted to TmpD/mochikit.tmp
  91. * we will return the location of /TmpD/mochikit.tmp* so you can reference the files locally
  92. */
  93. function extractJarToTmp(jar) {
  94. var tmpdir = Components.classes["@mozilla.org/file/directory_service;1"]
  95. .getService(Components.interfaces.nsIProperties)
  96. .get("ProfD", Components.interfaces.nsILocalFile);
  97. tmpdir.append("mochikit.tmp");
  98. // parseInt is used because octal escape sequences cause deprecation warnings
  99. // in strict mode (which is turned on in debug builds)
  100. tmpdir.createUnique(Components.interfaces.nsIFile.DIRECTORY_TYPE, parseInt("0777", 8));
  101. var zReader = Components.classes["@mozilla.org/libjar/zip-reader;1"].
  102. createInstance(Components.interfaces.nsIZipReader);
  103. var fileHandler = Components.classes["@mozilla.org/network/protocol;1?name=file"].
  104. getService(Components.interfaces.nsIFileProtocolHandler);
  105. var fileName = fileHandler.getFileFromURLSpec(jar.JARFile.spec);
  106. zReader.open(fileName);
  107. //filepath represents the path in the jar file without the filename
  108. var filepath = "";
  109. var parts = jar.JAREntry.split('/');
  110. for (var i =0; i < parts.length - 1; i++) {
  111. if (parts[i] != '') {
  112. filepath += parts[i] + '/';
  113. }
  114. }
  115. /* Create dir structure first, no guarantee about ordering of directories and
  116. * files returned from findEntries.
  117. */
  118. var dirs = zReader.findEntries(filepath + '*/');
  119. while (dirs.hasMore()) {
  120. var targetDir = buildRelativePath(dirs.getNext(), tmpdir, filepath);
  121. // parseInt is used because octal escape sequences cause deprecation warnings
  122. // in strict mode (which is turned on in debug builds)
  123. if (!targetDir.exists()) {
  124. targetDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, parseInt("0777", 8));
  125. }
  126. }
  127. //now do the files
  128. var files = zReader.findEntries(filepath + "*");
  129. while (files.hasMore()) {
  130. var fname = files.getNext();
  131. if (fname.substr(-1) != '/') {
  132. var targetFile = buildRelativePath(fname, tmpdir, filepath);
  133. zReader.extract(fname, targetFile);
  134. }
  135. }
  136. return tmpdir;
  137. }
  138. /*
  139. * Take a relative path from the current mochitest file
  140. * and returns the absolute path for the given test data file.
  141. */
  142. function getTestFilePath(path) {
  143. if (path[0] == "/") {
  144. throw new Error("getTestFilePath only accepts relative path");
  145. }
  146. // Get the chrome/jar uri for the current mochitest file
  147. // gTestPath being defined by the test harness in browser-chrome tests
  148. // or window is being used for mochitest-browser
  149. var baseURI = typeof(gTestPath) == "string" ? gTestPath : window.location.href;
  150. var parentURI = getResolvedURI(getRootDirectory(baseURI));
  151. var file;
  152. if (parentURI.JARFile) {
  153. // If it's a jar/zip, we have to extract it first
  154. file = extractJarToTmp(parentURI);
  155. } else {
  156. // Otherwise, we can directly cast it to a file URI
  157. var fileHandler = Components.classes["@mozilla.org/network/protocol;1?name=file"].
  158. getService(Components.interfaces.nsIFileProtocolHandler);
  159. file = fileHandler.getFileFromURLSpec(parentURI.spec);
  160. }
  161. // Then walk by the given relative path
  162. path.split("/")
  163. .forEach(function (p) {
  164. if (p == "..") {
  165. file = file.parent;
  166. } else if (p != ".") {
  167. file.append(p);
  168. }
  169. });
  170. return file.path;
  171. }
  172. /*
  173. * Simple utility function to take the directory structure in jarentryname and
  174. * translate that to a path of a nsILocalFile.
  175. */
  176. function buildRelativePath(jarentryname, destdir, basepath)
  177. {
  178. var baseParts = basepath.split('/');
  179. if (baseParts[baseParts.length-1] == '') {
  180. baseParts.pop();
  181. }
  182. var parts = jarentryname.split('/');
  183. var targetFile = Components.classes["@mozilla.org/file/local;1"]
  184. .createInstance(Components.interfaces.nsILocalFile);
  185. targetFile.initWithFile(destdir);
  186. for (var i = baseParts.length; i < parts.length; i++) {
  187. targetFile.append(parts[i]);
  188. }
  189. return targetFile;
  190. }
  191. function readConfig(filename) {
  192. filename = filename || "testConfig.js";
  193. var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"].
  194. getService(Components.interfaces.nsIProperties);
  195. var configFile = fileLocator.get("ProfD", Components.interfaces.nsIFile);
  196. configFile.append(filename);
  197. if (!configFile.exists())
  198. return {};
  199. var fileInStream = Components.classes["@mozilla.org/network/file-input-stream;1"].
  200. createInstance(Components.interfaces.nsIFileInputStream);
  201. fileInStream.init(configFile, -1, 0, 0);
  202. var str = NetUtil.readInputStreamToString(fileInStream, fileInStream.available());
  203. fileInStream.close();
  204. return JSON.parse(str);
  205. }
  206. function getTestList(params, callback) {
  207. var baseurl = 'chrome://mochitests/content';
  208. if (window.parseQueryString) {
  209. params = parseQueryString(location.search.substring(1), true);
  210. }
  211. if (!params.baseurl) {
  212. params.baseurl = baseurl;
  213. }
  214. var config = readConfig();
  215. for (var p in params) {
  216. if (params[p] == 1) {
  217. config[p] = true;
  218. } else if (params[p] == 0) {
  219. config[p] = false;
  220. } else {
  221. config[p] = params[p];
  222. }
  223. }
  224. params = config;
  225. getTestManifest("http://mochi.test:8888/" + params.manifestFile, params, callback);
  226. return;
  227. }