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.

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

mercurial