test_smart-trace-grouping.html (4648B)
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 <!DOCTYPE HTML> 5 <html> 6 <!-- 7 Test the rendering of a stack trace 8 --> 9 <head> 10 <meta charset="utf-8"> 11 <title>StackTrace component test</title> 12 <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> 13 <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> 14 </head> 15 <body> 16 <script src="head.js"></script> 17 <script> 18 "use strict"; 19 20 window.onload = function() { 21 const ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom"); 22 const React = browserRequire("devtools/client/shared/vendor/react"); 23 const SmartTrace = React.createFactory( 24 browserRequire("devtools/client/shared/components/SmartTrace")); 25 ok(SmartTrace, "Got the SmartTrace factory"); 26 27 add_task(async function() { 28 const REACT_FRAMES_COUNT = 10; 29 30 const stacktrace = [ 31 { 32 filename: "https://myfile.com/mahscripts.js", 33 lineNumber: 55, 34 columnNumber: 10, 35 functionName: null, 36 }, 37 // Simulated Redux frame 38 { 39 functionName: "rootReducer", 40 filename: "https://myfile.com/loader.js -> https://myfile.com/redux.js", 41 lineNumber: 2, 42 }, 43 { 44 functionName: "loadFunc", 45 filename: "https://myfile.com/loader.js -> https://myfile.com/loadee.js", 46 lineNumber: 10, 47 }, 48 // Simulated react frames 49 ...(Array.from({length: REACT_FRAMES_COUNT}, (_, i) => ({ 50 functionName: "internalReact" + (REACT_FRAMES_COUNT - i), 51 filename: "https://myfile.com/loader.js -> https://myfile.com/react.js", 52 lineNumber: Number(i.toString().repeat(2)), 53 }))), 54 { 55 filename: "https://myfile.com/mahscripts.js", 56 lineNumber: 10, 57 columnNumber: 3, 58 functionName: "onClick", 59 }, 60 ]; 61 62 const props = { 63 stacktrace, 64 onViewSourceInDebugger: () => {}, 65 }; 66 67 const trace = ReactDOM.render(SmartTrace(props), window.document.body); 68 await forceRender(trace); 69 70 const traceEl = ReactDOM.findDOMNode(trace); 71 ok(traceEl, "Rendered SmartTrace has an element"); 72 73 isDeeply(getStacktraceText(traceEl), [ 74 `<anonymous> https://myfile.com/mahscripts.js:55`, 75 `rootReducer Redux`, 76 `loadFunc https://myfile.com/loadee.js:10`, 77 `▶︎ React 10`, 78 `onClick https://myfile.com/mahscripts.js:10`, 79 ], "React frames are grouped - Redux frame is not"); 80 81 info("Expand React group"); 82 let onReactGroupExpanded = waitFor(() => 83 traceEl.querySelector(".frames-group.expanded")); 84 traceEl.querySelector(".frames-group").click(); 85 await onReactGroupExpanded; 86 87 isDeeply(getStacktraceText(traceEl), [ 88 `<anonymous> https://myfile.com/mahscripts.js:55`, 89 `rootReducer Redux`, 90 `loadFunc https://myfile.com/loadee.js:10`, 91 `▼ React 10`, 92 `| internalReact10`, 93 `| internalReact9`, 94 `| internalReact8`, 95 `| internalReact7`, 96 `| internalReact6`, 97 `| internalReact5`, 98 `| internalReact4`, 99 `| internalReact3`, 100 `| internalReact2`, 101 `| internalReact1`, 102 `onClick https://myfile.com/mahscripts.js:10`, 103 ], "React frames can be expanded"); 104 105 info("Collapse React group"); 106 onReactGroupExpanded = waitFor(() => 107 !traceEl.querySelector(".frames-group.expanded")); 108 traceEl.querySelector(".frames-group").click(); 109 await onReactGroupExpanded; 110 111 isDeeply(getStacktraceText(traceEl), [ 112 `<anonymous> https://myfile.com/mahscripts.js:55`, 113 `rootReducer Redux`, 114 `loadFunc https://myfile.com/loadee.js:10`, 115 `▶︎ React 10`, 116 `onClick https://myfile.com/mahscripts.js:10`, 117 ], "React frames can be collapsed"); 118 }); 119 120 function getStacktraceText(traceElement) { 121 return Array.from(traceElement.querySelectorAll(".frame")).map(el => { 122 // If it's a group, we want to append an arrow representing the group state 123 if (el.classList.contains("frames-group")) { 124 const arrow = el.classList.contains("expanded") ? "▼" : "▶︎"; 125 const content = el.textContent.trim(); 126 return `${arrow} ${content}`; 127 } 128 129 const title = el.querySelector(".title"); 130 if (el.closest(".frames-list")) { 131 return `| ${title.textContent}`; 132 } 133 134 const location = el.querySelector(".location"); 135 return `${title.textContent} ${location.textContent}`; 136 }); 137 } 138 }; 139 </script> 140 </body> 141 </html>