browser_webconsole_stacktrace_location_debugger_link.js (3771B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 // Test that message source links for js errors and console API calls open in 5 // the jsdebugger when clicked. 6 7 "use strict"; 8 9 // There are shutdown issues for which multiple rejections are left uncaught. 10 // See bug 1018184 for resolving these issues. 11 PromiseTestUtils.allowMatchingRejectionsGlobally(/Component not initialized/); 12 PromiseTestUtils.allowMatchingRejectionsGlobally(/this\.worker is null/); 13 14 const TEST_URI = 15 "https://example.com/browser/devtools/client/webconsole/" + 16 "test/browser/" + 17 "test-stacktrace-location-debugger-link.html"; 18 19 add_task(async function () { 20 const hud = await openNewTabAndConsole(TEST_URI); 21 const toolbox = gDevTools.getToolboxForTab(gBrowser.selectedTab); 22 23 await testOpenFrameInDebugger(hud, toolbox, "console.trace()", [ 24 { url: TEST_URI, line: 21, column: 17 }, 25 { url: TEST_URI, line: 15, column: 9 }, 26 { url: TEST_URI, line: 30, column: 7 }, 27 ]); 28 await testOpenFrameInDebugger(hud, toolbox, "myErrorObject", [ 29 { url: TEST_URI, line: 19, column: 21 }, 30 { url: TEST_URI, line: 15, column: 9 }, 31 { url: TEST_URI, line: 30, column: 7 }, 32 ]); 33 await testOpenFrameInDebugger(hud, toolbox, "customSourceURL", [ 34 { url: "http://example.org/source.js", line: 1, column: 13 }, 35 { url: TEST_URI, line: 25, column: 9 }, 36 { url: TEST_URI, line: 15, column: 9 }, 37 { url: TEST_URI, line: 30, column: 7 }, 38 ]); 39 await testOpenFrameInDebugger( 40 hud, 41 toolbox, 42 "String contains an invalid character", 43 [ 44 { url: TEST_URI, line: 27, column: 13 }, 45 { url: TEST_URI, line: 15, column: 9 }, 46 { url: TEST_URI, line: 30, column: 7 }, 47 ], 48 ".error" 49 ); 50 }); 51 52 async function testOpenFrameInDebugger( 53 hud, 54 toolbox, 55 text, 56 frames, 57 typeSelector = ".console-api" 58 ) { 59 info(`Testing message with text "${text}"`); 60 const messageNode = await waitFor(() => 61 findMessageByType(hud, text, typeSelector) 62 ); 63 const framesNode = await waitFor(() => messageNode.querySelector(".frames")); 64 65 const frameNodes = framesNode.querySelectorAll(".frame"); 66 is( 67 frameNodes.length, 68 frames.length, 69 "The message does have the expected number of frames in the stacktrace" 70 ); 71 72 for (let i = 0; i < frames.length; i++) { 73 info(`Asserting frame #${i + 1}`); 74 const frameNode = frameNodes[i]; 75 await checkMousedownOnNode(hud, toolbox, frameNode, frames[i]); 76 77 info("Selecting the console again"); 78 await toolbox.selectTool("webconsole"); 79 } 80 } 81 82 async function checkMousedownOnNode(hud, toolbox, frameNode, frame) { 83 info("checking click on node location"); 84 const onSourceInDebuggerOpened = once(hud, "source-in-debugger-opened"); 85 EventUtils.sendMouseEvent( 86 { type: "click" }, 87 frameNode.querySelector(".location") 88 ); 89 await onSourceInDebuggerOpened; 90 91 const url = frameNode.querySelector(".filename").textContent; 92 const line = Number(frameNode.querySelector(".line").textContent); 93 // The customSourceURL isn't resolved whereas it will be in the debugger 94 is(URL.parse(url).href, frame.url); 95 is(line, frame.line); 96 const dbg = toolbox.getPanel("jsdebugger"); 97 const selectedLocation = dbg._selectors.getSelectedLocation(dbg._getState()); 98 is( 99 selectedLocation.source.url, 100 // The customSourceURL isn't resolved whereas it will be in the debugger 101 URL.parse(frame.url).href, 102 `Debugger is opened at expected source url (${frame.url})` 103 ); 104 is( 105 selectedLocation.line, 106 line, 107 `Debugger is opened at expected line (${frame.line})` 108 ); 109 // Debugger's column is 0-based 110 is( 111 selectedLocation.column + 1, 112 frame.column, 113 `Debugger is opened at expected column (${frame.column})` 114 ); 115 }