toolkit/devtools/server/tests/mochitest/inspector-helpers.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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.

     1 var Cu = Components.utils;
     3 Cu.import("resource://gre/modules/devtools/Loader.jsm");
     4 Cu.import("resource://gre/modules/devtools/dbg-client.jsm");
     5 Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
     7 const Services = devtools.require("Services");
     8 const {_documentWalker} = devtools.require("devtools/server/actors/inspector");
    10 // Always log packets when running tests.
    11 Services.prefs.setBoolPref("devtools.debugger.log", true);
    12 SimpleTest.registerCleanupFunction(function() {
    13   Services.prefs.clearUserPref("devtools.debugger.log");
    14 });
    17 if (!DebuggerServer.initialized) {
    18   DebuggerServer.init(() => true);
    19   DebuggerServer.addBrowserActors();
    20   SimpleTest.registerCleanupFunction(function() {
    21     DebuggerServer.destroy();
    22   });
    23 }
    25 var gAttachCleanups = [];
    27 SimpleTest.registerCleanupFunction(function() {
    28   for (let cleanup of gAttachCleanups) {
    29     cleanup();
    30   }
    31 });
    33 /**
    34  * Open a tab, load the url, wait for it to signal its readiness,
    35  * find the tab with the debugger server, and call the callback.
    36  *
    37  * Returns a function which can be called to close the opened ta
    38  * and disconnect its debugger client.
    39  */
    40 function attachURL(url, callback) {
    41   var win = window.open(url, "_blank");
    42   var client = null;
    44   let cleanup = () => {
    45     if (client) {
    46       client.close();
    47       client = null;
    48     }
    49     if (win) {
    50       win.close();
    51       win = null;
    52     }
    53   };
    54   gAttachCleanups.push(cleanup);
    56   window.addEventListener("message", function loadListener(event) {
    57     if (event.data === "ready") {
    58       client = new DebuggerClient(DebuggerServer.connectPipe());
    59       client.connect((applicationType, traits) => {
    60         client.listTabs(response => {
    61           for (let tab of response.tabs) {
    62             if (tab.url === url) {
    63               window.removeEventListener("message", loadListener, false);
    64               client.attachTab(tab.actor, function(aResponse, aTabClient) {
    65                 try {
    66                   callback(null, client, tab, win.document);
    67                 } catch(ex) {
    68                   Cu.reportError(ex);
    69                   dump(ex);
    70                 }
    71               });
    72               break;
    73             }
    74           }
    75         });
    76       });
    77     }
    78   }, false);
    80   return cleanup;
    81 }
    83 function promiseOnce(target, event) {
    84   let deferred = promise.defer();
    85   target.on(event, (...args) => {
    86     if (args.length === 1) {
    87       deferred.resolve(args[0]);
    88     } else {
    89       deferred.resolve(args);
    90     }
    91   });
    92   return deferred.promise;
    93 }
    95 function sortOwnershipChildren(children) {
    96   return children.sort((a, b) => a.name.localeCompare(b.name));
    97 }
    99 function serverOwnershipSubtree(walker, node) {
   100   let actor = walker._refMap.get(node);
   101   if (!actor) {
   102     return undefined;
   103   }
   105   let children = [];
   106   let docwalker = _documentWalker(node, window);
   107   let child = docwalker.firstChild();
   108   while (child) {
   109     let item = serverOwnershipSubtree(walker, child);
   110     if (item) {
   111       children.push(item);
   112     }
   113     child = docwalker.nextSibling();
   114   }
   115   return {
   116     name: actor.actorID,
   117     children: sortOwnershipChildren(children)
   118   }
   119 }
   121 function serverOwnershipTree(walker) {
   122   let serverConnection = walker.conn._transport._serverConnection;
   123   let serverWalker = serverConnection.getActor(walker.actorID);
   125   return {
   126     root: serverOwnershipSubtree(serverWalker, serverWalker.rootDoc ),
   127     orphaned: [serverOwnershipSubtree(serverWalker, o.rawNode) for (o of serverWalker._orphaned)],
   128     retained: [serverOwnershipSubtree(serverWalker, o.rawNode) for (o of serverWalker._retainedOrphans)]
   129   };
   130 }
   132 function clientOwnershipSubtree(node) {
   133   return {
   134     name: node.actorID,
   135     children: sortOwnershipChildren([clientOwnershipSubtree(child) for (child of node.treeChildren())])
   136   }
   137 }
   139 function clientOwnershipTree(walker) {
   140   return {
   141     root: clientOwnershipSubtree(walker.rootNode),
   142     orphaned: [clientOwnershipSubtree(o) for (o of walker._orphaned)],
   143     retained: [clientOwnershipSubtree(o) for (o of walker._retainedOrphans)]
   144   }
   145 }
   147 function ownershipTreeSize(tree) {
   148   let size = 1;
   149   for (let child of tree.children) {
   150     size += ownershipTreeSize(child);
   151   }
   152   return size;
   153 }
   155 function assertOwnershipTrees(walker) {
   156   let serverTree = serverOwnershipTree(walker);
   157   let clientTree = clientOwnershipTree(walker);
   158   is(JSON.stringify(clientTree, null, ' '), JSON.stringify(serverTree, null, ' '), "Server and client ownership trees should match.");
   160   return ownershipTreeSize(clientTree.root);
   161 }
   163 // Verify that an actorID is inaccessible both from the client library and the server.
   164 function checkMissing(client, actorID) {
   165   let deferred = promise.defer();
   166   let front = client.getActor(actorID);
   167   ok(!front, "Front shouldn't be accessible from the client for actorID: " + actorID);
   169   let deferred = promise.defer();
   170   client.request({
   171     to: actorID,
   172     type: "request",
   173   }, response => {
   174     is(response.error, "noSuchActor", "node list actor should no longer be contactable.");
   175     deferred.resolve(undefined);
   176   });
   177   return deferred.promise;
   178 }
   180 // Verify that an actorID is accessible both from the client library and the server.
   181 function checkAvailable(client, actorID) {
   182   let deferred = promise.defer();
   183   let front = client.getActor(actorID);
   184   ok(front, "Front should be accessible from the client for actorID: " + actorID);
   186   let deferred = promise.defer();
   187   client.request({
   188     to: actorID,
   189     type: "garbageAvailableTest",
   190   }, response => {
   191     is(response.error, "unrecognizedPacketType", "node list actor should be contactable.");
   192     deferred.resolve(undefined);
   193   });
   194   return deferred.promise;
   195 }
   197 function promiseDone(promise) {
   198   promise.then(null, err => {
   199     ok(false, "Promise failed: " + err);
   200     if (err.stack) {
   201       dump(err.stack);
   202     }
   203     SimpleTest.finish();
   204   });
   205 }
   207 // Mutation list testing
   209 function isSrcChange(change) {
   210   return (change.type === "attributes" && change.attributeName === "src");
   211 }
   213 function assertAndStrip(mutations, message, test) {
   214   let size = mutations.length;
   215   mutations = mutations.filter(test);
   216   ok((mutations.size != size), message);
   217   return mutations;
   218 }
   220 function isSrcChange(change) {
   221   return change.type === "attributes" && change.attributeName === "src";
   222 }
   224 function isUnload(change) {
   225   return change.type === "documentUnload";
   226 }
   228 function isFrameLoad(change) {
   229   return change.type === "frameLoad";
   230 }
   232 function isUnretained(change) {
   233   return change.type === "unretained";
   234 }
   236 function isChildList(change) {
   237   return change.type === "childList";
   238 }
   240 function isNewRoot(change) {
   241   return change.type === "newRoot";
   242 }
   244 // Make sure an iframe's src attribute changed and then
   245 // strip that mutation out of the list.
   246 function assertSrcChange(mutations) {
   247   return assertAndStrip(mutations, "Should have had an iframe source change.", isSrcChange);
   248 }
   250 // Make sure there's an unload in the mutation list and strip
   251 // that mutation out of the list
   252 function assertUnload(mutations) {
   253   return assertAndStrip(mutations, "Should have had a document unload change.", isUnload);
   254 }
   256 // Make sure there's a frame load in the mutation list and strip
   257 // that mutation out of the list
   258 function assertFrameLoad(mutations) {
   259   return assertAndStrip(mutations, "Should have had a frame load change.", isFrameLoad);
   260 }
   262 // Make sure there's a childList change in the mutation list and strip
   263 // that mutation out of the list
   264 function assertChildList(mutations) {
   265   return assertAndStrip(mutations, "Should have had a frame load change.", isChildList);
   266 }
   268 // Load mutations aren't predictable, so keep accumulating mutations until
   269 // the one we're looking for shows up.
   270 function waitForMutation(walker, test, mutations=[]) {
   271   let deferred = promise.defer();
   272   for (let change of mutations) {
   273     if (test(change)) {
   274       deferred.resolve(mutations);
   275     }
   276   }
   278   walker.once("mutations", newMutations => {
   279     waitForMutation(walker, test, mutations.concat(newMutations)).then(finalMutations => {
   280       deferred.resolve(finalMutations);
   281     })
   282   });
   284   return deferred.promise;
   285 }
   288 var _tests = [];
   289 function addTest(test) {
   290   _tests.push(test);
   291 }
   293 function runNextTest() {
   294   if (_tests.length == 0) {
   295     SimpleTest.finish()
   296     return;
   297   }
   298   var fn = _tests.shift();
   299   try {
   300     fn();
   301   } catch (ex) {
   302     info("Test function " + (fn.name ? "'" + fn.name + "' " : "") +
   303          "threw an exception: " + ex);
   304   }
   305 }

mercurial