1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/devtools/debugger/test/browser_dbg_conditional-breakpoints-01.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,233 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +/** 1.8 + * Bug 740825: Test the debugger conditional breakpoints. 1.9 + */ 1.10 + 1.11 +const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html"; 1.12 + 1.13 +function test() { 1.14 + // Linux debug test slaves are a bit slow at this test sometimes. 1.15 + requestLongerTimeout(2); 1.16 + 1.17 + let gTab, gDebuggee, gPanel, gDebugger; 1.18 + let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving; 1.19 + 1.20 + initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { 1.21 + gTab = aTab; 1.22 + gDebuggee = aDebuggee; 1.23 + gPanel = aPanel; 1.24 + gDebugger = gPanel.panelWin; 1.25 + gEditor = gDebugger.DebuggerView.editor; 1.26 + gSources = gDebugger.DebuggerView.Sources; 1.27 + gBreakpoints = gDebugger.DebuggerController.Breakpoints; 1.28 + gBreakpointsAdded = gBreakpoints._added; 1.29 + gBreakpointsRemoving = gBreakpoints._removing; 1.30 + 1.31 + // This test forces conditional breakpoints to be evaluated on the 1.32 + // client-side 1.33 + var client = gPanel.target.client; 1.34 + client.mainRoot.traits.conditionalBreakpoints = false; 1.35 + 1.36 + waitForSourceAndCaretAndScopes(gPanel, ".html", 17) 1.37 + .then(() => addBreakpoints()) 1.38 + .then(() => initialChecks()) 1.39 + .then(() => resumeAndTestBreakpoint(20)) 1.40 + .then(() => resumeAndTestBreakpoint(21)) 1.41 + .then(() => resumeAndTestBreakpoint(22)) 1.42 + .then(() => resumeAndTestBreakpoint(23)) 1.43 + .then(() => resumeAndTestBreakpoint(24)) 1.44 + .then(() => resumeAndTestBreakpoint(25)) 1.45 + .then(() => resumeAndTestBreakpoint(27)) 1.46 + .then(() => resumeAndTestBreakpoint(28)) 1.47 + .then(() => { 1.48 + // Note: the breakpoint on line 29 should not be hit since the 1.49 + // conditional expression evaluates to undefined. It used to 1.50 + // be on line 30, but it can't be the last breakpoint because 1.51 + // there is a race condition (the "frames cleared" event might 1.52 + // fire from the conditional expression evaluation if it's too 1.53 + // slow, which is what we wait for to reload the page) 1.54 + return resumeAndTestBreakpoint(30); 1.55 + }) 1.56 + .then(() => resumeAndTestNoBreakpoint()) 1.57 + .then(() => reloadActiveTab(gPanel, gDebugger.EVENTS.BREAKPOINT_SHOWN, 13)) 1.58 + .then(() => testAfterReload()) 1.59 + .then(() => closeDebuggerAndFinish(gPanel)) 1.60 + .then(null, aError => { 1.61 + ok(false, "Got an error: " + aError.message + "\n" + aError.stack); 1.62 + }); 1.63 + 1.64 + gDebuggee.ermahgerd(); 1.65 + }); 1.66 + 1.67 + function addBreakpoints() { 1.68 + return promise.resolve(null) 1.69 + .then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 18 })) 1.70 + .then(aClient => aClient.conditionalExpression = "undefined") 1.71 + .then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 19 })) 1.72 + .then(aClient => aClient.conditionalExpression = "null") 1.73 + .then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 20 })) 1.74 + .then(aClient => aClient.conditionalExpression = "42") 1.75 + .then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 21 })) 1.76 + .then(aClient => aClient.conditionalExpression = "true") 1.77 + .then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 22 })) 1.78 + .then(aClient => aClient.conditionalExpression = "'nasu'") 1.79 + .then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 23 })) 1.80 + .then(aClient => aClient.conditionalExpression = "/regexp/") 1.81 + .then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 24 })) 1.82 + .then(aClient => aClient.conditionalExpression = "({})") 1.83 + .then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 25 })) 1.84 + .then(aClient => aClient.conditionalExpression = "(function() {})") 1.85 + .then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 26 })) 1.86 + .then(aClient => aClient.conditionalExpression = "(function() { return false; })()") 1.87 + .then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 27 })) 1.88 + .then(aClient => aClient.conditionalExpression = "a") 1.89 + .then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 28 })) 1.90 + .then(aClient => aClient.conditionalExpression = "a !== undefined") 1.91 + .then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 29 })) 1.92 + .then(aClient => aClient.conditionalExpression = "b") 1.93 + .then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 30 })) 1.94 + .then(aClient => aClient.conditionalExpression = "a !== null"); 1.95 + } 1.96 + 1.97 + function initialChecks() { 1.98 + is(gDebugger.gThreadClient.state, "paused", 1.99 + "Should only be getting stack frames while paused."); 1.100 + is(gSources.itemCount, 1, 1.101 + "Found the expected number of sources."); 1.102 + is(gEditor.getText().indexOf("ermahgerd"), 253, 1.103 + "The correct source was loaded initially."); 1.104 + is(gSources.selectedValue, gSources.values[0], 1.105 + "The correct source is selected."); 1.106 + 1.107 + is(gBreakpointsAdded.size, 13, 1.108 + "13 breakpoints currently added."); 1.109 + is(gBreakpointsRemoving.size, 0, 1.110 + "No breakpoints currently being removed."); 1.111 + is(gEditor.getBreakpoints().length, 13, 1.112 + "13 breakpoints currently shown in the editor."); 1.113 + 1.114 + ok(!gBreakpoints._getAdded({ url: "foo", line: 3 }), 1.115 + "_getAdded('foo', 3) returns falsey."); 1.116 + ok(!gBreakpoints._getRemoving({ url: "bar", line: 3 }), 1.117 + "_getRemoving('bar', 3) returns falsey."); 1.118 + } 1.119 + 1.120 + function resumeAndTestBreakpoint(aLine) { 1.121 + let finished = waitForCaretUpdated(gPanel, aLine).then(() => testBreakpoint(aLine)); 1.122 + 1.123 + EventUtils.sendMouseEvent({ type: "mousedown" }, 1.124 + gDebugger.document.getElementById("resume"), 1.125 + gDebugger); 1.126 + 1.127 + return finished; 1.128 + } 1.129 + 1.130 + function resumeAndTestNoBreakpoint() { 1.131 + let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => { 1.132 + is(gSources.itemCount, 1, 1.133 + "Found the expected number of sources."); 1.134 + is(gEditor.getText().indexOf("ermahgerd"), 253, 1.135 + "The correct source was loaded initially."); 1.136 + is(gSources.selectedValue, gSources.values[0], 1.137 + "The correct source is selected."); 1.138 + 1.139 + ok(gSources.selectedItem, 1.140 + "There should be a selected source in the sources pane.") 1.141 + ok(!gSources._selectedBreakpointItem, 1.142 + "There should be no selected breakpoint in the sources pane.") 1.143 + is(gSources._conditionalPopupVisible, false, 1.144 + "The breakpoint conditional expression popup should not be shown."); 1.145 + 1.146 + is(gDebugger.document.querySelectorAll(".dbg-stackframe").length, 0, 1.147 + "There should be no visible stackframes."); 1.148 + is(gDebugger.document.querySelectorAll(".dbg-breakpoint").length, 13, 1.149 + "There should be thirteen visible breakpoints."); 1.150 + }); 1.151 + 1.152 + gDebugger.gThreadClient.resume(); 1.153 + 1.154 + return finished; 1.155 + } 1.156 + 1.157 + function testBreakpoint(aLine, aHighlightBreakpoint) { 1.158 + // Highlight the breakpoint only if required. 1.159 + if (aHighlightBreakpoint) { 1.160 + let finished = waitForCaretUpdated(gPanel, aLine).then(() => testBreakpoint(aLine)); 1.161 + gSources.highlightBreakpoint({ url: gSources.selectedValue, line: aLine }); 1.162 + return finished; 1.163 + } 1.164 + 1.165 + let selectedUrl = gSources.selectedValue; 1.166 + let selectedBreakpoint = gSources._selectedBreakpointItem; 1.167 + 1.168 + ok(selectedUrl, 1.169 + "There should be a selected item in the sources pane."); 1.170 + ok(selectedBreakpoint, 1.171 + "There should be a selected breakpoint in the sources pane."); 1.172 + 1.173 + is(selectedBreakpoint.attachment.url, selectedUrl, 1.174 + "The breakpoint on line " + aLine + " wasn't added on the correct source."); 1.175 + is(selectedBreakpoint.attachment.line, aLine, 1.176 + "The breakpoint on line " + aLine + " wasn't found."); 1.177 + is(!!selectedBreakpoint.attachment.disabled, false, 1.178 + "The breakpoint on line " + aLine + " should be enabled."); 1.179 + is(!!selectedBreakpoint.attachment.openPopup, false, 1.180 + "The breakpoint on line " + aLine + " should not have opened a popup."); 1.181 + is(gSources._conditionalPopupVisible, false, 1.182 + "The breakpoint conditional expression popup should not have been shown."); 1.183 + 1.184 + return gBreakpoints._getAdded(selectedBreakpoint.attachment).then(aBreakpointClient => { 1.185 + is(aBreakpointClient.location.url, selectedUrl, 1.186 + "The breakpoint's client url is correct"); 1.187 + is(aBreakpointClient.location.line, aLine, 1.188 + "The breakpoint's client line is correct"); 1.189 + isnot(aBreakpointClient.conditionalExpression, undefined, 1.190 + "The breakpoint on line " + aLine + " should have a conditional expression."); 1.191 + 1.192 + ok(isCaretPos(gPanel, aLine), 1.193 + "The editor caret position is not properly set."); 1.194 + }); 1.195 + } 1.196 + 1.197 + function testAfterReload() { 1.198 + let selectedUrl = gSources.selectedValue; 1.199 + let selectedBreakpoint = gSources._selectedBreakpointItem; 1.200 + 1.201 + ok(selectedUrl, 1.202 + "There should be a selected item in the sources pane after reload."); 1.203 + ok(!selectedBreakpoint, 1.204 + "There should be no selected breakpoint in the sources pane after reload."); 1.205 + 1.206 + return promise.resolve(null) 1.207 + .then(() => testBreakpoint(18, true)) 1.208 + .then(() => testBreakpoint(19, true)) 1.209 + .then(() => testBreakpoint(20, true)) 1.210 + .then(() => testBreakpoint(21, true)) 1.211 + .then(() => testBreakpoint(22, true)) 1.212 + .then(() => testBreakpoint(23, true)) 1.213 + .then(() => testBreakpoint(24, true)) 1.214 + .then(() => testBreakpoint(25, true)) 1.215 + .then(() => testBreakpoint(26, true)) 1.216 + .then(() => testBreakpoint(27, true)) 1.217 + .then(() => testBreakpoint(28, true)) 1.218 + .then(() => testBreakpoint(29, true)) 1.219 + .then(() => testBreakpoint(30, true)) 1.220 + .then(() => { 1.221 + is(gSources.itemCount, 1, 1.222 + "Found the expected number of sources."); 1.223 + is(gEditor.getText().indexOf("ermahgerd"), 253, 1.224 + "The correct source was loaded again."); 1.225 + is(gSources.selectedValue, gSources.values[0], 1.226 + "The correct source is selected."); 1.227 + 1.228 + ok(gSources.selectedItem, 1.229 + "There should be a selected source in the sources pane.") 1.230 + ok(gSources._selectedBreakpointItem, 1.231 + "There should be a selected breakpoint in the sources pane.") 1.232 + is(gSources._conditionalPopupVisible, false, 1.233 + "The breakpoint conditional expression popup should not be shown."); 1.234 + }); 1.235 + } 1.236 +}