browser_dbg-scopes-duplicated.js (4610B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */ 4 5 // Test that properties with the same value objec be expanded. See Bug 1617210. 6 7 "use strict"; 8 9 const httpServer = createTestHTTPServer(); 10 httpServer.registerContentType("html", "text/html"); 11 httpServer.registerContentType("js", "application/javascript"); 12 13 httpServer.registerPathHandler(`/`, function (request, response) { 14 response.setStatusLine(request.httpVersion, 200, "OK"); 15 response.write(` 16 <html> 17 <button class="pause">Click me</button> 18 <script type="text/javascript" src="test.js"></script> 19 </html>`); 20 }); 21 22 httpServer.registerPathHandler("/test.js", function (request, response) { 23 response.setHeader("Content-Type", "application/javascript"); 24 response.write(` 25 document.addEventListener("click", function onClick(e) { 26 var sharedValue = {hello: "world"}; 27 var x = { 28 a: sharedValue, 29 b: sharedValue, 30 c: sharedValue, 31 d: { 32 e: { 33 g: sharedValue 34 }, 35 f: { 36 h: sharedValue 37 } 38 } 39 }; 40 debugger; 41 }); 42 `); 43 }); 44 const port = httpServer.identity.primaryPort; 45 const TEST_URL = `http://localhost:${port}/`; 46 47 add_task(async function () { 48 const dbg = await initDebuggerWithAbsoluteURL(TEST_URL); 49 50 const ready = Promise.all([ 51 waitForPaused(dbg), 52 waitForLoadedSource(dbg, "test.js"), 53 ]); 54 55 SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { 56 content.document.querySelector("button.pause").click(); 57 }); 58 59 await ready; 60 61 checkScopesLabels( 62 dbg, 63 ` 64 | e 65 | sharedValue 66 | x 67 `, 68 { startIndex: 3 } 69 ); 70 71 info("Expand `x` node"); 72 await toggleScopeNode(dbg, 6); 73 checkScopesLabels( 74 dbg, 75 ` 76 | x 77 | | a 78 | | b 79 | | c 80 | | d 81 `, 82 { startIndex: 5 } 83 ); 84 85 info("Expand node `d`"); 86 await toggleScopeNode(dbg, 10); 87 checkScopesLabels( 88 dbg, 89 ` 90 | | d 91 | | | e 92 | | | f 93 `, 94 { startIndex: 9 } 95 ); 96 97 info("Expand `f` and `e` nodes"); 98 await toggleScopeNode(dbg, 12); 99 await toggleScopeNode(dbg, 11); 100 checkScopesLabels( 101 dbg, 102 ` 103 | | d 104 | | | e 105 | | | | g 106 | | | | <prototype> 107 | | | f 108 | | | | h 109 | | | | <prototype> 110 `, 111 { startIndex: 9 } 112 ); 113 114 info("Expand `h`, `g`, `e`, `c`, `b` and `a` nodes"); 115 await toggleScopeNode(dbg, 15); 116 await toggleScopeNode(dbg, 12); 117 await toggleScopeNode(dbg, 9); 118 await toggleScopeNode(dbg, 8); 119 await toggleScopeNode(dbg, 7); 120 121 checkScopesLabels( 122 dbg, 123 ` 124 | x 125 | | a 126 | | | hello 127 | | | <prototype> 128 | | b 129 | | | hello 130 | | | <prototype> 131 | | c 132 | | | hello 133 | | | <prototype> 134 | | d 135 | | | e 136 | | | | g 137 | | | | | hello 138 | | | | | <prototype> 139 | | | | <prototype> 140 | | | f 141 | | | | h 142 | | | | | hello 143 | | | | | <prototype> 144 | | | | <prototype> 145 `, 146 { startIndex: 5 } 147 ); 148 149 info("Expand `e`"); 150 await toggleScopeNode(dbg, 4); 151 152 info("Expand the `target` node"); 153 let nodes = getAllLabels(dbg); 154 const originalNodesCount = nodes.length; 155 const targetNodeIndex = nodes.indexOf("target"); 156 Assert.greater(targetNodeIndex, -1, "Found the target node"); 157 // toggleScopeNode looks for the target with `querySelector` with `:nth-child` 158 // selector. Therefore, the index starts from 1, not 0. So, we need to 159 // increment the index. 160 await toggleScopeNode(dbg, targetNodeIndex + 1); 161 nodes = getAllLabels(dbg); 162 Assert.greater( 163 nodes.length, 164 originalNodesCount, 165 "the target node was expanded" 166 ); 167 ok(nodes.includes("classList"), "classList is displayed"); 168 169 await resume(dbg); 170 }); 171 172 function getAllLabels(dbg, withIndent = false) { 173 return Array.from(findAllElements(dbg, "scopeNodes")).map(el => { 174 let text = el.innerText; 175 if (withIndent) { 176 const node = el.closest(".tree-node"); 177 const level = Number(node.getAttribute("aria-level")); 178 if (!Number.isNaN(level)) { 179 text = `${"| ".repeat(level - 1)}${text}`.trim(); 180 } 181 } 182 return text; 183 }); 184 } 185 186 function checkScopesLabels(dbg, expected, { startIndex = 0 } = {}) { 187 const lines = expected 188 .trim() 189 .split("\n") 190 .map(line => line.trim()); 191 192 const labels = getAllLabels(dbg, true).slice( 193 startIndex, 194 startIndex + lines.length 195 ); 196 197 const format = arr => `\n${arr.join("\n")}\n`; 198 is(format(labels), format(lines), "got expected scope labels"); 199 }