toolkit/devtools/server/tests/mochitest/test_inspector-retain.html

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 <!DOCTYPE HTML>
michael@0 2 <html>
michael@0 3 <!--
michael@0 4 https://bugzilla.mozilla.org/show_bug.cgi?id=
michael@0 5 -->
michael@0 6 <head>
michael@0 7 <meta charset="utf-8">
michael@0 8 <title>Test for Bug </title>
michael@0 9
michael@0 10 <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
michael@0 11 <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
michael@0 12 <script type="application/javascript;version=1.8" src="inspector-helpers.js"></script>
michael@0 13 <script type="application/javascript;version=1.8">
michael@0 14 Components.utils.import("resource://gre/modules/devtools/Loader.jsm");
michael@0 15 const {Promise: promise} = Components.utils.import("resource://gre/modules/Promise.jsm", {});
michael@0 16
michael@0 17 const inspector = devtools.require("devtools/server/actors/inspector");
michael@0 18
michael@0 19 window.onload = function() {
michael@0 20 SimpleTest.waitForExplicitFinish();
michael@0 21 runNextTest();
michael@0 22 }
michael@0 23
michael@0 24 var gWalker = null;
michael@0 25 var gClient = null;
michael@0 26 var gInspectee = null;
michael@0 27
michael@0 28 function assertOwnership() {
michael@0 29 return assertOwnershipTrees(gWalker);
michael@0 30 }
michael@0 31
michael@0 32 addTest(function setup() {
michael@0 33 let url = document.getElementById("inspectorContent").href;
michael@0 34 attachURL(url, function(err, client, tab, doc) {
michael@0 35 gInspectee = doc;
michael@0 36 let {InspectorFront} = devtools.require("devtools/server/actors/inspector");
michael@0 37 let inspector = InspectorFront(client, tab);
michael@0 38 promiseDone(inspector.getWalker().then(walker => {
michael@0 39 ok(walker, "getWalker() should return an actor.");
michael@0 40 gClient = client;
michael@0 41 gWalker = walker;
michael@0 42 }).then(runNextTest));
michael@0 43 });
michael@0 44 });
michael@0 45
michael@0 46 // Retain a node, and a second-order child (in another document, for kicks)
michael@0 47 // Release the parent of the top item, which should cause one retained orphan.
michael@0 48
michael@0 49 // Then unretain the top node, which should retain the orphan.
michael@0 50
michael@0 51 // Then change the source of the iframe, which should kill that orphan.
michael@0 52
michael@0 53 addTest(function testRetain() {
michael@0 54 let originalOwnershipSize = 0;
michael@0 55 let bodyFront = null;
michael@0 56 let frameFront = null;
michael@0 57 let childListFront = null;
michael@0 58 // Get the toplevel body element and retain it.
michael@0 59 promiseDone(gWalker.querySelector(gWalker.rootNode, "body").then(front => {
michael@0 60 bodyFront = front;
michael@0 61 return gWalker.retainNode(bodyFront);
michael@0 62 }).then(() => {
michael@0 63 // Get an element in the child frame and retain it.
michael@0 64 return gWalker.querySelector(gWalker.rootNode, "#childFrame");
michael@0 65 }).then(frame => {
michael@0 66 frameFront = frame;
michael@0 67 return gWalker.children(frame, { maxNodes: 1 }).then(children => {
michael@0 68 return children.nodes[0];
michael@0 69 });
michael@0 70 }).then(childDoc => {
michael@0 71 return gWalker.querySelector(childDoc, "#longlist");
michael@0 72 }).then(list => {
michael@0 73 childListFront = list;
michael@0 74 originalOwnershipSize = assertOwnership();
michael@0 75 // and rtain it.
michael@0 76 return gWalker.retainNode(childListFront);
michael@0 77 }).then(() => {
michael@0 78 // OK, try releasing the parent of the first retained.
michael@0 79 return gWalker.releaseNode(bodyFront.parentNode());
michael@0 80 }).then(() => {
michael@0 81 let size = assertOwnership();
michael@0 82 let clientTree = clientOwnershipTree(gWalker);
michael@0 83
michael@0 84 // That request should have freed the parent of the first retained
michael@0 85 // but moved the rest into the retained orphaned tree.
michael@0 86 is(ownershipTreeSize(clientTree.root) + ownershipTreeSize(clientTree.retained[0]) + 1,
michael@0 87 originalOwnershipSize,
michael@0 88 "Should have only lost one item overall.");
michael@0 89 is(gWalker._retainedOrphans.size, 1, "Should have retained one orphan");
michael@0 90 ok(gWalker._retainedOrphans.has(bodyFront), "Should have retained the expected node.");
michael@0 91 }).then(() => {
michael@0 92 // Unretain the body, which should promote the childListFront to a retained orphan.
michael@0 93 return gWalker.unretainNode(bodyFront);
michael@0 94 }).then(() => {
michael@0 95 assertOwnership();
michael@0 96 let clientTree = clientOwnershipTree(gWalker);
michael@0 97
michael@0 98 is(gWalker._retainedOrphans.size, 1, "Should still only have one retained orphan.");
michael@0 99 ok(!gWalker._retainedOrphans.has(bodyFront), "Should have dropped the body node.")
michael@0 100 ok(gWalker._retainedOrphans.has(childListFront), "Should have retained the child node.")
michael@0 101 }).then(() => {
michael@0 102 // Change the source of the iframe, which should kill the retained orphan.
michael@0 103 gInspectee.querySelector("#childFrame").src = "data:text/html,<html>new child</html>";
michael@0 104 return waitForMutation(gWalker, isUnretained);
michael@0 105 }).then(mutations => {
michael@0 106 assertOwnership();
michael@0 107 let clientTree = clientOwnershipTree(gWalker);
michael@0 108 is(gWalker._retainedOrphans.size, 0, "Should have no more retained orphans.");
michael@0 109
michael@0 110 }).then(runNextTest));
michael@0 111 });
michael@0 112
michael@0 113 // Get a hold of a node, remove it from the doc and retain it at the same time.
michael@0 114 // We should always win that race (even though the mutation happens before the
michael@0 115 // retain request), because we haven't issued `getMutations` yet.
michael@0 116 addTest(function testWinRace() {
michael@0 117 let front = null;
michael@0 118 promiseDone(gWalker.querySelector(gWalker.rootNode, "#a").then(node => {
michael@0 119 front = node;
michael@0 120 let contentNode = gInspectee.querySelector("#a");
michael@0 121 contentNode.parentNode.removeChild(contentNode);
michael@0 122 // Now wait for that mutation and retain response to come in.
michael@0 123 return promise.all([
michael@0 124 gWalker.retainNode(front),
michael@0 125 waitForMutation(gWalker, isChildList)
michael@0 126 ]);
michael@0 127 }).then(() => {
michael@0 128 assertOwnership();
michael@0 129 let clientTree = clientOwnershipTree(gWalker);
michael@0 130 is(gWalker._retainedOrphans.size, 1, "Should have a retained orphan.");
michael@0 131 ok(gWalker._retainedOrphans.has(front), "Should have retained our expected node.");
michael@0 132 return gWalker.unretainNode(front);
michael@0 133 }).then(() => {
michael@0 134 // Make sure we're clear for the next test.
michael@0 135 assertOwnership();
michael@0 136 let clientTree = clientOwnershipTree(gWalker);
michael@0 137 is(gWalker._retainedOrphans.size, 0, "Should have no more retained orphans.");
michael@0 138 }).then(runNextTest));
michael@0 139 });
michael@0 140
michael@0 141 // Same as above, but issue the request right after the 'new-mutations' event, so that
michael@0 142 // we *lose* the race.
michael@0 143 addTest(function testLoseRace() {
michael@0 144 let front = null;
michael@0 145 promiseDone(gWalker.querySelector(gWalker.rootNode, "#z").then(node => {
michael@0 146 front = node;
michael@0 147 gInspectee.querySelector("#z").parentNode = null;
michael@0 148 let contentNode = gInspectee.querySelector("#a");
michael@0 149 contentNode.parentNode.removeChild(contentNode);
michael@0 150 return promiseOnce(gWalker, "new-mutations");
michael@0 151 }).then(() => {
michael@0 152 // Verify that we have an outstanding request (no good way to tell that it's a
michael@0 153 // getMutations request, but there's nothing else it would be).
michael@0 154 is(gWalker._requests.length, 1, "Should have an outstanding request.");
michael@0 155 return gWalker.retainNode(front)
michael@0 156 }).then(() => { ok(false, "Request should not have succeeded!"); },
michael@0 157 (err) => {
michael@0 158 ok(err, "noSuchActor", "Should have lost the race.");
michael@0 159 let clientTree = clientOwnershipTree(gWalker);
michael@0 160 is(gWalker._retainedOrphans.size, 0, "Should have no more retained orphans.");
michael@0 161 // Don't re-throw the error.
michael@0 162 }).then(runNextTest));
michael@0 163 });
michael@0 164
michael@0 165 addTest(function cleanup() {
michael@0 166 delete gWalker;
michael@0 167 delete gClient;
michael@0 168 runNextTest();
michael@0 169 });
michael@0 170
michael@0 171 </script>
michael@0 172 </head>
michael@0 173 <body>
michael@0 174 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a>
michael@0 175 <a id="inspectorContent" target="_blank" href="inspector-traversal-data.html">Test Document</a>
michael@0 176 <p id="display"></p>
michael@0 177 <div id="content" style="display: none">
michael@0 178
michael@0 179 </div>
michael@0 180 <pre id="test">
michael@0 181 </pre>
michael@0 182 </body>
michael@0 183 </html>

mercurial