browser_dbg-log-points.js (6243B)
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 /* 6 * Tests that log points are correctly logged to the console 7 */ 8 9 "use strict"; 10 11 add_task(async function () { 12 Services.prefs.setBoolPref("devtools.toolbox.splitconsole.open", true); 13 const dbg = await initDebugger( 14 "doc-script-switching.html", 15 "script-switching-01.js" 16 ); 17 18 const source = findSource(dbg, "script-switching-01.js"); 19 await selectSource(dbg, "script-switching-01.js"); 20 21 await getDebuggerSplitConsole(dbg); 22 23 info( 24 `Add a first log breakpoint with no argument, which will log "display name", i.e. firstCall` 25 ); 26 await altClickElement(dbg, "gutterElement", 7); 27 await waitForBreakpoint(dbg, "script-switching-01.js", 7); 28 29 info("Add another log breakpoint with multiple arguments"); 30 await dbg.actions.addBreakpoint(createLocation({ line: 8, source }), { 31 logValue: "'a', 'b', 'c', firstCall", 32 }); 33 34 invokeInTab("firstCall"); 35 await waitForPaused(dbg); 36 37 info("Wait for the two log breakpoints"); 38 await hasConsoleMessage(dbg, "firstCall"); 39 await hasConsoleMessage(dbg, "a b c"); 40 41 const { link, value } = await findConsoleMessage(dbg, "a b c"); 42 is(link, "script-switching-01.js:8:3", "logs should have the relevant link"); 43 is(value, "a b c \nfunction firstCall()", "logs should have multiple values"); 44 await removeBreakpoint(dbg, source.id, 7); 45 await removeBreakpoint(dbg, source.id, 8); 46 47 await resume(dbg); 48 49 info( 50 "Now set a log point calling a method with a debugger statement and a breakpoint, it shouldn't pause on the log point" 51 ); 52 await addBreakpoint(dbg, "script-switching-01.js", 8); 53 await addBreakpoint(dbg, "script-switching-01.js", 7); 54 await dbg.actions.addBreakpoint(createLocation({ line: 7, source }), { 55 logValue: "'second call', secondCall()", 56 }); 57 58 invokeInTab("firstCall"); 59 await waitForPaused(dbg); 60 // We aren't pausing on secondCall's debugger statement, 61 // called by the condition, but only on the breakpoint we set on firstCall, line 8 62 await assertPausedAtSourceAndLine(dbg, source.id, 8); 63 64 // The log point is visible, even if it had a debugger statement in it. 65 await hasConsoleMessage(dbg, "second call 44"); 66 await removeBreakpoint(dbg, source.id, 7); 67 await removeBreakpoint(dbg, source.id, 8); 68 69 await resume(dbg); 70 // Resume a second time as we are hittin the debugger statement as firstCall calls secondCall 71 await resume(dbg); 72 73 info( 74 "Set a log point throwing an exception and ensure the exception is displayed" 75 ); 76 await dbg.actions.addBreakpoint(createLocation({ line: 7, source }), { 77 logValue: "jsWithError(", 78 }); 79 invokeInTab("firstCall"); 80 await waitForPaused(dbg); 81 // Exceptions in conditional breakpoint would not trigger a pause, 82 // So we end up pausing on the debugger statement in the other script. 83 await assertPausedAtSourceAndLine( 84 dbg, 85 findSource(dbg, "script-switching-02.js").id, 86 6 87 ); 88 89 // But verify that the exception message is visible even if we didn't pause. 90 // As the logValue is evaled within an array `[${logValue}]`, 91 // the exception message is a bit cryptic... 92 await hasConsoleMessage(dbg, "expected expression, got ']'"); 93 94 await dbg.actions.removeAllBreakpoints(); 95 96 await resume(dbg); 97 info("About to set log point"); 98 99 await selectSource(dbg, "script-switching-01.js"); 100 101 await setLogPoint(dbg, 8, "'stacktrace test'", true); 102 103 invokeInTab("logPointTest"); 104 info("logPointTest invoked in tab"); 105 await waitForPaused(dbg); 106 await resume(dbg); 107 108 info("Checking for any console messages"); 109 await hasConsoleMessage(dbg, "stacktrace test"); 110 111 const [stacktraceMsg] = await findConsoleMessages( 112 dbg.toolbox, 113 "stacktrace test" 114 ); 115 const stacktraceFrames = await waitFor(() => 116 stacktraceMsg.querySelector(".frames") 117 ); 118 119 const frameNodes = stacktraceFrames.querySelectorAll(".frame"); 120 info(`Found ${frameNodes.length} frames in the stacktrace`); 121 122 is( 123 frameNodes.length, 124 2, 125 "The message does have the expected number of frames in the stacktrace" 126 ); 127 ok( 128 frameNodes[0].textContent.includes("script-switching-01.js:6"), 129 "First frame should be from line 6" 130 ); 131 ok( 132 frameNodes[1].textContent.includes("script-switching-01.js:12"), 133 "Second frame should be from line 12" 134 ); 135 136 // reopen the panel 137 info("Reopening the panel to test the checkbox"); 138 await selectSource(dbg, "script-switching-01.js"); 139 140 rightClickElement(dbg, "gutterElement", 8); 141 await waitForContextMenu(dbg); 142 selectDebuggerContextMenuItem( 143 dbg, 144 `${selectors.addLogItem},${selectors.editLogItem}` 145 ); 146 await waitForConditionalPanelFocus(dbg); 147 148 info("Updating the log point input value"); 149 type(dbg, "'logpoint without stacktrace'"); 150 // wait for a bit so codemirror is able to process the input 151 await wait(1000); 152 153 //make sure that the checkbox is checked 154 const stacktraceCheckbox = dbg.win.document.querySelector("#showStacktrace"); 155 ok( 156 stacktraceCheckbox.checked, 157 "Checkbox is still checked when reopening the logpoint panel" 158 ); 159 160 // uncheck the checkbox 161 info("Click the checkbox to uncheck it"); 162 stacktraceCheckbox.click(); 163 info("Checkbox clicked to uncheck it"); 164 await waitFor(() => { 165 return !stacktraceCheckbox.checked; 166 }); 167 168 ok(true, "Checkbox is unchecked after clicking"); 169 170 const saveButton = dbg.win.document.getElementById("save-logpoint"); 171 const onBreakpointSet = waitForDispatch(dbg.store, "SET_BREAKPOINT"); 172 saveButton.click(); 173 await onBreakpointSet; 174 175 info("Call logPointTest to hit the logpoint"); 176 invokeInTab("logPointTest"); 177 // the functions has a debugger statement, so wait for pause and resume 178 await waitForPaused(dbg); 179 await resume(dbg); 180 181 await hasConsoleMessage(dbg, "logpoint without stacktrace"); 182 const [logpointMsg] = await findConsoleMessages( 183 dbg.toolbox, 184 "logpoint without stacktrace" 185 ); 186 // Wait for a bit so stacktrace would be rendered 187 await wait(1000); 188 is( 189 logpointMsg.querySelector(".frames"), 190 null, 191 "There is no stacktrace for the logpoint without stacktrace" 192 ); 193 });