browser_webconsole_console_dir.js (4527B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 // Check console.dir() calls. 7 const TEST_URI = 8 "data:text/html;charset=utf8,<!DOCTYPE html><h1>test console.dir</h1>"; 9 10 add_task(async function () { 11 const hud = await openNewTabAndConsole(TEST_URI); 12 13 logAllStoreChanges(hud); 14 15 info("console.dir on an array"); 16 await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { 17 content.wrappedJSObject.console.dir([1, 2, { a: "a", b: "b" }]); 18 }); 19 let dirMessageNode = await waitFor(() => 20 findConsoleDir(hud.ui.outputNode, 0) 21 ); 22 let objectInspectors = [...dirMessageNode.querySelectorAll(".tree")]; 23 is( 24 objectInspectors.length, 25 1, 26 "There is the expected number of object inspectors" 27 ); 28 const [arrayOi] = objectInspectors; 29 let arrayOiNodes = arrayOi.querySelectorAll(".node"); 30 // The tree can be collapsed since the properties are fetched asynchronously. 31 if (arrayOiNodes.length === 1) { 32 // If this is the case, we wait for the properties to be fetched and displayed. 33 await waitForNodeMutation(arrayOi, { 34 childList: true, 35 }); 36 arrayOiNodes = arrayOi.querySelectorAll(".node"); 37 } 38 39 // There are 6 nodes: the root, 1, 2, {a: "a", b: "b"}, length and the proto. 40 is( 41 arrayOiNodes.length, 42 6, 43 "There is the expected number of nodes in the tree" 44 ); 45 let propertiesNodes = [...arrayOi.querySelectorAll(".object-label")].map( 46 el => el.textContent 47 ); 48 const arrayPropertiesNames = ["0", "1", "2", "length", "<prototype>"]; 49 is(JSON.stringify(propertiesNodes), JSON.stringify(arrayPropertiesNames)); 50 51 info("console.dir on a long object"); 52 const obj = Array.from({ length: 100 }).reduce((res, _, i) => { 53 res["item-" + (i + 1).toString().padStart(3, "0")] = i + 1; 54 return res; 55 }, {}); 56 await SpecialPowers.spawn(gBrowser.selectedBrowser, [obj], function (data) { 57 content.wrappedJSObject.console.dir(data); 58 }); 59 dirMessageNode = await waitFor(() => findConsoleDir(hud.ui.outputNode, 1)); 60 objectInspectors = [...dirMessageNode.querySelectorAll(".tree")]; 61 is( 62 objectInspectors.length, 63 1, 64 "There is the expected number of object inspectors" 65 ); 66 const [objectOi] = objectInspectors; 67 let objectOiNodes = objectOi.querySelectorAll(".node"); 68 // The tree can be collapsed since the properties are fetched asynchronously. 69 if (objectOiNodes.length === 1) { 70 // If this is the case, we wait for the properties to be fetched and displayed. 71 await waitForNodeMutation(objectOi, { 72 childList: true, 73 }); 74 objectOiNodes = objectOi.querySelectorAll(".node"); 75 } 76 77 // There are 102 nodes: the root, 100 "item-N" properties, and the proto. 78 is( 79 objectOiNodes.length, 80 102, 81 "There is the expected number of nodes in the tree" 82 ); 83 const objectPropertiesNames = Object.getOwnPropertyNames(obj).map( 84 name => `"${name}"` 85 ); 86 objectPropertiesNames.push("<prototype>"); 87 propertiesNodes = [...objectOi.querySelectorAll(".object-label")].map( 88 el => el.textContent 89 ); 90 is(JSON.stringify(propertiesNodes), JSON.stringify(objectPropertiesNames)); 91 92 info("console.dir on an error object"); 93 await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { 94 const err = new Error("myErrorMessage"); 95 err.myCustomProperty = "myCustomPropertyValue"; 96 content.wrappedJSObject.console.dir(err); 97 }); 98 dirMessageNode = await waitFor(() => findConsoleDir(hud.ui.outputNode, 2)); 99 objectInspectors = [...dirMessageNode.querySelectorAll(".tree")]; 100 is( 101 objectInspectors.length, 102 1, 103 "There is the expected number of object inspectors" 104 ); 105 const [errorOi] = objectInspectors; 106 let errorOiNodes = errorOi.querySelectorAll(".node"); 107 // The tree can be collapsed since the properties are fetched asynchronously. 108 if (errorOiNodes.length === 1) { 109 // If this is the case, we wait for the properties to be fetched and displayed. 110 await waitForNodeMutation(errorOi, { 111 childList: true, 112 }); 113 errorOiNodes = errorOi.querySelectorAll(".node"); 114 } 115 116 propertiesNodes = [...errorOi.querySelectorAll(".object-label")].map( 117 el => el.textContent 118 ); 119 is( 120 JSON.stringify(propertiesNodes), 121 JSON.stringify([ 122 "columnNumber", 123 "fileName", 124 "lineNumber", 125 "message", 126 "myCustomProperty", 127 "stack", 128 "<prototype>", 129 ]) 130 ); 131 }); 132 133 function findConsoleDir(node, index) { 134 return node.querySelectorAll(".dir.message")[index]; 135 }