browser_dbg-preview-wrapped-lines.js (5347B)
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 the tooltip previews are correct with wrapped editor lines. 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( 14 "/doc-wrapped-lines.html", 15 (request, response) => { 16 response.setStatusLine(request.httpVersion, 200, "OK"); 17 response.write(`<!DOCTYPE html> 18 <html> 19 <head> 20 <script type="text/javascript"> 21 const cs1 = getComputedStyle(document.documentElement); 22 const cs2 = getComputedStyle(document.documentElement); 23 // This line generates a very long inline-preview which is loaded a bit later after the 24 // initial positions for the page has been calculated 25 function add(a,b,k){var result=a+b;return k(result)}function sub(a,b,k){var result=a-b;return k(result)}function mul(a,b,k){var result=a*b;return k(result)}function div(a,b,k){var result=a/b;return k(result)}function arithmetic(){ 26 add(4,4,function(a){ 27 sub(a,2,function(b){mul(b,3,function(c){div(c,2,function(d){console.log("arithmetic",d)})})})})}; 28 isNaN(cs1, cs2); 29 const foo = { prop: 0 }; 30 const bar = Math.min(foo); 31 const myVeryLongVariableNameThatMayWrap = 42; 32 myVeryLongVariableNameThatMayWrap * 2; 33 debugger; 34 </script> 35 </head> 36 </html> 37 `); 38 } 39 ); 40 41 const BASE_URL = `http://localhost:${httpServer.identity.primaryPort}/`; 42 43 add_task(async function () { 44 await pushPref("devtools.toolbox.footer.height", 500); 45 await pushPref("devtools.debugger.ui.editor-wrapping", true); 46 47 // Reset toolbox height and end panel size to avoid impacting other tests 48 registerCleanupFunction(() => { 49 Services.prefs.clearUserPref("debugger.end-panel-size"); 50 }); 51 52 const dbg = await initDebuggerWithAbsoluteURL( 53 `${BASE_URL}doc-wrapped-lines.html` 54 ); 55 await waitForSources(dbg, "doc-wrapped-lines.html"); 56 57 const onReloaded = reload(dbg); 58 await waitForPaused(dbg); 59 60 await assertPreviews(dbg, [ 61 { 62 line: 13, 63 column: 18, 64 expression: "foo", 65 fields: [["prop", "0"]], 66 }, 67 { 68 line: 14, 69 column: 18, 70 result: "NaN", 71 expression: "bar", 72 }, 73 ]); 74 75 info( 76 "Resize the editor until the content on line 6 => ` const cs2 = getComputedStyle(document.documentElement);` wraps" 77 ); 78 // Use splitter to resize to make sure CodeMirror internal state is refreshed 79 // in such case (CodeMirror already handle window resize on its own). 80 const splitter = dbg.win.document.querySelectorAll(".splitter")[1]; 81 const splitterOriginalX = splitter.getBoundingClientRect().left; 82 ok(splitter, "Got the splitter"); 83 84 // Get the height of a simple unwrapped line (without any previews) 85 const lineHeightWithoutAnyWrap = getElementBoxQuadHeight( 86 findElement(dbg, "line", 1) 87 ); 88 89 const lineEl = findElement(dbg, "line", 6); 90 // Note this contains inline previews which might wrap a bit in certain scenarios 91 const lineHeightBeforeWrap = getElementBoxQuadHeight(lineEl); 92 let lineHeightAfterWrap = 0; 93 94 info("Resize the editor width to one third of the size of the line element"); 95 const lineElBoundingClientRect = lineEl.getBoundingClientRect(); 96 await resizeSplitter( 97 dbg, 98 splitter, 99 lineElBoundingClientRect.left + lineElBoundingClientRect.width / 3 100 ); 101 102 info("Wait until the line does wrap"); 103 await waitFor(async () => { 104 const el = findElement(dbg, "line", 6); 105 lineHeightAfterWrap = getElementBoxQuadHeight(el); 106 return lineHeightAfterWrap > lineHeightBeforeWrap; 107 }); 108 109 info("Assert that the line wrapped"); 110 const EXPECTED_LINES_TO_WRAP_OVER = 6; // Note: This includes inline previews 111 is( 112 Math.floor(lineHeightAfterWrap), 113 Math.floor(lineHeightWithoutAnyWrap * EXPECTED_LINES_TO_WRAP_OVER), 114 "The content on line 6 to wrap over 6 lines (including the inline previews)" 115 ); 116 117 info("Assert the previews still work with wrapping"); 118 await assertPreviews(dbg, [ 119 { 120 line: 16, 121 column: 13, 122 expression: "myVeryLongVariableNameThatMayWrap", 123 result: "42", 124 }, 125 ]); 126 127 // clearing the pref isn't enough to have consistent sizes between runs, 128 // so set it back to its original position 129 await resizeSplitter(dbg, splitter, splitterOriginalX); 130 131 await resume(dbg); 132 await onReloaded; 133 134 Services.prefs.clearUserPref("debugger.end-panel-size"); 135 await wait(1000); 136 }); 137 138 async function resizeSplitter(dbg, splitterEl, x) { 139 EventUtils.synthesizeMouse(splitterEl, 0, 0, { type: "mousedown" }, dbg.win); 140 // Move the splitter of the secondary pane to the middle of the token, 141 // this should cause the token to wrap. 142 EventUtils.synthesizeMouseAtPoint( 143 x, 144 splitterEl.getBoundingClientRect().top + 10, 145 { type: "mousemove" }, 146 dbg.win 147 ); 148 149 // Stop dragging 150 EventUtils.synthesizeMouseAtCenter(splitterEl, { type: "mouseup" }, dbg.win); 151 } 152 153 // Calculates the height of the element for the line 154 function getElementBoxQuadHeight(lineEl) { 155 const boxQ = lineEl.getBoxQuads()[0]; 156 return boxQ.p4.y - boxQ.p1.y; 157 }