Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | /** |
michael@0 | 2 | * This script is used for testing XUL templates. Call test_template within |
michael@0 | 3 | * a load event handler. |
michael@0 | 4 | * |
michael@0 | 5 | * A test should have a root node with the datasources attribute with the |
michael@0 | 6 | * id 'root', and a few global variables defined in the test's XUL file: |
michael@0 | 7 | * |
michael@0 | 8 | * testid: the testid, used when outputting test results |
michael@0 | 9 | * expectedOutput: e4x data containing the expected output. It can optionally |
michael@0 | 10 | * be enclosed in an <output> element as most tests generate |
michael@0 | 11 | * more than one node of output. |
michael@0 | 12 | * isTreeBuilder: true for dont-build-content trees, false otherwise |
michael@0 | 13 | * queryType: 'rdf', 'xml', etc. |
michael@0 | 14 | * needsOpen: true for menu tests where the root menu must be opened before |
michael@0 | 15 | * comparing results |
michael@0 | 16 | * notWorkingYet: true if this test isn't working yet, outputs todo results |
michael@0 | 17 | * notWorkingYetDynamic: true if the dynamic changes portion of the test |
michael@0 | 18 | * isn't working yet, outputs todo results |
michael@0 | 19 | * changes: an array of functions to perform in sequence to test dynamic changes |
michael@0 | 20 | * to the datasource. |
michael@0 | 21 | * |
michael@0 | 22 | * If the <output> element has an unordered attribute set to true, the |
michael@0 | 23 | * children within it must all appear to match, but may appear in any order. |
michael@0 | 24 | * If the unordered attribute is not set, the children must appear in the same |
michael@0 | 25 | * order. |
michael@0 | 26 | * |
michael@0 | 27 | * If the 'changes' array is used, it should be an array of functions. Each |
michael@0 | 28 | * function will be called in order and a comparison of the output will be |
michael@0 | 29 | * performed. This allows changes to be made to the datasource to ensure that |
michael@0 | 30 | * the generated template output has been updated. Within the expected output |
michael@0 | 31 | * XML, the step attribute may be set to a number on an element to indicate |
michael@0 | 32 | * that an element only applies before or after a particular change. If step |
michael@0 | 33 | * is set to a positive number, that element will only exist after that step in |
michael@0 | 34 | * the list of changes made. If step is set to a negative number, that element |
michael@0 | 35 | * will only exist until that step. Steps are numbered starting at 1. For |
michael@0 | 36 | * example: |
michael@0 | 37 | * <label value="Cat"/> |
michael@0 | 38 | * <label step="2" value="Dog"/> |
michael@0 | 39 | * <label step="-5" value="Mouse"/> |
michael@0 | 40 | * The first element will always exist. The second element will only appear |
michael@0 | 41 | * after the second change is made. The third element will only appear until |
michael@0 | 42 | * the fifth change and it will no longer be present at later steps. |
michael@0 | 43 | * |
michael@0 | 44 | * If the anyid attribute is set to true on an element in the expected output, |
michael@0 | 45 | * then the value of the id attribute on that element is not compared for a |
michael@0 | 46 | * match. This is used, for example, for xml datasources, where the ids set on |
michael@0 | 47 | * the generated output are pseudo-random. |
michael@0 | 48 | */ |
michael@0 | 49 | |
michael@0 | 50 | const ZOO_NS = "http://www.some-fictitious-zoo.com/"; |
michael@0 | 51 | const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; |
michael@0 | 52 | const debug = false; |
michael@0 | 53 | |
michael@0 | 54 | var expectedConsoleMessages = []; |
michael@0 | 55 | var expectLoggedMessages = null; |
michael@0 | 56 | |
michael@0 | 57 | try { |
michael@0 | 58 | const RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"]. |
michael@0 | 59 | getService(Components.interfaces.nsIRDFService); |
michael@0 | 60 | const ContainerUtils = Components.classes["@mozilla.org/rdf/container-utils;1"]. |
michael@0 | 61 | getService(Components.interfaces.nsIRDFContainerUtils); |
michael@0 | 62 | } catch(ex) { } |
michael@0 | 63 | |
michael@0 | 64 | var xmlDoc; |
michael@0 | 65 | |
michael@0 | 66 | function test_template() |
michael@0 | 67 | { |
michael@0 | 68 | var root = document.getElementById("root"); |
michael@0 | 69 | |
michael@0 | 70 | var ds; |
michael@0 | 71 | if (queryType == "rdf" && RDF) { |
michael@0 | 72 | var ioService = Components.classes["@mozilla.org/network/io-service;1"]. |
michael@0 | 73 | getService(Components.interfaces.nsIIOService); |
michael@0 | 74 | |
michael@0 | 75 | var src = window.location.href.replace(/test_tmpl.*xul/, "animals.rdf"); |
michael@0 | 76 | ds = RDF.GetDataSourceBlocking(src); |
michael@0 | 77 | |
michael@0 | 78 | if (expectLoggedMessages) { |
michael@0 | 79 | Components.classes["@mozilla.org/consoleservice;1"]. |
michael@0 | 80 | getService(Components.interfaces.nsIConsoleService).reset(); |
michael@0 | 81 | } |
michael@0 | 82 | |
michael@0 | 83 | if (root.getAttribute("datasources") == "rdf:null") |
michael@0 | 84 | root.setAttribute("datasources", "animals.rdf"); |
michael@0 | 85 | } |
michael@0 | 86 | else if (queryType == "xml") { |
michael@0 | 87 | var src = window.location.href.replace(/test_tmpl.*xul/, "animals.xml"); |
michael@0 | 88 | xmlDoc = new XMLHttpRequest(); |
michael@0 | 89 | xmlDoc.open("get", src, false); |
michael@0 | 90 | xmlDoc.send(null); |
michael@0 | 91 | } |
michael@0 | 92 | |
michael@0 | 93 | // open menus if necessary |
michael@0 | 94 | if (needsOpen) |
michael@0 | 95 | root.open = true; |
michael@0 | 96 | |
michael@0 | 97 | if (expectLoggedMessages) |
michael@0 | 98 | expectLoggedMessages(); |
michael@0 | 99 | |
michael@0 | 100 | checkResults(root, 0); |
michael@0 | 101 | |
michael@0 | 102 | if (changes.length) { |
michael@0 | 103 | var usedds = ds; |
michael@0 | 104 | // within these chrome tests, RDF datasources won't be modifiable unless |
michael@0 | 105 | // an in-memory datasource is used instead. Call copyRDFDataSource to |
michael@0 | 106 | // copy the datasource. |
michael@0 | 107 | if (queryType == "rdf") |
michael@0 | 108 | usedds = copyRDFDataSource(root, ds); |
michael@0 | 109 | if (needsOpen) |
michael@0 | 110 | root.open = true; |
michael@0 | 111 | setTimeout(iterateChanged, 0, root, usedds); |
michael@0 | 112 | } |
michael@0 | 113 | else { |
michael@0 | 114 | if (needsOpen) |
michael@0 | 115 | root.open = false; |
michael@0 | 116 | if (expectedConsoleMessages.length) |
michael@0 | 117 | compareConsoleMessages(); |
michael@0 | 118 | SimpleTest.finish(); |
michael@0 | 119 | } |
michael@0 | 120 | } |
michael@0 | 121 | |
michael@0 | 122 | function iterateChanged(root, ds) |
michael@0 | 123 | { |
michael@0 | 124 | Components.classes["@mozilla.org/consoleservice;1"]. |
michael@0 | 125 | getService(Components.interfaces.nsIConsoleService).reset(); |
michael@0 | 126 | |
michael@0 | 127 | for (var c = 0; c < changes.length; c++) { |
michael@0 | 128 | changes[c](ds, root); |
michael@0 | 129 | checkResults(root, c + 1); |
michael@0 | 130 | } |
michael@0 | 131 | |
michael@0 | 132 | if (needsOpen) |
michael@0 | 133 | root.open = false; |
michael@0 | 134 | if (expectedConsoleMessages.length) |
michael@0 | 135 | compareConsoleMessages(); |
michael@0 | 136 | SimpleTest.finish(); |
michael@0 | 137 | } |
michael@0 | 138 | |
michael@0 | 139 | function checkResults(root, step) |
michael@0 | 140 | { |
michael@0 | 141 | var output = expectedOutput.cloneNode(true); |
michael@0 | 142 | setForCurrentStep(output, step); |
michael@0 | 143 | |
michael@0 | 144 | var error; |
michael@0 | 145 | var actualoutput = root; |
michael@0 | 146 | if (isTreeBuilder) { |
michael@0 | 147 | // convert the tree's view data into the equivalent DOM structure |
michael@0 | 148 | // for easier comparison |
michael@0 | 149 | actualoutput = treeViewToDOM(root); |
michael@0 | 150 | var treechildrenElements = [e for (e of output.children) if (e.localName === "treechildren")]; |
michael@0 | 151 | error = compareOutput(actualoutput, treechildrenElements[0], false); |
michael@0 | 152 | } |
michael@0 | 153 | else { |
michael@0 | 154 | error = compareOutput(actualoutput, output, true); |
michael@0 | 155 | } |
michael@0 | 156 | |
michael@0 | 157 | var adjtestid = testid; |
michael@0 | 158 | if (step > 0) |
michael@0 | 159 | adjtestid += " dynamic step " + step; |
michael@0 | 160 | |
michael@0 | 161 | var stilltodo = ((step == 0 && notWorkingYet) || (step > 0 && notWorkingYetDynamic)); |
michael@0 | 162 | if (stilltodo) |
michael@0 | 163 | todo(false, adjtestid); |
michael@0 | 164 | else |
michael@0 | 165 | ok(!error, adjtestid); |
michael@0 | 166 | |
michael@0 | 167 | if ((!stilltodo && error) || debug) { |
michael@0 | 168 | // for debugging, serialize the XML output |
michael@0 | 169 | var serializedXML = ""; |
michael@0 | 170 | var rootNodes = actualoutput.childNodes; |
michael@0 | 171 | for (var n = 0; n < rootNodes.length; n++) { |
michael@0 | 172 | var node = rootNodes[n]; |
michael@0 | 173 | if (node.localName != "template") |
michael@0 | 174 | serializedXML += ((new XMLSerializer()).serializeToString(node)); |
michael@0 | 175 | } |
michael@0 | 176 | |
michael@0 | 177 | // remove the XUL namespace declarations to make the output more readable |
michael@0 | 178 | const nsrepl = new RegExp("xmlns=\"" + XUL_NS + "\" ", "g"); |
michael@0 | 179 | serializedXML = serializedXML.replace(nsrepl, ""); |
michael@0 | 180 | if (debug) |
michael@0 | 181 | dump("-------- " + adjtestid + " " + error + ":\n" + serializedXML + "\n"); |
michael@0 | 182 | if (!stilltodo && error) |
michael@0 | 183 | is(serializedXML, "Same", "Error is: " + error); |
michael@0 | 184 | } |
michael@0 | 185 | } |
michael@0 | 186 | |
michael@0 | 187 | /** |
michael@0 | 188 | * Adjust the expected output to acccount for any step attributes. |
michael@0 | 189 | */ |
michael@0 | 190 | function setForCurrentStep(content, currentStep) |
michael@0 | 191 | { |
michael@0 | 192 | var todelete = []; |
michael@0 | 193 | for (var child of content.childNodes) { |
michael@0 | 194 | if (child.nodeType === Node.ELEMENT_NODE) { |
michael@0 | 195 | var stepstr = child.getAttribute("step") || ""; |
michael@0 | 196 | var stepsarr = stepstr.split(","); |
michael@0 | 197 | for (var s = 0; s < stepsarr.length; s++) { |
michael@0 | 198 | var step = parseInt(stepsarr[s]); |
michael@0 | 199 | if ((step > 0 && step > currentStep) || |
michael@0 | 200 | (step < 0 && -step <= currentStep)) { |
michael@0 | 201 | todelete.push(child); |
michael@0 | 202 | } |
michael@0 | 203 | } |
michael@0 | 204 | } else if (child.nodeType === Node.TEXT_NODE) { |
michael@0 | 205 | // Drop empty text nodes. |
michael@0 | 206 | if (child.nodeValue.trim() === "") |
michael@0 | 207 | todelete.push(child); |
michael@0 | 208 | } |
michael@0 | 209 | } |
michael@0 | 210 | |
michael@0 | 211 | for (var e of todelete) |
michael@0 | 212 | content.removeChild(e); |
michael@0 | 213 | |
michael@0 | 214 | for (var child of content.children) { |
michael@0 | 215 | child.removeAttribute("step"); |
michael@0 | 216 | setForCurrentStep(child, currentStep); |
michael@0 | 217 | } |
michael@0 | 218 | } |
michael@0 | 219 | |
michael@0 | 220 | /** |
michael@0 | 221 | * Compares the 'actual' DOM output with the 'expected' output. This function |
michael@0 | 222 | * is called recursively, with isroot true if actual refers to the root of the |
michael@0 | 223 | * template. Returns a null string if they are equal and an error string if |
michael@0 | 224 | * they are not equal. This function is called recursively as it iterates |
michael@0 | 225 | * through each node in the DOM tree. |
michael@0 | 226 | */ |
michael@0 | 227 | function compareOutput(actual, expected, isroot) |
michael@0 | 228 | { |
michael@0 | 229 | if (isroot && expected.localName != "data") |
michael@0 | 230 | return "expected must be a <data> element"; |
michael@0 | 231 | |
michael@0 | 232 | var t; |
michael@0 | 233 | |
michael@0 | 234 | // compare text nodes |
michael@0 | 235 | if (expected.nodeType == Node.TEXT_NODE) { |
michael@0 | 236 | if (actual.nodeValue !== expected.nodeValue.trim()) |
michael@0 | 237 | return "Text " + actual.nodeValue + " doesn't match " + expected.nodeValue; |
michael@0 | 238 | return ""; |
michael@0 | 239 | } |
michael@0 | 240 | |
michael@0 | 241 | if (!isroot) { |
michael@0 | 242 | var anyid = false; |
michael@0 | 243 | // make sure that the tags match |
michael@0 | 244 | if (actual.localName != expected.localName) |
michael@0 | 245 | return "Tag name " + expected.localName + " not found"; |
michael@0 | 246 | |
michael@0 | 247 | // loop through the attributes in the expected node and compare their |
michael@0 | 248 | // values with the corresponding attribute on the actual node |
michael@0 | 249 | |
michael@0 | 250 | var expectedAttrs = expected.attributes; |
michael@0 | 251 | for (var a = 0; a < expectedAttrs.length; a++) { |
michael@0 | 252 | var attr = expectedAttrs[a]; |
michael@0 | 253 | var expectval = attr.value; |
michael@0 | 254 | // skip checking the id when anyid="true", however make sure to |
michael@0 | 255 | // ensure that the id is actually present. |
michael@0 | 256 | if (attr.name == "anyid" && expectval == "true") { |
michael@0 | 257 | anyid = true; |
michael@0 | 258 | if (!actual.hasAttribute("id")) |
michael@0 | 259 | return "expected id attribute"; |
michael@0 | 260 | } |
michael@0 | 261 | else if (actual.getAttribute(attr.name) != expectval) { |
michael@0 | 262 | return "attribute " + attr.name + " is '" + |
michael@0 | 263 | actual.getAttribute(attr.name) + "' instead of '" + expectval + "'"; |
michael@0 | 264 | } |
michael@0 | 265 | } |
michael@0 | 266 | |
michael@0 | 267 | // now loop through the actual attributes and make sure that there aren't |
michael@0 | 268 | // any extra attributes that weren't expected |
michael@0 | 269 | var length = actual.attributes.length; |
michael@0 | 270 | for (t = 0; t < length; t++) { |
michael@0 | 271 | var aattr = actual.attributes[t]; |
michael@0 | 272 | var expectval = expected.getAttribute(aattr.name); |
michael@0 | 273 | // ignore some attributes that don't matter |
michael@0 | 274 | if (expectval != actual.getAttribute(aattr.name) && |
michael@0 | 275 | aattr.name != "staticHint" && aattr.name != "xmlns" && |
michael@0 | 276 | (aattr.name != "id" || !anyid)) |
michael@0 | 277 | return "extra attribute " + aattr.name; |
michael@0 | 278 | } |
michael@0 | 279 | } |
michael@0 | 280 | |
michael@0 | 281 | // ensure that the node has the right number of children. Subtract one for |
michael@0 | 282 | // the root node to account for the <template> node. |
michael@0 | 283 | length = actual.childNodes.length - (isroot ? 1 : 0); |
michael@0 | 284 | if (length != expected.childNodes.length) |
michael@0 | 285 | return "incorrect child node count of " + actual.localName + " " + length + |
michael@0 | 286 | " expected " + expected.childNodes.length; |
michael@0 | 287 | |
michael@0 | 288 | // if <data unordered="true"> is used, then the child nodes may be in any order |
michael@0 | 289 | var unordered = (expected.localName == "data" && expected.getAttribute("unordered") == "true"); |
michael@0 | 290 | |
michael@0 | 291 | // next, loop over the children and call compareOutput recursively on each one |
michael@0 | 292 | var adj = 0; |
michael@0 | 293 | for (t = 0; t < actual.childNodes.length; t++) { |
michael@0 | 294 | var actualnode = actual.childNodes[t]; |
michael@0 | 295 | // skip the <template> element, and add one to the indices when looking |
michael@0 | 296 | // at the later nodes to account for it |
michael@0 | 297 | if (isroot && actualnode.localName == "template") { |
michael@0 | 298 | adj++; |
michael@0 | 299 | } |
michael@0 | 300 | else { |
michael@0 | 301 | var output = "unexpected"; |
michael@0 | 302 | if (unordered) { |
michael@0 | 303 | var expectedChildren = expected.childNodes; |
michael@0 | 304 | for (var e = 0; e < expectedChildren.length; e++) { |
michael@0 | 305 | output = compareOutput(actualnode, expectedChildren[e], false); |
michael@0 | 306 | if (!output) |
michael@0 | 307 | break; |
michael@0 | 308 | } |
michael@0 | 309 | } |
michael@0 | 310 | else { |
michael@0 | 311 | output = compareOutput(actualnode, expected.childNodes[t - adj], false); |
michael@0 | 312 | } |
michael@0 | 313 | |
michael@0 | 314 | // an error was returned, so return early |
michael@0 | 315 | if (output) |
michael@0 | 316 | return output; |
michael@0 | 317 | } |
michael@0 | 318 | } |
michael@0 | 319 | |
michael@0 | 320 | return ""; |
michael@0 | 321 | } |
michael@0 | 322 | |
michael@0 | 323 | /* |
michael@0 | 324 | * copy the datasource into an in-memory datasource so that it can be modified |
michael@0 | 325 | */ |
michael@0 | 326 | function copyRDFDataSource(root, sourceds) |
michael@0 | 327 | { |
michael@0 | 328 | var dsourcesArr = []; |
michael@0 | 329 | var composite = root.database; |
michael@0 | 330 | var dsources = composite.GetDataSources(); |
michael@0 | 331 | while (dsources.hasMoreElements()) { |
michael@0 | 332 | sourceds = dsources.getNext().QueryInterface(Components.interfaces.nsIRDFDataSource); |
michael@0 | 333 | dsourcesArr.push(sourceds); |
michael@0 | 334 | } |
michael@0 | 335 | |
michael@0 | 336 | for (var d = 0; d < dsourcesArr.length; d++) |
michael@0 | 337 | composite.RemoveDataSource(dsourcesArr[d]); |
michael@0 | 338 | |
michael@0 | 339 | var newds = Components.classes["@mozilla.org/rdf/datasource;1?name=in-memory-datasource"]. |
michael@0 | 340 | createInstance(Components.interfaces.nsIRDFDataSource); |
michael@0 | 341 | |
michael@0 | 342 | var sourcelist = sourceds.GetAllResources(); |
michael@0 | 343 | while (sourcelist.hasMoreElements()) { |
michael@0 | 344 | var source = sourcelist.getNext(); |
michael@0 | 345 | var props = sourceds.ArcLabelsOut(source); |
michael@0 | 346 | while (props.hasMoreElements()) { |
michael@0 | 347 | var prop = props.getNext(); |
michael@0 | 348 | if (prop instanceof Components.interfaces.nsIRDFResource) { |
michael@0 | 349 | var targets = sourceds.GetTargets(source, prop, true); |
michael@0 | 350 | while (targets.hasMoreElements()) |
michael@0 | 351 | newds.Assert(source, prop, targets.getNext(), true); |
michael@0 | 352 | } |
michael@0 | 353 | } |
michael@0 | 354 | } |
michael@0 | 355 | |
michael@0 | 356 | composite.AddDataSource(newds); |
michael@0 | 357 | root.builder.rebuild(); |
michael@0 | 358 | |
michael@0 | 359 | return newds; |
michael@0 | 360 | } |
michael@0 | 361 | |
michael@0 | 362 | /** |
michael@0 | 363 | * Converts a tree view (nsITreeView) into the equivalent DOM tree. |
michael@0 | 364 | * Returns the treechildren |
michael@0 | 365 | */ |
michael@0 | 366 | function treeViewToDOM(tree) |
michael@0 | 367 | { |
michael@0 | 368 | var treechildren = document.createElement("treechildren"); |
michael@0 | 369 | |
michael@0 | 370 | if (tree.view) |
michael@0 | 371 | treeViewToDOMInner(tree.columns, treechildren, tree.view, tree.builder, 0, 0); |
michael@0 | 372 | |
michael@0 | 373 | return treechildren; |
michael@0 | 374 | } |
michael@0 | 375 | |
michael@0 | 376 | function treeViewToDOMInner(columns, treechildren, view, builder, start, level) |
michael@0 | 377 | { |
michael@0 | 378 | var end = view.rowCount; |
michael@0 | 379 | |
michael@0 | 380 | for (var i = start; i < end; i++) { |
michael@0 | 381 | if (view.getLevel(i) < level) |
michael@0 | 382 | return i - 1; |
michael@0 | 383 | |
michael@0 | 384 | var id = builder ? builder.getResourceAtIndex(i).Value : "id" + i; |
michael@0 | 385 | var item = document.createElement("treeitem"); |
michael@0 | 386 | item.setAttribute("id", id); |
michael@0 | 387 | treechildren.appendChild(item); |
michael@0 | 388 | |
michael@0 | 389 | var row = document.createElement("treerow"); |
michael@0 | 390 | item.appendChild(row); |
michael@0 | 391 | |
michael@0 | 392 | for (var c = 0; c < columns.length; c++) { |
michael@0 | 393 | var cell = document.createElement("treecell"); |
michael@0 | 394 | var label = view.getCellText(i, columns[c]); |
michael@0 | 395 | if (label) |
michael@0 | 396 | cell.setAttribute("label", label); |
michael@0 | 397 | row.appendChild(cell); |
michael@0 | 398 | } |
michael@0 | 399 | |
michael@0 | 400 | if (view.isContainer(i)) { |
michael@0 | 401 | item.setAttribute("container", "true"); |
michael@0 | 402 | item.setAttribute("empty", view.isContainerEmpty(i) ? "true" : "false"); |
michael@0 | 403 | |
michael@0 | 404 | if (!view.isContainerEmpty(i) && view.isContainerOpen(i)) { |
michael@0 | 405 | item.setAttribute("open", "true"); |
michael@0 | 406 | |
michael@0 | 407 | var innertreechildren = document.createElement("treechildren"); |
michael@0 | 408 | item.appendChild(innertreechildren); |
michael@0 | 409 | |
michael@0 | 410 | i = treeViewToDOMInner(columns, innertreechildren, view, builder, i + 1, level + 1); |
michael@0 | 411 | } |
michael@0 | 412 | } |
michael@0 | 413 | } |
michael@0 | 414 | |
michael@0 | 415 | return i; |
michael@0 | 416 | } |
michael@0 | 417 | |
michael@0 | 418 | function expectConsoleMessage(ref, id, isNew, isActive, extra) |
michael@0 | 419 | { |
michael@0 | 420 | var message = "In template with id root" + |
michael@0 | 421 | (ref ? " using ref " + ref : "") + "\n " + |
michael@0 | 422 | (isNew ? "New " : "Removed ") + (isActive ? "active" : "inactive") + |
michael@0 | 423 | " result for query " + extra + ": " + id; |
michael@0 | 424 | expectedConsoleMessages.push(message); |
michael@0 | 425 | } |
michael@0 | 426 | |
michael@0 | 427 | function compareConsoleMessages() |
michael@0 | 428 | { |
michael@0 | 429 | var consoleService = Components.classes["@mozilla.org/consoleservice;1"]. |
michael@0 | 430 | getService(Components.interfaces.nsIConsoleService); |
michael@0 | 431 | var messages = consoleService.getMessageArray() || []; |
michael@0 | 432 | messages = messages.map(function (m) m.message); |
michael@0 | 433 | // Copy to avoid modifying expectedConsoleMessages |
michael@0 | 434 | var expect = expectedConsoleMessages.concat(); |
michael@0 | 435 | for (var m = 0; m < messages.length; m++) { |
michael@0 | 436 | if (messages[m] == expect[0]) { |
michael@0 | 437 | ok(true, "found message " + expect.shift()); |
michael@0 | 438 | } |
michael@0 | 439 | } |
michael@0 | 440 | if (expect.length != 0) { |
michael@0 | 441 | ok(false, "failed to find expected console messages: " + expect); |
michael@0 | 442 | } |
michael@0 | 443 | } |
michael@0 | 444 | |
michael@0 | 445 | function copyToProfile(filename) |
michael@0 | 446 | { |
michael@0 | 447 | if (Cc === undefined) { |
michael@0 | 448 | var Cc = Components.classes; |
michael@0 | 449 | var Ci = Components.interfaces; |
michael@0 | 450 | } |
michael@0 | 451 | |
michael@0 | 452 | var loader = Cc["@mozilla.org/moz/jssubscript-loader;1"] |
michael@0 | 453 | .getService(Ci.mozIJSSubScriptLoader); |
michael@0 | 454 | loader.loadSubScript("chrome://mochikit/content/chrome-harness.js"); |
michael@0 | 455 | |
michael@0 | 456 | var file = Cc["@mozilla.org/file/directory_service;1"] |
michael@0 | 457 | .getService(Ci.nsIProperties) |
michael@0 | 458 | .get("ProfD", Ci.nsIFile); |
michael@0 | 459 | file.append(filename); |
michael@0 | 460 | |
michael@0 | 461 | var parentURI = getResolvedURI(getRootDirectory(window.location.href)); |
michael@0 | 462 | if (parentURI.JARFile) { |
michael@0 | 463 | parentURI = extractJarToTmp(parentURI); |
michael@0 | 464 | } else { |
michael@0 | 465 | var fileHandler = Cc["@mozilla.org/network/protocol;1?name=file"]. |
michael@0 | 466 | getService(Ci.nsIFileProtocolHandler); |
michael@0 | 467 | parentURI = fileHandler.getFileFromURLSpec(parentURI.spec); |
michael@0 | 468 | } |
michael@0 | 469 | |
michael@0 | 470 | parentURI = parentURI.QueryInterface(Ci.nsILocalFile); |
michael@0 | 471 | parentURI.append(filename); |
michael@0 | 472 | try { |
michael@0 | 473 | var retVal = parentURI.copyToFollowingLinks(file.parent, filename); |
michael@0 | 474 | } catch (ex) { |
michael@0 | 475 | //ignore this error as the file could exist already |
michael@0 | 476 | } |
michael@0 | 477 | } |