chrome-harness.js (7666B)
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 7 var { NetUtil } = ChromeUtils.importESModule( 8 "resource://gre/modules/NetUtil.sys.mjs" 9 ); 10 11 /* import-globals-from manifestLibrary.js */ 12 13 // Defined in browser-test.js 14 /* global gTestPath */ 15 16 /* 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); 25 } 26 27 /* 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); 39 40 try { 41 resolvedURI = resolvedURI.QueryInterface(Ci.nsIJARURI); 42 } catch (ex) {} // not a jar file 43 44 return resolvedURI; 45 } 46 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); 62 } 63 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; 71 72 if (mydir.match("/$") != "/") { 73 mydir += "/"; 74 } 75 76 return chromeURI.prePath + mydir; 77 } 78 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 } 84 85 return chromeURI.prePath; 86 } 87 88 /* 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; 100 } 101 102 /* 103 * input: 104 * jar: a nsIJARURI object with the jarfile and jarentry (path in jar file) 105 * 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)); 116 117 var zReader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance( 118 Ci.nsIZipReader 119 ); 120 121 var fileHandler = Cc["@mozilla.org/network/protocol;1?name=file"].getService( 122 Ci.nsIFileProtocolHandler 123 ); 124 125 var fileName = fileHandler.getFileFromURLSpec(jar.JARFile.spec); 126 zReader.open(fileName); 127 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 } 136 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 } 148 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; 157 } 158 159 /* 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; 192 } 193 194 /* 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 } 203 204 var parts = jarentryname.split("/"); 205 206 var targetFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); 207 targetFile.initWithFile(destdir); 208 209 for (var i = baseParts.length; i < parts.length; i++) { 210 targetFile.append(parts[i]); 211 } 212 213 return targetFile; 214 } 215 216 function readConfig(filename) { 217 filename = filename || "testConfig.js"; 218 219 var configFile = Services.dirsvc.get("ProfD", Ci.nsIFile); 220 configFile.append(filename); 221 222 if (!configFile.exists()) { 223 return {}; 224 } 225 226 var fileInStream = Cc[ 227 "@mozilla.org/network/file-input-stream;1" 228 ].createInstance(Ci.nsIFileInputStream); 229 fileInStream.init(configFile, -1, 0, 0); 230 231 var str = NetUtil.readInputStreamToString( 232 fileInStream, 233 fileInStream.available() 234 ); 235 fileInStream.close(); 236 return JSON.parse(str); 237 } 238 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 } 247 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 ); 264 }