mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Merge mozilla-central and fx-team
This commit is contained in:
commit
ef26a08f6d
@ -1089,10 +1089,6 @@ pref("devtools.inspector.markupPreview", false);
|
||||
pref("devtools.inspector.remote", false);
|
||||
pref("devtools.inspector.show_pseudo_elements", true);
|
||||
|
||||
// Enable the Layout View
|
||||
pref("devtools.layoutview.enabled", true);
|
||||
pref("devtools.layoutview.open", false);
|
||||
|
||||
// Enable the Responsive UI tool
|
||||
pref("devtools.responsiveUI.enabled", true);
|
||||
pref("devtools.responsiveUI.no-reload-notification", false);
|
||||
|
@ -28,9 +28,8 @@ tests.testConsole = function(options) {
|
||||
}
|
||||
Services.obs.addObserver(onWebConsoleOpen, "web-console-created", false);
|
||||
|
||||
function onExecute () {
|
||||
let labels = hud.outputNode.querySelectorAll(".webconsole-msg-output");
|
||||
ok(labels.length > 0, "output for pprint(window)");
|
||||
function onExecute (msg) {
|
||||
ok(msg, "output for pprint(window)");
|
||||
|
||||
hud.jsterm.once("messages-cleared", onClear);
|
||||
|
||||
@ -45,7 +44,7 @@ tests.testConsole = function(options) {
|
||||
}
|
||||
|
||||
function onClear() {
|
||||
let labels = hud.outputNode.querySelectorAll(".webconsole-msg-output");
|
||||
let labels = hud.outputNode.querySelectorAll(".message");
|
||||
is(labels.length, 0, "no output in console");
|
||||
|
||||
helpers.audit(options, [
|
||||
|
@ -19,33 +19,32 @@ XPCOMUtils.defineLazyModuleGetter(this, "console",
|
||||
"resource://gre/modules/devtools/Console.jsm");
|
||||
|
||||
/**
|
||||
* Utility to get access to the current breakpoint list
|
||||
* @param dbg The debugger panel
|
||||
* @returns an array of object, one for each breakpoint, where each breakpoint
|
||||
* object has the following properties:
|
||||
* - id: A unique identifier for the breakpoint. This is not designed to be
|
||||
* shown to the user.
|
||||
* - label: A unique string identifier designed to be user visible. In theory
|
||||
* the label of a breakpoint could change
|
||||
* - url: The URL of the source file
|
||||
* - lineNumber: The line number of the breakpoint in the source file
|
||||
* - lineText: The text of the line at the breakpoint
|
||||
* - truncatedLineText: lineText truncated to MAX_LINE_TEXT_LENGTH
|
||||
* Utility to get access to the current breakpoint list.
|
||||
*
|
||||
* @param DebuggerPanel dbg
|
||||
* The debugger panel.
|
||||
* @return array
|
||||
* An array of objects, one for each breakpoint, where each breakpoint
|
||||
* object has the following properties:
|
||||
* - url: the URL of the source file.
|
||||
* - label: a unique string identifier designed to be user visible.
|
||||
* - lineNumber: the line number of the breakpoint in the source file.
|
||||
* - lineText: the text of the line at the breakpoint.
|
||||
* - truncatedLineText: lineText truncated to MAX_LINE_TEXT_LENGTH.
|
||||
*/
|
||||
function getAllBreakpoints(dbg) {
|
||||
let breakpoints = [];
|
||||
let sources = dbg.panelWin.DebuggerView.Sources;
|
||||
let { trimUrlLength: tr } = dbg.panelWin.SourceUtils;
|
||||
let sources = dbg._view.Sources;
|
||||
let { trimUrlLength: trim } = dbg.panelWin.SourceUtils;
|
||||
|
||||
for (let source in sources) {
|
||||
for (let { attachment: breakpoint } in source) {
|
||||
breakpoints.push({
|
||||
id: source.value + ":" + breakpoint.lineNumber,
|
||||
label: source.label + ":" + breakpoint.lineNumber,
|
||||
url: source.value,
|
||||
lineNumber: breakpoint.lineNumber,
|
||||
lineText: breakpoint.lineText,
|
||||
truncatedLineText: tr(breakpoint.lineText, MAX_LINE_TEXT_LENGTH, "end")
|
||||
label: source.label + ":" + breakpoint.line,
|
||||
lineNumber: breakpoint.line,
|
||||
lineText: breakpoint.text,
|
||||
truncatedLineText: trim(breakpoint.text, MAX_LINE_TEXT_LENGTH, "end")
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -70,10 +69,8 @@ gcli.addCommand({
|
||||
description: gcli.lookup("breaklistDesc"),
|
||||
returnType: "breakpoints",
|
||||
exec: function(args, context) {
|
||||
let dbg = getPanel(context, "jsdebugger", { ensure_opened: true });
|
||||
return dbg.then(function(dbg) {
|
||||
return getAllBreakpoints(dbg);
|
||||
});
|
||||
let dbg = getPanel(context, "jsdebugger", { ensureOpened: true });
|
||||
return dbg.then(getAllBreakpoints);
|
||||
}
|
||||
});
|
||||
|
||||
@ -151,7 +148,7 @@ gcli.addCommand({
|
||||
data: function(context) {
|
||||
let dbg = getPanel(context, "jsdebugger");
|
||||
if (dbg) {
|
||||
return dbg.panelWin.DebuggerView.Sources.values;
|
||||
return dbg._view.Sources.values;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
@ -166,8 +163,6 @@ gcli.addCommand({
|
||||
],
|
||||
returnType: "string",
|
||||
exec: function(args, context) {
|
||||
args.type = "line";
|
||||
|
||||
let dbg = getPanel(context, "jsdebugger");
|
||||
if (!dbg) {
|
||||
return gcli.lookup("debuggerStopped");
|
||||
@ -175,13 +170,13 @@ gcli.addCommand({
|
||||
|
||||
let deferred = context.defer();
|
||||
let position = { url: args.file, line: args.line };
|
||||
dbg.addBreakpoint(position, function(aBreakpoint, aError) {
|
||||
if (aError) {
|
||||
deferred.resolve(gcli.lookupFormat("breakaddFailed", [aError]));
|
||||
return;
|
||||
}
|
||||
|
||||
dbg.addBreakpoint(position).then(() => {
|
||||
deferred.resolve(gcli.lookup("breakaddAdded"));
|
||||
}, aError => {
|
||||
deferred.resolve(gcli.lookupFormat("breakaddFailed", [aError]));
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
});
|
||||
@ -199,16 +194,14 @@ gcli.addCommand({
|
||||
name: "selection",
|
||||
lookup: function(context) {
|
||||
let dbg = getPanel(context, "jsdebugger");
|
||||
if (dbg == null) {
|
||||
if (!dbg) {
|
||||
return [];
|
||||
}
|
||||
return getAllBreakpoints(dbg).map(breakpoint => {
|
||||
return {
|
||||
name: breakpoint.label,
|
||||
value: breakpoint,
|
||||
description: breakpoint.truncatedLineText
|
||||
};
|
||||
});
|
||||
return getAllBreakpoints(dbg).map(breakpoint => ({
|
||||
name: breakpoint.label,
|
||||
value: breakpoint,
|
||||
description: breakpoint.truncatedLineText
|
||||
}));
|
||||
}
|
||||
},
|
||||
description: gcli.lookup("breakdelBreakidDesc")
|
||||
@ -221,23 +214,15 @@ gcli.addCommand({
|
||||
return gcli.lookup("debuggerStopped");
|
||||
}
|
||||
|
||||
let breakpoint = dbg.getBreakpoint(
|
||||
args.breakpoint.url, args.breakpoint.lineNumber);
|
||||
|
||||
if (breakpoint == null) {
|
||||
return gcli.lookup("breakNotFound");
|
||||
}
|
||||
|
||||
let deferred = context.defer();
|
||||
try {
|
||||
dbg.removeBreakpoint(breakpoint, function() {
|
||||
deferred.resolve(gcli.lookup("breakdelRemoved"));
|
||||
});
|
||||
} catch (ex) {
|
||||
console.error('Error removing breakpoint, already removed?', ex);
|
||||
// If the debugger has been closed already, don't scare the user.
|
||||
let position = { url: args.breakpoint.url, line: args.breakpoint.lineNumber };
|
||||
|
||||
dbg.removeBreakpoint(position).then(() => {
|
||||
deferred.resolve(gcli.lookup("breakdelRemoved"));
|
||||
}
|
||||
}, () => {
|
||||
deferred.resolve(gcli.lookup("breakNotFound"));
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
});
|
||||
@ -259,8 +244,8 @@ gcli.addCommand({
|
||||
description: gcli.lookup("dbgOpen"),
|
||||
params: [],
|
||||
exec: function(args, context) {
|
||||
return gDevTools.showToolbox(context.environment.target, "jsdebugger")
|
||||
.then(() => null);
|
||||
let target = context.environment.target;
|
||||
return gDevTools.showToolbox(target, "jsdebugger").then(() => null);
|
||||
}
|
||||
});
|
||||
|
||||
@ -272,11 +257,11 @@ gcli.addCommand({
|
||||
description: gcli.lookup("dbgClose"),
|
||||
params: [],
|
||||
exec: function(args, context) {
|
||||
if (!getPanel(context, "jsdebugger"))
|
||||
if (!getPanel(context, "jsdebugger")) {
|
||||
return;
|
||||
|
||||
return gDevTools.closeToolbox(context.environment.target)
|
||||
.then(() => null);
|
||||
}
|
||||
let target = context.environment.target;
|
||||
return gDevTools.closeToolbox(target).then(() => null);
|
||||
}
|
||||
});
|
||||
|
||||
@ -404,17 +389,18 @@ gcli.addCommand({
|
||||
returnType: "dom",
|
||||
exec: function(args, context) {
|
||||
let dbg = getPanel(context, "jsdebugger");
|
||||
let doc = context.environment.chromeDocument;
|
||||
if (!dbg) {
|
||||
return gcli.lookup("debuggerClosed");
|
||||
}
|
||||
|
||||
let sources = dbg._view.Sources.values;
|
||||
let doc = context.environment.chromeDocument;
|
||||
let div = createXHTMLElement(doc, "div");
|
||||
let ol = createXHTMLElement(doc, "ol");
|
||||
sources.forEach(function(src) {
|
||||
|
||||
sources.forEach(source => {
|
||||
let li = createXHTMLElement(doc, "li");
|
||||
li.textContent = src;
|
||||
li.textContent = source;
|
||||
ol.appendChild(li);
|
||||
});
|
||||
div.appendChild(ol);
|
||||
@ -437,8 +423,8 @@ gcli.addCommand({
|
||||
clientMethod: "unblackBox",
|
||||
l10nPrefix: "dbgUnBlackBox"
|
||||
}
|
||||
].forEach(function (cmd) {
|
||||
const lookup = function (id) {
|
||||
].forEach(function(cmd) {
|
||||
const lookup = function(id) {
|
||||
return gcli.lookup(cmd.l10nPrefix + id);
|
||||
};
|
||||
|
||||
@ -450,11 +436,12 @@ gcli.addCommand({
|
||||
name: "source",
|
||||
type: {
|
||||
name: "selection",
|
||||
data: function (context) {
|
||||
data: function(context) {
|
||||
let dbg = getPanel(context, "jsdebugger");
|
||||
return dbg
|
||||
? [s for (s of dbg._view.Sources.values)]
|
||||
: [];
|
||||
if (dbg) {
|
||||
return dbg._view.Sources.values;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
},
|
||||
description: lookup("SourceDesc"),
|
||||
@ -473,7 +460,7 @@ gcli.addCommand({
|
||||
}
|
||||
],
|
||||
returnType: "dom",
|
||||
exec: function (args, context) {
|
||||
exec: function(args, context) {
|
||||
const dbg = getPanel(context, "jsdebugger");
|
||||
const doc = context.environment.chromeDocument;
|
||||
if (!dbg) {
|
||||
@ -482,9 +469,7 @@ gcli.addCommand({
|
||||
|
||||
const { promise, resolve, reject } = context.defer();
|
||||
const { activeThread } = dbg._controller;
|
||||
const globRegExp = args.glob
|
||||
? globToRegExp(args.glob)
|
||||
: null;
|
||||
const globRegExp = args.glob ? globToRegExp(args.glob) : null;
|
||||
|
||||
// Filter the sources down to those that we will need to black box.
|
||||
|
||||
@ -512,12 +497,11 @@ gcli.addCommand({
|
||||
const blackBoxed = [];
|
||||
|
||||
for (let source of toBlackBox) {
|
||||
let { url } = source;
|
||||
activeThread.source(source)[cmd.clientMethod](function ({ error }) {
|
||||
activeThread.source(source)[cmd.clientMethod](function({ error }) {
|
||||
if (error) {
|
||||
blackBoxed.push(lookup("ErrorDesc") + " " + url);
|
||||
blackBoxed.push(lookup("ErrorDesc") + " " + source.url);
|
||||
} else {
|
||||
blackBoxed.push(url);
|
||||
blackBoxed.push(source.url);
|
||||
}
|
||||
|
||||
if (toBlackBox.length === blackBoxed.length) {
|
||||
@ -531,8 +515,10 @@ gcli.addCommand({
|
||||
function displayResults() {
|
||||
const results = doc.createElement("div");
|
||||
results.textContent = lookup("NonEmptyDesc");
|
||||
|
||||
const list = createXHTMLElement(doc, "ul");
|
||||
results.appendChild(list);
|
||||
|
||||
for (let result of blackBoxed) {
|
||||
const item = createXHTMLElement(doc, "li");
|
||||
item.textContent = result;
|
||||
@ -547,23 +533,24 @@ gcli.addCommand({
|
||||
});
|
||||
|
||||
/**
|
||||
* A helper to create xhtml namespaced elements
|
||||
* A helper to create xhtml namespaced elements.
|
||||
*/
|
||||
function createXHTMLElement(document, tagname) {
|
||||
return document.createElementNS("http://www.w3.org/1999/xhtml", tagname);
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper to go from a command context to a debugger panel
|
||||
* A helper to go from a command context to a debugger panel.
|
||||
*/
|
||||
function getPanel(context, id, options = {}) {
|
||||
if (context == null) {
|
||||
if (!context) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let target = context.environment.target;
|
||||
if (options.ensure_opened) {
|
||||
return gDevTools.showToolbox(target, id).then(function(toolbox) {
|
||||
|
||||
if (options.ensureOpened) {
|
||||
return gDevTools.showToolbox(target, id).then(toolbox => {
|
||||
return toolbox.getPanel(id);
|
||||
});
|
||||
} else {
|
||||
@ -577,11 +564,11 @@ function getPanel(context, id, options = {}) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a glob to a regular expression
|
||||
* Converts a glob to a regular expression.
|
||||
*/
|
||||
function globToRegExp(glob) {
|
||||
const reStr = glob
|
||||
// Escape existing regular expression syntax
|
||||
// Escape existing regular expression syntax.
|
||||
.replace(/\\/g, "\\\\")
|
||||
.replace(/\//g, "\\/")
|
||||
.replace(/\^/g, "\\^")
|
||||
@ -600,7 +587,7 @@ function globToRegExp(glob) {
|
||||
.replace(/\[/g, "\\[")
|
||||
.replace(/\]/g, "\\]")
|
||||
.replace(/\-/g, "\\-")
|
||||
// Turn * into the match everything wildcard
|
||||
// Turn * into the match everything wildcard.
|
||||
.replace(/\*/g, ".*")
|
||||
return new RegExp("^" + reStr + "$");
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ this.BrowserDebuggerProcess = function BrowserDebuggerProcess(aOnClose, aOnRun)
|
||||
this._initServer();
|
||||
this._initProfile();
|
||||
this._create();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes and starts a chrome debugger process.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6,23 +6,24 @@
|
||||
"use strict";
|
||||
|
||||
const { Cc, Ci, Cu, Cr } = require("chrome");
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const promise = require("sdk/core/promise");
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
|
||||
function DebuggerPanel(iframeWindow, toolbox) {
|
||||
this.panelWin = iframeWindow;
|
||||
this._toolbox = toolbox;
|
||||
this._destroyer = null;
|
||||
|
||||
this._view = this.panelWin.DebuggerView;
|
||||
this._controller = this.panelWin.DebuggerController;
|
||||
this._controller._target = this.target;
|
||||
this._bkp = this._controller.Breakpoints;
|
||||
|
||||
this.highlightWhenPaused = this.highlightWhenPaused.bind(this);
|
||||
this.unhighlightWhenResumed = this.unhighlightWhenResumed.bind(this);
|
||||
|
||||
EventEmitter.decorate(this);
|
||||
}
|
||||
};
|
||||
|
||||
exports.DebuggerPanel = DebuggerPanel;
|
||||
|
||||
DebuggerPanel.prototype = {
|
||||
@ -32,7 +33,7 @@ DebuggerPanel.prototype = {
|
||||
* @return object
|
||||
* A promise that is resolved when the Debugger completes opening.
|
||||
*/
|
||||
open: function DebuggerPanel_open() {
|
||||
open: function() {
|
||||
let targetPromise;
|
||||
|
||||
// Local debugging needs to make the target remote.
|
||||
@ -54,40 +55,41 @@ DebuggerPanel.prototype = {
|
||||
})
|
||||
.then(null, function onError(aReason) {
|
||||
Cu.reportError("DebuggerPanel open failed. " +
|
||||
reason.error + ": " + reason.message);
|
||||
aReason.error + ": " + aReason.message);
|
||||
});
|
||||
},
|
||||
|
||||
// DevToolPanel API
|
||||
|
||||
get target() this._toolbox.target,
|
||||
|
||||
destroy: function() {
|
||||
// Make sure this panel is not already destroyed.
|
||||
if (this._destroyer) {
|
||||
return this._destroyer;
|
||||
}
|
||||
|
||||
this.target.off("thread-paused", this.highlightWhenPaused);
|
||||
this.target.off("thread-resumed", this.unhighlightWhenResumed);
|
||||
this.emit("destroyed");
|
||||
return promise.resolve(null);
|
||||
|
||||
return this._destroyer = this._controller.shutdownDebugger().then(() => {
|
||||
this.emit("destroyed");
|
||||
});
|
||||
},
|
||||
|
||||
// DebuggerPanel API
|
||||
|
||||
addBreakpoint: function() {
|
||||
this._bkp.addBreakpoint.apply(this._bkp, arguments);
|
||||
addBreakpoint: function(aLocation, aOptions) {
|
||||
return this._controller.Breakpoints.addBreakpoint(aLocation, aOptions);
|
||||
},
|
||||
|
||||
removeBreakpoint: function() {
|
||||
this._bkp.removeBreakpoint.apply(this._bkp, arguments);
|
||||
},
|
||||
|
||||
getBreakpoint: function() {
|
||||
return this._bkp.getBreakpoint.apply(this._bkp, arguments);
|
||||
},
|
||||
|
||||
getAllBreakpoints: function() {
|
||||
return this._bkp.store;
|
||||
removeBreakpoint: function(aLocation) {
|
||||
return this._controller.Breakpoints.removeBreakpoint(aLocation);
|
||||
},
|
||||
|
||||
highlightWhenPaused: function() {
|
||||
this._toolbox.highlightTool("jsdebugger");
|
||||
|
||||
// Also raise the toolbox window if it is undocked or select the
|
||||
// corresponding tab when toolbox is docked.
|
||||
this._toolbox.raise();
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -5,8 +5,8 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const SOURCE_URL_DEFAULT_MAX_LENGTH = 64; // chars
|
||||
const SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE = 1048576; // 1 MB in bytes
|
||||
const SOURCE_URL_DEFAULT_MAX_LENGTH = 64; // chars
|
||||
const STACK_FRAMES_SOURCE_URL_MAX_LENGTH = 15; // chars
|
||||
const STACK_FRAMES_SOURCE_URL_TRIM_SECTION = "center";
|
||||
const STACK_FRAMES_POPUP_SOURCE_URL_MAX_LENGTH = 32; // chars
|
||||
@ -18,6 +18,7 @@ const BREAKPOINT_CONDITIONAL_POPUP_OFFSET_X = 7; // px
|
||||
const BREAKPOINT_CONDITIONAL_POPUP_OFFSET_Y = -3; // px
|
||||
const RESULTS_PANEL_POPUP_POSITION = "before_end";
|
||||
const RESULTS_PANEL_MAX_RESULTS = 10;
|
||||
const FILE_SEARCH_ACTION_MAX_DELAY = 300; // ms
|
||||
const GLOBAL_SEARCH_EXPAND_MAX_RESULTS = 50;
|
||||
const GLOBAL_SEARCH_LINE_MAX_LENGTH = 300; // chars
|
||||
const GLOBAL_SEARCH_ACTION_MAX_DELAY = 1500; // ms
|
||||
@ -27,8 +28,13 @@ const SEARCH_FUNCTION_FLAG = "@";
|
||||
const SEARCH_TOKEN_FLAG = "#";
|
||||
const SEARCH_LINE_FLAG = ":";
|
||||
const SEARCH_VARIABLE_FLAG = "*";
|
||||
|
||||
Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm");
|
||||
const DEFAULT_EDITOR_CONFIG = {
|
||||
mode: SourceEditor.MODES.TEXT,
|
||||
readOnly: true,
|
||||
showLineNumbers: true,
|
||||
showAnnotationRuler: true,
|
||||
showOverviewRuler: true
|
||||
};
|
||||
|
||||
/**
|
||||
* Object defining the debugger view components.
|
||||
@ -37,14 +43,18 @@ let DebuggerView = {
|
||||
/**
|
||||
* Initializes the debugger view.
|
||||
*
|
||||
* @param function aCallback
|
||||
* Called after the view finishes initializing.
|
||||
* @return object
|
||||
* A promise that is resolved when the view finishes initializing.
|
||||
*/
|
||||
initialize: function(aCallback) {
|
||||
dumpn("Initializing the DebuggerView");
|
||||
initialize: function() {
|
||||
if (this._startup) {
|
||||
return this._startup;
|
||||
}
|
||||
|
||||
let deferred = promise.defer();
|
||||
this._startup = deferred.promise;
|
||||
|
||||
this._initializePanes();
|
||||
|
||||
this.Toolbar.initialize();
|
||||
this.Options.initialize();
|
||||
this.Filtering.initialize();
|
||||
@ -55,19 +65,25 @@ let DebuggerView = {
|
||||
this.Sources.initialize();
|
||||
this.WatchExpressions.initialize();
|
||||
this.GlobalSearch.initialize();
|
||||
|
||||
this._initializeVariablesView();
|
||||
this._initializeEditor(aCallback);
|
||||
this._initializeEditor(deferred.resolve);
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroys the debugger view.
|
||||
*
|
||||
* @param function aCallback
|
||||
* Called after the view finishes destroying.
|
||||
* @return object
|
||||
* A promise that is resolved when the view finishes destroying.
|
||||
*/
|
||||
destroy: function(aCallback) {
|
||||
dumpn("Destroying the DebuggerView");
|
||||
destroy: function() {
|
||||
if (this._shutdown) {
|
||||
return this._shutdown;
|
||||
}
|
||||
|
||||
let deferred = promise.defer();
|
||||
this._shutdown = deferred.promise;
|
||||
|
||||
this.Toolbar.destroy();
|
||||
this.Options.destroy();
|
||||
@ -79,11 +95,10 @@ let DebuggerView = {
|
||||
this.Sources.destroy();
|
||||
this.WatchExpressions.destroy();
|
||||
this.GlobalSearch.destroy();
|
||||
|
||||
this._destroyPanes();
|
||||
this._destroyEditor();
|
||||
this._destroyEditor(deferred.resolve);
|
||||
|
||||
aCallback();
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -140,10 +155,10 @@ let DebuggerView = {
|
||||
this.Variables.on("fetched", (aEvent, aType) => {
|
||||
switch (aType) {
|
||||
case "variables":
|
||||
window.dispatchEvent(document, "Debugger:FetchedVariables");
|
||||
window.emit(EVENTS.FETCHED_VARIABLES);
|
||||
break;
|
||||
case "properties":
|
||||
window.dispatchEvent(document, "Debugger:FetchedProperties");
|
||||
window.emit(EVENTS.FETCHED_PROPERTIES);
|
||||
break;
|
||||
}
|
||||
});
|
||||
@ -158,44 +173,56 @@ let DebuggerView = {
|
||||
_initializeEditor: function(aCallback) {
|
||||
dumpn("Initializing the DebuggerView editor");
|
||||
|
||||
let placeholder = document.getElementById("editor");
|
||||
let config = {
|
||||
mode: SourceEditor.MODES.JAVASCRIPT,
|
||||
readOnly: true,
|
||||
showLineNumbers: true,
|
||||
showAnnotationRuler: true,
|
||||
showOverviewRuler: true
|
||||
};
|
||||
|
||||
this.editor = new SourceEditor();
|
||||
this.editor.init(placeholder, config, () => {
|
||||
this.editor.init(document.getElementById("editor"), DEFAULT_EDITOR_CONFIG, () => {
|
||||
this._loadingText = L10N.getStr("loadingText");
|
||||
this._onEditorLoad();
|
||||
aCallback();
|
||||
this._onEditorLoad(aCallback);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* The load event handler for the source editor, also executing any necessary
|
||||
* post-load operations.
|
||||
*
|
||||
* @param function aCallback
|
||||
* Called after the editor finishes loading.
|
||||
*/
|
||||
_onEditorLoad: function() {
|
||||
_onEditorLoad: function(aCallback) {
|
||||
dumpn("Finished loading the DebuggerView editor");
|
||||
|
||||
DebuggerController.Breakpoints.initialize();
|
||||
window.dispatchEvent(document, "Debugger:EditorLoaded", this.editor);
|
||||
this.editor.focus();
|
||||
DebuggerController.Breakpoints.initialize().then(() => {
|
||||
window.emit(EVENTS.EDITOR_LOADED, this.editor);
|
||||
aCallback();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroys the SourceEditor instance and also executes any necessary
|
||||
* post-unload operations.
|
||||
*
|
||||
* @param function aCallback
|
||||
* Called after the editor finishes destroying.
|
||||
*/
|
||||
_destroyEditor: function() {
|
||||
_destroyEditor: function(aCallback) {
|
||||
dumpn("Destroying the DebuggerView editor");
|
||||
|
||||
DebuggerController.Breakpoints.destroy();
|
||||
window.dispatchEvent(document, "Debugger:EditorUnloaded", this.editor);
|
||||
DebuggerController.Breakpoints.destroy().then(() => {
|
||||
window.emit(EVENTS.EDITOR_UNLOADED, this.editor);
|
||||
aCallback();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the currently displayed text contents in the source editor.
|
||||
* This resets the mode and undo stack.
|
||||
*
|
||||
* @param string aTextContent
|
||||
* The source text content.
|
||||
*/
|
||||
_setEditorText: function(aTextContent = "") {
|
||||
this.editor.setMode(SourceEditor.MODES.TEXT);
|
||||
this.editor.setText(aTextContent);
|
||||
this.editor.resetUndo();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -209,7 +236,7 @@ let DebuggerView = {
|
||||
* @param string aTextContent [optional]
|
||||
* The source text content.
|
||||
*/
|
||||
setEditorMode: function(aUrl, aContentType = "", aTextContent = "") {
|
||||
_setEditorMode: function(aUrl, aContentType = "", aTextContent = "") {
|
||||
// Avoid setting the editor mode for very large files.
|
||||
if (aTextContent.length >= SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE) {
|
||||
this.editor.setMode(SourceEditor.MODES.TEXT);
|
||||
@ -239,144 +266,123 @@ let DebuggerView = {
|
||||
/**
|
||||
* Sets the currently displayed source text in the editor.
|
||||
*
|
||||
* To update the source editor's current caret and debug location based on
|
||||
* a requested url and line, use the DebuggerView.updateEditor method.
|
||||
* You should use DebuggerView.updateEditor instead. It updates the current
|
||||
* caret and debug location based on a requested url and line.
|
||||
*
|
||||
* @param object aSource
|
||||
* The source object coming from the active thread.
|
||||
* @return object
|
||||
* A promise that is resolved after the source text has been set.
|
||||
*/
|
||||
set editorSource(aSource) {
|
||||
if (!this._isInitialized || this._isDestroyed || this._editorSource == aSource) {
|
||||
return;
|
||||
_setEditorSource: function(aSource) {
|
||||
// Avoid setting the same source text in the editor again.
|
||||
if (this._editorSource.url == aSource.url) {
|
||||
return this._editorSource.promise;
|
||||
}
|
||||
|
||||
dumpn("Setting the DebuggerView editor source: " + aSource.url +
|
||||
", fetched: " + !!aSource._fetched);
|
||||
let deferred = promise.defer();
|
||||
|
||||
this.editor.setMode(SourceEditor.MODES.TEXT);
|
||||
this.editor.setText(L10N.getStr("loadingText"));
|
||||
this.editor.resetUndo();
|
||||
this._editorSource = aSource;
|
||||
this._setEditorText(L10N.getStr("loadingText"));
|
||||
this._editorSource = { url: aSource.url, promise: deferred.promise };
|
||||
|
||||
DebuggerController.SourceScripts.getTextForSource(aSource).then(([, aText]) => {
|
||||
// Avoid setting an unexpected source. This may happen when fast switching
|
||||
// between sources that haven't been fetched yet.
|
||||
if (this._editorSource != aSource) {
|
||||
DebuggerController.SourceScripts.getText(aSource).then(([, aText]) => {
|
||||
// Avoid setting an unexpected source. This may happen when switching
|
||||
// very fast between sources that haven't been fetched yet.
|
||||
if (this._editorSource.url != aSource.url) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.editor.setText(aText);
|
||||
this.editor.resetUndo();
|
||||
this.setEditorMode(aSource.url, aSource.contentType, aText);
|
||||
|
||||
// Update the editor's current caret and debug locations given by the
|
||||
// currently active frame in the stack, if there's one available.
|
||||
this.updateEditor();
|
||||
this._setEditorText(aText);
|
||||
this._setEditorMode(aSource.url, aSource.contentType, aText);
|
||||
|
||||
// Synchronize any other components with the currently displayed source.
|
||||
DebuggerView.Sources.selectedValue = aSource.url;
|
||||
DebuggerController.Breakpoints.updateEditorBreakpoints();
|
||||
|
||||
// Notify that we've shown a source file.
|
||||
window.dispatchEvent(document, "Debugger:SourceShown", aSource);
|
||||
// Resolve and notify that a source file was shown.
|
||||
window.emit(EVENTS.SOURCE_SHOWN, aSource);
|
||||
deferred.resolve([aSource, aText]);
|
||||
},
|
||||
([, aError]) => {
|
||||
// Rejected.
|
||||
let msg = L10N.getStr("errorLoadingText") + DevToolsUtils.safeErrorString(aError);
|
||||
this.editor.setText(msg);
|
||||
window.dispatchEvent(document, "Debugger:SourceErrorShown", aError);
|
||||
dumpn(msg);
|
||||
this._setEditorText(msg);
|
||||
Cu.reportError(msg);
|
||||
dumpn(msg);
|
||||
|
||||
// Reject and notify that there was an error showing the source file.
|
||||
window.emit(EVENTS.SOURCE_ERROR_SHOWN, aSource);
|
||||
deferred.reject([aSource, aError]);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the currently displayed source text in the editor.
|
||||
*
|
||||
* @return object
|
||||
* The source object coming from the active thread.
|
||||
*/
|
||||
get editorSource() this._editorSource,
|
||||
|
||||
/**
|
||||
* Update the source editor's current caret and debug location based on
|
||||
* a requested url and line. If unspecified, they default to the location
|
||||
* given by the currently active frame in the stack.
|
||||
* a requested url and line.
|
||||
*
|
||||
* @param string aUrl [optional]
|
||||
* @param string aUrl
|
||||
* The target source url.
|
||||
* @param number aLine [optional]
|
||||
* The target line number in the source.
|
||||
* The target line in the source.
|
||||
* @param object aFlags [optional]
|
||||
* Additional options for showing the source. Supported options:
|
||||
* - charOffset: character offset for the caret or debug location
|
||||
* - lineOffset: line offset for the caret or debug location
|
||||
* - columnOffset: column offset for the caret or debug location
|
||||
* - noSwitch: don't switch to the source if not currently selected
|
||||
* - noCaret: don't set the caret location at the specified line
|
||||
* - noDebug: don't set the debug location at the specified line
|
||||
* @return object
|
||||
* A promise that is resolved after the source text has been set.
|
||||
*/
|
||||
updateEditor: function(aUrl, aLine, aFlags = {}) {
|
||||
if (!this._isInitialized || this._isDestroyed) {
|
||||
return;
|
||||
setEditorLocation: function(aUrl, aLine = 0, aFlags = {}) {
|
||||
// Avoid trying to set a source for a url that isn't known yet.
|
||||
if (!this.Sources.containsValue(aUrl)) {
|
||||
return promise.reject(new Error("Unknown source for the specified URL."));
|
||||
}
|
||||
// If the location is not specified, default to the location given by
|
||||
// the currently active frame in the stack.
|
||||
if (!aUrl && !aLine) {
|
||||
// If the line is not specified, default to the current frame's position,
|
||||
// if available and the frame's url corresponds to the requested url.
|
||||
if (!aLine) {
|
||||
let cachedFrames = DebuggerController.activeThread.cachedFrames;
|
||||
let currentFrame = DebuggerController.StackFrames.currentFrame;
|
||||
let frame = cachedFrames[currentFrame];
|
||||
if (frame) {
|
||||
let { url, line } = frame.where;
|
||||
this.updateEditor(url, line, { noSwitch: true });
|
||||
let currentDepth = DebuggerController.StackFrames.currentFrameDepth;
|
||||
let frame = cachedFrames[currentDepth];
|
||||
if (frame && frame.where.url == aUrl) {
|
||||
aLine = frame.where.line;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
dumpn("Updating the DebuggerView editor: " + aUrl + " @ " + aLine +
|
||||
", flags: " + aFlags.toSource());
|
||||
let sourceItem = this.Sources.getItemByValue(aUrl);
|
||||
let sourceForm = sourceItem.attachment.source;
|
||||
|
||||
// If the currently displayed source is the requested one, update.
|
||||
if (this.Sources.selectedValue == aUrl) {
|
||||
set(aLine);
|
||||
}
|
||||
// If the requested source exists, display it and update.
|
||||
else if (this.Sources.containsValue(aUrl) && !aFlags.noSwitch) {
|
||||
this.Sources.selectedValue = aUrl;
|
||||
set(aLine);
|
||||
}
|
||||
// Dumb request, invalidate the caret position and debug location.
|
||||
else {
|
||||
set(0);
|
||||
}
|
||||
|
||||
// Updates the source editor's caret position and debug location.
|
||||
// @param number a Line
|
||||
function set(aLine) {
|
||||
let editor = DebuggerView.editor;
|
||||
|
||||
// Handle any additional options for showing the source.
|
||||
// Make sure the requested source client is shown in the editor, then
|
||||
// update the source editor's caret position and debug location.
|
||||
return this._setEditorSource(sourceForm).then(() => {
|
||||
// Line numbers in the source editor should start from 1. If invalid
|
||||
// or not specified, then don't do anything.
|
||||
if (aLine < 1) {
|
||||
return;
|
||||
}
|
||||
if (aFlags.charOffset) {
|
||||
aLine += editor.getLineAtOffset(aFlags.charOffset);
|
||||
aLine += this.editor.getLineAtOffset(aFlags.charOffset);
|
||||
}
|
||||
if (aFlags.lineOffset) {
|
||||
aLine += aFlags.lineOffset;
|
||||
}
|
||||
if (!aFlags.noCaret) {
|
||||
editor.setCaretPosition(aLine - 1, aFlags.columnOffset);
|
||||
this.editor.setCaretPosition(aLine - 1, aFlags.columnOffset);
|
||||
}
|
||||
if (!aFlags.noDebug) {
|
||||
editor.setDebugLocation(aLine - 1, aFlags.columnOffset);
|
||||
this.editor.setDebugLocation(aLine - 1, aFlags.columnOffset);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the text in the source editor's specified line.
|
||||
*
|
||||
* @param number aLine [optional]
|
||||
* The line to get the text from.
|
||||
* If unspecified, it defaults to the current caret position line.
|
||||
* The line to get the text from. If unspecified, it defaults to
|
||||
* the current caret position.
|
||||
* @return string
|
||||
* The specified line's text.
|
||||
*/
|
||||
@ -387,17 +393,6 @@ let DebuggerView = {
|
||||
return this.editor.getText(start, end);
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the text in the source editor's selection bounds.
|
||||
*
|
||||
* @return string
|
||||
* The selected text.
|
||||
*/
|
||||
getEditorSelectionText: function() {
|
||||
let selection = this.editor.getSelection();
|
||||
return this.editor.getText(selection.start, selection.end);
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the visibility state of the instruments pane.
|
||||
* @return boolean
|
||||
@ -461,12 +456,15 @@ let DebuggerView = {
|
||||
this.Variables.empty();
|
||||
|
||||
if (this.editor) {
|
||||
this.editor.setMode(SourceEditor.MODES.TEXT);
|
||||
this.editor.setText("");
|
||||
this.editor.focus();
|
||||
this._editorSource = null;
|
||||
this.editor.resetUndo();
|
||||
this._editorSource = {};
|
||||
}
|
||||
},
|
||||
|
||||
_startup: null,
|
||||
_shutdown: null,
|
||||
Toolbar: null,
|
||||
Options: null,
|
||||
Filtering: null,
|
||||
@ -478,16 +476,14 @@ let DebuggerView = {
|
||||
Sources: null,
|
||||
Variables: null,
|
||||
WatchExpressions: null,
|
||||
_editor: null,
|
||||
_editorSource: null,
|
||||
editor: null,
|
||||
_editorSource: {},
|
||||
_loadingText: "",
|
||||
_sourcesPane: null,
|
||||
_instrumentsPane: null,
|
||||
_instrumentsPaneToggleButton: null,
|
||||
_collapsePaneString: "",
|
||||
_expandPaneString: "",
|
||||
_isInitialized: false,
|
||||
_isDestroyed: false
|
||||
};
|
||||
|
||||
/**
|
||||
@ -760,10 +756,11 @@ ResultsPanelContainer.prototype = Heritage.extend(WidgetMethods, {
|
||||
*/
|
||||
set hidden(aFlag) {
|
||||
if (aFlag) {
|
||||
this._panel.hidden = true;
|
||||
this._panel.hidePopup();
|
||||
} else {
|
||||
this._panel.hidden = false;
|
||||
this._panel.openPopup(this._anchor, this.position, this.left, this.top);
|
||||
this.anchor.focus();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
MOCHITEST_BROWSER_TESTS = \
|
||||
browser_dbg_aaa_run_first_leaktest.js \
|
||||
browser_dbg_bfcache.js \
|
||||
browser_dbg_blackboxing-01.js \
|
||||
browser_dbg_blackboxing-02.js \
|
||||
browser_dbg_blackboxing-03.js \
|
||||
@ -11,167 +12,172 @@ MOCHITEST_BROWSER_TESTS = \
|
||||
browser_dbg_blackboxing-05.js \
|
||||
browser_dbg_blackboxing-06.js \
|
||||
browser_dbg_blackboxing-07.js \
|
||||
browser_dbg_breadcrumbs-access.js \
|
||||
browser_dbg_breakpoints-actual-location.js \
|
||||
browser_dbg_breakpoints-contextmenu.js \
|
||||
browser_dbg_breakpoints-editor.js \
|
||||
browser_dbg_breakpoints-highlight.js \
|
||||
browser_dbg_breakpoints-new-script.js \
|
||||
browser_dbg_breakpoints-pane.js \
|
||||
browser_dbg_chrome-debugging.js \
|
||||
browser_dbg_clean-exit.js \
|
||||
browser_dbg_cmd.js \
|
||||
browser_dbg_cmd_blackbox.js \
|
||||
browser_dbg_cmd_break.js \
|
||||
browser_dbg_debuggerstatement.js \
|
||||
browser_dbg_cmd-blackbox.js \
|
||||
browser_dbg_cmd-break.js \
|
||||
browser_dbg_cmd-dbg.js \
|
||||
browser_dbg_conditional-breakpoints-01.js \
|
||||
browser_dbg_conditional-breakpoints-02.js \
|
||||
browser_dbg_debugger-statement.js \
|
||||
browser_dbg_editor-contextmenu.js \
|
||||
browser_dbg_editor-mode.js \
|
||||
browser_dbg_function-display-name.js \
|
||||
browser_dbg_globalactor.js \
|
||||
browser_dbg_iframes.js \
|
||||
browser_dbg_instruments-pane-collapse.js \
|
||||
browser_dbg_listaddons.js \
|
||||
browser_dbg_listtabs-01.js \
|
||||
browser_dbg_listtabs-02.js \
|
||||
browser_dbg_tabactor-01.js \
|
||||
browser_dbg_tabactor-02.js \
|
||||
browser_dbg_globalactor-01.js \
|
||||
browser_dbg_nav-01.js \
|
||||
browser_dbg_propertyview-01.js \
|
||||
browser_dbg_propertyview-02.js \
|
||||
browser_dbg_propertyview-03.js \
|
||||
browser_dbg_propertyview-04.js \
|
||||
browser_dbg_propertyview-05.js \
|
||||
browser_dbg_propertyview-06.js \
|
||||
browser_dbg_propertyview-07.js \
|
||||
browser_dbg_propertyview-08.js \
|
||||
browser_dbg_propertyview-09.js \
|
||||
browser_dbg_propertyview-10.js \
|
||||
browser_dbg_propertyview-11.js \
|
||||
browser_dbg_propertyview-12.js \
|
||||
browser_dbg_propertyview-edit-value.js \
|
||||
browser_dbg_propertyview-edit-watch.js \
|
||||
browser_dbg_propertyview-data-big.js \
|
||||
browser_dbg_propertyview-data-getset-01.js \
|
||||
browser_dbg_propertyview-data-getset-02.js \
|
||||
browser_dbg_propertyview-data.js \
|
||||
browser_dbg_propertyview-filter-01.js \
|
||||
browser_dbg_propertyview-filter-02.js \
|
||||
browser_dbg_propertyview-filter-03.js \
|
||||
browser_dbg_propertyview-filter-04.js \
|
||||
browser_dbg_propertyview-filter-05.js \
|
||||
browser_dbg_propertyview-filter-06.js \
|
||||
browser_dbg_propertyview-filter-07.js \
|
||||
browser_dbg_propertyview-filter-08.js \
|
||||
browser_dbg_propertyview-reexpand.js \
|
||||
$(filter disabled-temporarily--bug-782179, browser_dbg_reload-same-script.js) \
|
||||
browser_dbg_reload-preferred-script.js \
|
||||
browser_dbg_pane-collapse.js \
|
||||
browser_dbg_panesize-inner.js \
|
||||
browser_dbg_breadcrumbs-access.js \
|
||||
browser_dbg_location-changes-01-simple.js \
|
||||
browser_dbg_location-changes-02-blank.js \
|
||||
browser_dbg_location-changes-03-new.js \
|
||||
browser_dbg_location-changes-04-breakpoint.js \
|
||||
browser_dbg_multiple-windows.js \
|
||||
browser_dbg_navigation.js \
|
||||
browser_dbg_on-pause-highlight.js \
|
||||
browser_dbg_panel-size.js \
|
||||
browser_dbg_pause-exceptions-01.js \
|
||||
browser_dbg_pause-exceptions-02.js \
|
||||
browser_dbg_pause-resume.js \
|
||||
browser_dbg_pause-warning.js \
|
||||
browser_dbg_progress-listener-bug.js \
|
||||
browser_dbg_reload-preferred-script-01.js \
|
||||
browser_dbg_reload-preferred-script-02.js \
|
||||
browser_dbg_reload-preferred-script-03.js \
|
||||
browser_dbg_reload-same-script.js \
|
||||
browser_dbg_scripts-switching-01.js \
|
||||
browser_dbg_scripts-switching-02.js \
|
||||
browser_dbg_scripts-switching-03.js \
|
||||
browser_dbg_search-basic-01.js \
|
||||
browser_dbg_search-basic-02.js \
|
||||
browser_dbg_search-basic-03.js \
|
||||
browser_dbg_search-basic-04.js \
|
||||
browser_dbg_search-global-01.js \
|
||||
browser_dbg_search-global-02.js \
|
||||
browser_dbg_search-global-03.js \
|
||||
browser_dbg_search-global-04.js \
|
||||
browser_dbg_search-global-05.js \
|
||||
browser_dbg_search-global-06.js \
|
||||
browser_dbg_search-sources-01.js \
|
||||
browser_dbg_search-sources-02.js \
|
||||
browser_dbg_search-sources-03.js \
|
||||
browser_dbg_search-symbols.js \
|
||||
browser_dbg_searchbox-help-popup-01.js \
|
||||
browser_dbg_searchbox-help-popup-02.js \
|
||||
browser_dbg_searchbox-parse.js \
|
||||
browser_dbg_source-maps-01.js \
|
||||
browser_dbg_source-maps-02.js \
|
||||
browser_dbg_source-maps-03.js \
|
||||
browser_dbg_sources-cache.js \
|
||||
browser_dbg_sources-labels.js \
|
||||
browser_dbg_sources-sorting.js \
|
||||
browser_dbg_stack-01.js \
|
||||
browser_dbg_stack-02.js \
|
||||
browser_dbg_stack-03.js \
|
||||
browser_dbg_stack-04.js \
|
||||
browser_dbg_stack-05.js \
|
||||
browser_dbg_location-changes.js \
|
||||
browser_dbg_location-changes-new.js \
|
||||
browser_dbg_location-changes-blank.js \
|
||||
browser_dbg_location-changes-bp.js \
|
||||
browser_dbg_sources-cache.js \
|
||||
browser_dbg_scripts-switching.js \
|
||||
browser_dbg_scripts-switching-02.js \
|
||||
browser_dbg_scripts-switching-03.js \
|
||||
browser_dbg_scripts-sorting.js \
|
||||
browser_dbg_scripts-searching-01.js \
|
||||
browser_dbg_scripts-searching-02.js \
|
||||
browser_dbg_scripts-searching-03.js \
|
||||
browser_dbg_scripts-searching-04.js \
|
||||
browser_dbg_scripts-searching-05.js \
|
||||
browser_dbg_scripts-searching-06.js \
|
||||
browser_dbg_scripts-searching-07.js \
|
||||
browser_dbg_scripts-searching-08.js \
|
||||
browser_dbg_scripts-searching-files_ui.js \
|
||||
browser_dbg_scripts-searching-popup.js \
|
||||
browser_dbg_function-search.js \
|
||||
browser_dbg_pause-resume.js \
|
||||
browser_dbg_pause-warning.js \
|
||||
browser_dbg_update-editor-mode.js \
|
||||
browser_dbg_select-line.js \
|
||||
browser_dbg_breakpoint-new-script.js \
|
||||
browser_dbg_bug723069_editor-breakpoints.js \
|
||||
browser_dbg_bug723071_editor-breakpoints-pane.js \
|
||||
browser_dbg_bug723071_editor-breakpoints-highlight.js \
|
||||
browser_dbg_bug723071_editor-breakpoints-contextmenu.js \
|
||||
browser_dbg_bug740825_conditional-breakpoints-01.js \
|
||||
browser_dbg_bug740825_conditional-breakpoints-02.js \
|
||||
browser_dbg_bug727429_watch-expressions-01.js \
|
||||
browser_dbg_bug727429_watch-expressions-02.js \
|
||||
browser_dbg_bug731394_editor-contextmenu.js \
|
||||
browser_dbg_bug737803_editor_actual_location.js \
|
||||
browser_dbg_bug786070_hide_nonenums.js \
|
||||
browser_dbg_bug868163_highight_on_pause.js \
|
||||
browser_dbg_displayName.js \
|
||||
browser_dbg_pause-exceptions.js \
|
||||
browser_dbg_pause-exceptions-reload.js \
|
||||
browser_dbg_multiple-windows.js \
|
||||
browser_dbg_iframes.js \
|
||||
browser_dbg_bfcache.js \
|
||||
browser_dbg_progress-listener-bug.js \
|
||||
browser_dbg_chrome-debugging.js \
|
||||
browser_dbg_source_maps-01.js \
|
||||
browser_dbg_source_maps-02.js \
|
||||
browser_dbg_source_maps-03.js \
|
||||
browser_dbg_stack-06.js \
|
||||
browser_dbg_step-out.js \
|
||||
browser_dbg_event-listeners.js \
|
||||
browser_dbg_tabactor-01.js \
|
||||
browser_dbg_tabactor-02.js \
|
||||
browser_dbg_variables-view-01.js \
|
||||
browser_dbg_variables-view-02.js \
|
||||
browser_dbg_variables-view-03.js \
|
||||
browser_dbg_variables-view-04.js \
|
||||
browser_dbg_variables-view-05.js \
|
||||
browser_dbg_variables-view-accessibility.js \
|
||||
browser_dbg_variables-view-data.js \
|
||||
browser_dbg_variables-view-edit-getset-01.js \
|
||||
browser_dbg_variables-view-edit-getset-02.js \
|
||||
browser_dbg_variables-view-edit-value.js \
|
||||
browser_dbg_variables-view-edit-watch.js \
|
||||
browser_dbg_variables-view-filter-01.js \
|
||||
browser_dbg_variables-view-filter-02.js \
|
||||
browser_dbg_variables-view-filter-03.js \
|
||||
browser_dbg_variables-view-filter-04.js \
|
||||
browser_dbg_variables-view-filter-05.js \
|
||||
browser_dbg_variables-view-filter-pref.js \
|
||||
browser_dbg_variables-view-filter-searchbox.js \
|
||||
browser_dbg_variables-view-frame-parameters-01.js \
|
||||
browser_dbg_variables-view-frame-parameters-02.js \
|
||||
browser_dbg_variables-view-frame-parameters-03.js \
|
||||
browser_dbg_variables-view-frame-with.js \
|
||||
browser_dbg_variables-view-frozen-sealed-nonext.js \
|
||||
browser_dbg_variables-view-hide-non-enums.js \
|
||||
browser_dbg_variables-view-large-array-buffer.js \
|
||||
browser_dbg_variables-view-reexpand-01.js \
|
||||
browser_dbg_variables-view-reexpand-02.js \
|
||||
browser_dbg_variables-view-webidl.js \
|
||||
browser_dbg_watch-expressions-01.js \
|
||||
browser_dbg_watch-expressions-02.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
MOCHITEST_BROWSER_PAGES = \
|
||||
browser_dbg_blackboxing.html \
|
||||
blackboxing_blackboxme.js \
|
||||
blackboxing_one.js \
|
||||
blackboxing_two.js \
|
||||
blackboxing_three.js \
|
||||
browser_dbg_cmd_break.html \
|
||||
browser_dbg_cmd.html \
|
||||
doc_binary_search.html \
|
||||
doc_blackboxing.html \
|
||||
doc_cmd-break.html \
|
||||
doc_cmd-dbg.html \
|
||||
doc_conditional-breakpoints.html \
|
||||
doc_editor-mode.html \
|
||||
doc_empty-tab-01.html \
|
||||
doc_empty-tab-02.html \
|
||||
doc_event-listeners.html \
|
||||
doc_frame-parameters.html \
|
||||
doc_function-display-name.html \
|
||||
doc_function-search.html \
|
||||
doc_iframes.html \
|
||||
doc_included-script.html \
|
||||
doc_inline-debugger-statement.html \
|
||||
doc_inline-script.html \
|
||||
doc_large-array-buffer.html \
|
||||
doc_minified.html \
|
||||
doc_pause-exceptions.html \
|
||||
doc_recursion-stack.html \
|
||||
doc_script-switching-01.html \
|
||||
doc_script-switching-02.html \
|
||||
doc_step-out.html \
|
||||
doc_watch-expressions.html \
|
||||
doc_with-frame.html \
|
||||
code_binary_search.coffee \
|
||||
code_binary_search.js \
|
||||
code_binary_search.map \
|
||||
code_blackboxing_blackboxme.js \
|
||||
code_blackboxing_one.js \
|
||||
code_blackboxing_two.js \
|
||||
code_blackboxing_three.js \
|
||||
code_function-search-01.js \
|
||||
code_function-search-02.js \
|
||||
code_function-search-03.js \
|
||||
code_location-changes.js \
|
||||
code_math.js \
|
||||
code_math.map \
|
||||
code_math.min.js \
|
||||
code_script-switching-01.js \
|
||||
code_script-switching-02.js \
|
||||
code_test-editor-mode \
|
||||
testactors.js \
|
||||
browser_dbg_tab1.html \
|
||||
browser_dbg_tab2.html \
|
||||
browser_dbg_addon1.xpi \
|
||||
browser_dbg_addon2.xpi \
|
||||
browser_dbg_debuggerstatement.html \
|
||||
browser_dbg_stack.html \
|
||||
browser_dbg_script-switching.html \
|
||||
browser_dbg_script-switching-02.html \
|
||||
test-script-switching-01.js \
|
||||
test-script-switching-02.js \
|
||||
browser_dbg_big-data.html \
|
||||
browser_dbg_frame-parameters.html \
|
||||
browser_dbg_update-editor-mode.html \
|
||||
test-editor-mode \
|
||||
browser_dbg_displayName.html \
|
||||
browser_dbg_iframes.html \
|
||||
browser_dbg_with-frame.html \
|
||||
browser_dbg_pause-exceptions.html \
|
||||
browser_dbg_breakpoint-new-script.html \
|
||||
browser_dbg_conditional-breakpoints.html \
|
||||
browser_dbg_watch-expressions.html \
|
||||
browser_dbg_function-search-01.html \
|
||||
browser_dbg_function-search-02.html \
|
||||
test-function-search-01.js \
|
||||
test-function-search-02.js \
|
||||
test-function-search-03.js \
|
||||
binary_search.html \
|
||||
binary_search.coffee \
|
||||
binary_search.js \
|
||||
binary_search.map \
|
||||
math.js \
|
||||
math.min.js \
|
||||
math.map \
|
||||
minified.html \
|
||||
test-location-changes-bp.js \
|
||||
test-location-changes-bp.html \
|
||||
test-step-out.html \
|
||||
test-pause-exceptions-reload.html \
|
||||
test-event-listeners.html \
|
||||
addon1.xpi \
|
||||
addon2.xpi \
|
||||
$(NULL)
|
||||
|
||||
# Bug 888811 & bug 891176:
|
||||
# Disable browser_dbg_bug883220_raise_on_pause.js due to frequent failures
|
||||
# Disable browser_dbg_on-pause-raise.js due to frequent failures
|
||||
# Bug 847558:
|
||||
# Disable browser_dbg_chrome-create.js to fix Ubuntu hangs
|
||||
ifneq (Linux,$(OS_ARCH))
|
||||
MOCHITEST_BROWSER_TESTS += \
|
||||
browser_dbg_bug883220_raise_on_pause.js \
|
||||
browser_dbg_createChrome.js \
|
||||
browser_dbg_chrome-create.js \
|
||||
browser_dbg_on-pause-raise.js \
|
||||
$(NULL)
|
||||
else
|
||||
$(browser_dbg_createChrome.js disabled to fix for ubuntu hangs, bug 847558)
|
||||
endif
|
||||
|
||||
# Bug 895426:
|
||||
@ -179,6 +185,7 @@ endif
|
||||
ifneq (Darwin,$(OS_ARCH))
|
||||
MOCHITEST_BROWSER_TESTS += \
|
||||
browser_dbg_break-on-dom-event.js \
|
||||
browser_dbg_event-listeners.js \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<title>Browser Debugger Source Map Test</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="text/javascript" src="binary_search.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
function one() { two(); }
|
@ -1 +0,0 @@
|
||||
function three() { doDebuggerStatement(); }
|
@ -1 +0,0 @@
|
||||
function two() { three(); }
|
@ -2,72 +2,27 @@
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* This tests if the debugger leaks.
|
||||
* This tests if the debugger leaks on initialization and sudden destruction.
|
||||
* You can also use this initialization format as a template for other tests.
|
||||
* If leaks happen here, there's something very, very fishy going on.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
|
||||
|
||||
let gPane = null;
|
||||
let gTab = null;
|
||||
let gDebuggee = null;
|
||||
let gDebugger = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
// Wait longer for this very simple test that comes first, to make sure that
|
||||
// GC from previous tests does not interfere with the debugger suite.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
resumed = true;
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
ok(aTab, "Should have a tab available.");
|
||||
ok(aDebuggee, "Should have a debuggee available.");
|
||||
ok(aPanel, "Should have a debugger pane available.");
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", onScriptShown);
|
||||
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
framesAdded = true;
|
||||
executeSoon(startTest);
|
||||
waitForSourceAndCaretAndScopes(aPanel, "-02.js", 6).then(() => {
|
||||
resumeDebuggerThenCloseAndFinish(aPanel);
|
||||
});
|
||||
|
||||
executeSoon(function() {
|
||||
gDebuggee.firstCall();
|
||||
});
|
||||
});
|
||||
|
||||
function onScriptShown(aEvent)
|
||||
{
|
||||
scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
|
||||
executeSoon(startTest);
|
||||
}
|
||||
|
||||
function startTest()
|
||||
{
|
||||
if (scriptShown && framesAdded && resumed && !testStarted) {
|
||||
gDebugger.removeEventListener("Debugger:SourceShown", onScriptShown);
|
||||
testStarted = true;
|
||||
Services.tm.currentThread.dispatch({ run: performTest }, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function performTest()
|
||||
{
|
||||
closeDebuggerAndFinish();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
aDebuggee.firstCall();
|
||||
});
|
||||
}
|
||||
|
@ -1,129 +1,92 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that the debugger is updated with the correct scripts when moving
|
||||
* Make sure that the debugger is updated with the correct sources when moving
|
||||
* back and forward in the tab.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
var gSources = null;
|
||||
const TAB_URL_1 = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
const TAB_URL_2 = EXAMPLE_URL + "doc_recursion-stack.html";
|
||||
|
||||
function test()
|
||||
{
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gSources;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL_1).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
testInitialLoad();
|
||||
});
|
||||
}
|
||||
|
||||
function testInitialLoad() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
executeSoon(function() {
|
||||
validateFirstPage();
|
||||
testLocationChange();
|
||||
});
|
||||
});
|
||||
|
||||
gDebuggee.firstCall();
|
||||
}
|
||||
|
||||
function testLocationChange()
|
||||
{
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController._target.once("navigate", function onTabNavigated(aEvent, aPacket) {
|
||||
ok(true, "tabNavigated event was fired.");
|
||||
info("Still attached to the tab.");
|
||||
|
||||
gDebugger.addEventListener("Debugger:AfterSourcesAdded", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
|
||||
executeSoon(function() {
|
||||
validateSecondPage();
|
||||
testBack();
|
||||
});
|
||||
testFirstPage()
|
||||
.then(testLocationChange)
|
||||
.then(testBack)
|
||||
.then(testForward)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
gDebugger.DebuggerController.client.activeTab.navigateTo(STACK_URL);
|
||||
});
|
||||
}
|
||||
|
||||
function testBack()
|
||||
{
|
||||
gDebugger.DebuggerController._target.once("navigate", function onTabNavigated(aEvent, aPacket) {
|
||||
ok(true, "tabNavigated event was fired after going back.");
|
||||
info("Still attached to the tab.");
|
||||
function testFirstPage() {
|
||||
info("Testing first page.");
|
||||
|
||||
gDebugger.addEventListener("Debugger:AfterSourcesAdded", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
// Spin the event loop before causing the debuggee to pause, to allow
|
||||
// this function to return first.
|
||||
executeSoon(() => gDebuggee.firstCall());
|
||||
|
||||
executeSoon(function() {
|
||||
validateFirstPage();
|
||||
testForward();
|
||||
});
|
||||
});
|
||||
return waitForSourceAndCaretAndScopes(gPanel, "-02.js", 6).then(() => {
|
||||
validateFirstPage();
|
||||
});
|
||||
}
|
||||
|
||||
function testLocationChange() {
|
||||
info("Navigating to a different page.");
|
||||
|
||||
return navigateActiveTabTo(gPanel, TAB_URL_2, gDebugger.EVENTS.SOURCES_ADDED).then(() => {
|
||||
validateSecondPage();
|
||||
});
|
||||
}
|
||||
|
||||
function testBack() {
|
||||
info("Going back.");
|
||||
content.history.back();
|
||||
|
||||
return navigateActiveTabInHistory(gPanel, "back", gDebugger.EVENTS.SOURCES_ADDED).then(() => {
|
||||
validateFirstPage();
|
||||
});
|
||||
}
|
||||
|
||||
function testForward()
|
||||
{
|
||||
gDebugger.DebuggerController._target.once("navigate", function onTabNavigated(aEvent, aPacket) {
|
||||
ok(true, "tabNavigated event was fired after going forward.");
|
||||
info("Still attached to the tab.");
|
||||
|
||||
gDebugger.addEventListener("Debugger:AfterSourcesAdded", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
|
||||
executeSoon(function() {
|
||||
validateSecondPage();
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function testForward() {
|
||||
info("Going forward.");
|
||||
content.history.forward();
|
||||
|
||||
return navigateActiveTabInHistory(gPanel, "forward", gDebugger.EVENTS.SOURCES_ADDED).then(() => {
|
||||
validateSecondPage();
|
||||
});
|
||||
}
|
||||
|
||||
function validateFirstPage() {
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
is(gSources.itemCount, 2,
|
||||
"Found the expected number of scripts.");
|
||||
|
||||
ok(gDebugger.DebuggerView.Sources.containsLabel("test-script-switching-01.js"),
|
||||
"Found the first script label.");
|
||||
ok(gDebugger.DebuggerView.Sources.containsLabel("test-script-switching-02.js"),
|
||||
"Found the second script label.");
|
||||
"Found the expected number of sources.");
|
||||
ok(gSources.containsLabel("code_script-switching-01.js"),
|
||||
"Found the first source label.");
|
||||
ok(gSources.containsLabel("code_script-switching-02.js"),
|
||||
"Found the second source label.");
|
||||
}
|
||||
|
||||
function validateSecondPage() {
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of scripts.");
|
||||
|
||||
ok(gDebugger.DebuggerView.Sources.containsLabel("browser_dbg_stack.html"),
|
||||
"Found the single script label.");
|
||||
"Found the expected number of sources.");
|
||||
ok(gSources.containsLabel("doc_recursion-stack.html"),
|
||||
"Found the single source label.");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gSources = null;
|
||||
});
|
||||
|
@ -1,27 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<title>Debugger Big Data Test</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="text/javascript">
|
||||
window.addEventListener("load", function() {
|
||||
function test(aNumber) {
|
||||
var buffer = new ArrayBuffer(aNumber);
|
||||
var z = new Int8Array(buffer);
|
||||
debugger;
|
||||
};
|
||||
function load() {
|
||||
test(10000);
|
||||
}
|
||||
var button = document.querySelector("button");
|
||||
button.addEventListener("click", load, false);
|
||||
});
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<button>Click me!</button>
|
||||
</body>
|
||||
</html>
|
@ -5,72 +5,52 @@
|
||||
* Test that if we black box a source and then refresh, it is still black boxed.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "binary_search.html";
|
||||
const TAB_URL = EXAMPLE_URL + "doc_binary_search.html";
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
resumed = true;
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
testBlackBoxSource();
|
||||
waitForSourceShown(gPanel, ".coffee")
|
||||
.then(testBlackBoxSource)
|
||||
.then(testBlackBoxReload)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBoxSource() {
|
||||
once(gDebugger, "Debugger:SourceShown", function () {
|
||||
const checkbox = gDebugger.document.querySelector(".side-menu-widget-item-checkbox");
|
||||
ok(checkbox, "Should get the checkbox for black boxing the source");
|
||||
ok(checkbox.checked, "Should not be black boxed by default");
|
||||
const checkbox = gDebugger.document.querySelector(".side-menu-widget-item-checkbox");
|
||||
ok(checkbox, "Should get the checkbox for black boxing the source.");
|
||||
ok(checkbox.checked, "Should not be black boxed by default.");
|
||||
|
||||
const { activeThread } = gDebugger.DebuggerController;
|
||||
activeThread.addOneTimeListener("blackboxchange", function (event, sourceClient) {
|
||||
ok(sourceClient.isBlackBoxed, "The source should be black boxed now");
|
||||
ok(!checkbox.checked, "The checkbox should no longer be checked.");
|
||||
|
||||
testBlackBoxReload();
|
||||
});
|
||||
|
||||
checkbox.click();
|
||||
let finished = waitForThreadEvents(gPanel, "blackboxchange").then(aSource => {
|
||||
ok(aSource.isBlackBoxed, "The source should be black boxed now.");
|
||||
ok(!checkbox.checked, "The checkbox should no longer be checked.");
|
||||
});
|
||||
|
||||
checkbox.click();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testBlackBoxReload() {
|
||||
once(gDebugger, "Debugger:SourceShown", function () {
|
||||
return reloadActiveTab(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(() => {
|
||||
const checkbox = gDebugger.document.querySelector(".side-menu-widget-item-checkbox");
|
||||
ok(checkbox, "Should get the checkbox for black boxing the source");
|
||||
ok(!checkbox.checked, "Should still be black boxed");
|
||||
|
||||
closeDebuggerAndFinish();
|
||||
ok(checkbox, "Should get the checkbox for black boxing the source.");
|
||||
ok(!checkbox.checked, "Should still be black boxed.");
|
||||
});
|
||||
|
||||
gDebuggee.location.reload();
|
||||
}
|
||||
|
||||
function once(target, event, callback) {
|
||||
target.addEventListener(event, function _listener(...args) {
|
||||
target.removeEventListener(event, _listener, false);
|
||||
callback.apply(null, args);
|
||||
}, false);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
@ -6,82 +6,63 @@
|
||||
* view.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_blackboxing.html";
|
||||
const BLACKBOXME_URL = EXAMPLE_URL + "blackboxing_blackboxme.js"
|
||||
const TAB_URL = EXAMPLE_URL + "doc_blackboxing.html";
|
||||
const BLACKBOXME_URL = EXAMPLE_URL + "code_blackboxing_blackboxme.js"
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gFrames;
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
resumed = true;
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gFrames = gDebugger.DebuggerView.StackFrames;
|
||||
|
||||
testBlackBoxSource();
|
||||
waitForSourceShown(gPanel, BLACKBOXME_URL)
|
||||
.then(testBlackBoxSource)
|
||||
.then(testBlackBoxStack)
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBoxSource() {
|
||||
once(gDebugger, "Debugger:SourceShown", function () {
|
||||
const checkbox = getBlackBoxCheckbox(BLACKBOXME_URL);
|
||||
ok(checkbox, "Should get the checkbox for blackBoxing the source");
|
||||
|
||||
const { activeThread } = gDebugger.DebuggerController;
|
||||
activeThread.addOneTimeListener("blackboxchange", function (event, sourceClient) {
|
||||
ok(sourceClient.isBlackBoxed, "The source should be black boxed now");
|
||||
|
||||
testBlackBoxStack();
|
||||
});
|
||||
|
||||
checkbox.click();
|
||||
let finished = waitForThreadEvents(gPanel, "blackboxchange").then(aSource => {
|
||||
ok(aSource.isBlackBoxed, "The source should be black boxed now.");
|
||||
});
|
||||
|
||||
getBlackBoxCheckbox(BLACKBOXME_URL).click();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testBlackBoxStack() {
|
||||
const { activeThread } = gDebugger.DebuggerController;
|
||||
activeThread.addOneTimeListener("framesadded", function () {
|
||||
const frames = gDebugger.DebuggerView.StackFrames.widget._list;
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 3,
|
||||
"Should only get 3 frames");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe-black-boxed").length, 1,
|
||||
"And one of them should be the combined black boxed frames");
|
||||
|
||||
closeDebuggerAndFinish();
|
||||
let finished = waitForSourceAndCaretAndScopes(gPanel, ".html", 21).then(() => {
|
||||
is(gFrames.itemCount, 3,
|
||||
"Should only get 3 frames.");
|
||||
is(gDebugger.document.querySelectorAll(".dbg-stackframe-black-boxed").length, 1,
|
||||
"And one of them should be the combined black boxed frames.");
|
||||
});
|
||||
|
||||
gDebuggee.runTest();
|
||||
// Spin the event loop before causing the debuggee to pause, to allow
|
||||
// this function to return first.
|
||||
executeSoon(() => gDebuggee.runTest());
|
||||
return finished;
|
||||
}
|
||||
|
||||
function getBlackBoxCheckbox(url) {
|
||||
function getBlackBoxCheckbox(aUrl) {
|
||||
return gDebugger.document.querySelector(
|
||||
".side-menu-widget-item[tooltiptext=\""
|
||||
+ url + "\"] .side-menu-widget-item-checkbox");
|
||||
}
|
||||
|
||||
function once(target, event, callback) {
|
||||
target.addEventListener(event, function _listener(...args) {
|
||||
target.removeEventListener(event, _listener, false);
|
||||
callback.apply(null, args);
|
||||
}, false);
|
||||
".side-menu-widget-item[tooltiptext=\"" + aUrl + "\"] " +
|
||||
".side-menu-widget-item-checkbox");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gFrames = null;
|
||||
});
|
||||
|
@ -6,88 +6,63 @@
|
||||
* view when we are already paused.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_blackboxing.html";
|
||||
const BLACKBOXME_URL = EXAMPLE_URL + "blackboxing_blackboxme.js"
|
||||
const TAB_URL = EXAMPLE_URL + "doc_blackboxing.html";
|
||||
const BLACKBOXME_URL = EXAMPLE_URL + "code_blackboxing_blackboxme.js"
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gFrames;
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
resumed = true;
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gFrames = gDebugger.DebuggerView.StackFrames;
|
||||
|
||||
once(gDebugger, "Debugger:SourceShown", function () {
|
||||
testBlackBoxStack();
|
||||
});
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 21)
|
||||
.then(testBlackBoxStack)
|
||||
.then(testBlackBoxSource)
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
gDebuggee.runTest();
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBoxStack() {
|
||||
const { activeThread } = gDebugger.DebuggerController;
|
||||
activeThread.addOneTimeListener("framesadded", function () {
|
||||
const frames = gDebugger.DebuggerView.StackFrames.widget._list;
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 6,
|
||||
"Should get 6 frames");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe-black-boxed").length, 0,
|
||||
"And none of them are black boxed");
|
||||
|
||||
testBlackBoxSource();
|
||||
});
|
||||
|
||||
gDebuggee.runTest();
|
||||
is(gFrames.itemCount, 6,
|
||||
"Should get 6 frames.");
|
||||
is(gDebugger.document.querySelectorAll(".dbg-stackframe-black-boxed").length, 0,
|
||||
"And none of them are black boxed.");
|
||||
}
|
||||
|
||||
function testBlackBoxSource() {
|
||||
const checkbox = getBlackBoxCheckbox(BLACKBOXME_URL);
|
||||
ok(checkbox, "Should get the checkbox for black boxing the source");
|
||||
let finished = waitForThreadEvents(gPanel, "blackboxchange").then(aSource => {
|
||||
ok(aSource.isBlackBoxed, "The source should be black boxed now.");
|
||||
|
||||
const { activeThread } = gDebugger.DebuggerController;
|
||||
activeThread.addOneTimeListener("blackboxchange", function (event, sourceClient) {
|
||||
ok(sourceClient.isBlackBoxed, "The source should be black boxed now");
|
||||
|
||||
const frames = gDebugger.DebuggerView.StackFrames.widget._list;
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 3,
|
||||
"Should only get 3 frames");
|
||||
is(frames.querySelectorAll(".dbg-stackframe-black-boxed").length, 1,
|
||||
"And one of them is the combined black boxed frames");
|
||||
|
||||
closeDebuggerAndFinish();
|
||||
is(gFrames.itemCount, 3,
|
||||
"Should only get 3 frames.");
|
||||
is(gDebugger.document.querySelectorAll(".dbg-stackframe-black-boxed").length, 1,
|
||||
"And one of them should be the combined black boxed frames.");
|
||||
});
|
||||
|
||||
checkbox.click();
|
||||
getBlackBoxCheckbox(BLACKBOXME_URL).click();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function getBlackBoxCheckbox(url) {
|
||||
function getBlackBoxCheckbox(aUrl) {
|
||||
return gDebugger.document.querySelector(
|
||||
".side-menu-widget-item[tooltiptext=\""
|
||||
+ url + "\"] .side-menu-widget-item-checkbox");
|
||||
}
|
||||
|
||||
function once(target, event, callback) {
|
||||
target.addEventListener(event, function _listener(...args) {
|
||||
target.removeEventListener(event, _listener, false);
|
||||
callback.apply(null, args);
|
||||
}, false);
|
||||
".side-menu-widget-item[tooltiptext=\"" + aUrl + "\"] " +
|
||||
".side-menu-widget-item-checkbox");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gFrames = null;
|
||||
});
|
||||
|
@ -6,78 +6,62 @@
|
||||
* for all of them.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_blackboxing.html";
|
||||
const TAB_URL = EXAMPLE_URL + "doc_blackboxing.html";
|
||||
const BLACKBOXME_URL = EXAMPLE_URL + "code_blackboxing_blackboxme.js"
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gFrames;
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
resumed = true;
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gFrames = gDebugger.DebuggerView.StackFrames;
|
||||
|
||||
once(gDebugger, "Debugger:SourceShown", function () {
|
||||
blackBoxSources();
|
||||
});
|
||||
waitForSourceShown(gPanel, BLACKBOXME_URL)
|
||||
.then(blackBoxSources)
|
||||
.then(testBlackBoxStack)
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function blackBoxSources() {
|
||||
let timesFired = 0;
|
||||
const { activeThread } = gDebugger.DebuggerController;
|
||||
activeThread.addListener("blackboxchange", function _onBlackBoxChange() {
|
||||
if (++timesFired !== 3) {
|
||||
return;
|
||||
}
|
||||
activeThread.removeListener("blackboxchange", _onBlackBoxChange);
|
||||
|
||||
activeThread.addOneTimeListener("framesadded", testStackFrames);
|
||||
gDebuggee.one();
|
||||
}, false);
|
||||
|
||||
getBlackBoxCheckbox(EXAMPLE_URL + "blackboxing_one.js").click();
|
||||
getBlackBoxCheckbox(EXAMPLE_URL + "blackboxing_two.js").click();
|
||||
getBlackBoxCheckbox(EXAMPLE_URL + "blackboxing_three.js").click();
|
||||
let finished = waitForThreadEvents(gPanel, "blackboxchange", 3);
|
||||
getBlackBoxCheckbox(EXAMPLE_URL + "code_blackboxing_one.js").click();
|
||||
getBlackBoxCheckbox(EXAMPLE_URL + "code_blackboxing_two.js").click();
|
||||
getBlackBoxCheckbox(EXAMPLE_URL + "code_blackboxing_three.js").click();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testStackFrames() {
|
||||
const frames = gDebugger.DebuggerView.StackFrames.widget._list;
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 4,
|
||||
"Should get 4 frames (one -> two -> three -> doDebuggerStatement)");
|
||||
is(frames.querySelectorAll(".dbg-stackframe-black-boxed").length, 3,
|
||||
"And one, two, and three should each have their own black boxed frame.");
|
||||
function testBlackBoxStack() {
|
||||
let finished = waitForSourceAndCaretAndScopes(gPanel, ".html", 21).then(() => {
|
||||
is(gFrames.itemCount, 4,
|
||||
"Should get 4 frames (one -> two -> three -> doDebuggerStatement).");
|
||||
is(gDebugger.document.querySelectorAll(".dbg-stackframe-black-boxed").length, 3,
|
||||
"And 'one', 'two', and 'three' should each have their own black boxed frame.");
|
||||
});
|
||||
|
||||
closeDebuggerAndFinish();
|
||||
// Spin the event loop before causing the debuggee to pause, to allow
|
||||
// this function to return first.
|
||||
executeSoon(() => gDebuggee.one());
|
||||
return finished;
|
||||
}
|
||||
|
||||
function getBlackBoxCheckbox(url) {
|
||||
function getBlackBoxCheckbox(aUrl) {
|
||||
return gDebugger.document.querySelector(
|
||||
".side-menu-widget-item[tooltiptext=\""
|
||||
+ url + "\"] .side-menu-widget-item-checkbox");
|
||||
}
|
||||
|
||||
function once(target, event, callback) {
|
||||
target.addEventListener(event, function _listener(...args) {
|
||||
target.removeEventListener(event, _listener, false);
|
||||
callback.apply(null, args);
|
||||
}, false);
|
||||
".side-menu-widget-item[tooltiptext=\"" + aUrl + "\"] " +
|
||||
".side-menu-widget-item-checkbox");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gFrames = null;
|
||||
});
|
||||
|
@ -2,67 +2,61 @@
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that we get a stack frame for each black boxed source, not a single one
|
||||
* for all of them.
|
||||
* Test that a "this source is blackboxed" message is shown when necessary
|
||||
* and can be properly dismissed.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "binary_search.html";
|
||||
const TAB_URL = EXAMPLE_URL + "doc_binary_search.html";
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gDeck;
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
resumed = true;
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gDeck = gDebugger.document.getElementById("editor-deck");
|
||||
|
||||
once(gDebugger, "Debugger:SourceShown", testSourceEditorShown);
|
||||
waitForSourceShown(gPanel, ".coffee")
|
||||
.then(testSourceEditorShown)
|
||||
.then(blackBoxSource)
|
||||
.then(testBlackBoxMessageShown)
|
||||
.then(clickStopBlackBoxingButton)
|
||||
.then(testSourceEditorShownAgain)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testSourceEditorShown() {
|
||||
const deck = gDebugger.document.getElementById("editor-deck");
|
||||
is(deck.selectedIndex, "0",
|
||||
"The first item in the deck should be selected (the source editor)");
|
||||
blackBoxSource();
|
||||
is(gDeck.selectedIndex, "0",
|
||||
"The first item in the deck should be selected (the source editor).");
|
||||
}
|
||||
|
||||
function blackBoxSource() {
|
||||
const { activeThread } = gDebugger.DebuggerController;
|
||||
activeThread.addOneTimeListener("blackboxchange", testBlackBoxMessageShown);
|
||||
let finished = waitForThreadEvents(gPanel, "blackboxchange");
|
||||
getAnyBlackBoxCheckbox().click();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testBlackBoxMessageShown() {
|
||||
const deck = gDebugger.document.getElementById("editor-deck");
|
||||
is(deck.selectedIndex, "1",
|
||||
"The second item in the deck should be selected (the black box message)");
|
||||
clickStopBlackBoxingButton();
|
||||
is(gDeck.selectedIndex, "1",
|
||||
"The second item in the deck should be selected (the black box message).");
|
||||
}
|
||||
|
||||
function clickStopBlackBoxingButton() {
|
||||
const button = gDebugger.document.getElementById("black-boxed-message-button");
|
||||
const { activeThread } = gDebugger.DebuggerController;
|
||||
activeThread.addOneTimeListener("blackboxchange", testSourceEditorShownAgain);
|
||||
button.click();
|
||||
let finished = waitForThreadEvents(gPanel, "blackboxchange");
|
||||
getEditorBlackboxMessageButton().click();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testSourceEditorShownAgain() {
|
||||
const deck = gDebugger.document.getElementById("editor-deck");
|
||||
is(deck.selectedIndex, "0",
|
||||
"The first item in the deck should be selected again (the source editor)");
|
||||
closeDebuggerAndFinish();
|
||||
is(gDeck.selectedIndex, "0",
|
||||
"The first item in the deck should be selected again (the source editor).");
|
||||
}
|
||||
|
||||
function getAnyBlackBoxCheckbox() {
|
||||
@ -70,17 +64,14 @@ function getAnyBlackBoxCheckbox() {
|
||||
".side-menu-widget-item .side-menu-widget-item-checkbox");
|
||||
}
|
||||
|
||||
function once(target, event, callback) {
|
||||
target.addEventListener(event, function _listener(...args) {
|
||||
target.removeEventListener(event, _listener, false);
|
||||
callback.apply(null, args);
|
||||
}, false);
|
||||
function getEditorBlackboxMessageButton() {
|
||||
return gDebugger.document.getElementById("black-boxed-message-button");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gDeck = null;
|
||||
});
|
||||
|
@ -5,66 +5,52 @@
|
||||
* Test that clicking the black box checkbox doesn't select that source.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_blackboxing.html";
|
||||
const TAB_URL = EXAMPLE_URL + "doc_blackboxing.html";
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gSources;
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
resumed = true;
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
once(gDebugger, "Debugger:SourceShown", testBlackBox);
|
||||
waitForSourceShown(gPanel, ".js")
|
||||
.then(testBlackBox)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBox() {
|
||||
const sources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
const selectedUrl = sources.selectedItem.attachment.source.url;
|
||||
const selectedUrl = gSources.selectedValue;
|
||||
const checkbox = getDifferentBlackBoxCheckbox(selectedUrl);
|
||||
ok(checkbox, "We should be able to grab a checkbox");
|
||||
ok(checkbox, "We should be able to grab a different checkbox.");
|
||||
|
||||
const { activeThread } = gDebugger.DebuggerController;
|
||||
activeThread.addOneTimeListener("blackboxchange", function () {
|
||||
is(selectedUrl,
|
||||
sources.selectedItem.attachment.source.url,
|
||||
"The same source should be selected");
|
||||
closeDebuggerAndFinish();
|
||||
let finished = waitForThreadEvents(gPanel, "blackboxchange").then(() => {
|
||||
is(selectedUrl, gSources.selectedValue,
|
||||
"The same source should still be selected.");
|
||||
});
|
||||
|
||||
checkbox.click();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function getDifferentBlackBoxCheckbox(url) {
|
||||
function getDifferentBlackBoxCheckbox(aUrl) {
|
||||
return gDebugger.document.querySelector(
|
||||
".side-menu-widget-item:not([tooltiptext=\""
|
||||
+ url + "\"]) .side-menu-widget-item-checkbox");
|
||||
}
|
||||
|
||||
function once(target, event, callback) {
|
||||
target.addEventListener(event, function _listener(...args) {
|
||||
target.removeEventListener(event, _listener, false);
|
||||
callback.apply(null, args);
|
||||
}, false);
|
||||
".side-menu-widget-item:not([tooltiptext=\"" + aUrl + "\"]) " +
|
||||
".side-menu-widget-item-checkbox");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gSources = null;
|
||||
});
|
||||
|
@ -6,81 +6,61 @@
|
||||
* currently paused frame's source.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_blackboxing.html";
|
||||
const TAB_URL = EXAMPLE_URL + "doc_blackboxing.html";
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gSources;
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
resumed = true;
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
once(gDebugger, "Debugger:SourceShown", runTest);
|
||||
});
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
const { activeThread } = gDebugger.DebuggerController;
|
||||
activeThread.addOneTimeListener("paused", function () {
|
||||
const sources = gDebugger.DebuggerView.Sources;
|
||||
const selectedUrl = sources.selectedItem.attachment.source.url;
|
||||
|
||||
once(gDebugger, "Debugger:SourceShown", function () {
|
||||
const newSelectedUrl = sources.selectedItem.attachment.source.url;
|
||||
isnot(selectedUrl, newSelectedUrl,
|
||||
"Should not have the same url selected");
|
||||
|
||||
activeThread.addOneTimeListener("blackboxchange", function () {
|
||||
isnot(sources.selectedItem.attachment.source.url,
|
||||
selectedUrl,
|
||||
"The selected source did not change");
|
||||
closeDebuggerAndFinish();
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 21)
|
||||
.then(testBlackBox)
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
getBlackBoxCheckbox(newSelectedUrl).click();
|
||||
gDebuggee.runTest();
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBox() {
|
||||
const selectedUrl = gSources.selectedValue;
|
||||
|
||||
let finished = waitForSourceShown(gPanel, "blackboxme.js").then(() => {
|
||||
const newSelectedUrl = gSources.selectedValue;
|
||||
isnot(selectedUrl, newSelectedUrl,
|
||||
"Should not have the same url selected.");
|
||||
|
||||
let finished = waitForThreadEvents(gPanel, "blackboxchange").then(() => {
|
||||
is(gSources.selectedValue, newSelectedUrl,
|
||||
"The selected source did not change.");
|
||||
});
|
||||
|
||||
getDifferentSource(selectedUrl).click();
|
||||
getBlackBoxCheckbox(newSelectedUrl).click()
|
||||
return finished;
|
||||
});
|
||||
|
||||
gDebuggee.runTest();
|
||||
gSources.selectedIndex = 0;
|
||||
return finished;
|
||||
}
|
||||
|
||||
function getDifferentSource(url) {
|
||||
function getBlackBoxCheckbox(aUrl) {
|
||||
return gDebugger.document.querySelector(
|
||||
".side-menu-widget-item:not([tooltiptext=\""
|
||||
+ url + "\"])");
|
||||
}
|
||||
|
||||
function getBlackBoxCheckbox(url) {
|
||||
return gDebugger.document.querySelector(
|
||||
".side-menu-widget-item[tooltiptext=\""
|
||||
+ url + "\"] .side-menu-widget-item-checkbox");
|
||||
}
|
||||
|
||||
function once(target, event, callback) {
|
||||
target.addEventListener(event, function _listener(...args) {
|
||||
target.removeEventListener(event, _listener, false);
|
||||
callback.apply(null, args);
|
||||
}, false);
|
||||
".side-menu-widget-item[tooltiptext=\"" + aUrl + "\"] " +
|
||||
".side-menu-widget-item-checkbox");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gSources = null;
|
||||
});
|
||||
|
@ -1,23 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<title>Browser Debugger Blackbox Test</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="text/javascript" src="blackboxing_blackboxme.js"></script>
|
||||
<script type="text/javascript" src="blackboxing_one.js"></script>
|
||||
<script type="text/javascript" src="blackboxing_two.js"></script>
|
||||
<script type="text/javascript" src="blackboxing_three.js"></script>
|
||||
<script>
|
||||
function runTest() {
|
||||
blackboxme(doDebuggerStatement);
|
||||
}
|
||||
function doDebuggerStatement() {
|
||||
debugger;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -1,154 +1,89 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
|
||||
/**
|
||||
* Tests if the stackframe breadcrumbs are keyboard accessible.
|
||||
*/
|
||||
|
||||
let gPane = null;
|
||||
let gTab = null;
|
||||
let gDebuggee = null;
|
||||
let gDebugger = null;
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gSources, gFrames;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
resumed = true;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gFrames = gDebugger.DebuggerView.StackFrames;
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", onScriptShown);
|
||||
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
framesAdded = true;
|
||||
executeSoon(startTest);
|
||||
});
|
||||
|
||||
executeSoon(function() {
|
||||
gDebuggee.firstCall();
|
||||
});
|
||||
});
|
||||
|
||||
function onScriptShown(aEvent)
|
||||
{
|
||||
scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
|
||||
executeSoon(startTest);
|
||||
}
|
||||
|
||||
function startTest()
|
||||
{
|
||||
if (scriptShown && framesAdded && resumed && !testStarted) {
|
||||
gDebugger.removeEventListener("Debugger:SourceShown", onScriptShown);
|
||||
testStarted = true;
|
||||
Services.tm.currentThread.dispatch({ run: performTest }, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function performTest()
|
||||
{
|
||||
let editor = gDebugger.DebuggerView.editor;
|
||||
let sources = gDebugger.DebuggerView.Sources;
|
||||
let stackframes = gDebugger.DebuggerView.StackFrames;
|
||||
|
||||
is(editor.getCaretPosition().line, 5,
|
||||
"The source editor caret position was incorrect (1).");
|
||||
is(sources.selectedLabel, "test-script-switching-02.js",
|
||||
"The currently selected source is incorrect (1).");
|
||||
is(stackframes.selectedIndex, 3,
|
||||
"The currently selected stackframe is incorrect (1).");
|
||||
|
||||
EventUtils.sendKey("DOWN", gDebugger);
|
||||
is(editor.getCaretPosition().line, 6,
|
||||
"The source editor caret position was incorrect (2).");
|
||||
is(sources.selectedLabel, "test-script-switching-02.js",
|
||||
"The currently selected source is incorrect (2).");
|
||||
is(stackframes.selectedIndex, 3,
|
||||
"The currently selected stackframe is incorrect (2).");
|
||||
|
||||
EventUtils.sendKey("UP", gDebugger);
|
||||
is(editor.getCaretPosition().line, 5,
|
||||
"The source editor caret position was incorrect (3).");
|
||||
is(sources.selectedLabel, "test-script-switching-02.js",
|
||||
"The currently selected source is incorrect (3).");
|
||||
is(stackframes.selectedIndex, 3,
|
||||
"The currently selected stackframe is incorrect (3).");
|
||||
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
stackframes.selectedItem.target,
|
||||
gDebugger);
|
||||
|
||||
|
||||
EventUtils.sendKey("UP", gDebugger);
|
||||
is(editor.getCaretPosition().line, 5,
|
||||
"The source editor caret position was incorrect (4).");
|
||||
is(sources.selectedLabel, "test-script-switching-02.js",
|
||||
"The currently selected source is incorrect (4).");
|
||||
is(stackframes.selectedIndex, 2,
|
||||
"The currently selected stackframe is incorrect (4).");
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
|
||||
is(editor.getCaretPosition().line, 4,
|
||||
"The source editor caret position was incorrect (5).");
|
||||
is(sources.selectedLabel, "test-script-switching-01.js",
|
||||
"The currently selected source is incorrect (5).");
|
||||
is(stackframes.selectedIndex, 1,
|
||||
"The currently selected stackframe is incorrect (5).");
|
||||
|
||||
EventUtils.sendKey("UP", gDebugger);
|
||||
|
||||
is(editor.getCaretPosition().line, 4,
|
||||
"The source editor caret position was incorrect (6).");
|
||||
is(sources.selectedLabel, "test-script-switching-01.js",
|
||||
"The currently selected source is incorrect (6).");
|
||||
is(stackframes.selectedIndex, 0,
|
||||
"The currently selected stackframe is incorrect (6).");
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
|
||||
is(editor.getCaretPosition().line, 5,
|
||||
"The source editor caret position was incorrect (7).");
|
||||
is(sources.selectedLabel, "test-script-switching-02.js",
|
||||
"The currently selected source is incorrect (7).");
|
||||
is(stackframes.selectedIndex, 3,
|
||||
"The currently selected stackframe is incorrect (7).");
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
|
||||
is(editor.getCaretPosition().line, 4,
|
||||
"The source editor caret position was incorrect (8).");
|
||||
is(sources.selectedLabel, "test-script-switching-01.js",
|
||||
"The currently selected source is incorrect (8).");
|
||||
is(stackframes.selectedIndex, 0,
|
||||
"The currently selected stackframe is incorrect (8).");
|
||||
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
|
||||
EventUtils.sendKey("HOME", gDebugger);
|
||||
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 6)
|
||||
.then(checkNavigationWhileNotFocused)
|
||||
.then(focusCurrentStackFrame)
|
||||
.then(checkNavigationWhileFocused)
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
EventUtils.sendKey("END", gDebugger);
|
||||
});
|
||||
gDebuggee.firstCall();
|
||||
});
|
||||
|
||||
function checkNavigationWhileNotFocused() {
|
||||
checkState({ frame: 3, source: 1, line: 6 });
|
||||
|
||||
EventUtils.sendKey("DOWN", gDebugger);
|
||||
checkState({ frame: 3, source: 1, line: 7 });
|
||||
|
||||
EventUtils.sendKey("UP", gDebugger);
|
||||
checkState({ frame: 3, source: 1, line: 6 });
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
function focusCurrentStackFrame() {
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gFrames.selectedItem.target,
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function checkNavigationWhileFocused() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
EventUtils.sendKey("UP", gDebugger);
|
||||
checkState({ frame: 2, source: 1, line: 6 });
|
||||
|
||||
waitForSourceAndCaret(gPanel, "-01.js", 5).then(() => {
|
||||
checkState({ frame: 1, source: 0, line: 5 });
|
||||
|
||||
EventUtils.sendKey("UP", gDebugger);
|
||||
checkState({ frame: 0, source: 0, line: 5 });
|
||||
|
||||
waitForSourceAndCaret(gPanel, "-02.js", 6).then(() => {
|
||||
checkState({ frame: 3, source: 1, line: 6 });
|
||||
|
||||
waitForSourceAndCaret(gPanel, "-01.js", 5).then(() => {
|
||||
checkState({ frame: 0, source: 0, line: 5 });
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
EventUtils.sendKey("HOME", gDebugger)
|
||||
});
|
||||
|
||||
EventUtils.sendKey("END", gDebugger)
|
||||
});
|
||||
|
||||
EventUtils.sendKey("UP", gDebugger)
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function checkState({ frame, source, line }) {
|
||||
is(gFrames.selectedIndex, frame,
|
||||
"The currently selected stackframe is incorrect.");
|
||||
is(gSources.selectedIndex, source,
|
||||
"The currently selected source is incorrect.");
|
||||
ok(isCaretPos(gPanel, line),
|
||||
"The source editor caret position was incorrect.");
|
||||
}
|
||||
}
|
||||
|
@ -1,195 +1,228 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the break-on-dom-events request works.
|
||||
*/
|
||||
|
||||
// Tests that the break-on-dom-events request works.
|
||||
const TAB_URL = EXAMPLE_URL + "doc_event-listeners.html";
|
||||
|
||||
var gClient = null;
|
||||
var gTab = null;
|
||||
var gThreadClient = null;
|
||||
var gInput = null;
|
||||
var gButton = null;
|
||||
const DEBUGGER_TAB_URL = EXAMPLE_URL + "test-event-listeners.html";
|
||||
let gClient, gThreadClient, gInput, gButton;
|
||||
|
||||
function test() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init(() => true);
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect(function(type, traits) {
|
||||
gTab = addTab(DEBUGGER_TAB_URL, function() {
|
||||
attach_thread_actor_for_url(gClient,
|
||||
DEBUGGER_TAB_URL,
|
||||
function(threadClient) {
|
||||
gThreadClient = threadClient;
|
||||
gInput = content.document.querySelector("input");
|
||||
gButton = content.document.querySelector("button");
|
||||
testBreakOnAll();
|
||||
gClient.connect((aType, aTraits) => {
|
||||
is(aType, "browser",
|
||||
"Root actor should identify itself as a browser.");
|
||||
|
||||
addTab(TAB_URL)
|
||||
.then(() => attachThreadActorForUrl(gClient, TAB_URL))
|
||||
.then(setupGlobals)
|
||||
.then(pauseDebuggee)
|
||||
.then(testBreakOnAll)
|
||||
.then(testBreakOnDisabled)
|
||||
.then(testBreakOnNone)
|
||||
.then(testBreakOnClick)
|
||||
.then(closeConnection)
|
||||
.then(finish)
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function setupGlobals(aThreadClient) {
|
||||
gThreadClient = aThreadClient;
|
||||
gInput = content.document.querySelector("input");
|
||||
gButton = content.document.querySelector("button");
|
||||
}
|
||||
|
||||
function pauseDebuggee() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.type, "paused",
|
||||
"We should now be paused.");
|
||||
is(aPacket.why.type, "debuggerStatement",
|
||||
"The debugger statement was hit.");
|
||||
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
// Spin the event loop before causing the debuggee to pause, to allow
|
||||
// this function to return first.
|
||||
executeSoon(triggerButtonClick);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
// Test pause on all events.
|
||||
function testBreakOnAll()
|
||||
{
|
||||
gClient.addOneTimeListener("paused", function(event, packet) {
|
||||
is(packet.why.type, "debuggerStatement", "debugger statement was hit.");
|
||||
// Test calling pauseOnDOMEvents from a paused state.
|
||||
gThreadClient.pauseOnDOMEvents("*", function(packet) {
|
||||
is(packet, undefined, "The pause-on-any-event request completed successfully.");
|
||||
function testBreakOnAll() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gClient.addOneTimeListener("paused", function(event, packet) {
|
||||
is(packet.why.type, "pauseOnDOMEvents", "A hidden breakpoint was hit.");
|
||||
is(packet.frame.callee.name, "keyupHandler", "The keyupHandler is entered.");
|
||||
// Test calling pauseOnDOMEvents from a paused state.
|
||||
gThreadClient.pauseOnDOMEvents("*", (aPacket) => {
|
||||
is(aPacket, undefined,
|
||||
"The pause-on-any-event request completed successfully.");
|
||||
|
||||
gClient.addOneTimeListener("paused", function(event, packet) {
|
||||
is(packet.why.type, "pauseOnDOMEvents", "A hidden breakpoint was hit.");
|
||||
is(packet.frame.callee.name, "clickHandler", "The clickHandler is entered.");
|
||||
gClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.why.type, "pauseOnDOMEvents",
|
||||
"A hidden breakpoint was hit.");
|
||||
is(aPacket.frame.callee.name, "keyupHandler",
|
||||
"The keyupHandler is entered.");
|
||||
|
||||
gClient.addOneTimeListener("paused", function(event, packet) {
|
||||
is(packet.why.type, "pauseOnDOMEvents", "A hidden breakpoint was hit.");
|
||||
is(packet.frame.callee.name, "onchange", "The onchange handler is entered.");
|
||||
gClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.why.type, "pauseOnDOMEvents",
|
||||
"A hidden breakpoint was hit.");
|
||||
is(aPacket.frame.callee.name, "clickHandler",
|
||||
"The clickHandler is entered.");
|
||||
|
||||
gThreadClient.resume(testBreakOnDisabled);
|
||||
});
|
||||
gClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.why.type, "pauseOnDOMEvents",
|
||||
"A hidden breakpoint was hit.");
|
||||
is(aPacket.frame.callee.name, "onchange",
|
||||
"The onchange handler is entered.");
|
||||
|
||||
gThreadClient.resume(function() {
|
||||
gInput.focus();
|
||||
gInput.value = "foo";
|
||||
gInput.blur();
|
||||
});
|
||||
gThreadClient.resume(deferred.resolve);
|
||||
});
|
||||
|
||||
gThreadClient.resume(function() {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, gButton);
|
||||
});
|
||||
gThreadClient.resume(triggerInputChange);
|
||||
});
|
||||
|
||||
gThreadClient.resume(function() {
|
||||
// Make sure that the focus is not on the input box so that a focus event
|
||||
// will be triggered.
|
||||
window.focus();
|
||||
gBrowser.selectedBrowser.focus();
|
||||
gButton.focus();
|
||||
|
||||
// Focus the element and wait for focus event.
|
||||
gInput.addEventListener("focus", function onfocus() {
|
||||
gInput.removeEventListener("focus", onfocus, false);
|
||||
executeSoon(function() {
|
||||
EventUtils.synthesizeKey("e", { shiftKey: 1 }, content);
|
||||
});
|
||||
}, false);
|
||||
|
||||
gInput.focus();
|
||||
});
|
||||
gThreadClient.resume(triggerButtonClick);
|
||||
});
|
||||
|
||||
gThreadClient.resume(triggerInputKeyup);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, gButton);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
// Test that removing events from the array disables them.
|
||||
function testBreakOnDisabled()
|
||||
{
|
||||
function testBreakOnDisabled() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
// Test calling pauseOnDOMEvents from a running state.
|
||||
gThreadClient.pauseOnDOMEvents(["click"], function(packet) {
|
||||
is(packet.error, undefined, "The pause-on-click-only request completed successfully.");
|
||||
gThreadClient.pauseOnDOMEvents(["click"], (aPacket) => {
|
||||
is(aPacket.error, undefined,
|
||||
"The pause-on-click-only request completed successfully.");
|
||||
|
||||
gClient.addListener("paused", unexpectedListener);
|
||||
|
||||
// This non-capturing event listener is guaranteed to run after the page's
|
||||
// capturing one had a chance to execute and modify window.foobar.
|
||||
gInput.addEventListener("keyup", function tempHandler() {
|
||||
gInput.removeEventListener("keyup", tempHandler, false);
|
||||
is(content.wrappedJSObject.foobar, "keyupHandler", "No hidden breakpoint was hit.");
|
||||
once(gInput, "keyup").then(() => {
|
||||
is(content.wrappedJSObject.foobar, "keyupHandler",
|
||||
"No hidden breakpoint was hit.");
|
||||
|
||||
gClient.removeListener("paused", unexpectedListener);
|
||||
testBreakOnNone();
|
||||
}, false);
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
// Make sure that the focus is not on the input box so that a focus event
|
||||
// will be triggered.
|
||||
window.focus();
|
||||
gBrowser.selectedBrowser.focus();
|
||||
gButton.focus();
|
||||
|
||||
// Focus the element and wait for focus event.
|
||||
gInput.addEventListener("focus", function onfocus() {
|
||||
gInput.removeEventListener("focus", onfocus, false);
|
||||
executeSoon(function() {
|
||||
EventUtils.synthesizeKey("e", { shiftKey: 1 }, content);
|
||||
});
|
||||
}, false);
|
||||
|
||||
gInput.focus();
|
||||
triggerInputKeyup();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
// Test that specifying an empty event array clears all hidden breakpoints.
|
||||
function testBreakOnNone()
|
||||
{
|
||||
function testBreakOnNone() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
// Test calling pauseOnDOMEvents from a running state.
|
||||
gThreadClient.pauseOnDOMEvents([], function(packet) {
|
||||
is(packet.error, undefined, "The pause-on-none request completed successfully.");
|
||||
gThreadClient.pauseOnDOMEvents([], (aPacket) => {
|
||||
is(aPacket.error, undefined,
|
||||
"The pause-on-none request completed successfully.");
|
||||
|
||||
gClient.addListener("paused", unexpectedListener);
|
||||
|
||||
// This non-capturing event listener is guaranteed to run after the page's
|
||||
// capturing one had a chance to execute and modify window.foobar.
|
||||
gInput.addEventListener("keyup", function tempHandler() {
|
||||
gInput.removeEventListener("keyup", tempHandler, false);
|
||||
is(content.wrappedJSObject.foobar, "keyupHandler", "No hidden breakpoint was hit.");
|
||||
once(gInput, "keyup").then(() => {
|
||||
is(content.wrappedJSObject.foobar, "keyupHandler",
|
||||
"No hidden breakpoint was hit.");
|
||||
|
||||
gClient.removeListener("paused", unexpectedListener);
|
||||
testBreakOnClick();
|
||||
}, false);
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
// Make sure that the focus is not on the input box so that a focus event
|
||||
// will be triggered.
|
||||
window.focus();
|
||||
gBrowser.selectedBrowser.focus();
|
||||
gButton.focus();
|
||||
|
||||
// Focus the element and wait for focus event.
|
||||
gInput.addEventListener("focus", function onfocus() {
|
||||
gInput.removeEventListener("focus", onfocus, false);
|
||||
executeSoon(function() {
|
||||
EventUtils.synthesizeKey("g", { shiftKey: 1 }, content);
|
||||
});
|
||||
}, false);
|
||||
|
||||
gInput.focus();
|
||||
triggerInputKeyup();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function unexpectedListener(event, packet, callback) {
|
||||
// Test pause on a single event.
|
||||
function testBreakOnClick() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
// Test calling pauseOnDOMEvents from a running state.
|
||||
gThreadClient.pauseOnDOMEvents(["click"], (aPacket) => {
|
||||
is(aPacket.error, undefined,
|
||||
"The pause-on-click request completed successfully.");
|
||||
|
||||
gClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.why.type, "pauseOnDOMEvents",
|
||||
"A hidden breakpoint was hit.");
|
||||
is(aPacket.frame.callee.name, "clickHandler",
|
||||
"The clickHandler is entered.");
|
||||
|
||||
gThreadClient.resume(deferred.resolve);
|
||||
});
|
||||
|
||||
triggerButtonClick();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function closeConnection() {
|
||||
let deferred = promise.defer();
|
||||
gClient.close(deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function unexpectedListener() {
|
||||
gClient.removeListener("paused", unexpectedListener);
|
||||
ok(false, "An unexpected hidden breakpoint was hit.");
|
||||
gThreadClient.resume(testBreakOnClick);
|
||||
}
|
||||
|
||||
// Test pause on a single event.
|
||||
function testBreakOnClick()
|
||||
{
|
||||
// Test calling pauseOnDOMEvents from a running state.
|
||||
gThreadClient.pauseOnDOMEvents(["click"], function(packet) {
|
||||
is(packet.error, undefined, "The pause-on-click request completed successfully.");
|
||||
function triggerInputKeyup() {
|
||||
// Make sure that the focus is not on the input box so that a focus event
|
||||
// will be triggered.
|
||||
window.focus();
|
||||
gBrowser.selectedBrowser.focus();
|
||||
gButton.focus();
|
||||
|
||||
gClient.addOneTimeListener("paused", function(event, packet) {
|
||||
is(packet.why.type, "pauseOnDOMEvents", "A hidden breakpoint was hit.");
|
||||
is(packet.frame.callee.name, "clickHandler", "The clickHandler is entered.");
|
||||
|
||||
gThreadClient.resume(function() {
|
||||
gClient.close(finish);
|
||||
});
|
||||
// Focus the element and wait for focus event.
|
||||
once(gInput, "focus").then(() => {
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeKey("e", { shiftKey: 1 }, content);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, gButton);
|
||||
});
|
||||
|
||||
gInput.focus();
|
||||
}
|
||||
|
||||
function triggerButtonClick() {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, gButton)
|
||||
}
|
||||
|
||||
function triggerInputChange() {
|
||||
gInput.focus();
|
||||
gInput.value = "foo";
|
||||
gInput.blur();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gTab = null;
|
||||
removeTab(gBrowser.selectedTab);
|
||||
gClient = null;
|
||||
gThreadClient = null;
|
||||
gInput = null;
|
||||
|
@ -1,20 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<script type="text/javascript">
|
||||
function runDebuggerStatement() {
|
||||
debugger;
|
||||
}
|
||||
function myFunction() {
|
||||
var a = 1;
|
||||
debugger;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<button type="button" onclick="myFunction()">Run</button>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,92 +0,0 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Bug 771452: make sure that setting a breakpoint in an inline script doesn't
|
||||
// add it twice.
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_breakpoint-new-script.html";
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebugger = null;
|
||||
var gDebuggee = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
gDebuggee = aDebuggee;
|
||||
|
||||
testAddBreakpoint();
|
||||
});
|
||||
}
|
||||
|
||||
function testAddBreakpoint()
|
||||
{
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
var frames = gDebugger.DebuggerView.StackFrames.widget._list;
|
||||
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"The debugger statement was reached.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 1,
|
||||
"Should have one frame.");
|
||||
|
||||
gPane.addBreakpoint({ url: TAB_URL, line: 9 }, function (aResponse, bpClient) {
|
||||
testResume();
|
||||
});
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.runDebuggerStatement();
|
||||
}
|
||||
|
||||
function testResume()
|
||||
{
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"The breakpoint wasn't hit yet.");
|
||||
|
||||
let thread = gDebugger.DebuggerController.activeThread;
|
||||
thread.addOneTimeListener("resumed", function() {
|
||||
thread.addOneTimeListener("paused", function() {
|
||||
executeSoon(testBreakpointHit);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
content.document.querySelector("button"));
|
||||
});
|
||||
|
||||
thread.resume();
|
||||
}
|
||||
|
||||
function testBreakpointHit()
|
||||
{
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"The breakpoint was hit.");
|
||||
|
||||
let thread = gDebugger.DebuggerController.activeThread;
|
||||
thread.addOneTimeListener("paused", function test(aEvent, aPacket) {
|
||||
thread.addOneTimeListener("resumed", function() {
|
||||
executeSoon(closeDebuggerAndFinish);
|
||||
});
|
||||
|
||||
is(aPacket.why.type, "debuggerStatement", "Execution has advanced to the next line.");
|
||||
isnot(aPacket.why.type, "breakpoint", "No ghost breakpoint was hit.");
|
||||
thread.resume();
|
||||
});
|
||||
|
||||
thread.resume();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebugger = null;
|
||||
gDebuggee = null;
|
||||
});
|
@ -0,0 +1,97 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 737803: Setting a breakpoint in a line without code should move
|
||||
* the icon to the actual location.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
|
||||
gBreakpointsAdded = gBreakpoints._added;
|
||||
gBreakpointsRemoving = gBreakpoints._removing;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 6).then(performTest);
|
||||
gDebuggee.firstCall();
|
||||
});
|
||||
|
||||
function performTest() {
|
||||
is(gBreakpointsAdded.size, 0,
|
||||
"No breakpoints currently added.");
|
||||
is(gBreakpointsRemoving.size, 0,
|
||||
"No breakpoints currently being removed.");
|
||||
is(gEditor.getBreakpoints().length, 0,
|
||||
"No breakpoints currently shown in the editor.");
|
||||
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAdd);
|
||||
gPanel.addBreakpoint({ url: gSources.selectedValue, line: 4 }).then(onBreakpointAdd);
|
||||
}
|
||||
|
||||
let onBpDebuggerAdd = false;
|
||||
let onBpEditorAdd = false;
|
||||
|
||||
function onBreakpointAdd(aBreakpointClient) {
|
||||
ok(aBreakpointClient,
|
||||
"Breakpoint added, client received.");
|
||||
is(aBreakpointClient.location.url, gSources.selectedValue,
|
||||
"Breakpoint client url is the same.");
|
||||
is(aBreakpointClient.location.line, 6,
|
||||
"Breakpoint client line is new.");
|
||||
|
||||
is(aBreakpointClient.requestedLocation.url, gSources.selectedValue,
|
||||
"Requested location url is correct");
|
||||
is(aBreakpointClient.requestedLocation.line, 4,
|
||||
"Requested location line is correct");
|
||||
|
||||
onBpDebuggerAdd = true;
|
||||
maybeFinish();
|
||||
}
|
||||
|
||||
function onEditorBreakpointAdd(aEvent) {
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAdd);
|
||||
|
||||
is(gEditor.getBreakpoints().length, 1,
|
||||
"There is only one breakpoint in the editor");
|
||||
|
||||
ok(!gBreakpoints._getAdded({ url: gSources.selectedValue, line: 4 }),
|
||||
"There isn't any breakpoint added on an invalid line.");
|
||||
ok(!gBreakpoints._getRemoving({ url: gSources.selectedValue, line: 4 }),
|
||||
"There isn't any breakpoint removed from an invalid line.");
|
||||
|
||||
ok(gBreakpoints._getAdded({ url: gSources.selectedValue, line: 6 }),
|
||||
"There is a breakpoint added on the actual line.");
|
||||
ok(!gBreakpoints._getRemoving({ url: gSources.selectedValue, line: 6 }),
|
||||
"There isn't any breakpoint removed from the actual line.");
|
||||
|
||||
gBreakpoints._getAdded({ url: gSources.selectedValue, line: 6 }).then(aBreakpointClient => {
|
||||
is(aBreakpointClient.location.url, gSources.selectedValue,
|
||||
"Breakpoint client location url is correct.");
|
||||
is(aBreakpointClient.location.line, 6,
|
||||
"Breakpoint client location line is correct.");
|
||||
|
||||
onBpEditorAdd = true;
|
||||
maybeFinish();
|
||||
});
|
||||
}
|
||||
|
||||
function maybeFinish() {
|
||||
info("onBpDebuggerAdd: " + onBpDebuggerAdd);
|
||||
info("onBpEditorAdd: " + onBpEditorAdd);
|
||||
|
||||
if (onBpDebuggerAdd && onBpEditorAdd) {
|
||||
resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,322 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test if the context menu associated with each breakpoint does what it should.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources, gBreakpoints;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
|
||||
|
||||
waitForSourceShown(gPanel, "-01.js")
|
||||
.then(performTestWhileNotPaused)
|
||||
.then(performTestWhilePaused)
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
|
||||
function addBreakpoints() {
|
||||
return promise.resolve(null)
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.values[0], line: 5 }))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.values[1], line: 6 }))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.values[1], line: 7 }))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.values[1], line: 8 }))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.values[1], line: 9 }))
|
||||
}
|
||||
|
||||
function performTestWhileNotPaused() {
|
||||
info("Performing test while not paused...");
|
||||
|
||||
return addBreakpoints()
|
||||
.then(initialChecks)
|
||||
.then(() => checkBreakpointToggleSelf(0))
|
||||
.then(() => checkBreakpointToggleOthers(0))
|
||||
.then(() => checkBreakpointToggleSelf(1))
|
||||
.then(() => checkBreakpointToggleOthers(1))
|
||||
.then(() => checkBreakpointToggleSelf(2))
|
||||
.then(() => checkBreakpointToggleOthers(2))
|
||||
.then(() => checkBreakpointToggleSelf(3))
|
||||
.then(() => checkBreakpointToggleOthers(3))
|
||||
.then(() => checkBreakpointToggleSelf(4))
|
||||
.then(() => checkBreakpointToggleOthers(4))
|
||||
.then(testDeleteAll);
|
||||
}
|
||||
|
||||
function performTestWhilePaused() {
|
||||
info("Performing test while paused...");
|
||||
|
||||
return addBreakpoints()
|
||||
.then(initialChecks)
|
||||
.then(pauseAndCheck)
|
||||
.then(() => checkBreakpointToggleSelf(0))
|
||||
.then(() => checkBreakpointToggleOthers(0))
|
||||
.then(() => checkBreakpointToggleSelf(1))
|
||||
.then(() => checkBreakpointToggleOthers(1))
|
||||
.then(() => checkBreakpointToggleSelf(2))
|
||||
.then(() => checkBreakpointToggleOthers(2))
|
||||
.then(() => checkBreakpointToggleSelf(3))
|
||||
.then(() => checkBreakpointToggleOthers(3))
|
||||
.then(() => checkBreakpointToggleSelf(4))
|
||||
.then(() => checkBreakpointToggleOthers(4))
|
||||
.then(testDeleteAll);
|
||||
}
|
||||
|
||||
function pauseAndCheck() {
|
||||
let finished = waitForSourceAndCaretAndScopes(gPanel, "-01.js", 5).then(() => {
|
||||
is(gSources.selectedLabel, "code_script-switching-01.js",
|
||||
"The currently selected source is incorrect (3).");
|
||||
is(gSources.selectedIndex, 0,
|
||||
"The currently selected source is incorrect (4).");
|
||||
ok(isCaretPos(gPanel, 5),
|
||||
"The editor location is correct after pausing.");
|
||||
});
|
||||
|
||||
is(gSources.selectedLabel, "code_script-switching-02.js",
|
||||
"The currently selected source is incorrect (1).");
|
||||
is(gSources.selectedIndex, 1,
|
||||
"The currently selected source is incorrect (2).");
|
||||
ok(isCaretPos(gPanel, 9),
|
||||
"The editor location is correct before pausing.");
|
||||
|
||||
ensureThreadClientState(gPanel, "resumed").then(() => {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
});
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
function initialChecks() {
|
||||
for (let source in gSources) {
|
||||
for (let breakpoint in source) {
|
||||
ok(gBreakpoints._getAdded(breakpoint.attachment),
|
||||
"All breakpoint items should have corresponding promises (1).");
|
||||
ok(!gBreakpoints._getRemoving(breakpoint.attachment),
|
||||
"All breakpoint items should have corresponding promises (2).");
|
||||
ok(breakpoint.attachment.actor,
|
||||
"All breakpoint items should have corresponding promises (3).");
|
||||
is(!!breakpoint.attachment.disabled, false,
|
||||
"All breakpoints should initially be enabled.");
|
||||
|
||||
let actor = breakpoint.attachment.actor;
|
||||
let prefix = "bp-cMenu-"; // "breakpoints context menu"
|
||||
let enableSelfId = prefix + "enableSelf-" + actor + "-menuitem";
|
||||
let disableSelfId = prefix + "disableSelf-" + actor + "-menuitem";
|
||||
|
||||
is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true",
|
||||
"The 'Enable breakpoint' context menu item should initially be hidden'.");
|
||||
ok(!gDebugger.document.getElementById(disableSelfId).hasAttribute("hidden"),
|
||||
"The 'Disable breakpoint' context menu item should initially not be hidden'.");
|
||||
is(breakpoint.attachment.view.checkbox.getAttribute("checked"), "true",
|
||||
"All breakpoints should initially have a checked checkbox.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkBreakpointToggleSelf(aIndex) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelectorAll(".dbg-breakpoint")[aIndex],
|
||||
gDebugger);
|
||||
|
||||
let selectedBreakpoint = gSources._selectedBreakpointItem;
|
||||
|
||||
ok(gBreakpoints._getAdded(selectedBreakpoint.attachment),
|
||||
"There should be a breakpoint client available (1).");
|
||||
ok(!gBreakpoints._getRemoving(selectedBreakpoint.attachment),
|
||||
"There should be a breakpoint client available (2).");
|
||||
ok(selectedBreakpoint.attachment.actor,
|
||||
"There should be a breakpoint client available (3).");
|
||||
is(!!selectedBreakpoint.attachment.disabled, false,
|
||||
"The breakpoint should not be disabled yet (" + aIndex + ").");
|
||||
|
||||
gBreakpoints._getAdded(selectedBreakpoint.attachment).then(aBreakpointClient => {
|
||||
ok(aBreakpointClient,
|
||||
"There should be a breakpoint client available as a promise.");
|
||||
});
|
||||
|
||||
let actor = selectedBreakpoint.attachment.actor;
|
||||
let prefix = "bp-cMenu-"; // "breakpoints context menu"
|
||||
let enableSelfId = prefix + "enableSelf-" + actor + "-menuitem";
|
||||
let disableSelfId = prefix + "disableSelf-" + actor + "-menuitem";
|
||||
|
||||
is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true",
|
||||
"The 'Enable breakpoint' context menu item should be hidden'.");
|
||||
ok(!gDebugger.document.getElementById(disableSelfId).hasAttribute("hidden"),
|
||||
"The 'Disable breakpoint' context menu item should not be hidden'.");
|
||||
|
||||
ok(isCaretPos(gPanel, selectedBreakpoint.attachment.line),
|
||||
"The source editor caret position was incorrect (" + aIndex + ").");
|
||||
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED).then(() => {
|
||||
ok(!gBreakpoints._getAdded(selectedBreakpoint.attachment),
|
||||
"There should be no breakpoint client available (4).");
|
||||
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED).then(() => {
|
||||
ok(gBreakpoints._getAdded(selectedBreakpoint.attachment),
|
||||
"There should be a breakpoint client available (5).");
|
||||
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
// Test re-disabling this breakpoint.
|
||||
gSources._onEnableSelf(selectedBreakpoint.attachment.actor);
|
||||
is(selectedBreakpoint.attachment.disabled, false,
|
||||
"The current breakpoint should now be enabled.")
|
||||
|
||||
is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true",
|
||||
"The 'Enable breakpoint' context menu item should be hidden'.");
|
||||
ok(!gDebugger.document.getElementById(disableSelfId).hasAttribute("hidden"),
|
||||
"The 'Disable breakpoint' context menu item should not be hidden'.");
|
||||
ok(selectedBreakpoint.attachment.view.checkbox.hasAttribute("checked"),
|
||||
"The breakpoint should now be checked.");
|
||||
});
|
||||
|
||||
// Test disabling this breakpoint.
|
||||
gSources._onDisableSelf(selectedBreakpoint.attachment.actor);
|
||||
is(selectedBreakpoint.attachment.disabled, true,
|
||||
"The current breakpoint should now be disabled.")
|
||||
|
||||
ok(!gDebugger.document.getElementById(enableSelfId).hasAttribute("hidden"),
|
||||
"The 'Enable breakpoint' context menu item should not be hidden'.");
|
||||
is(gDebugger.document.getElementById(disableSelfId).getAttribute("hidden"), "true",
|
||||
"The 'Disable breakpoint' context menu item should be hidden'.");
|
||||
ok(!selectedBreakpoint.attachment.view.checkbox.hasAttribute("checked"),
|
||||
"The breakpoint should now be unchecked.");
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function checkBreakpointToggleOthers(aIndex) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED, 4).then(() => {
|
||||
let selectedBreakpoint = gSources._selectedBreakpointItem;
|
||||
|
||||
ok(gBreakpoints._getAdded(selectedBreakpoint.attachment),
|
||||
"There should be a breakpoint client available (6).");
|
||||
ok(!gBreakpoints._getRemoving(selectedBreakpoint.attachment),
|
||||
"There should be a breakpoint client available (7).");
|
||||
ok(selectedBreakpoint.attachment.actor,
|
||||
"There should be a breakpoint client available (8).");
|
||||
is(!!selectedBreakpoint.attachment.disabled, false,
|
||||
"The targetted breakpoint should not have been disabled (" + aIndex + ").");
|
||||
|
||||
for (let source in gSources) {
|
||||
for (let otherBreakpoint in source) {
|
||||
if (otherBreakpoint != selectedBreakpoint) {
|
||||
ok(!gBreakpoints._getAdded(otherBreakpoint.attachment),
|
||||
"There should be no breakpoint client for a disabled breakpoint (9).");
|
||||
is(otherBreakpoint.attachment.disabled, true,
|
||||
"Non-targetted breakpoints should have been disabled (10).");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED, 4).then(() => {
|
||||
for (let source in gSources) {
|
||||
for (let someBreakpoint in source) {
|
||||
ok(gBreakpoints._getAdded(someBreakpoint.attachment),
|
||||
"There should be a breakpoint client for all enabled breakpoints (11).");
|
||||
is(someBreakpoint.attachment.disabled, false,
|
||||
"All breakpoints should now have been enabled (12).");
|
||||
}
|
||||
}
|
||||
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED, 5).then(() => {
|
||||
for (let source in gSources) {
|
||||
for (let someBreakpoint in source) {
|
||||
ok(!gBreakpoints._getAdded(someBreakpoint.attachment),
|
||||
"There should be no breakpoint client for a disabled breakpoint (13).");
|
||||
is(someBreakpoint.attachment.disabled, true,
|
||||
"All breakpoints should now have been disabled (14).");
|
||||
}
|
||||
}
|
||||
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED, 5).then(() => {
|
||||
for (let source in gSources) {
|
||||
for (let someBreakpoint in source) {
|
||||
ok(gBreakpoints._getAdded(someBreakpoint.attachment),
|
||||
"There should be a breakpoint client for all enabled breakpoints (15).");
|
||||
is(someBreakpoint.attachment.disabled, false,
|
||||
"All breakpoints should now have been enabled (16).");
|
||||
}
|
||||
}
|
||||
|
||||
// Done.
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
// Test re-enabling all breakpoints.
|
||||
enableAll();
|
||||
});
|
||||
|
||||
// Test disabling all breakpoints.
|
||||
disableAll();
|
||||
});
|
||||
|
||||
// Test re-enabling other breakpoints.
|
||||
enableOthers();
|
||||
});
|
||||
|
||||
// Test disabling other breakpoints.
|
||||
disableOthers();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testDeleteAll() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED, 5).then(() => {
|
||||
ok(!gSources._selectedBreakpointItem,
|
||||
"There should be no breakpoint available after removing all breakpoints.");
|
||||
|
||||
for (let source in gSources) {
|
||||
for (let otherBreakpoint in source) {
|
||||
ok(false, "It's a trap!");
|
||||
}
|
||||
}
|
||||
|
||||
// Done.
|
||||
deferred.resolve()
|
||||
});
|
||||
|
||||
// Test deleting all breakpoints.
|
||||
deleteAll();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function disableOthers() {
|
||||
gSources._onDisableOthers(gSources._selectedBreakpointItem.attachment.actor);
|
||||
}
|
||||
function enableOthers() {
|
||||
gSources._onEnableOthers(gSources._selectedBreakpointItem.attachment.actor);
|
||||
}
|
||||
function disableAll() {
|
||||
gSources._onDisableAll();
|
||||
}
|
||||
function enableAll() {
|
||||
gSources._onEnableAll();
|
||||
}
|
||||
function deleteAll() {
|
||||
gSources._onDeleteAll();
|
||||
}
|
||||
}
|
331
browser/devtools/debugger/test/browser_dbg_breakpoints-editor.js
Normal file
331
browser/devtools/debugger/test/browser_dbg_breakpoints-editor.js
Normal file
@ -0,0 +1,331 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 723069: Test the debugger breakpoint API and connection to the
|
||||
* source editor.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
|
||||
gBreakpointsAdded = gBreakpoints._added;
|
||||
gBreakpointsRemoving = gBreakpoints._removing;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 6).then(performTest);
|
||||
gDebuggee.firstCall();
|
||||
});
|
||||
|
||||
function performTest() {
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
is(gSources.itemCount, 2,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("debugger"), 172,
|
||||
"The correct source was loaded initially.");
|
||||
is(gSources.selectedValue, gSources.values[1],
|
||||
"The correct source is selected.");
|
||||
|
||||
is(gBreakpointsAdded.size, 0,
|
||||
"No breakpoints currently added.");
|
||||
is(gBreakpointsRemoving.size, 0,
|
||||
"No breakpoints currently being removed.");
|
||||
is(gEditor.getBreakpoints().length, 0,
|
||||
"No breakpoints currently shown in the editor.");
|
||||
|
||||
ok(!gBreakpoints._getAdded({ url: "foo", line: 3 }),
|
||||
"_getAdded('foo', 3) returns falsey.");
|
||||
ok(!gBreakpoints._getRemoving({ url: "bar", line: 3 }),
|
||||
"_getRemoving('bar', 3) returns falsey.");
|
||||
|
||||
is(gSources.values[1], gSources.selectedValue,
|
||||
"The second source should be currently selected.");
|
||||
|
||||
info("Add the first breakpoint.");
|
||||
let location = { url: gSources.selectedValue, line: 6 };
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddFirst);
|
||||
gPanel.addBreakpoint(location).then(onBreakpointAddFirst);
|
||||
}
|
||||
|
||||
let breakpointsAdded = 0;
|
||||
let breakpointsRemoved = 0;
|
||||
let editorBreakpointChanges = 0;
|
||||
|
||||
function onEditorBreakpointAddFirst(aEvent) {
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddFirst);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent,
|
||||
"breakpoint1 added to the editor.");
|
||||
is(aEvent.added.length, 1,
|
||||
"One breakpoint added to the editor.");
|
||||
is(aEvent.removed.length, 0,
|
||||
"No breakpoint was removed from the editor.");
|
||||
is(aEvent.added[0].line, 5,
|
||||
"Editor breakpoint line is correct.");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 1,
|
||||
"editor.getBreakpoints().length is correct.");
|
||||
}
|
||||
|
||||
function onBreakpointAddFirst(aBreakpointClient) {
|
||||
breakpointsAdded++;
|
||||
|
||||
ok(aBreakpointClient,
|
||||
"breakpoint1 added, client received.");
|
||||
is(aBreakpointClient.location.url, gSources.selectedValue,
|
||||
"breakpoint1 client url is correct.");
|
||||
is(aBreakpointClient.location.line, 6,
|
||||
"breakpoint1 client line is correct.");
|
||||
|
||||
ok(gBreakpoints._getAdded(aBreakpointClient.location),
|
||||
"breakpoint1 client found in the list of added breakpoints.");
|
||||
ok(!gBreakpoints._getRemoving(aBreakpointClient.location),
|
||||
"breakpoint1 client found in the list of removing breakpoints.");
|
||||
|
||||
is(gBreakpointsAdded.size, 1,
|
||||
"The list of added breakpoints holds only one breakpoint.");
|
||||
is(gBreakpointsRemoving.size, 0,
|
||||
"The list of removing breakpoints holds no breakpoint.");
|
||||
|
||||
gBreakpoints._getAdded(aBreakpointClient.location).then(aClient => {
|
||||
is(aClient, aBreakpointClient,
|
||||
"_getAdded() returns the correct breakpoint.");
|
||||
});
|
||||
|
||||
is(gSources.values[1], gSources.selectedValue,
|
||||
"The second source should be currently selected.");
|
||||
|
||||
info("Remove the first breakpoint.");
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointRemoveFirst);
|
||||
gPanel.removeBreakpoint(aBreakpointClient.location).then(onBreakpointRemoveFirst);
|
||||
}
|
||||
|
||||
function onEditorBreakpointRemoveFirst(aEvent) {
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointRemoveFirst);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent,
|
||||
"breakpoint1 removed from the editor.");
|
||||
is(aEvent.added.length, 0,
|
||||
"No breakpoint was added to the editor.");
|
||||
is(aEvent.removed.length, 1,
|
||||
"One breakpoint was removed from the editor.");
|
||||
is(aEvent.removed[0].line, 5,
|
||||
"Editor breakpoint line is correct.");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 0,
|
||||
"editor.getBreakpoints().length is correct.");
|
||||
}
|
||||
|
||||
function onBreakpointRemoveFirst(aLocation) {
|
||||
breakpointsRemoved++;
|
||||
|
||||
ok(aLocation,
|
||||
"breakpoint1 removed");
|
||||
is(aLocation.url, gSources.selectedValue,
|
||||
"breakpoint1 removal url is correct.");
|
||||
is(aLocation.line, 6,
|
||||
"breakpoint1 removal line is correct.");
|
||||
|
||||
testBreakpointAddBackground();
|
||||
}
|
||||
|
||||
function testBreakpointAddBackground() {
|
||||
is(gBreakpointsAdded.size, 0,
|
||||
"No breakpoints currently added.");
|
||||
is(gBreakpointsRemoving.size, 0,
|
||||
"No breakpoints currently being removed.");
|
||||
is(gEditor.getBreakpoints().length, 0,
|
||||
"No breakpoints currently shown in the editor.");
|
||||
|
||||
ok(!gBreakpoints._getAdded({ url: gSources.selectedValue, line: 6 }),
|
||||
"_getAdded('gSources.selectedValue', 6) returns falsey.");
|
||||
ok(!gBreakpoints._getRemoving({ url: gSources.selectedValue, line: 6 }),
|
||||
"_getRemoving('gSources.selectedValue', 6) returns falsey.");
|
||||
|
||||
is(gSources.values[1], gSources.selectedValue,
|
||||
"The second source should be currently selected.");
|
||||
|
||||
info("Add a breakpoint to the first source, which is not selected.");
|
||||
let location = { url: gSources.values[0], line: 5 };
|
||||
let options = { noEditorUpdate: true };
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddBackgroundTrap);
|
||||
gPanel.addBreakpoint(location, options).then(onBreakpointAddBackground);
|
||||
}
|
||||
|
||||
function onEditorBreakpointAddBackgroundTrap(aEvent) {
|
||||
// Trap listener: no breakpoint must be added to the editor when a
|
||||
// breakpoint is added to a source that is not currently selected.
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddBackgroundTrap);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(false, "breakpoint2 must not be added to the editor.");
|
||||
}
|
||||
|
||||
function onBreakpointAddBackground(aBreakpointClient, aResponseError) {
|
||||
breakpointsAdded++;
|
||||
|
||||
ok(aBreakpointClient,
|
||||
"breakpoint2 added, client received");
|
||||
is(aBreakpointClient.location.url, gSources.values[0],
|
||||
"breakpoint2 client url is correct.");
|
||||
is(aBreakpointClient.location.line, 5,
|
||||
"breakpoint2 client line is correct.");
|
||||
|
||||
ok(gBreakpoints._getAdded(aBreakpointClient.location),
|
||||
"breakpoint2 client found in the list of added breakpoints.");
|
||||
ok(!gBreakpoints._getRemoving(aBreakpointClient.location),
|
||||
"breakpoint2 client found in the list of removing breakpoints.");
|
||||
|
||||
is(gBreakpointsAdded.size, 1,
|
||||
"The list of added breakpoints holds only one breakpoint.");
|
||||
is(gBreakpointsRemoving.size, 0,
|
||||
"The list of removing breakpoints holds no breakpoint.");
|
||||
|
||||
gBreakpoints._getAdded(aBreakpointClient.location).then(aClient => {
|
||||
is(aClient, aBreakpointClient,
|
||||
"_getAdded() returns the correct breakpoint.");
|
||||
});
|
||||
|
||||
is(gSources.values[1], gSources.selectedValue,
|
||||
"The second source should be currently selected.");
|
||||
|
||||
// Remove the trap listener.
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddBackgroundTrap);
|
||||
|
||||
info("Switch to the first source, which is not yet selected");
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddSwitch);
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onEditorTextChanged);
|
||||
gSources.selectedIndex = 0;
|
||||
}
|
||||
|
||||
function onEditorBreakpointAddSwitch(aEvent) {
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddSwitch);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent,
|
||||
"breakpoint2 added to the editor.");
|
||||
is(aEvent.added.length, 1,
|
||||
"One breakpoint added to the editor.");
|
||||
is(aEvent.removed.length, 0,
|
||||
"No breakpoint was removed from the editor.");
|
||||
is(aEvent.added[0].line, 4,
|
||||
"Editor breakpoint line is correct.");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 1,
|
||||
"editor.getBreakpoints().length is correct");
|
||||
}
|
||||
|
||||
function onEditorTextChanged() {
|
||||
// Wait for the actual text to be shown.
|
||||
if (gEditor.getText() != gDebugger.L10N.getStr("loadingText")) {
|
||||
onEditorTextReallyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
function onEditorTextReallyChanged() {
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onEditorTextChanged);
|
||||
|
||||
is(gEditor.getText().indexOf("debugger"), -1,
|
||||
"The second source is no longer displayed.");
|
||||
is(gEditor.getText().indexOf("firstCall"), 118,
|
||||
"The first source is displayed.");
|
||||
|
||||
is(gSources.values[0], gSources.selectedValue,
|
||||
"The first source should be currently selected.");
|
||||
|
||||
let window = gEditor.editorElement.contentWindow;
|
||||
executeSoon(() => window.mozRequestAnimationFrame(onReadyForClick));
|
||||
}
|
||||
|
||||
function onReadyForClick() {
|
||||
info("Remove the second breakpoint using the mouse.");
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointRemoveSecond);
|
||||
|
||||
let iframe = gEditor.editorElement;
|
||||
let testWin = iframe.ownerDocument.defaultView;
|
||||
|
||||
// Flush the layout for the iframe.
|
||||
info("rect " + iframe.contentDocument.documentElement.getBoundingClientRect());
|
||||
|
||||
let utils = testWin
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
let lineOffset = gEditor.getLineStart(4);
|
||||
let coords = gEditor.getLocationAtOffset(lineOffset);
|
||||
|
||||
let rect = iframe.getBoundingClientRect();
|
||||
let left = rect.left + 10;
|
||||
let top = rect.top + coords.y + 4;
|
||||
utils.sendMouseEventToWindow("mousedown", left, top, 0, 1, 0, false, 0, 0);
|
||||
utils.sendMouseEventToWindow("mouseup", left, top, 0, 1, 0, false, 0, 0);
|
||||
}
|
||||
|
||||
function onEditorBreakpointRemoveSecond(aEvent) {
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointRemoveSecond);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent,
|
||||
"breakpoint2 removed from the editor.");
|
||||
is(aEvent.added.length, 0,
|
||||
"No breakpoint was added to the editor.");
|
||||
is(aEvent.removed.length, 1,
|
||||
"One breakpoint was removed from the editor.");
|
||||
is(aEvent.removed[0].line, 4,
|
||||
"Editor breakpoint line is correct.");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 0,
|
||||
"editor.getBreakpoints().length is correct.");
|
||||
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
|
||||
finalCheck();
|
||||
closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
|
||||
gDebugger.gThreadClient.resume();
|
||||
}
|
||||
|
||||
function finalCheck() {
|
||||
is(gBreakpointsAdded.size, 0,
|
||||
"No breakpoints currently added.");
|
||||
is(gBreakpointsRemoving.size, 0,
|
||||
"No breakpoints currently being removed.");
|
||||
is(gEditor.getBreakpoints().length, 0,
|
||||
"No breakpoints currently shown in the editor.");
|
||||
|
||||
ok(!gBreakpoints._getAdded({ url: gSources.values[0], line: 5 }),
|
||||
"_getAdded('gSources.values[0]', 5) returns falsey.");
|
||||
ok(!gBreakpoints._getRemoving({ url: gSources.values[0], line: 5 }),
|
||||
"_getRemoving('gSources.values[0]', 5) returns falsey.");
|
||||
|
||||
ok(!gBreakpoints._getAdded({ url: gSources.values[1], line: 6 }),
|
||||
"_getAdded('gSources.values[1]', 6) returns falsey.");
|
||||
ok(!gBreakpoints._getRemoving({ url: gSources.values[1], line: 6 }),
|
||||
"_getRemoving('gSources.values[1]', 6) returns falsey.");
|
||||
|
||||
ok(!gBreakpoints._getAdded({ url: "foo", line: 3 }),
|
||||
"_getAdded('foo', 3) returns falsey.");
|
||||
ok(!gBreakpoints._getRemoving({ url: "bar", line: 3 }),
|
||||
"_getRemoving('bar', 3) returns falsey.");
|
||||
|
||||
is(breakpointsAdded, 2,
|
||||
"Correct number of breakpoints have been added.");
|
||||
is(breakpointsRemoved, 1,
|
||||
"Correct number of breakpoints have been removed.");
|
||||
is(editorBreakpointChanges, 4,
|
||||
"Correct number of editor breakpoint changes.");
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test if breakpoints are highlighted when they should.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
waitForSourceShown(gPanel, "-01.js")
|
||||
.then(addBreakpoints)
|
||||
.then(() => clickBreakpointAndCheck(0, 0, 5))
|
||||
.then(() => clickBreakpointAndCheck(1, 1, 6))
|
||||
.then(() => clickBreakpointAndCheck(2, 1, 7))
|
||||
.then(() => clickBreakpointAndCheck(3, 1, 8))
|
||||
.then(() => clickBreakpointAndCheck(4, 1, 9))
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
|
||||
function addBreakpoints() {
|
||||
return promise.resolve(null)
|
||||
.then(() => initialChecks(0, 1))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.values[0], line: 5 }))
|
||||
.then(() => initialChecks(0, 5))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.values[1], line: 6 }))
|
||||
.then(() => waitForSourceShown(gPanel, "-02.js"))
|
||||
.then(() => waitForCaretUpdated(gPanel, 6))
|
||||
.then(() => initialChecks(1, 6))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.values[1], line: 7 }))
|
||||
.then(() => initialChecks(1, 7))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.values[1], line: 8 }))
|
||||
.then(() => initialChecks(1, 8))
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.values[1], line: 9 }))
|
||||
.then(() => initialChecks(1, 9));
|
||||
}
|
||||
|
||||
function initialChecks(aSourceIndex, aCaretLine) {
|
||||
checkEditorContents(aSourceIndex);
|
||||
|
||||
is(gSources.selectedLabel, gSources.items[aSourceIndex].label,
|
||||
"The currently selected source label is incorrect (0).");
|
||||
is(gSources.selectedValue, gSources.items[aSourceIndex].value,
|
||||
"The currently selected source value is incorrect (0).");
|
||||
ok(isCaretPos(gPanel, aCaretLine),
|
||||
"The editor caret line and column were incorrect (0).");
|
||||
}
|
||||
|
||||
function clickBreakpointAndCheck(aBreakpointIndex, aSourceIndex, aCaretLine) {
|
||||
let finished = waitForCaretUpdated(gPanel, aCaretLine).then(() => {
|
||||
checkHighlight(gSources.values[aSourceIndex], aCaretLine);
|
||||
checkEditorContents(aSourceIndex);
|
||||
|
||||
is(gSources.selectedLabel, gSources.items[aSourceIndex].label,
|
||||
"The currently selected source label is incorrect (1).");
|
||||
is(gSources.selectedValue, gSources.items[aSourceIndex].value,
|
||||
"The currently selected source value is incorrect (1).");
|
||||
ok(isCaretPos(gPanel, aCaretLine),
|
||||
"The editor caret line and column were incorrect (1).");
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelectorAll(".dbg-breakpoint")[aBreakpointIndex],
|
||||
gDebugger);
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
function checkHighlight(aUrl, aLine) {
|
||||
is(gSources._selectedBreakpointItem, gSources.getBreakpoint({ url: aUrl, line: aLine }),
|
||||
"The currently selected breakpoint item is incorrect.");
|
||||
is(gSources._selectedBreakpointItem.attachment.url, aUrl,
|
||||
"The selected breakpoint item's source location attachment is incorrect.");
|
||||
is(gSources._selectedBreakpointItem.attachment.line, aLine,
|
||||
"The selected breakpoint item's source line number is incorrect.");
|
||||
ok(gSources._selectedBreakpointItem.target.classList.contains("selected"),
|
||||
"The selected breakpoint item's target should have a selected class.");
|
||||
}
|
||||
|
||||
function checkEditorContents(aSourceIndex) {
|
||||
if (aSourceIndex == 0) {
|
||||
is(gEditor.getText().indexOf("firstCall"), 118,
|
||||
"The first source is correctly displayed.");
|
||||
} else {
|
||||
is(gEditor.getText().indexOf("debugger"), 172,
|
||||
"The second source is correctly displayed.");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 771452: Make sure that setting a breakpoint in an inline source doesn't
|
||||
* add it twice.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_inline-script.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
addBreakpoint();
|
||||
});
|
||||
}
|
||||
|
||||
function addBreakpoint() {
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 16).then(() => {
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"The debugger statement was reached.");
|
||||
ok(isCaretPos(gPanel, 16),
|
||||
"The source editor caret position is incorrect (1).");
|
||||
|
||||
gPanel.addBreakpoint({ url: TAB_URL, line: 20 }).then(() => {
|
||||
testResume();
|
||||
});
|
||||
});
|
||||
|
||||
gDebuggee.runDebuggerStatement();
|
||||
}
|
||||
|
||||
function testResume() {
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"The breakpoint wasn't hit yet.");
|
||||
|
||||
gDebugger.gThreadClient.resume(() => {
|
||||
gDebugger.gThreadClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES).then(() => {
|
||||
is(aPacket.why.type, "breakpoint",
|
||||
"Execution has advanced to the next breakpoint.");
|
||||
isnot(aPacket.why.type, "debuggerStatement",
|
||||
"The breakpoint was hit before the debugger statement.");
|
||||
ok(isCaretPos(gPanel, 20),
|
||||
"The source editor caret position is incorrect (2).");
|
||||
|
||||
testBreakpointHit();
|
||||
});
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
});
|
||||
}
|
||||
|
||||
function testBreakpointHit() {
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"The breakpoint was hit.");
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES).then(() => {
|
||||
is(aPacket.why.type, "debuggerStatement",
|
||||
"Execution has advanced to the next line.");
|
||||
isnot(aPacket.why.type, "breakpoint",
|
||||
"No ghost breakpoint was hit.");
|
||||
ok(isCaretPos(gPanel, 20),
|
||||
"The source editor caret position is incorrect (3).");
|
||||
|
||||
resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
255
browser/devtools/debugger/test/browser_dbg_breakpoints-pane.js
Normal file
255
browser/devtools/debugger/test/browser_dbg_breakpoints-pane.js
Normal file
@ -0,0 +1,255 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 723071: Test adding a pane to display the list of breakpoints across
|
||||
* all sources in the debuggee.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
|
||||
gBreakpointsAdded = gBreakpoints._added;
|
||||
gBreakpointsRemoving = gBreakpoints._removing;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 6).then(performTest);
|
||||
gDebuggee.firstCall();
|
||||
});
|
||||
|
||||
let breakpointsAdded = 0;
|
||||
let breakpointsDisabled = 0;
|
||||
let breakpointsRemoved = 0;
|
||||
|
||||
function performTest() {
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
is(gSources.itemCount, 2,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("debugger"), 172,
|
||||
"The correct source was loaded initially.");
|
||||
is(gSources.selectedValue, gSources.values[1],
|
||||
"The correct source is selected.");
|
||||
|
||||
is(gBreakpointsAdded.size, 0,
|
||||
"No breakpoints currently added.");
|
||||
is(gBreakpointsRemoving.size, 0,
|
||||
"No breakpoints currently being removed.");
|
||||
is(gEditor.getBreakpoints().length, 0,
|
||||
"No breakpoints currently shown in the editor.");
|
||||
|
||||
ok(!gBreakpoints._getAdded({ url: "foo", line: 3 }),
|
||||
"_getAdded('foo', 3) returns falsey.");
|
||||
ok(!gBreakpoints._getRemoving({ url: "bar", line: 3 }),
|
||||
"_getRemoving('bar', 3) returns falsey.");
|
||||
|
||||
let breakpointsParent = gSources.widget._parent;
|
||||
let breakpointsList = gSources.widget._list;
|
||||
|
||||
is(breakpointsParent.childNodes.length, 1, // one sources list
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.childNodes.length, 1, // one sources group
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.querySelectorAll(".dbg-breakpoint").length, 0,
|
||||
"No breakpoints should be visible at this point.");
|
||||
|
||||
addBreakpoints(true).then(() => {
|
||||
is(breakpointsAdded, 3,
|
||||
"Should have added 3 breakpoints so far.");
|
||||
is(breakpointsDisabled, 0,
|
||||
"Shouldn't have disabled anything so far.");
|
||||
is(breakpointsRemoved, 0,
|
||||
"Shouldn't have removed anything so far.");
|
||||
|
||||
is(breakpointsParent.childNodes.length, 1, // one sources list
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.childNodes.length, 1, // one sources group
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.querySelectorAll(".dbg-breakpoint").length, 3,
|
||||
"3 breakpoints should be visible at this point.");
|
||||
|
||||
disableBreakpoints().then(() => {
|
||||
is(breakpointsAdded, 3,
|
||||
"Should still have 3 breakpoints added so far.");
|
||||
is(breakpointsDisabled, 3,
|
||||
"Should have 3 disabled breakpoints.");
|
||||
is(breakpointsRemoved, 0,
|
||||
"Shouldn't have removed anything so far.");
|
||||
|
||||
is(breakpointsParent.childNodes.length, 1, // one sources list
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.childNodes.length, 1, // one sources group
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.querySelectorAll(".dbg-breakpoint").length, breakpointsAdded,
|
||||
"Should have the same number of breakpoints in the pane.");
|
||||
is(breakpointsList.querySelectorAll(".dbg-breakpoint").length, breakpointsDisabled,
|
||||
"Should have the same number of disabled breakpoints.");
|
||||
|
||||
addBreakpoints().then(() => {
|
||||
is(breakpointsAdded, 3,
|
||||
"Should still have only 3 breakpoints added so far.");
|
||||
is(breakpointsDisabled, 3,
|
||||
"Should still have 3 disabled breakpoints.");
|
||||
is(breakpointsRemoved, 0,
|
||||
"Shouldn't have removed anything so far.");
|
||||
|
||||
is(breakpointsParent.childNodes.length, 1, // one sources list
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.childNodes.length, 1, // one sources group
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.querySelectorAll(".dbg-breakpoint").length, breakpointsAdded,
|
||||
"Since half of the breakpoints already existed, but disabled, " +
|
||||
"only half of the added breakpoints are actually in the pane.");
|
||||
|
||||
removeBreakpoints().then(() => {
|
||||
is(breakpointsRemoved, 3,
|
||||
"Should have 3 removed breakpoints.");
|
||||
|
||||
is(breakpointsParent.childNodes.length, 1, // one sources list
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.childNodes.length, 1, // one sources group
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.querySelectorAll(".dbg-breakpoint").length, 0,
|
||||
"No breakpoints should be visible at this point.");
|
||||
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
|
||||
finalCheck();
|
||||
closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
|
||||
gDebugger.gThreadClient.resume();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function addBreakpoints(aIncrementFlag) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gPanel.addBreakpoint({ url: gSources.selectedValue, line: 6 }).then(aClient => {
|
||||
onBreakpointAdd(aClient, {
|
||||
increment: aIncrementFlag,
|
||||
line: 6,
|
||||
text: "eval(\"debugger;\");"
|
||||
});
|
||||
|
||||
gPanel.addBreakpoint({ url: gSources.selectedValue, line: 7 }).then(aClient => {
|
||||
onBreakpointAdd(aClient, {
|
||||
increment: aIncrementFlag,
|
||||
line: 7,
|
||||
text: "function foo() {}"
|
||||
});
|
||||
|
||||
gPanel.addBreakpoint({ url: gSources.selectedValue, line: 9 }).then(aClient => {
|
||||
onBreakpointAdd(aClient, {
|
||||
increment: aIncrementFlag,
|
||||
line: 9,
|
||||
text: "foo();"
|
||||
});
|
||||
|
||||
deferred.resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function disableBreakpoints() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let nodes = breakpointsList.querySelectorAll(".dbg-breakpoint");
|
||||
info("Nodes to disable: " + breakpointsAdded.length);
|
||||
|
||||
is(nodes.length, breakpointsAdded,
|
||||
"The number of nodes to disable is incorrect.");
|
||||
|
||||
for (let node of nodes) {
|
||||
info("Disabling breakpoint: " + node.id);
|
||||
|
||||
let sourceItem = gSources.getItemForElement(node);
|
||||
let breakpointItem = gSources.getItemForElement.call(sourceItem, node);
|
||||
info("Found data: " + breakpointItem.attachment.toSource());
|
||||
|
||||
gSources.disableBreakpoint(breakpointItem.attachment).then(() => {
|
||||
if (++breakpointsDisabled == breakpointsAdded) {
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function removeBreakpoints() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let nodes = breakpointsList.querySelectorAll(".dbg-breakpoint");
|
||||
info("Nodes to remove: " + breakpointsAdded.length);
|
||||
|
||||
is(nodes.length, breakpointsAdded,
|
||||
"The number of nodes to remove is incorrect.");
|
||||
|
||||
for (let node of nodes) {
|
||||
info("Removing breakpoint: " + node.id);
|
||||
|
||||
let sourceItem = gSources.getItemForElement(node);
|
||||
let breakpointItem = gSources.getItemForElement.call(sourceItem, node);
|
||||
info("Found data: " + breakpointItem.attachment.toSource());
|
||||
|
||||
gPanel.removeBreakpoint(breakpointItem.attachment).then(() => {
|
||||
if (++breakpointsRemoved == breakpointsAdded) {
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function onBreakpointAdd(aBreakpointClient, aTestData) {
|
||||
if (aTestData.increment) {
|
||||
breakpointsAdded++;
|
||||
}
|
||||
|
||||
is(breakpointsList.querySelectorAll(".dbg-breakpoint").length, breakpointsAdded,
|
||||
aTestData.increment
|
||||
? "Should have added a breakpoint in the pane."
|
||||
: "Should have the same number of breakpoints in the pane.");
|
||||
|
||||
let id = "breakpoint-" + aBreakpointClient.actor;
|
||||
let node = gDebugger.document.getElementById(id);
|
||||
let line = node.getElementsByClassName("dbg-breakpoint-line")[0];
|
||||
let text = node.getElementsByClassName("dbg-breakpoint-text")[0];
|
||||
let check = node.querySelector("checkbox");
|
||||
|
||||
is(node.id, id,
|
||||
"Breakpoint element " + id + " found successfully.");
|
||||
is(line.getAttribute("value"), aTestData.line,
|
||||
"The expected information wasn't found in the breakpoint element.");
|
||||
is(text.getAttribute("value"), aTestData.text,
|
||||
"The expected line text wasn't found in the breakpoint element.");
|
||||
is(check.getAttribute("checked"), "true",
|
||||
"The breakpoint enable checkbox is checked as expected.");
|
||||
}
|
||||
}
|
||||
|
||||
function finalCheck() {
|
||||
is(gBreakpointsAdded.size, 0,
|
||||
"No breakpoints currently added.");
|
||||
is(gBreakpointsRemoving.size, 0,
|
||||
"No breakpoints currently being removed.");
|
||||
is(gEditor.getBreakpoints().length, 0,
|
||||
"No breakpoints currently shown in the editor.");
|
||||
}
|
||||
}
|
@ -1,308 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 723069: test the debugger breakpoint API and connection to the source
|
||||
* editor.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
|
||||
|
||||
let gPane = null;
|
||||
let gTab = null;
|
||||
let gDebuggee = null;
|
||||
let gDebugger = null;
|
||||
let gEditor = null;
|
||||
let gSources = null;
|
||||
let gBreakpoints = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
resumed = true;
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", onSourceShown);
|
||||
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
framesAdded = true;
|
||||
executeSoon(startTest);
|
||||
});
|
||||
|
||||
executeSoon(function() {
|
||||
gDebuggee.firstCall();
|
||||
});
|
||||
});
|
||||
|
||||
function onSourceShown(aEvent)
|
||||
{
|
||||
scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
|
||||
executeSoon(startTest);
|
||||
}
|
||||
|
||||
function startTest()
|
||||
{
|
||||
if (scriptShown && framesAdded && !testStarted) {
|
||||
gDebugger.removeEventListener("Debugger:SourceShown", onSourceShown);
|
||||
testStarted = true;
|
||||
Services.tm.currentThread.dispatch({ run: performTest }, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function performTest()
|
||||
{
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gEditor = gDebugger.editor;
|
||||
gBreakpoints = gPane.getAllBreakpoints();
|
||||
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(gSources.itemCount, 2,
|
||||
"Found the expected number of scripts.");
|
||||
|
||||
isnot(gEditor.getText().indexOf("debugger"), -1,
|
||||
"The correct script was loaded initially.");
|
||||
|
||||
isnot(gSources.selectedValue, gSources.values[0],
|
||||
"The correct script is selected");
|
||||
|
||||
is(Object.keys(gBreakpoints), 0, "no breakpoints");
|
||||
ok(!gPane.getBreakpoint("foo", 3), "getBreakpoint('foo', 3) returns falsey");
|
||||
is(gEditor.getBreakpoints().length, 0, "no breakpoints in the editor");
|
||||
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddFirst);
|
||||
executeSoon(function() {
|
||||
gPane.addBreakpoint({url: gSources.selectedValue, line: 6}, onBreakpointAddFirst);
|
||||
});
|
||||
}
|
||||
|
||||
let breakpointsAdded = 0;
|
||||
let breakpointsRemoved = 0;
|
||||
let editorBreakpointChanges = 0;
|
||||
|
||||
function onEditorBreakpointAddFirst(aEvent)
|
||||
{
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddFirst);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent, "breakpoint1 added to the editor");
|
||||
is(aEvent.added.length, 1, "one breakpoint added to the editor");
|
||||
is(aEvent.removed.length, 0, "no breakpoint was removed from the editor");
|
||||
is(aEvent.added[0].line, 5, "editor breakpoint line is correct");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 1,
|
||||
"editor.getBreakpoints().length is correct");
|
||||
}
|
||||
|
||||
function onBreakpointAddFirst(aBreakpointClient, aResponseError)
|
||||
{
|
||||
breakpointsAdded++;
|
||||
|
||||
ok(aBreakpointClient, "breakpoint1 added, client received");
|
||||
ok(!aResponseError, "breakpoint1 added without errors");
|
||||
is(aBreakpointClient.location.url, gSources.selectedValue,
|
||||
"breakpoint1 client url is correct");
|
||||
is(aBreakpointClient.location.line, 6,
|
||||
"breakpoint1 client line is correct");
|
||||
|
||||
executeSoon(function() {
|
||||
ok(aBreakpointClient.actor in gBreakpoints,
|
||||
"breakpoint1 client found in the list of debugger breakpoints");
|
||||
is(Object.keys(gBreakpoints).length, 1,
|
||||
"the list of debugger breakpoints holds only one breakpoint");
|
||||
is(gPane.getBreakpoint(gSources.selectedValue, 6), aBreakpointClient,
|
||||
"getBreakpoint returns the correct breakpoint");
|
||||
|
||||
info("remove the first breakpoint");
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointRemoveFirst);
|
||||
gPane.removeBreakpoint(aBreakpointClient, onBreakpointRemoveFirst);
|
||||
});
|
||||
}
|
||||
|
||||
function onBreakpointRemoveFirst(aLocation)
|
||||
{
|
||||
breakpointsRemoved++;
|
||||
|
||||
ok(aLocation, "breakpoint1 removed");
|
||||
is(aLocation.url, gSources.selectedValue, "breakpoint1 remove: url is correct");
|
||||
is(aLocation.line, 6, "breakpoint1 remove: line is correct");
|
||||
|
||||
executeSoon(testBreakpointAddBackground);
|
||||
}
|
||||
|
||||
function onEditorBreakpointRemoveFirst(aEvent)
|
||||
{
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointRemoveFirst);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent, "breakpoint1 removed from the editor");
|
||||
is(aEvent.added.length, 0, "no breakpoint was added to the editor");
|
||||
is(aEvent.removed.length, 1, "one breakpoint was removed from the editor");
|
||||
is(aEvent.removed[0].line, 5, "editor breakpoint line is correct");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 0,
|
||||
"editor.getBreakpoints().length is correct");
|
||||
}
|
||||
|
||||
function testBreakpointAddBackground()
|
||||
{
|
||||
info("add a breakpoint to the second script which is not selected");
|
||||
|
||||
is(Object.keys(gBreakpoints).length, 0,
|
||||
"no breakpoints in the debugger");
|
||||
ok(!gPane.getBreakpoint(gSources.selectedValue, 6),
|
||||
"getBreakpoint(selectedScript, 6) returns no breakpoint");
|
||||
isnot(gSources.values[0], gSources.selectedValue,
|
||||
"first script location is not the currently selected script");
|
||||
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddBackgroundTrap);
|
||||
gPane.addBreakpoint({url: gSources.values[0], line: 5}, onBreakpointAddBackground);
|
||||
}
|
||||
|
||||
function onEditorBreakpointAddBackgroundTrap(aEvent)
|
||||
{
|
||||
// Trap listener: no breakpoint must be added to the editor when a
|
||||
// breakpoint is added to a script that is not currently selected.
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddBackgroundTrap);
|
||||
editorBreakpointChanges++;
|
||||
ok(false, "breakpoint2 must not be added to the editor");
|
||||
}
|
||||
|
||||
function onBreakpointAddBackground(aBreakpointClient, aResponseError)
|
||||
{
|
||||
breakpointsAdded++;
|
||||
|
||||
ok(aBreakpointClient, "breakpoint2 added, client received");
|
||||
ok(!aResponseError, "breakpoint2 added without errors");
|
||||
is(aBreakpointClient.location.url, gSources.values[0],
|
||||
"breakpoint2 client url is correct");
|
||||
is(aBreakpointClient.location.line, 5,
|
||||
"breakpoint2 client line is correct");
|
||||
|
||||
executeSoon(function() {
|
||||
ok(aBreakpointClient.actor in gBreakpoints,
|
||||
"breakpoint2 client found in the list of debugger breakpoints");
|
||||
|
||||
is(Object.keys(gBreakpoints).length, 1,
|
||||
"one breakpoint in the debugger");
|
||||
is(gPane.getBreakpoint(gSources.values[0], 5), aBreakpointClient,
|
||||
"getBreakpoint(locations[0], 5) returns the correct breakpoint");
|
||||
|
||||
// remove the trap listener
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddBackgroundTrap);
|
||||
|
||||
info("switch to the second script");
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddSwitch);
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onEditorTextChanged);
|
||||
gSources.selectedIndex = 0;
|
||||
});
|
||||
}
|
||||
|
||||
function onEditorBreakpointAddSwitch(aEvent)
|
||||
{
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddSwitch);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent, "breakpoint2 added to the editor");
|
||||
is(aEvent.added.length, 1, "one breakpoint added to the editor");
|
||||
is(aEvent.removed.length, 0, "no breakpoint was removed from the editor");
|
||||
is(aEvent.added[0].line, 4, "editor breakpoint line is correct");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 1,
|
||||
"editor.getBreakpoints().length is correct");
|
||||
}
|
||||
|
||||
function onEditorTextChanged()
|
||||
{
|
||||
// Wait for the actual text to be shown.
|
||||
if (gDebugger.editor.getText() == gDebugger.L10N.getStr("loadingText")) {
|
||||
return;
|
||||
}
|
||||
// The requested source text has been shown, remove the event listener.
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onEditorTextChanged);
|
||||
|
||||
is(gEditor.getText().indexOf("debugger"), -1,
|
||||
"The second script is no longer displayed.");
|
||||
|
||||
isnot(gEditor.getText().indexOf("firstCall"), -1,
|
||||
"The first script is displayed.");
|
||||
|
||||
let window = gEditor.editorElement.contentWindow;
|
||||
executeSoon(() => window.mozRequestAnimationFrame(onReadyForClick));
|
||||
}
|
||||
|
||||
function onReadyForClick()
|
||||
{
|
||||
info("remove the second breakpoint using the mouse");
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointRemoveSecond);
|
||||
|
||||
let iframe = gEditor.editorElement;
|
||||
let testWin = iframe.ownerDocument.defaultView;
|
||||
|
||||
// flush the layout for the iframe
|
||||
info("rect " + iframe.contentDocument.documentElement.getBoundingClientRect());
|
||||
|
||||
let utils = testWin.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
let lineOffset = gEditor.getLineStart(4);
|
||||
let coords = gEditor.getLocationAtOffset(lineOffset);
|
||||
|
||||
let rect = iframe.getBoundingClientRect();
|
||||
let left = rect.left + 10;
|
||||
let top = rect.top + coords.y + 4;
|
||||
utils.sendMouseEventToWindow("mousedown", left, top, 0, 1, 0, false, 0, 0);
|
||||
utils.sendMouseEventToWindow("mouseup", left, top, 0, 1, 0, false, 0, 0);
|
||||
}
|
||||
|
||||
function onEditorBreakpointRemoveSecond(aEvent)
|
||||
{
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointRemoveSecond);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent, "breakpoint2 removed from the editor");
|
||||
is(aEvent.added.length, 0, "no breakpoint was added to the editor");
|
||||
is(aEvent.removed.length, 1, "one breakpoint was removed from the editor");
|
||||
is(aEvent.removed[0].line, 4, "editor breakpoint line is correct");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 0,
|
||||
"editor.getBreakpoints().length is correct");
|
||||
|
||||
executeSoon(function() {
|
||||
gDebugger.gClient.addOneTimeListener("resumed", function() {
|
||||
finalCheck();
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
gDebugger.DebuggerController.activeThread.resume();
|
||||
});
|
||||
}
|
||||
|
||||
function finalCheck() {
|
||||
is(Object.keys(gBreakpoints).length, 0, "no breakpoint in the debugger");
|
||||
ok(!gPane.getBreakpoint(gSources.values[0], 5),
|
||||
"getBreakpoint(locations[0], 5) returns no breakpoint");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
is(breakpointsAdded, 2, "correct number of breakpoints have been added");
|
||||
is(breakpointsRemoved, 1, "correct number of breakpoints have been removed");
|
||||
is(editorBreakpointChanges, 4, "correct number of editor breakpoint changes");
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
gBreakpoints = null;
|
||||
});
|
||||
}
|
@ -1,466 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test if the context menu associated with each breakpoint does what it should.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
|
||||
|
||||
let gPane = null;
|
||||
let gTab = null;
|
||||
let gDebuggee = null;
|
||||
let gDebugger = null;
|
||||
let gEditor = null;
|
||||
let gSources = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gSources.preferredSource = EXAMPLE_URL + "test-script-switching-02.js";
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
|
||||
let { url, loaded, text } = aEvent.detail;
|
||||
info("Shown source: " + url + ", loaded: " + loaded + ", text:\n" + text);
|
||||
info("Shown label: " + gSources.selectedLabel);
|
||||
info("All labels:" + gSources.labels);
|
||||
if (url.indexOf("-02") != -1) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
performTestWhileNotPaused();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function addBreakpoints(callback) {
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[0].value, line: 5}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[1].value, line: 6}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[1].value, line: 7}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[1].value, line: 8}, function(cl, err) {
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[1].value, line: 9}, function(cl, err) {
|
||||
callback();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function performTestWhileNotPaused()
|
||||
{
|
||||
info("Performing test while not paused...");
|
||||
|
||||
addBreakpoints(function() {
|
||||
initialChecks();
|
||||
|
||||
checkBreakpointToggleSelf(0, function() {
|
||||
checkBreakpointToggleOthers(0, function() {
|
||||
checkBreakpointToggleSelf(1, function() {
|
||||
checkBreakpointToggleOthers(1, function() {
|
||||
checkBreakpointToggleSelf(2, function() {
|
||||
checkBreakpointToggleOthers(2, function() {
|
||||
checkBreakpointToggleSelf(3, function() {
|
||||
checkBreakpointToggleOthers(3, function() {
|
||||
checkBreakpointToggleSelf(4, function() {
|
||||
checkBreakpointToggleOthers(4, function() {
|
||||
testDeleteAll(function() {
|
||||
performTestWhilePaused();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function performTestWhilePaused()
|
||||
{
|
||||
info("Performing test while paused...");
|
||||
|
||||
addBreakpoints(function() {
|
||||
initialChecks();
|
||||
|
||||
pauseAndCheck(function() {
|
||||
checkBreakpointToggleSelf(0, function() {
|
||||
checkBreakpointToggleOthers(0, function() {
|
||||
checkBreakpointToggleSelf(1, function() {
|
||||
checkBreakpointToggleOthers(1, function() {
|
||||
checkBreakpointToggleSelf(2, function() {
|
||||
checkBreakpointToggleOthers(2, function() {
|
||||
checkBreakpointToggleSelf(3, function() {
|
||||
checkBreakpointToggleOthers(3, function() {
|
||||
checkBreakpointToggleSelf(4, function() {
|
||||
checkBreakpointToggleOthers(4, function() {
|
||||
testDeleteAll(function() {
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
}, true);
|
||||
});
|
||||
}, true);
|
||||
});
|
||||
}, true);
|
||||
});
|
||||
}, true);
|
||||
});
|
||||
}, true);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function pauseAndCheck(callback) {
|
||||
gDebugger.gThreadClient.addOneTimeListener("resumed", function() {
|
||||
pauseAndCallback(function() {
|
||||
is(gSources.selectedLabel, "test-script-switching-01.js",
|
||||
"The currently selected source is incorrect (1).");
|
||||
is(gSources.selectedIndex, 1,
|
||||
"The currently selected source is incorrect (2).");
|
||||
|
||||
waitForCaretPos(4, function() {
|
||||
ok(true, "The editor location is correct after pausing.");
|
||||
callback();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function pauseAndCallback(callback) {
|
||||
let scriptShown = false;
|
||||
let framesadded = false;
|
||||
let testContinued = false;
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
|
||||
let url = aEvent.detail.url;
|
||||
if (url.indexOf("-01") != -1) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
scriptShown = true;
|
||||
executeSoon(continueTest);
|
||||
}
|
||||
});
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("framesadded", function() {
|
||||
framesadded = true;
|
||||
executeSoon(continueTest);
|
||||
});
|
||||
|
||||
function continueTest() {
|
||||
if (scriptShown && framesadded && !testContinued) {
|
||||
testContinued = true;
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee.window);
|
||||
}
|
||||
|
||||
function initialChecks() {
|
||||
for (let source in gSources) {
|
||||
for (let breakpoint in source) {
|
||||
let { sourceLocation: url, lineNumber: line, actor } = breakpoint.attachment;
|
||||
|
||||
ok(gPane.getBreakpoint(url, line),
|
||||
"All breakpoint items should have corresponding clients (1).");
|
||||
ok(breakpoint.attachment.actor,
|
||||
"All breakpoint items should have corresponding clients (2).");
|
||||
is(!!breakpoint.attachment.disabled, false,
|
||||
"All breakpoints should initially be enabled.");
|
||||
|
||||
let prefix = "bp-cMenu-"; // "breakpoints context menu"
|
||||
let enableSelfId = prefix + "enableSelf-" + actor + "-menuitem";
|
||||
let disableSelfId = prefix + "disableSelf-" + actor + "-menuitem";
|
||||
|
||||
is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true",
|
||||
"The 'Enable breakpoint' context menu item should initially be hidden'.");
|
||||
ok(!gDebugger.document.getElementById(disableSelfId).hasAttribute("hidden"),
|
||||
"The 'Disable breakpoint' context menu item should initially not be hidden'.");
|
||||
is(breakpoint.attachment.view.checkbox.getAttribute("checked"), "true",
|
||||
"All breakpoints should initially have a checked checkbox.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkBreakpointToggleSelf(index, callback) {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelectorAll(".dbg-breakpoint")[index],
|
||||
gDebugger);
|
||||
|
||||
let selectedBreakpoint = gSources.selectedBreakpointItem;
|
||||
let { sourceLocation: url, lineNumber: line, actor } = selectedBreakpoint.attachment;
|
||||
|
||||
ok(gPane.getBreakpoint(url, line),
|
||||
"There should be a breakpoint client available (1).");
|
||||
ok(gSources.selectedBreakpointClient,
|
||||
"There should be a breakpoint client available (2).");
|
||||
is(!!selectedBreakpoint.attachment.disabled, false,
|
||||
"The breakpoint should not be disabled yet.");
|
||||
|
||||
let prefix = "bp-cMenu-"; // "breakpoints context menu"
|
||||
let enableSelfId = prefix + "enableSelf-" + actor + "-menuitem";
|
||||
let disableSelfId = prefix + "disableSelf-" + actor + "-menuitem";
|
||||
|
||||
is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true",
|
||||
"The 'Enable breakpoint' context menu item should be hidden'.");
|
||||
ok(!gDebugger.document.getElementById(disableSelfId).hasAttribute("hidden"),
|
||||
"The 'Disable breakpoint' context menu item should not be hidden'.");
|
||||
|
||||
waitForCaretPos(selectedBreakpoint.attachment.lineNumber - 1, function() {
|
||||
ok(true, "The editor location is correct (" + index + ").");
|
||||
|
||||
gDebugger.addEventListener("Debugger:BreakpointHidden", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
|
||||
ok(!gPane.getBreakpoint(url, line),
|
||||
"There should be no breakpoint client available (2).");
|
||||
ok(!gSources.selectedBreakpointClient,
|
||||
"There should be no breakpoint client available (3).");
|
||||
|
||||
gDebugger.addEventListener("Debugger:BreakpointShown", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
|
||||
ok(gPane.getBreakpoint(url, line),
|
||||
"There should be a breakpoint client available (4).");
|
||||
ok(gSources.selectedBreakpointClient,
|
||||
"There should be a breakpoint client available (5).");
|
||||
|
||||
callback();
|
||||
});
|
||||
|
||||
// Test re-disabling this breakpoint.
|
||||
executeSoon(function() {
|
||||
gSources._onEnableSelf(selectedBreakpoint.attachment.actor);
|
||||
is(selectedBreakpoint.attachment.disabled, false,
|
||||
"The current breakpoint should now be enabled.")
|
||||
|
||||
is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true",
|
||||
"The 'Enable breakpoint' context menu item should be hidden'.");
|
||||
ok(!gDebugger.document.getElementById(disableSelfId).hasAttribute("hidden"),
|
||||
"The 'Disable breakpoint' context menu item should not be hidden'.");
|
||||
ok(selectedBreakpoint.attachment.view.checkbox.hasAttribute("checked"),
|
||||
"The breakpoint should now be checked.");
|
||||
});
|
||||
});
|
||||
|
||||
// Test disabling this breakpoint.
|
||||
executeSoon(function() {
|
||||
gSources._onDisableSelf(selectedBreakpoint.attachment.actor);
|
||||
is(selectedBreakpoint.attachment.disabled, true,
|
||||
"The current breakpoint should now be disabled.")
|
||||
|
||||
ok(!gDebugger.document.getElementById(enableSelfId).hasAttribute("hidden"),
|
||||
"The 'Enable breakpoint' context menu item should not be hidden'.");
|
||||
is(gDebugger.document.getElementById(disableSelfId).getAttribute("hidden"), "true",
|
||||
"The 'Disable breakpoint' context menu item should be hidden'.");
|
||||
ok(!selectedBreakpoint.attachment.view.checkbox.hasAttribute("checked"),
|
||||
"The breakpoint should now be unchecked.");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function checkBreakpointToggleOthers(index, callback, whilePaused) {
|
||||
let count = 4
|
||||
gDebugger.addEventListener("Debugger:BreakpointHidden", function _onEvent(aEvent) {
|
||||
info(count + " breakpoints remain to be hidden...");
|
||||
if (!(--count)) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
ok(true, "All breakpoints except one were hidden.");
|
||||
|
||||
let selectedBreakpoint = gSources.selectedBreakpointItem;
|
||||
let { sourceLocation: url, lineNumber: line, actor } = selectedBreakpoint.attachment;
|
||||
|
||||
ok(gPane.getBreakpoint(url, line),
|
||||
"There should be a breakpoint client available (6).");
|
||||
ok(gSources.selectedBreakpointClient,
|
||||
"There should be a breakpoint client available (7).");
|
||||
is(!!selectedBreakpoint.attachment.disabled, false,
|
||||
"The targetted breakpoint should not have been disabled.");
|
||||
|
||||
for (let source in gSources) {
|
||||
for (let otherBreakpoint in source) {
|
||||
if (otherBreakpoint != selectedBreakpoint) {
|
||||
ok(!gPane.getBreakpoint(
|
||||
otherBreakpoint.attachment.sourceLocation,
|
||||
otherBreakpoint.attachment.lineNumber),
|
||||
"There should be no breakpoint client for a disabled breakpoint (8).");
|
||||
is(otherBreakpoint.attachment.disabled, true,
|
||||
"Non-targetted breakpoints should have been disabled (9).");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
count = 4;
|
||||
gDebugger.addEventListener("Debugger:BreakpointShown", function _onEvent(aEvent) {
|
||||
info(count + " breakpoints remain to be reshown...");
|
||||
if (!(--count)) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
ok(true, "All breakpoints are now reshown.");
|
||||
|
||||
for (let source in gSources) {
|
||||
for (let someBreakpoint in source) {
|
||||
ok(gPane.getBreakpoint(
|
||||
someBreakpoint.attachment.sourceLocation,
|
||||
someBreakpoint.attachment.lineNumber),
|
||||
"There should be a breakpoint client for all enabled breakpoints (10).");
|
||||
is(someBreakpoint.attachment.disabled, false,
|
||||
"All breakpoints should now have been enabled (11).");
|
||||
}
|
||||
}
|
||||
|
||||
count = 5;
|
||||
gDebugger.addEventListener("Debugger:BreakpointHidden", function _onEvent(aEvent) {
|
||||
info(count + " breakpoints remain to be rehidden...");
|
||||
if (!(--count)) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
ok(true, "All breakpoints are now rehidden.");
|
||||
|
||||
for (let source in gSources) {
|
||||
for (let someBreakpoint in source) {
|
||||
ok(!gPane.getBreakpoint(
|
||||
someBreakpoint.attachment.sourceLocation,
|
||||
someBreakpoint.attachment.lineNumber),
|
||||
"There should be no breakpoint client for a disabled breakpoint (12).");
|
||||
is(someBreakpoint.attachment.disabled, true,
|
||||
"All breakpoints should now have been disabled (13).");
|
||||
}
|
||||
}
|
||||
|
||||
count = 5;
|
||||
gDebugger.addEventListener("Debugger:BreakpointShown", function _onEvent(aEvent) {
|
||||
info(count + " breakpoints remain to be reshown...");
|
||||
if (!(--count)) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
ok(true, "All breakpoints are now rehidden.");
|
||||
|
||||
for (let source in gSources) {
|
||||
for (let someBreakpoint in source) {
|
||||
ok(gPane.getBreakpoint(
|
||||
someBreakpoint.attachment.sourceLocation,
|
||||
someBreakpoint.attachment.lineNumber),
|
||||
"There should be a breakpoint client for all enabled breakpoints (14).");
|
||||
is(someBreakpoint.attachment.disabled, false,
|
||||
"All breakpoints should now have been enabled (15).");
|
||||
}
|
||||
}
|
||||
|
||||
// Done.
|
||||
if (!whilePaused) {
|
||||
gDebugger.gThreadClient.addOneTimeListener("resumed", callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Test re-enabling all breakpoints.
|
||||
enableAll();
|
||||
}
|
||||
});
|
||||
|
||||
// Test disabling all breakpoints.
|
||||
if (!whilePaused) {
|
||||
gDebugger.gThreadClient.addOneTimeListener("resumed", disableAll);
|
||||
} else {
|
||||
disableAll();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Test re-enabling other breakpoints.
|
||||
enableOthers();
|
||||
}
|
||||
});
|
||||
|
||||
// Test disabling other breakpoints.
|
||||
if (!whilePaused) {
|
||||
gDebugger.gThreadClient.addOneTimeListener("resumed", disableOthers);
|
||||
} else {
|
||||
disableOthers();
|
||||
}
|
||||
}
|
||||
|
||||
function testDeleteAll(callback) {
|
||||
let count = 5
|
||||
gDebugger.addEventListener("Debugger:BreakpointHidden", function _onEvent(aEvent) {
|
||||
info(count + " breakpoints remain to be hidden...");
|
||||
if (!(--count)) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
ok(true, "All breakpoints were hidden.");
|
||||
|
||||
ok(!gSources.selectedBreakpointItem,
|
||||
"There should be no breakpoint item available (16).");
|
||||
ok(!gSources.selectedBreakpointClient,
|
||||
"There should be no breakpoint client available (17).");
|
||||
|
||||
for (let source in gSources) {
|
||||
for (let otherBreakpoint in source) {
|
||||
ok(false, "It's a trap!");
|
||||
}
|
||||
}
|
||||
|
||||
// Done.
|
||||
callback();
|
||||
}
|
||||
});
|
||||
|
||||
// Test deleting all breakpoints.
|
||||
deleteAll();
|
||||
}
|
||||
|
||||
function disableOthers() {
|
||||
gSources._onDisableOthers(gSources.selectedBreakpointItem.attachment.actor);
|
||||
}
|
||||
function enableOthers() {
|
||||
gSources._onEnableOthers(gSources.selectedBreakpointItem.attachment.actor);
|
||||
}
|
||||
function disableAll() {
|
||||
gSources._onDisableAll(gSources.selectedBreakpointItem.attachment.actor);
|
||||
}
|
||||
function enableAll() {
|
||||
gSources._onEnableAll(gSources.selectedBreakpointItem.attachment.actor);
|
||||
}
|
||||
function deleteAll() {
|
||||
gSources._onDeleteAll(gSources.selectedBreakpointItem.attachment.actor);
|
||||
}
|
||||
|
||||
function waitForCaretPos(number, callback)
|
||||
{
|
||||
// Poll every few milliseconds until the source editor line is active.
|
||||
let count = 0;
|
||||
let intervalID = window.setInterval(function() {
|
||||
info("count: " + count + " ");
|
||||
if (++count > 50) {
|
||||
ok(false, "Timed out while polling for the line.");
|
||||
window.clearInterval(intervalID);
|
||||
return closeDebuggerAndFinish();
|
||||
}
|
||||
if (gEditor.getCaretPosition().line != number) {
|
||||
return;
|
||||
}
|
||||
// We got the source editor at the expected line, it's safe to callback.
|
||||
window.clearInterval(intervalID);
|
||||
callback();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
});
|
||||
}
|
@ -1,224 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test if breakpoints are highlighted when they should.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
|
||||
|
||||
let gPane = null;
|
||||
let gTab = null;
|
||||
let gDebuggee = null;
|
||||
let gDebugger = null;
|
||||
let gEditor = null;
|
||||
let gSources = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gSources.preferredSource = EXAMPLE_URL + "test-script-switching-02.js";
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
|
||||
let { url, loaded, text } = aEvent.detail;
|
||||
info("Shown source: " + url + ", loaded: " + loaded + ", text:\n" + text);
|
||||
info("Shown label: " + gSources.selectedLabel);
|
||||
info("All labels:" + gSources.labels);
|
||||
if (url.indexOf("-02") != -1) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
performTest();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function performTest()
|
||||
{
|
||||
initialChecks();
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[0].value, line: 5}, function(cl, err) {
|
||||
initialChecks();
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[1].value, line: 6}, function(cl, err) {
|
||||
initialChecks();
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[1].value, line: 7}, function(cl, err) {
|
||||
initialChecks();
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[1].value, line: 8}, function(cl, err) {
|
||||
initialChecks();
|
||||
gPane.addBreakpoint({url: gSources.orderedItems[1].value, line: 9}, function(cl, err) {
|
||||
initialChecks();
|
||||
testHighlight1();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function initialChecks() {
|
||||
is(gSources.selectedValue, gSources.orderedItems[1].value,
|
||||
"The currently selected source is incorrect (0).");
|
||||
is(gEditor.getCaretPosition().line, 0,
|
||||
"The editor caret line was incorrect (0).");
|
||||
is(gEditor.getCaretPosition().col, 0,
|
||||
"The editor caret column was incorrect (0).");
|
||||
}
|
||||
|
||||
function testHighlight1() {
|
||||
gSources.highlightBreakpoint(gSources.orderedItems[0].value, 5);
|
||||
checkHighlight(gSources.orderedItems[0].value, 5);
|
||||
|
||||
is(gSources.selectedValue, gSources.orderedItems[1].value,
|
||||
"The currently selected source is incorrect (1).");
|
||||
|
||||
is(gEditor.getCaretPosition().line, 0,
|
||||
"The editor caret line was incorrect (1).");
|
||||
is(gEditor.getCaretPosition().col, 0,
|
||||
"The editor caret column was incorrect (1).");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelectorAll(".dbg-breakpoint")[0],
|
||||
gDebugger);
|
||||
|
||||
waitForCaretPos(4, function() {
|
||||
ok(true, "The editor location is correct (1).");
|
||||
testHighlight2();
|
||||
});
|
||||
}
|
||||
|
||||
function testHighlight2() {
|
||||
gSources.highlightBreakpoint(gSources.orderedItems[1].value, 6);
|
||||
checkHighlight(gSources.orderedItems[1].value, 6);
|
||||
|
||||
is(gSources.selectedValue, gSources.orderedItems[0].value,
|
||||
"The currently selected source is incorrect (2).");
|
||||
|
||||
is(gEditor.getCaretPosition().line, 4,
|
||||
"The editor caret line was incorrect (2).");
|
||||
is(gEditor.getCaretPosition().col, 0,
|
||||
"The editor caret column was incorrect (2).");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelectorAll(".dbg-breakpoint")[1],
|
||||
gDebugger);
|
||||
|
||||
waitForCaretPos(5, function() {
|
||||
ok(true, "The editor location is correct (2).");
|
||||
testHighlight3();
|
||||
});
|
||||
}
|
||||
|
||||
function testHighlight3() {
|
||||
gSources.highlightBreakpoint(gSources.orderedItems[1].value, 7);
|
||||
checkHighlight(gSources.orderedItems[1].value, 7);
|
||||
|
||||
is(gSources.selectedValue, gSources.orderedItems[1].value,
|
||||
"The currently selected source is incorrect (3).");
|
||||
|
||||
is(gEditor.getCaretPosition().line, 5,
|
||||
"The editor caret line was incorrect (3).");
|
||||
is(gEditor.getCaretPosition().col, 0,
|
||||
"The editor caret column was incorrect (3).");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelectorAll(".dbg-breakpoint")[2],
|
||||
gDebugger);
|
||||
|
||||
waitForCaretPos(6, function() {
|
||||
ok(true, "The editor location is correct (3).");
|
||||
testHighlight4();
|
||||
});
|
||||
}
|
||||
|
||||
function testHighlight4() {
|
||||
gSources.highlightBreakpoint(gSources.orderedItems[1].value, 8);
|
||||
checkHighlight(gSources.orderedItems[1].value, 8);
|
||||
|
||||
is(gSources.selectedValue, gSources.orderedItems[1].value,
|
||||
"The currently selected source is incorrect (4).");
|
||||
|
||||
is(gEditor.getCaretPosition().line, 6,
|
||||
"The editor caret line was incorrect (4).");
|
||||
is(gEditor.getCaretPosition().col, 0,
|
||||
"The editor caret column was incorrect (4).");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelectorAll(".dbg-breakpoint")[3],
|
||||
gDebugger);
|
||||
|
||||
waitForCaretPos(7, function() {
|
||||
ok(true, "The editor location is correct (4).");
|
||||
testHighlight5();
|
||||
});
|
||||
}
|
||||
|
||||
function testHighlight5() {
|
||||
gSources.highlightBreakpoint(gSources.orderedItems[1].value, 9);
|
||||
checkHighlight(gSources.orderedItems[1].value, 9);
|
||||
|
||||
is(gSources.selectedValue, gSources.orderedItems[1].value,
|
||||
"The currently selected source is incorrect (5).");
|
||||
|
||||
is(gEditor.getCaretPosition().line, 7,
|
||||
"The editor caret line was incorrect (5).");
|
||||
is(gEditor.getCaretPosition().col, 0,
|
||||
"The editor caret column was incorrect (5).");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelectorAll(".dbg-breakpoint")[4],
|
||||
gDebugger);
|
||||
|
||||
waitForCaretPos(8, function() {
|
||||
ok(true, "The editor location is correct (5).");
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
}
|
||||
|
||||
function checkHighlight(aUrl, aLine) {
|
||||
is(gSources.selectedBreakpointItem, gSources.getBreakpoint(aUrl, aLine),
|
||||
"The currently selected breakpoint item is incorrect.");
|
||||
is(gSources.selectedBreakpointClient, gPane.getBreakpoint(aUrl, aLine),
|
||||
"The currently selected breakpoint client is incorrect.");
|
||||
|
||||
is(gSources.selectedBreakpointItem.attachment.sourceLocation, aUrl,
|
||||
"The selected breakpoint item's source location attachment is incorrect.");
|
||||
is(gSources.selectedBreakpointItem.attachment.lineNumber, aLine,
|
||||
"The selected breakpoint item's source line number is incorrect.");
|
||||
|
||||
ok(gSources.selectedBreakpointItem.target.classList.contains("selected"),
|
||||
"The selected breakpoint item's target should have a selected class.");
|
||||
}
|
||||
|
||||
function waitForCaretPos(number, callback)
|
||||
{
|
||||
// Poll every few milliseconds until the source editor line is active.
|
||||
let count = 0;
|
||||
let intervalID = window.setInterval(function() {
|
||||
info("count: " + count + " ");
|
||||
if (++count > 50) {
|
||||
ok(false, "Timed out while polling for the line.");
|
||||
window.clearInterval(intervalID);
|
||||
return closeDebuggerAndFinish();
|
||||
}
|
||||
if (gEditor.getCaretPosition().line != number) {
|
||||
return;
|
||||
}
|
||||
// We got the source editor at the expected line, it's safe to callback.
|
||||
window.clearInterval(intervalID);
|
||||
callback();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
});
|
||||
}
|
@ -1,301 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 723071: test adding a pane to display the list of breakpoints across
|
||||
* all scripts in the debuggee.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
|
||||
|
||||
let gPane = null;
|
||||
let gTab = null;
|
||||
let gDebuggee = null;
|
||||
let gDebugger = null;
|
||||
let gEditor = null;
|
||||
let gSources = null;
|
||||
let gBreakpoints = null;
|
||||
let gBreakpointsParent = null;
|
||||
let gBreakpointsList = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
resumed = true;
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", onScriptShown);
|
||||
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
framesAdded = true;
|
||||
executeSoon(startTest);
|
||||
});
|
||||
|
||||
executeSoon(function() {
|
||||
gDebuggee.firstCall();
|
||||
});
|
||||
});
|
||||
|
||||
function onScriptShown(aEvent)
|
||||
{
|
||||
scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
|
||||
executeSoon(startTest);
|
||||
}
|
||||
|
||||
function startTest()
|
||||
{
|
||||
if (scriptShown && framesAdded && resumed && !testStarted) {
|
||||
gDebugger.removeEventListener("Debugger:SourceShown", onScriptShown);
|
||||
testStarted = true;
|
||||
Services.tm.currentThread.dispatch({ run: performTest }, 0);
|
||||
}
|
||||
}
|
||||
|
||||
let breakpointsAdded = 0;
|
||||
let breakpointsDisabled = 0;
|
||||
let breakpointsRemoved = 0;
|
||||
|
||||
function performTest()
|
||||
{
|
||||
gEditor = gDebugger.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gBreakpoints = gPane.getAllBreakpoints();
|
||||
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(gSources.itemCount, 2,
|
||||
"Found the expected number of scripts.");
|
||||
|
||||
isnot(gEditor.getText().indexOf("debugger"), -1,
|
||||
"The correct script was loaded initially.");
|
||||
|
||||
isnot(gSources.selectedValue, gSources.values[0],
|
||||
"The correct script is selected");
|
||||
|
||||
is(Object.keys(gBreakpoints).length, 0, "no breakpoints");
|
||||
ok(!gPane.getBreakpoint("chocolate", 3), "getBreakpoint('chocolate', 3) returns falsey");
|
||||
is(gEditor.getBreakpoints().length, 0, "no breakpoints in the editor");
|
||||
|
||||
gBreakpointsParent = gSources.widget._parent;
|
||||
gBreakpointsList = gSources.widget._list;
|
||||
|
||||
is(gBreakpointsParent.childNodes.length, 1, // one sources list
|
||||
"Found junk in the breakpoints container.");
|
||||
is(gBreakpointsList.childNodes.length, 1, // one sources group
|
||||
"Found junk in the breakpoints container.");
|
||||
is(gBreakpointsList.querySelectorAll(".dbg-breakpoint").length, 0,
|
||||
"No breakpoints should be visible at this point.");
|
||||
|
||||
addBreakpoints(function() {
|
||||
is(breakpointsAdded, 3,
|
||||
"Should have added 3 breakpoints so far.");
|
||||
is(breakpointsDisabled, 0,
|
||||
"Shouldn't have disabled anything so far.");
|
||||
is(breakpointsRemoved, 0,
|
||||
"Shouldn't have removed anything so far.");
|
||||
|
||||
is(gBreakpointsParent.childNodes.length, 1, // one sources list
|
||||
"Found junk in the breakpoints container.");
|
||||
is(gBreakpointsList.childNodes.length, 1, // one sources group
|
||||
"Found junk in the breakpoints container.");
|
||||
is(gBreakpointsList.querySelectorAll(".dbg-breakpoint").length, 3,
|
||||
"3 breakpoints should be visible at this point.");
|
||||
|
||||
disableBreakpoints(function() {
|
||||
is(breakpointsAdded, 3,
|
||||
"Should still have 3 breakpoints added so far.");
|
||||
is(breakpointsDisabled, 3,
|
||||
"Should have 3 disabled breakpoints.");
|
||||
is(breakpointsRemoved, 0,
|
||||
"Shouldn't have removed anything so far.");
|
||||
|
||||
is(gBreakpointsParent.childNodes.length, 1, // one sources list
|
||||
"Found junk in the breakpoints container.");
|
||||
is(gBreakpointsList.childNodes.length, 1, // one sources group
|
||||
"Found junk in the breakpoints container.");
|
||||
is(gBreakpointsList.querySelectorAll(".dbg-breakpoint").length, breakpointsAdded,
|
||||
"Should have the same number of breakpoints in the pane.");
|
||||
is(gBreakpointsList.querySelectorAll(".dbg-breakpoint").length, breakpointsDisabled,
|
||||
"Should have the same number of disabled breakpoints.");
|
||||
|
||||
addBreakpoints(function() {
|
||||
is(breakpointsAdded, 3,
|
||||
"Should still have only 3 breakpoints added so far.");
|
||||
is(breakpointsDisabled, 3,
|
||||
"Should still have 3 disabled breakpoints.");
|
||||
is(breakpointsRemoved, 0,
|
||||
"Shouldn't have removed anything so far.");
|
||||
|
||||
is(gBreakpointsParent.childNodes.length, 1, // one sources list
|
||||
"Found junk in the breakpoints container.");
|
||||
is(gBreakpointsList.childNodes.length, 1, // one sources group
|
||||
"Found junk in the breakpoints container.");
|
||||
is(gBreakpointsList.querySelectorAll(".dbg-breakpoint").length, breakpointsAdded,
|
||||
"Since half of the breakpoints already existed, but disabled, " +
|
||||
"only half of the added breakpoints are actually in the pane.");
|
||||
|
||||
removeBreakpoints(function() {
|
||||
is(breakpointsRemoved, 3,
|
||||
"Should have 3 removed breakpoints.");
|
||||
|
||||
is(gBreakpointsParent.childNodes.length, 1, // one sources list
|
||||
"Found junk in the breakpoints container.");
|
||||
is(gBreakpointsList.childNodes.length, 1, // one sources group
|
||||
"Found junk in the breakpoints container.");
|
||||
is(gBreakpointsList.querySelectorAll(".dbg-breakpoint").length, 0,
|
||||
"No breakpoints should be visible at this point.");
|
||||
|
||||
executeSoon(function() {
|
||||
gDebugger.gClient.addOneTimeListener("resumed", function() {
|
||||
finalCheck();
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
gDebugger.DebuggerController.activeThread.resume();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}, true);
|
||||
|
||||
function addBreakpoints(callback, increment)
|
||||
{
|
||||
let line;
|
||||
|
||||
executeSoon(function()
|
||||
{
|
||||
line = 6;
|
||||
gPane.addBreakpoint({url: gSources.selectedValue, line: line},
|
||||
function(cl, err) {
|
||||
onBreakpointAdd.call({ increment: increment, line: line }, cl, err);
|
||||
|
||||
line = 7;
|
||||
gPane.addBreakpoint({url: gSources.selectedValue, line: line},
|
||||
function(cl, err) {
|
||||
onBreakpointAdd.call({ increment: increment, line: line }, cl, err);
|
||||
|
||||
line = 9;
|
||||
gPane.addBreakpoint({url: gSources.selectedValue, line: line},
|
||||
function(cl, err) {
|
||||
onBreakpointAdd.call({ increment: increment, line: line }, cl, err);
|
||||
|
||||
executeSoon(function() {
|
||||
callback();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function disableBreakpoints(callback)
|
||||
{
|
||||
let nodes = Array.slice(gBreakpointsList.querySelectorAll(".dbg-breakpoint"));
|
||||
info("Nodes to disable: " + breakpointsAdded);
|
||||
|
||||
is(nodes.length, breakpointsAdded,
|
||||
"The number of nodes to disable is incorrect.");
|
||||
|
||||
Array.forEach(nodes, function(bkp) {
|
||||
info("Disabling breakpoint: " + bkp.id);
|
||||
|
||||
let sourceItem = gSources.getItemForElement(bkp);
|
||||
let breakpointItem = gSources.getItemForElement.call(sourceItem, bkp);
|
||||
let { sourceLocation: url, lineNumber: line } = breakpointItem.attachment;
|
||||
info("Found data: " + breakpointItem.attachment.toSource());
|
||||
|
||||
gSources.disableBreakpoint(url, line, { callback: function() {
|
||||
if (++breakpointsDisabled !== breakpointsAdded) {
|
||||
return;
|
||||
}
|
||||
executeSoon(function() {
|
||||
callback();
|
||||
});
|
||||
}});
|
||||
});
|
||||
}
|
||||
|
||||
function removeBreakpoints(callback)
|
||||
{
|
||||
let nodes = Array.slice(gBreakpointsList.querySelectorAll(".dbg-breakpoint"));
|
||||
info("Nodes to remove: " + breakpointsAdded);
|
||||
|
||||
is(nodes.length, breakpointsAdded,
|
||||
"The number of nodes to remove is incorrect.");
|
||||
|
||||
Array.forEach(nodes, function(bkp) {
|
||||
info("Removing breakpoint: " + bkp.id);
|
||||
|
||||
let sourceItem = gSources.getItemForElement(bkp);
|
||||
let breakpointItem = gSources.getItemForElement.call(sourceItem, bkp);
|
||||
let { sourceLocation: url, lineNumber: line } = breakpointItem.attachment;
|
||||
info("Found data: " + breakpointItem.attachment.toSource());
|
||||
|
||||
gPane.removeBreakpoint(gPane.getBreakpoint(url, line), function() {
|
||||
if (++breakpointsRemoved !== breakpointsAdded) {
|
||||
return;
|
||||
}
|
||||
executeSoon(function() {
|
||||
callback();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function onBreakpointAdd(aBreakpointClient, aResponseError)
|
||||
{
|
||||
if (this.increment) {
|
||||
breakpointsAdded++;
|
||||
}
|
||||
|
||||
is(gBreakpointsList.querySelectorAll(".dbg-breakpoint").length, breakpointsAdded,
|
||||
this.increment ? "Should have added a breakpoint in the pane."
|
||||
: "Should have the same number of breakpoints in the pane.");
|
||||
|
||||
let id = "breakpoint-" + aBreakpointClient.actor;
|
||||
let bkp = gDebugger.document.getElementById(id);
|
||||
let line = bkp.getElementsByClassName("dbg-breakpoint-line")[0];
|
||||
let text = bkp.getElementsByClassName("dbg-breakpoint-text")[0];
|
||||
let check = bkp.querySelector("checkbox");
|
||||
|
||||
is(bkp.id, id,
|
||||
"Breakpoint element " + id + " found successfully.");
|
||||
is(line.getAttribute("value"), this.line,
|
||||
"The expected information wasn't found in the breakpoint element.");
|
||||
is(text.getAttribute("value"), gDebugger.DebuggerView.getEditorLineText(this.line - 1).trim(),
|
||||
"The expected line text wasn't found in the breakpoint element.");
|
||||
is(check.getAttribute("checked"), "true",
|
||||
"The breakpoint enable checkbox is checked as expected.");
|
||||
}
|
||||
}
|
||||
|
||||
function finalCheck() {
|
||||
is(Object.keys(gBreakpoints).length, 0, "no breakpoint in the debugger");
|
||||
ok(!gPane.getBreakpoint(gSources.values[0], 5),
|
||||
"getBreakpoint(locations[0], 5) returns no breakpoint");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
is(breakpointsAdded, 3, "correct number of breakpoints have been added");
|
||||
is(breakpointsDisabled, 3, "correct number of breakpoints have been disabled");
|
||||
is(breakpointsRemoved, 3, "correct number of breakpoints have been removed");
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
gBreakpoints = null;
|
||||
gBreakpointsParent = null;
|
||||
gBreakpointsList = null;
|
||||
});
|
||||
}
|
@ -1,241 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 727429: test the debugger watch expressions.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_watch-expressions.html";
|
||||
|
||||
let gPane = null;
|
||||
let gTab = null;
|
||||
let gDebuggee = null;
|
||||
let gDebugger = null;
|
||||
let gWatch = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
gWatch = gDebugger.DebuggerView.WatchExpressions;
|
||||
|
||||
gDebugger.DebuggerView.toggleInstrumentsPane({ visible: true, animated: false });
|
||||
performTest();
|
||||
});
|
||||
|
||||
function performTest()
|
||||
{
|
||||
is(gWatch.getAllStrings().length, 0,
|
||||
"There should initially be no watch expressions");
|
||||
|
||||
addAndCheckExpressions(1, 0, "a");
|
||||
addAndCheckExpressions(2, 0, "b");
|
||||
addAndCheckExpressions(3, 0, "c");
|
||||
|
||||
removeAndCheckExpression(2, 1, "a");
|
||||
removeAndCheckExpression(1, 0, "a");
|
||||
|
||||
|
||||
addAndCheckExpressions(2, 0, "", true);
|
||||
gDebugger.editor.focus();
|
||||
is(gWatch.getAllStrings().length, 1,
|
||||
"Empty watch expressions are automatically removed");
|
||||
|
||||
|
||||
addAndCheckExpressions(2, 0, "a", true);
|
||||
gDebugger.editor.focus();
|
||||
is(gWatch.getAllStrings().length, 1,
|
||||
"Duplicate watch expressions are automatically removed");
|
||||
|
||||
addAndCheckExpressions(2, 0, "a\t", true);
|
||||
addAndCheckExpressions(2, 0, "a\r", true);
|
||||
addAndCheckExpressions(2, 0, "a\n", true);
|
||||
gDebugger.editor.focus();
|
||||
is(gWatch.getAllStrings().length, 1,
|
||||
"Duplicate watch expressions are automatically removed");
|
||||
|
||||
addAndCheckExpressions(2, 0, "\ta", true);
|
||||
addAndCheckExpressions(2, 0, "\ra", true);
|
||||
addAndCheckExpressions(2, 0, "\na", true);
|
||||
gDebugger.editor.focus();
|
||||
is(gWatch.getAllStrings().length, 1,
|
||||
"Duplicate watch expressions are automatically removed");
|
||||
|
||||
|
||||
addAndCheckCustomExpression(2, 0, "bazΩΩka");
|
||||
addAndCheckCustomExpression(3, 0, "bambøøcha");
|
||||
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gWatch.getItemAtIndex(0).attachment.closeNode,
|
||||
gDebugger);
|
||||
|
||||
is(gWatch.getAllStrings().length, 2,
|
||||
"Watch expressions are removed when the close button is pressed");
|
||||
is(gWatch.getAllStrings()[0], "bazΩΩka",
|
||||
"The expression at index " + 0 + " should be correct (1)");
|
||||
is(gWatch.getAllStrings()[1], "a",
|
||||
"The expression at index " + 1 + " should be correct (2)");
|
||||
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gWatch.getItemAtIndex(0).attachment.closeNode,
|
||||
gDebugger);
|
||||
|
||||
is(gWatch.getAllStrings().length, 1,
|
||||
"Watch expressions are removed when the close button is pressed");
|
||||
is(gWatch.getAllStrings()[0], "a",
|
||||
"The expression at index " + 0 + " should be correct (3)");
|
||||
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gWatch.getItemAtIndex(0).attachment.closeNode,
|
||||
gDebugger);
|
||||
|
||||
is(gWatch.getAllStrings().length, 0,
|
||||
"Watch expressions are removed when the close button is pressed");
|
||||
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gWatch.widget._parent,
|
||||
gDebugger);
|
||||
|
||||
is(gWatch.getAllStrings().length, 1,
|
||||
"Watch expressions are added when the view container is pressed");
|
||||
|
||||
|
||||
closeDebuggerAndFinish();
|
||||
}
|
||||
|
||||
function addAndCheckCustomExpression(total, index, string, noBlur) {
|
||||
addAndCheckExpressions(total, index, "", true);
|
||||
|
||||
for (let i = 0; i < string.length; i++) {
|
||||
EventUtils.sendChar(string[i], gDebugger);
|
||||
}
|
||||
|
||||
gDebugger.editor.focus();
|
||||
|
||||
let element = gWatch.getItemAtIndex(index).target;
|
||||
|
||||
is(gWatch.getItemAtIndex(index).attachment.initialExpression, "",
|
||||
"The initial expression at index " + index + " should be correct (1)");
|
||||
is(gWatch.getItemForElement(element).attachment.initialExpression, "",
|
||||
"The initial expression at index " + index + " should be correct (2)");
|
||||
|
||||
is(gWatch.getItemAtIndex(index).attachment.currentExpression, string,
|
||||
"The expression at index " + index + " should be correct (1)");
|
||||
is(gWatch.getItemForElement(element).attachment.currentExpression, string,
|
||||
"The expression at index " + index + " should be correct (2)");
|
||||
|
||||
is(gWatch.getString(index), string,
|
||||
"The expression at index " + index + " should be correct (3)");
|
||||
is(gWatch.getAllStrings()[index], string,
|
||||
"The expression at index " + index + " should be correct (4)");
|
||||
}
|
||||
|
||||
function addAndCheckExpressions(total, index, string, noBlur) {
|
||||
gWatch.addExpression(string);
|
||||
|
||||
is(gWatch.getAllStrings().length, total,
|
||||
"There should be " + total + " watch expressions available (1)");
|
||||
is(gWatch.itemCount, total,
|
||||
"There should be " + total + " watch expressions available (2)");
|
||||
|
||||
ok(gWatch.getItemAtIndex(index),
|
||||
"The expression at index " + index + " should be available");
|
||||
is(gWatch.getItemAtIndex(index).attachment.initialExpression, string,
|
||||
"The expression at index " + index + " should have an initial expression");
|
||||
|
||||
let element = gWatch.getItemAtIndex(index).target;
|
||||
|
||||
ok(element,
|
||||
"There should be a new expression item in the view");
|
||||
ok(gWatch.getItemForElement(element),
|
||||
"The watch expression item should be accessible");
|
||||
is(gWatch.getItemForElement(element), gWatch.getItemAtIndex(index),
|
||||
"The correct watch expression item was accessed");
|
||||
|
||||
ok(gWatch.widget.getItemAtIndex(index) instanceof XULElement,
|
||||
"The correct watch expression element was accessed (1)");
|
||||
is(element, gWatch.widget.getItemAtIndex(index),
|
||||
"The correct watch expression element was accessed (2)");
|
||||
|
||||
is(gWatch.getItemForElement(element).attachment.arrowNode.hidden, false,
|
||||
"The arrow node should be visible");
|
||||
is(gWatch.getItemForElement(element).attachment.closeNode.hidden, false,
|
||||
"The close button should be visible");
|
||||
is(gWatch.getItemForElement(element).attachment.inputNode.getAttribute("focused"), "true",
|
||||
"The textbox input should be focused");
|
||||
|
||||
is(gDebugger.DebuggerView.Variables.parentNode.scrollTop, 0,
|
||||
"The variables view should be scrolled to top");
|
||||
|
||||
is(gWatch.orderedItems[0], gWatch.getItemAtIndex(index),
|
||||
"The correct watch expression was added to the cache (1)");
|
||||
is(gWatch.orderedItems[0], gWatch.getItemForElement(element),
|
||||
"The correct watch expression was added to the cache (2)");
|
||||
|
||||
if (!noBlur) {
|
||||
gDebugger.editor.focus();
|
||||
|
||||
is(gWatch.getItemAtIndex(index).attachment.initialExpression, string,
|
||||
"The initial expression at index " + index + " should be correct (1)");
|
||||
is(gWatch.getItemForElement(element).attachment.initialExpression, string,
|
||||
"The initial expression at index " + index + " should be correct (2)");
|
||||
|
||||
is(gWatch.getItemAtIndex(index).attachment.currentExpression, string,
|
||||
"The expression at index " + index + " should be correct (1)");
|
||||
is(gWatch.getItemForElement(element).attachment.currentExpression, string,
|
||||
"The expression at index " + index + " should be correct (2)");
|
||||
|
||||
is(gWatch.getString(index), string,
|
||||
"The expression at index " + index + " should be correct (3)");
|
||||
is(gWatch.getAllStrings()[index], string,
|
||||
"The expression at index " + index + " should be correct (4)");
|
||||
}
|
||||
}
|
||||
|
||||
function removeAndCheckExpression(total, index, string) {
|
||||
gWatch.removeAt(index);
|
||||
|
||||
is(gWatch.getAllStrings().length, total,
|
||||
"There should be " + total + " watch expressions available (1)");
|
||||
is(gWatch.itemCount, total,
|
||||
"There should be " + total + " watch expressions available (2)");
|
||||
|
||||
ok(gWatch.getItemAtIndex(index),
|
||||
"The expression at index " + index + " should still be available");
|
||||
is(gWatch.getItemAtIndex(index).attachment.initialExpression, string,
|
||||
"The expression at index " + index + " should still have an initial expression");
|
||||
|
||||
let element = gWatch.getItemAtIndex(index).target;
|
||||
|
||||
is(gWatch.getItemAtIndex(index).attachment.initialExpression, string,
|
||||
"The initial expression at index " + index + " should be correct (1)");
|
||||
is(gWatch.getItemForElement(element).attachment.initialExpression, string,
|
||||
"The initial expression at index " + index + " should be correct (2)");
|
||||
|
||||
is(gWatch.getItemAtIndex(index).attachment.currentExpression, string,
|
||||
"The expression at index " + index + " should be correct (1)");
|
||||
is(gWatch.getItemForElement(element).attachment.currentExpression, string,
|
||||
"The expression at index " + index + " should be correct (2)");
|
||||
|
||||
is(gWatch.getString(index), string,
|
||||
"The expression at index " + index + " should be correct (3)");
|
||||
is(gWatch.getAllStrings()[index], string,
|
||||
"The expression at index " + index + " should be correct (4)");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
gWatch = null;
|
||||
});
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 731394: test the debugger source editor default context menu.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
|
||||
|
||||
let gPane = null;
|
||||
let gTab = null;
|
||||
let gDebuggee = null;
|
||||
let gDebugger = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
let contextMenu = null;
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
resumed = true;
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", onSourceShown);
|
||||
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded",
|
||||
onFramesAdded);
|
||||
|
||||
executeSoon(function() {
|
||||
gDebuggee.firstCall();
|
||||
});
|
||||
});
|
||||
|
||||
function onFramesAdded(aEvent) {
|
||||
framesAdded = true;
|
||||
executeSoon(startTest);
|
||||
}
|
||||
|
||||
function onSourceShown(aEvent) {
|
||||
scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
|
||||
executeSoon(startTest);
|
||||
}
|
||||
|
||||
function startTest()
|
||||
{
|
||||
if (scriptShown && framesAdded && resumed && !testStarted) {
|
||||
testStarted = true;
|
||||
gDebugger.removeEventListener("Debugger:SourceShown", onSourceShown);
|
||||
executeSoon(performTest);
|
||||
}
|
||||
}
|
||||
|
||||
function performTest()
|
||||
{
|
||||
let scripts = gDebugger.DebuggerView.Sources;
|
||||
let editor = gDebugger.editor;
|
||||
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(scripts.itemCount, 2,
|
||||
"Found the expected number of scripts.");
|
||||
|
||||
isnot(editor.getText().indexOf("debugger"), -1,
|
||||
"The correct script was loaded initially.");
|
||||
|
||||
isnot(editor.getText().indexOf("\u263a"), -1,
|
||||
"Unicode characters are converted correctly.");
|
||||
|
||||
contextMenu = gDebugger.document.getElementById("sourceEditorContextMenu");
|
||||
ok(contextMenu, "source editor context menupopup");
|
||||
ok(editor.readOnly, "editor is read only");
|
||||
|
||||
editor.focus();
|
||||
editor.setSelection(0, 10);
|
||||
|
||||
contextMenu.addEventListener("popupshown", function onPopupShown() {
|
||||
contextMenu.removeEventListener("popupshown", onPopupShown, false);
|
||||
executeSoon(testContextMenu);
|
||||
}, false);
|
||||
contextMenu.openPopup(editor.editorElement, "overlap", 0, 0, true, false);
|
||||
}
|
||||
|
||||
function testContextMenu()
|
||||
{
|
||||
let document = gDebugger.document;
|
||||
|
||||
ok(document.getElementById("editMenuCommands"),
|
||||
"#editMenuCommands found");
|
||||
ok(!document.getElementById("editMenuKeys"),
|
||||
"#editMenuKeys not found");
|
||||
ok(document.getElementById("sourceEditorCommands"),
|
||||
"#sourceEditorCommands found");
|
||||
|
||||
// Map command ids to their expected disabled state.
|
||||
let commands = {"se-cmd-undo": true, "se-cmd-redo": true,
|
||||
"se-cmd-cut": true, "se-cmd-paste": true,
|
||||
"se-cmd-delete": true, "cmd_findAgain": true,
|
||||
"cmd_findPrevious": true, "cmd_find": false,
|
||||
"cmd_gotoLine": false, "cmd_copy": false,
|
||||
"se-cmd-selectAll": false};
|
||||
|
||||
for (let id in commands) {
|
||||
is(document.getElementById(id).hasAttribute("disabled"), commands[id],
|
||||
id + " hasAttribute('disabled') check");
|
||||
}
|
||||
|
||||
executeSoon(function() {
|
||||
contextMenu.hidePopup();
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
}
|
@ -1,121 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 737803: Setting a breakpoint in a line without code should move
|
||||
* the icon to the actual location.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
|
||||
|
||||
let gPane = null;
|
||||
let gTab = null;
|
||||
let gDebuggee = null;
|
||||
let gDebugger = null;
|
||||
let gSources = null;
|
||||
let gEditor = null;
|
||||
let gBreakpoints = null;
|
||||
|
||||
function test() {
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let testStarted = false;
|
||||
let resumed = false;
|
||||
|
||||
debug_tab_pane(TAB_URL, function (aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gPane = aPane;
|
||||
gDebuggee = aDebuggee;
|
||||
gDebugger = gPane.panelWin;
|
||||
resumed = true;
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", onSourceShown);
|
||||
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function () {
|
||||
framesAdded = true;
|
||||
executeSoon(startTest);
|
||||
});
|
||||
|
||||
executeSoon(function () {
|
||||
gDebuggee.firstCall();
|
||||
});
|
||||
});
|
||||
|
||||
function onSourceShown(aEvent) {
|
||||
scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
|
||||
executeSoon(startTest);
|
||||
}
|
||||
|
||||
function startTest() {
|
||||
if (scriptShown && framesAdded && resumed && !testStarted) {
|
||||
gDebugger.removeEventListener("Debugger:SourceShown", onSourceShown);
|
||||
testStarted = true;
|
||||
Services.tm.currentThread.dispatch({ run: performTest }, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function performTest() {
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gEditor = gDebugger.editor;
|
||||
gBreakpoints = gPane.getAllBreakpoints();
|
||||
is(Object.keys(gBreakpoints), 0, "There are no breakpoints");
|
||||
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointAdd);
|
||||
|
||||
let location = { url: gSources.selectedValue, line: 4 };
|
||||
executeSoon(function () {
|
||||
gPane.addBreakpoint(location, onBreakpointAdd);
|
||||
});
|
||||
}
|
||||
|
||||
let onBpDebuggerAdd = false;
|
||||
let onBpEditorAdd = false;
|
||||
|
||||
function onBreakpointAdd(aBpClient) {
|
||||
is(aBpClient.location.url, gSources.selectedValue, "URL is the same");
|
||||
is(aBpClient.location.line, 6, "Line number is new");
|
||||
is(aBpClient.requestedLocation.line, 4, "Requested location is correct");
|
||||
|
||||
onBpDebuggerAdd = true;
|
||||
tryFinish();
|
||||
}
|
||||
|
||||
function onEditorBreakpointAdd(aEvent) {
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointAdd);
|
||||
|
||||
is(gEditor.getBreakpoints().length, 1,
|
||||
"There is only one breakpoint in the editor");
|
||||
|
||||
ok(!gPane.getBreakpoint(gSources.selectedValue, 4),
|
||||
"There are no breakpoints on an invalid line");
|
||||
|
||||
let br = gPane.getBreakpoint(gSources.selectedValue, 6);
|
||||
is(br.location.url, gSources.selectedValue, "URL is correct");
|
||||
is(br.location.line, 6, "Line number is correct");
|
||||
|
||||
onBpEditorAdd = true;
|
||||
tryFinish();
|
||||
}
|
||||
|
||||
function tryFinish() {
|
||||
info("onBpDebuggerAdd: " + onBpDebuggerAdd);
|
||||
info("onBpEditorAdd: " + onBpEditorAdd);
|
||||
|
||||
if (onBpDebuggerAdd && onBpEditorAdd) {
|
||||
closeDebuggerAndFinish();
|
||||
}
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
gSources = null;
|
||||
gEditor = null;
|
||||
gBreakpoints = null;
|
||||
});
|
||||
}
|
@ -1,393 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 740825: test the debugger conditional breakpoints.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_conditional-breakpoints.html";
|
||||
|
||||
let gPane = null;
|
||||
let gTab = null;
|
||||
let gDebuggee = null;
|
||||
let gDebugger = null;
|
||||
let gEditor = null;
|
||||
let gSources = null;
|
||||
let gBreakpoints = null;
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
|
||||
gDebugger.DebuggerView.toggleInstrumentsPane({ visible: true, animated: false });
|
||||
resumed = true;
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", onScriptShown);
|
||||
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
framesAdded = true;
|
||||
executeSoon(startTest);
|
||||
});
|
||||
|
||||
executeSoon(function() {
|
||||
gDebuggee.ermahgerd(); // ermahgerd!!
|
||||
});
|
||||
});
|
||||
|
||||
function onScriptShown(aEvent)
|
||||
{
|
||||
scriptShown = aEvent.detail.url.indexOf("conditional-breakpoints") != -1;
|
||||
executeSoon(startTest);
|
||||
}
|
||||
|
||||
function startTest()
|
||||
{
|
||||
if (scriptShown && framesAdded && resumed && !testStarted) {
|
||||
gDebugger.removeEventListener("Debugger:SourceShown", onScriptShown);
|
||||
testStarted = true;
|
||||
Services.tm.currentThread.dispatch({ run: addBreakpoints }, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function performTest()
|
||||
{
|
||||
gEditor = gDebugger.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gBreakpoints = gPane.getAllBreakpoints();
|
||||
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of scripts.");
|
||||
|
||||
isnot(gEditor.getText().indexOf("ermahgerd"), -1,
|
||||
"The correct script was loaded initially.");
|
||||
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The correct script is selected");
|
||||
|
||||
is(Object.keys(gBreakpoints).length, 13, "thirteen breakpoints");
|
||||
ok(!gPane.getBreakpoint("foo", 3), "getBreakpoint('foo', 3) returns falsey");
|
||||
is(gEditor.getBreakpoints().length, 13, "thirteen breakpoints in the editor");
|
||||
|
||||
executeSoon(test1);
|
||||
}
|
||||
|
||||
function test1(callback)
|
||||
{
|
||||
resumeAndTestBreakpoint(gSources.selectedValue, 14, test2);
|
||||
}
|
||||
|
||||
function test2(callback)
|
||||
{
|
||||
resumeAndTestBreakpoint(gSources.selectedValue, 15, test3);
|
||||
}
|
||||
|
||||
function test3(callback)
|
||||
{
|
||||
resumeAndTestBreakpoint(gSources.selectedValue, 16, test4);
|
||||
}
|
||||
|
||||
function test4(callback)
|
||||
{
|
||||
resumeAndTestBreakpoint(gSources.selectedValue, 17, test5);
|
||||
}
|
||||
|
||||
function test5(callback)
|
||||
{
|
||||
resumeAndTestBreakpoint(gSources.selectedValue, 18, test6);
|
||||
}
|
||||
|
||||
function test6(callback)
|
||||
{
|
||||
resumeAndTestBreakpoint(gSources.selectedValue, 19, test7);
|
||||
}
|
||||
|
||||
function test7(callback)
|
||||
{
|
||||
resumeAndTestBreakpoint(gSources.selectedValue, 21, test8);
|
||||
}
|
||||
|
||||
function test8(callback)
|
||||
{
|
||||
resumeAndTestBreakpoint(gSources.selectedValue, 22, test9);
|
||||
}
|
||||
|
||||
function test9(callback)
|
||||
{
|
||||
resumeAndTestBreakpoint(gSources.selectedValue, 23, test10);
|
||||
}
|
||||
|
||||
function test10(callback)
|
||||
{
|
||||
gDebugger.addEventListener("Debugger:AfterFramesCleared", function listener() {
|
||||
gDebugger.removeEventListener("Debugger:AfterFramesCleared", listener, true);
|
||||
|
||||
isnot(gSources.selectedItem, null,
|
||||
"There should be a selected script in the scripts pane.")
|
||||
is(gSources.selectedBreakpointItem, null,
|
||||
"There should be no selected breakpoint in the scripts pane.")
|
||||
is(gSources.selectedBreakpointClient, null,
|
||||
"There should be no selected client in the scripts pane.");
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
|
||||
is(gDebugger.DebuggerView.StackFrames.widget._list.querySelectorAll(".dbg-stackframe").length, 0,
|
||||
"There should be no visible stackframes.");
|
||||
is(gDebugger.DebuggerView.Sources.widget._list.querySelectorAll(".dbg-breakpoint").length, 13,
|
||||
"There should be thirteen visible breakpoints.");
|
||||
|
||||
testReload();
|
||||
}, true);
|
||||
|
||||
gDebugger.DebuggerController.activeThread.resume();
|
||||
}
|
||||
|
||||
function resumeAndTestBreakpoint(url, line, callback)
|
||||
{
|
||||
resume(line, function() {
|
||||
waitForCaretPos(line - 1, function() {
|
||||
testBreakpoint(gSources.selectedBreakpointItem, gSources.selectedBreakpointClient, url, line, true);
|
||||
callback();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testBreakpoint(aBreakpointItem, aBreakpointClient, url, line, editor)
|
||||
{
|
||||
is(aBreakpointItem.attachment.sourceLocation, gSources.selectedValue,
|
||||
"The breakpoint on line " + line + " wasn't added on the correct source.");
|
||||
is(aBreakpointItem.attachment.lineNumber, line,
|
||||
"The breakpoint on line " + line + " wasn't found.");
|
||||
is(!!aBreakpointItem.attachment.disabled, false,
|
||||
"The breakpoint on line " + line + " should be enabled.");
|
||||
is(!!aBreakpointItem.attachment.openPopupFlag, false,
|
||||
"The breakpoint on line " + line + " should not open a popup.");
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
|
||||
is(aBreakpointClient.location.url, url,
|
||||
"The breakpoint's client url is correct");
|
||||
is(aBreakpointClient.location.line, line,
|
||||
"The breakpoint's client line is correct");
|
||||
isnot(aBreakpointClient.conditionalExpression, undefined,
|
||||
"The breakpoint on line " + line + " should have a conditional expression.");
|
||||
|
||||
if (editor) {
|
||||
is(gEditor.getCaretPosition().line + 1, line,
|
||||
"The editor caret position is not situated on the proper line.");
|
||||
is(gEditor.getCaretPosition().col, 0,
|
||||
"The editor caret position is not situated on the proper column.");
|
||||
}
|
||||
}
|
||||
|
||||
function addBreakpoints(callback)
|
||||
{
|
||||
let currentUrl = gDebugger.DebuggerView.Sources.selectedValue;
|
||||
|
||||
gPane.addBreakpoint({ url: currentUrl, line: 12 }, function() {
|
||||
gPane.addBreakpoint({ url: currentUrl, line: 13 }, function() {
|
||||
gPane.addBreakpoint({ url: currentUrl, line: 14 }, function() {
|
||||
gPane.addBreakpoint({ url: currentUrl, line: 15 }, function() {
|
||||
gPane.addBreakpoint({ url: currentUrl, line: 16 }, function() {
|
||||
gPane.addBreakpoint({ url: currentUrl, line: 17 }, function() {
|
||||
gPane.addBreakpoint({ url: currentUrl, line: 18 }, function() {
|
||||
gPane.addBreakpoint({ url: currentUrl, line: 19 }, function() {
|
||||
gPane.addBreakpoint({ url: currentUrl, line: 20 }, function() {
|
||||
gPane.addBreakpoint({ url: currentUrl, line: 21 }, function() {
|
||||
gPane.addBreakpoint({ url: currentUrl, line: 22 }, function() {
|
||||
gPane.addBreakpoint({ url: currentUrl, line: 23 }, function() {
|
||||
gPane.addBreakpoint({ url: currentUrl, line: 24 }, function() {
|
||||
performTest();
|
||||
}, {
|
||||
conditionalExpression: "b"
|
||||
});
|
||||
}, {
|
||||
conditionalExpression: "a !== null"
|
||||
});
|
||||
}, {
|
||||
conditionalExpression: "a !== undefined"
|
||||
});
|
||||
}, {
|
||||
conditionalExpression: "a"
|
||||
});
|
||||
}, {
|
||||
conditionalExpression: "(function() { return false; })()"
|
||||
});
|
||||
}, {
|
||||
conditionalExpression: "(function() {})"
|
||||
});
|
||||
}, {
|
||||
conditionalExpression: "({})"
|
||||
});
|
||||
}, {
|
||||
conditionalExpression: "/regexp/"
|
||||
});
|
||||
}, {
|
||||
conditionalExpression: "'nasu'"
|
||||
});
|
||||
}, {
|
||||
conditionalExpression: "true"
|
||||
});
|
||||
}, {
|
||||
conditionalExpression: "42"
|
||||
});
|
||||
}, {
|
||||
conditionalExpression: "null"
|
||||
});
|
||||
}, {
|
||||
conditionalExpression: "undefined"
|
||||
});
|
||||
}
|
||||
|
||||
function testReload()
|
||||
{
|
||||
info("Testing reload...");
|
||||
|
||||
function _get(url, line) {
|
||||
return [
|
||||
gDebugger.DebuggerView.Sources.getBreakpoint(url, line),
|
||||
gDebugger.DebuggerController.Breakpoints.getBreakpoint(url, line),
|
||||
url,
|
||||
line,
|
||||
];
|
||||
}
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onSourceShown() {
|
||||
gDebugger.removeEventListener("Debugger:SourceShown", _onSourceShown);
|
||||
|
||||
waitForBreakpoints(13, function() {
|
||||
testBreakpoint.apply(this, _get(gSources.selectedValue, 14));
|
||||
testBreakpoint.apply(this, _get(gSources.selectedValue, 15));
|
||||
testBreakpoint.apply(this, _get(gSources.selectedValue, 16));
|
||||
testBreakpoint.apply(this, _get(gSources.selectedValue, 17));
|
||||
testBreakpoint.apply(this, _get(gSources.selectedValue, 18));
|
||||
testBreakpoint.apply(this, _get(gSources.selectedValue, 19));
|
||||
testBreakpoint.apply(this, _get(gSources.selectedValue, 21));
|
||||
testBreakpoint.apply(this, _get(gSources.selectedValue, 22));
|
||||
testBreakpoint.apply(this, _get(gSources.selectedValue, 23));
|
||||
|
||||
isnot(gSources.selectedItem, null,
|
||||
"There should be a selected script in the scripts pane.")
|
||||
is(gSources.selectedBreakpointItem, null,
|
||||
"There should be no selected breakpoint in the scripts pane.")
|
||||
is(gSources.selectedBreakpointClient, null,
|
||||
"There should be no selected client in the scripts pane.");
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
});
|
||||
|
||||
finalCheck();
|
||||
gDebugger.DebuggerController.client.activeTab.reload();
|
||||
}
|
||||
|
||||
function finalCheck() {
|
||||
isnot(gEditor.getText().indexOf("ermahgerd"), -1,
|
||||
"The correct script is still loaded.");
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The correct script is still selected");
|
||||
}
|
||||
|
||||
function resume(expected, callback) {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("resumed", function() {
|
||||
waitForBreakpoint(expected, callback);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
let bogusClient = {
|
||||
location: {
|
||||
url: null,
|
||||
line: null
|
||||
}
|
||||
};
|
||||
|
||||
function waitForBreakpoint(expected, callback) {
|
||||
// Poll every few milliseconds until expected breakpoint is hit.
|
||||
let count = 0;
|
||||
let intervalID = window.setInterval(function() {
|
||||
info("count: " + count + " ");
|
||||
if (++count > 50) {
|
||||
ok(false, "Timed out while polling for the breakpoint.");
|
||||
window.clearInterval(intervalID);
|
||||
return closeDebuggerAndFinish();
|
||||
}
|
||||
if ((gSources.selectedBreakpointClient !== expected) &&
|
||||
(gSources.selectedBreakpointClient || bogusClient).location.line !== expected) {
|
||||
return;
|
||||
}
|
||||
// We arrived at the expected line, it's safe to callback.
|
||||
window.clearInterval(intervalID);
|
||||
callback();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function waitForBreakpoints(total, callback)
|
||||
{
|
||||
// Poll every few milliseconds until the breakpoints are retrieved.
|
||||
let count = 0;
|
||||
let intervalID = window.setInterval(function() {
|
||||
info("count: " + count + " ");
|
||||
if (++count > 50) {
|
||||
ok(false, "Timed out while polling for the breakpoints.");
|
||||
window.clearInterval(intervalID);
|
||||
return closeDebuggerAndFinish();
|
||||
}
|
||||
if (gSources.widget._list.querySelectorAll(".dbg-breakpoint").length != total) {
|
||||
return;
|
||||
}
|
||||
// We got all the breakpoints, it's safe to callback.
|
||||
window.clearInterval(intervalID);
|
||||
callback();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function waitForCaretPos(number, callback)
|
||||
{
|
||||
// Poll every few milliseconds until the source editor line is active.
|
||||
let count = 0;
|
||||
let intervalID = window.setInterval(function() {
|
||||
info("count: " + count + " ");
|
||||
if (++count > 50) {
|
||||
ok(false, "Timed out while polling for the line.");
|
||||
window.clearInterval(intervalID);
|
||||
return closeDebuggerAndFinish();
|
||||
}
|
||||
if (gEditor.getCaretPosition().line != number) {
|
||||
return;
|
||||
}
|
||||
// We got the source editor at the expected line, it's safe to callback.
|
||||
window.clearInterval(intervalID);
|
||||
callback();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
gBreakpoints = null;
|
||||
});
|
||||
}
|
@ -1,583 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 740825: test the debugger conditional breakpoints.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_conditional-breakpoints.html";
|
||||
|
||||
let gPane = null;
|
||||
let gTab = null;
|
||||
let gDebuggee = null;
|
||||
let gDebugger = null;
|
||||
let gEditor = null;
|
||||
let gSources = null;
|
||||
let gBreakpoints = null;
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
let resumed = false;
|
||||
let testStarted = false;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", onScriptShown);
|
||||
|
||||
gDebugger.DebuggerView.toggleInstrumentsPane({ visible: true, animated: false });
|
||||
resumed = true;
|
||||
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
framesAdded = true;
|
||||
executeSoon(startTest);
|
||||
});
|
||||
|
||||
executeSoon(function() {
|
||||
gDebuggee.ermahgerd(); // ermahgerd!!
|
||||
});
|
||||
});
|
||||
|
||||
function onScriptShown(aEvent)
|
||||
{
|
||||
scriptShown = aEvent.detail.url.indexOf("conditional-breakpoints") != -1;
|
||||
executeSoon(startTest);
|
||||
}
|
||||
|
||||
function startTest()
|
||||
{
|
||||
if (scriptShown && framesAdded && resumed && !testStarted) {
|
||||
gDebugger.removeEventListener("Debugger:SourceShown", onScriptShown);
|
||||
testStarted = true;
|
||||
Services.tm.currentThread.dispatch({ run: performTest }, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function performTest()
|
||||
{
|
||||
gEditor = gDebugger.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gBreakpoints = gPane.getAllBreakpoints();
|
||||
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of scripts.");
|
||||
|
||||
isnot(gEditor.getText().indexOf("ermahgerd"), -1,
|
||||
"The correct script was loaded initially.");
|
||||
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The correct script is selected");
|
||||
|
||||
is(Object.keys(gBreakpoints), 0, "no breakpoints");
|
||||
ok(!gPane.getBreakpoint("foo", 3), "getBreakpoint('foo', 3) returns falsey");
|
||||
is(gEditor.getBreakpoints().length, 0, "no breakpoints in the editor");
|
||||
|
||||
executeSoon(addBreakpoint1);
|
||||
}
|
||||
|
||||
function addBreakpoint1()
|
||||
{
|
||||
gPane.addBreakpoint({ url: gSources.selectedValue, line: 12 });
|
||||
|
||||
waitForBreakpoint(12, function() {
|
||||
waitForCaretPos(10, function() {
|
||||
waitForPopup(false, function() {
|
||||
testBreakpoint(gSources.selectedBreakpointItem,
|
||||
gSources.selectedBreakpointClient,
|
||||
gSources.selectedValue, 12, false, false, false);
|
||||
|
||||
executeSoon(addBreakpoint2);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function addBreakpoint2()
|
||||
{
|
||||
gSources._editorContextMenuLineNumber = 12;
|
||||
gSources._onCmdAddBreakpoint();
|
||||
|
||||
waitForBreakpoint(13, function() {
|
||||
waitForCaretPos(12, function() {
|
||||
waitForPopup(false, function() {
|
||||
testBreakpoint(gSources.selectedBreakpointItem,
|
||||
gSources.selectedBreakpointClient,
|
||||
gSources.selectedValue, 13, false, false, true);
|
||||
|
||||
executeSoon(modBreakpoint2);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function modBreakpoint2()
|
||||
{
|
||||
gSources._editorContextMenuLineNumber = 12;
|
||||
gSources._onCmdAddConditionalBreakpoint();
|
||||
|
||||
waitForBreakpoint(13, function() {
|
||||
waitForCaretPos(12, function() {
|
||||
waitForPopup(true, function() {
|
||||
testBreakpoint(gSources.selectedBreakpointItem,
|
||||
gSources.selectedBreakpointClient,
|
||||
gSources.selectedValue, 13, true, true, true);
|
||||
|
||||
executeSoon(addBreakpoint3);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function addBreakpoint3()
|
||||
{
|
||||
gSources._editorContextMenuLineNumber = 13;
|
||||
gSources._onCmdAddConditionalBreakpoint();
|
||||
|
||||
waitForBreakpoint(14, function() {
|
||||
waitForCaretPos(13, function() {
|
||||
waitForPopup(true, function() {
|
||||
testBreakpoint(gSources.selectedBreakpointItem,
|
||||
gSources.selectedBreakpointClient,
|
||||
gSources.selectedValue, 14, true, true, true);
|
||||
|
||||
executeSoon(modBreakpoint3);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function modBreakpoint3()
|
||||
{
|
||||
write("bamboocha");
|
||||
EventUtils.sendKey("RETURN", gDebugger);
|
||||
|
||||
waitForBreakpoint(14, function() {
|
||||
waitForCaretPos(13, function() {
|
||||
waitForPopup(false, function() {
|
||||
is(gSources.selectedBreakpointClient.conditionalExpression, "bamboocha",
|
||||
"The bamboocha expression wasn't fonud on the conditional breakpoint");
|
||||
|
||||
executeSoon(setContextMenu);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function setContextMenu()
|
||||
{
|
||||
let contextMenu = gDebugger.document.getElementById("sourceEditorContextMenu");
|
||||
info("Testing source editor popup...");
|
||||
|
||||
contextMenu.addEventListener("popupshown", function onPopupShown() {
|
||||
contextMenu.removeEventListener("popupshown", onPopupShown, false);
|
||||
info("Source editor popup shown...");
|
||||
|
||||
contextMenu.addEventListener("popuphidden", function onPopupHidden() {
|
||||
contextMenu.removeEventListener("popuphidden", onPopupHidden, false);
|
||||
info("Source editor popup hidden...");
|
||||
|
||||
is(gSources._editorContextMenuLineNumber, 14,
|
||||
"The context menu line number is incorrect after the popup was hidden.");
|
||||
executeSoon(addBreakpoint4);
|
||||
}, false);
|
||||
|
||||
is(gSources._editorContextMenuLineNumber, 14,
|
||||
"The context menu line number is incorrect after the popup was shown.");
|
||||
contextMenu.hidePopup();
|
||||
}, false);
|
||||
|
||||
is(gSources._editorContextMenuLineNumber, -1,
|
||||
"The context menu line number was incorrect before the popup was shown.");
|
||||
gSources._editorContextMenuLineNumber = 14;
|
||||
contextMenu.openPopup(gEditor.editorElement, "overlap", 0, 0, true, false);
|
||||
}
|
||||
|
||||
function addBreakpoint4()
|
||||
{
|
||||
gEditor.setCaretPosition(14);
|
||||
gSources._onCmdAddBreakpoint();
|
||||
|
||||
waitForBreakpoint(15, function() {
|
||||
waitForCaretPos(14, function() {
|
||||
waitForPopup(false, function() {
|
||||
testBreakpoint(gSources.selectedBreakpointItem,
|
||||
gSources.selectedBreakpointClient,
|
||||
gSources.selectedValue, 15, false, false, true);
|
||||
|
||||
executeSoon(delBreakpoint4);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function delBreakpoint4()
|
||||
{
|
||||
gEditor.setCaretPosition(14);
|
||||
gSources._onCmdAddBreakpoint();
|
||||
|
||||
waitForBreakpoint(null, function() {
|
||||
waitForCaretPos(14, function() {
|
||||
waitForPopup(false, function() {
|
||||
is(gSources.selectedBreakpointItem, null,
|
||||
"There should be no selected breakpoint in the breakpoints pane.")
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
|
||||
executeSoon(moveHighlight1);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function moveHighlight1()
|
||||
{
|
||||
gEditor.setCaretPosition(13);
|
||||
|
||||
waitForBreakpoint(14, function() {
|
||||
waitForCaretPos(13, function() {
|
||||
waitForPopup(false, function() {
|
||||
testBreakpoint(gSources.selectedBreakpointItem,
|
||||
gSources.selectedBreakpointClient,
|
||||
gSources.selectedValue, 14, false, true, true);
|
||||
|
||||
executeSoon(testHighlights1);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testHighlights1()
|
||||
{
|
||||
isnot(gSources.selectedBreakpointItem, null,
|
||||
"There should be a selected breakpoint in the breakpoints pane.");
|
||||
is(gSources.selectedBreakpointItem.attachment.sourceLocation, gSources.selectedValue,
|
||||
"The selected breakpoint should have the correct location.");
|
||||
is(gSources.selectedBreakpointItem.attachment.lineNumber, 14,
|
||||
"The selected breakpoint should have the correct line number.");
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
is(gEditor.getCaretPosition().line, 13,
|
||||
"The source editor caret position should be at line 13");
|
||||
is(gEditor.getCaretPosition().col, 0,
|
||||
"The source editor caret position should be at column 0");
|
||||
|
||||
gEditor.setCaretPosition(12);
|
||||
|
||||
waitForCaretPos(12, function() {
|
||||
waitForPopup(false, function() {
|
||||
isnot(gSources.selectedBreakpointItem, null,
|
||||
"There should be a selected breakpoint in the breakpoints pane.");
|
||||
is(gSources.selectedBreakpointItem.attachment.sourceLocation, gSources.selectedValue,
|
||||
"The selected breakpoint should have the correct location.");
|
||||
is(gSources.selectedBreakpointItem.attachment.lineNumber, 13,
|
||||
"The selected breakpoint should have the correct line number.");
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
is(gEditor.getCaretPosition().line, 12,
|
||||
"The source editor caret position should be at line 12");
|
||||
is(gEditor.getCaretPosition().col, 0,
|
||||
"The source editor caret position should be at column 0");
|
||||
|
||||
gEditor.setCaretPosition(11);
|
||||
|
||||
waitForCaretPos(11, function() {
|
||||
waitForPopup(false, function() {
|
||||
isnot(gSources.selectedBreakpointItem, null,
|
||||
"There should be a selected breakpoint in the breakpoints pane.");
|
||||
is(gSources.selectedBreakpointItem.attachment.sourceLocation, gSources.selectedValue,
|
||||
"The selected breakpoint should have the correct location.");
|
||||
is(gSources.selectedBreakpointItem.attachment.lineNumber, 12,
|
||||
"The selected breakpoint should have the correct line number.");
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
is(gEditor.getCaretPosition().line, 11,
|
||||
"The source editor caret position should be at line 11");
|
||||
is(gEditor.getCaretPosition().col, 0,
|
||||
"The source editor caret position should be at column 0");
|
||||
|
||||
gEditor.setCaretPosition(10);
|
||||
|
||||
waitForCaretPos(10, function() {
|
||||
waitForPopup(false, function() {
|
||||
is(gSources.selectedBreakpointItem, null,
|
||||
"There should not be a selected breakpoint in the breakpoints pane.");
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
is(gEditor.getCaretPosition().line, 10,
|
||||
"The source editor caret position should be at line 10");
|
||||
is(gEditor.getCaretPosition().col, 0,
|
||||
"The source editor caret position should be at column 0");
|
||||
|
||||
gEditor.setCaretPosition(14);
|
||||
|
||||
waitForCaretPos(14, function() {
|
||||
waitForPopup(false, function() {
|
||||
is(gSources.selectedBreakpointItem, null,
|
||||
"There should not be a selected breakpoint in the breakpoints pane.");
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
is(gEditor.getCaretPosition().line, 14,
|
||||
"The source editor caret position should be at line 14");
|
||||
is(gEditor.getCaretPosition().col, 0,
|
||||
"The source editor caret position should be at column 0");
|
||||
|
||||
executeSoon(testHighlights2);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testHighlights2()
|
||||
{
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gSources.widget._list.querySelectorAll(".dbg-breakpoint")[2],
|
||||
gDebugger);
|
||||
|
||||
waitForCaretPos(13, function() {
|
||||
waitForPopup(true, function() {
|
||||
isnot(gSources.selectedBreakpointItem, null,
|
||||
"There should be a selected breakpoint in the breakpoints pane.");
|
||||
is(gSources.selectedBreakpointItem.attachment.sourceLocation, gSources.selectedValue,
|
||||
"The selected breakpoint should have the correct location.");
|
||||
is(gSources.selectedBreakpointItem.attachment.lineNumber, 14,
|
||||
"The selected breakpoint should have the correct line number.");
|
||||
is(gSources._conditionalPopupVisible, true,
|
||||
"The breakpoint conditional expression popup should be shown.");
|
||||
is(gEditor.getCaretPosition().line, 13,
|
||||
"The source editor caret position should be at line 13");
|
||||
is(gEditor.getCaretPosition().col, 0,
|
||||
"The source editor caret position should be at column 0");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gSources.widget._list.querySelectorAll(".dbg-breakpoint")[1],
|
||||
gDebugger);
|
||||
|
||||
waitForCaretPos(12, function() {
|
||||
waitForPopup(true, function() {
|
||||
isnot(gSources.selectedBreakpointItem, null,
|
||||
"There should be a selected breakpoint in the breakpoints pane.");
|
||||
is(gSources.selectedBreakpointItem.attachment.sourceLocation, gSources.selectedValue,
|
||||
"The selected breakpoint should have the correct location.");
|
||||
is(gSources.selectedBreakpointItem.attachment.lineNumber, 13,
|
||||
"The selected breakpoint should have the correct line number.");
|
||||
is(gSources._conditionalPopupVisible, true,
|
||||
"The breakpoint conditional expression popup should be shown.");
|
||||
is(gEditor.getCaretPosition().line, 12,
|
||||
"The source editor caret position should be at line 12");
|
||||
is(gEditor.getCaretPosition().col, 0,
|
||||
"The source editor caret position should be at column 0");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gSources.widget._list.querySelectorAll(".dbg-breakpoint")[0],
|
||||
gDebugger);
|
||||
|
||||
waitForCaretPos(11, function() {
|
||||
waitForPopup(false, function() {
|
||||
isnot(gSources.selectedBreakpointItem, null,
|
||||
"There should be a selected breakpoint in the breakpoints pane.");
|
||||
is(gSources.selectedBreakpointItem.attachment.sourceLocation, gSources.selectedValue,
|
||||
"The selected breakpoint should have the correct location.");
|
||||
is(gSources.selectedBreakpointItem.attachment.lineNumber, 12,
|
||||
"The selected breakpoint should have the correct line number.");
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should be shown.");
|
||||
is(gEditor.getCaretPosition().line, 11,
|
||||
"The source editor caret position should be at line 11");
|
||||
is(gEditor.getCaretPosition().col, 0,
|
||||
"The source editor caret position should be at column 0");
|
||||
|
||||
executeSoon(delBreakpoint2);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function delBreakpoint2()
|
||||
{
|
||||
gSources._editorContextMenuLineNumber = 12;
|
||||
gSources._onCmdAddBreakpoint();
|
||||
|
||||
waitForBreakpoint(null, function() {
|
||||
waitForPopup(false, function() {
|
||||
is(gSources.selectedBreakpointItem, null,
|
||||
"There should be no selected breakpoint in the breakpoints pane.")
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
|
||||
executeSoon(delBreakpoint3);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function delBreakpoint3()
|
||||
{
|
||||
gSources._editorContextMenuLineNumber = 13;
|
||||
gSources._onCmdAddBreakpoint();
|
||||
|
||||
waitForBreakpoint(null, function() {
|
||||
waitForPopup(false, function() {
|
||||
is(gSources.selectedBreakpointItem, null,
|
||||
"There should be no selected breakpoint in the breakpoints pane.")
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
|
||||
executeSoon(testBreakpoints);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testBreakpoints()
|
||||
{
|
||||
is(Object.keys(gBreakpoints).length, 1, "one breakpoint");
|
||||
ok(!gPane.getBreakpoint("foo", 3), "getBreakpoint('foo', 3) returns falsey");
|
||||
is(gEditor.getBreakpoints().length, 1, "one breakpoint in the editor");
|
||||
|
||||
closeDebuggerAndFinish();
|
||||
}
|
||||
|
||||
function testBreakpoint(aBreakpointItem, aBreakpointClient, url, line, popup, conditional, editor)
|
||||
{
|
||||
is(aBreakpointItem.attachment.sourceLocation, gSources.selectedValue,
|
||||
"The breakpoint on line " + line + " wasn't added on the correct source.");
|
||||
is(aBreakpointItem.attachment.lineNumber, line,
|
||||
"The breakpoint on line " + line + " wasn't found.");
|
||||
is(!aBreakpointItem.attachment.disabled, true,
|
||||
"The breakpoint on line " + line + " should be enabled.");
|
||||
is(gSources._conditionalPopupVisible, popup,
|
||||
"The breakpoint conditional expression popup should " + (popup ? "" : "not ") + "be shown.");
|
||||
|
||||
is(aBreakpointClient.location.url, url,
|
||||
"The breakpoint's client url is correct");
|
||||
is(aBreakpointClient.location.line, line,
|
||||
"The breakpoint's client line is correct");
|
||||
|
||||
if (conditional) {
|
||||
isnot(aBreakpointClient.conditionalExpression, undefined,
|
||||
"The breakpoint on line " + line + " should have a conditional expression.");
|
||||
} else {
|
||||
is(aBreakpointClient.conditionalExpression, undefined,
|
||||
"The breakpoint on line " + line + " should not have a conditional expression.");
|
||||
}
|
||||
|
||||
if (editor) {
|
||||
is(gEditor.getCaretPosition().line + 1, line,
|
||||
"The editor caret position is not situated on the proper line.");
|
||||
is(gEditor.getCaretPosition().col, 0,
|
||||
"The editor caret position is not situated on the proper column.");
|
||||
}
|
||||
}
|
||||
|
||||
let bogusClient = {
|
||||
location: {
|
||||
url: null,
|
||||
line: null
|
||||
}
|
||||
};
|
||||
|
||||
function waitForBreakpoint(expected, callback) {
|
||||
// Poll every few milliseconds until expected breakpoint is hit.
|
||||
let count = 0;
|
||||
let intervalID = window.setInterval(function() {
|
||||
info("count: " + count + " ");
|
||||
if (++count > 50) {
|
||||
ok(false, "Timed out while polling for the breakpoint.");
|
||||
window.clearInterval(intervalID);
|
||||
return closeDebuggerAndFinish();
|
||||
}
|
||||
if ((gSources.selectedBreakpointClient !== expected) &&
|
||||
(gSources.selectedBreakpointClient || bogusClient).location.line !== expected) {
|
||||
return;
|
||||
}
|
||||
// We arrived at the expected line, it's safe to callback.
|
||||
window.clearInterval(intervalID);
|
||||
callback();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function waitForCaretPos(number, callback)
|
||||
{
|
||||
// Poll every few milliseconds until the source editor line is active.
|
||||
let count = 0;
|
||||
let intervalID = window.setInterval(function() {
|
||||
info("count: " + count + " ");
|
||||
if (++count > 50) {
|
||||
ok(false, "Timed out while polling for the line.");
|
||||
window.clearInterval(intervalID);
|
||||
return closeDebuggerAndFinish();
|
||||
}
|
||||
if (gEditor.getCaretPosition().line != number) {
|
||||
return;
|
||||
}
|
||||
// We got the source editor at the expected line, it's safe to callback.
|
||||
window.clearInterval(intervalID);
|
||||
callback();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function waitForPopup(state, callback)
|
||||
{
|
||||
// Poll every few milliseconds until the expression popup is shown.
|
||||
let count = 0;
|
||||
let intervalID = window.setInterval(function() {
|
||||
info("count: " + count + " ");
|
||||
if (++count > 50) {
|
||||
ok(false, "Timed out while polling for the popup.");
|
||||
window.clearInterval(intervalID);
|
||||
return closeDebuggerAndFinish();
|
||||
}
|
||||
if (gSources._conditionalPopupVisible != state) {
|
||||
return;
|
||||
}
|
||||
// We got the expression popup at the expected state, it's safe to callback.
|
||||
window.clearInterval(intervalID);
|
||||
callback();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function clear() {
|
||||
gSources._cbTextbox.focus();
|
||||
gSources._cbTextbox.value = "";
|
||||
}
|
||||
|
||||
function write(text) {
|
||||
clear();
|
||||
append(text);
|
||||
}
|
||||
|
||||
function append(text) {
|
||||
gSources._cbTextbox.focus();
|
||||
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
EventUtils.sendChar(text[i], gDebugger);
|
||||
}
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
gBreakpoints = null;
|
||||
});
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
|
||||
function test() {
|
||||
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
|
||||
testNonEnumProperties();
|
||||
});
|
||||
}
|
||||
|
||||
function testNonEnumProperties() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let testScope = gDebugger.DebuggerView.Variables.addScope("test-scope");
|
||||
let testVar = testScope.addItem("foo");
|
||||
|
||||
testVar.addItems({
|
||||
foo: {
|
||||
value: "bar",
|
||||
enumerable: true
|
||||
},
|
||||
bar: {
|
||||
value: "foo",
|
||||
enumerable: false
|
||||
}
|
||||
});
|
||||
|
||||
// Expand the variable.
|
||||
testScope.expand();
|
||||
testVar.expand();
|
||||
|
||||
executeSoon(function() {
|
||||
let details = testVar._enum;
|
||||
let nonenum = testVar._nonenum;
|
||||
|
||||
is(details.childNodes.length, 1,
|
||||
"There should be just one property in the .details container.");
|
||||
|
||||
ok(details.hasAttribute("open"),
|
||||
".details container should be visible.");
|
||||
|
||||
ok(nonenum.hasAttribute("open"),
|
||||
".nonenum container should be visible.");
|
||||
|
||||
is(nonenum.childNodes.length, 1,
|
||||
"There should be just one property in the .nonenum container.");
|
||||
|
||||
// Uncheck 'show hidden properties'.
|
||||
gDebugger.DebuggerView.Options._showVariablesOnlyEnumItem.setAttribute("checked", "true");
|
||||
gDebugger.DebuggerView.Options._toggleShowVariablesOnlyEnum();
|
||||
|
||||
executeSoon(function() {
|
||||
ok(details.hasAttribute("open"),
|
||||
".details container should stay visible.");
|
||||
|
||||
ok(!nonenum.hasAttribute("open"),
|
||||
".nonenum container should become hidden.");
|
||||
|
||||
// Check 'show hidden properties'.
|
||||
gDebugger.DebuggerView.Options._showVariablesOnlyEnumItem.setAttribute("checked", "false");
|
||||
gDebugger.DebuggerView.Options._toggleShowVariablesOnlyEnum();
|
||||
|
||||
executeSoon(function() {
|
||||
ok(details.hasAttribute("open"),
|
||||
".details container should stay visible.");
|
||||
|
||||
ok(nonenum.hasAttribute("open"),
|
||||
".nonenum container should become visible.");
|
||||
|
||||
// Collapse the variable.
|
||||
testVar.collapse();
|
||||
|
||||
executeSoon(function() {
|
||||
ok(!details.hasAttribute("open"),
|
||||
".details container should be hidden.");
|
||||
|
||||
ok(!nonenum.hasAttribute("open"),
|
||||
".nonenum container should be hidden.");
|
||||
|
||||
// Uncheck 'show hidden properties'.
|
||||
gDebugger.DebuggerView.Options._showVariablesOnlyEnumItem.setAttribute("checked", "true");
|
||||
gDebugger.DebuggerView.Options._toggleShowVariablesOnlyEnum();
|
||||
|
||||
executeSoon(function() {
|
||||
ok(!details.hasAttribute("open"),
|
||||
".details container should stay hidden.");
|
||||
|
||||
ok(!nonenum.hasAttribute("open"),
|
||||
".nonenum container should stay hidden.");
|
||||
|
||||
// Check 'show hidden properties'.
|
||||
gDebugger.DebuggerView.Options._showVariablesOnlyEnumItem.setAttribute("checked", "false");
|
||||
gDebugger.DebuggerView.Options._toggleShowVariablesOnlyEnum();
|
||||
|
||||
executeSoon(function() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.simpleCall();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
@ -1,78 +0,0 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Tests that debugger's tab is highlighted when it is paused and not the
|
||||
// currently selected tool.
|
||||
|
||||
var gTab = null;
|
||||
var gDebugger = null;
|
||||
var gToolbox = null;
|
||||
var gToolboxTab = null;
|
||||
|
||||
function test() {
|
||||
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebugger = aPane.panelWin;
|
||||
gToolbox = aPane._toolbox;
|
||||
gToolboxTab = gToolbox.doc.getElementById("toolbox-tab-jsdebugger");
|
||||
testPause();
|
||||
});
|
||||
}
|
||||
|
||||
function testPause() {
|
||||
is(gDebugger.DebuggerController.activeThread.paused, false,
|
||||
"Should be running after debug_tab_pane.");
|
||||
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("paused", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
gToolbox.selectTool("webconsole").then(() => {
|
||||
ok(gToolboxTab.classList.contains("highlighted"),
|
||||
"The highlighted class is present");
|
||||
ok(!gToolboxTab.hasAttribute("selected") ||
|
||||
gToolboxTab.getAttribute("selected") != "true",
|
||||
"The tab is not selected");
|
||||
}).then(() => gToolbox.selectTool("jsdebugger")).then(() => {
|
||||
ok(gToolboxTab.classList.contains("highlighted"),
|
||||
"The highlighted class is present");
|
||||
ok(gToolboxTab.hasAttribute("selected") &&
|
||||
gToolboxTab.getAttribute("selected") == "true",
|
||||
"and the tab is selected, so the orange glow will not be present.");
|
||||
}).then(testResume);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function testResume() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("resumed", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
gToolbox.selectTool("webconsole").then(() => {
|
||||
ok(!gToolboxTab.classList.contains("highlighted"),
|
||||
"The highlighted class is not present now after the resume");
|
||||
ok(!gToolboxTab.hasAttribute("selected") ||
|
||||
gToolboxTab.getAttribute("selected") != "true",
|
||||
"The tab is not selected");
|
||||
}).then(closeDebuggerAndFinish);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gTab = null;
|
||||
gDebugger = null;
|
||||
gToolbox = null;
|
||||
gToolboxTab = null;
|
||||
});
|
@ -1,134 +0,0 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Tests that debugger's tab is highlighted when it is paused and not the
|
||||
// currently selected tool.
|
||||
|
||||
var gTab = null;
|
||||
var gTab2 = null;
|
||||
var gDebugger = null;
|
||||
var gToolbox = null;
|
||||
var gToolboxTab = null;
|
||||
var gFocusedWindow = null;
|
||||
promise._reportErrors = true;
|
||||
|
||||
function test() {
|
||||
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebugger = aPane.panelWin;
|
||||
gToolbox = aPane._toolbox;
|
||||
gToolboxTab = gToolbox.doc.getElementById("toolbox-tab-jsdebugger");
|
||||
gBrowser.selectedTab = gTab2 = gBrowser.addTab();
|
||||
executeSoon(function() {
|
||||
is(gBrowser.selectedTab, gTab2, "Debugger's tab is not the selected tab.");
|
||||
gFocusedWindow = window;
|
||||
testPause();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function focusMainWindow() {
|
||||
// Make sure toolbox is not focused.
|
||||
window.addEventListener("focus", onFocus, true);
|
||||
|
||||
// execute soon to avoid any race conditions between toolbox and main window
|
||||
// getting focused.
|
||||
executeSoon(() => {
|
||||
window.focus();
|
||||
});
|
||||
}
|
||||
|
||||
function onFocus() {
|
||||
window.removeEventListener("focus", onFocus, true);
|
||||
info("main window focused.")
|
||||
gFocusedWindow = window;
|
||||
testPause();
|
||||
}
|
||||
|
||||
function testPause() {
|
||||
is(gDebugger.DebuggerController.activeThread.paused, false,
|
||||
"Should be running after debug_tab_pane.");
|
||||
|
||||
is(gFocusedWindow, window, "Main window is the top level window before pause");
|
||||
|
||||
if (gToolbox.hostType == devtools.Toolbox.HostType.WINDOW) {
|
||||
gToolbox._host._window.onfocus = () => {
|
||||
gFocusedWindow = gToolbox._host._window;
|
||||
};
|
||||
}
|
||||
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("paused", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
if (gToolbox.hostType == devtools.Toolbox.HostType.WINDOW) {
|
||||
is(gFocusedWindow, gToolbox._host._window,
|
||||
"Toolbox window is the top level window on pause.");
|
||||
}
|
||||
else {
|
||||
is(gBrowser.selectedTab, gTab, "Debugger's tab got selected.");
|
||||
}
|
||||
gToolbox.selectTool("webconsole").then(() => {
|
||||
ok(gToolboxTab.classList.contains("highlighted"),
|
||||
"The highlighted class is present");
|
||||
ok(!gToolboxTab.hasAttribute("selected") ||
|
||||
gToolboxTab.getAttribute("selected") != "true",
|
||||
"The tab is not selected");
|
||||
}).then(() => gToolbox.selectTool("jsdebugger")).then(() => {
|
||||
ok(gToolboxTab.classList.contains("highlighted"),
|
||||
"The highlighted class is present");
|
||||
ok(gToolboxTab.hasAttribute("selected") &&
|
||||
gToolboxTab.getAttribute("selected") == "true",
|
||||
"and the tab is selected, so the orange glow will not be present.");
|
||||
}).then(testResume);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function testResume() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("resumed", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
gToolbox.selectTool("webconsole").then(() => {
|
||||
ok(!gToolboxTab.classList.contains("highlighted"),
|
||||
"The highlighted class is not present now after the resume");
|
||||
ok(!gToolboxTab.hasAttribute("selected") ||
|
||||
gToolboxTab.getAttribute("selected") != "true",
|
||||
"The tab is not selected");
|
||||
}).then(maybeEndTest);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function maybeEndTest() {
|
||||
if (gToolbox.hostType == devtools.Toolbox.HostType.WINDOW) {
|
||||
gToolbox.switchHost(devtools.Toolbox.HostType.BOTTOM)
|
||||
.then(closeDebuggerAndFinish);
|
||||
}
|
||||
else {
|
||||
info("switching to toolbox window.")
|
||||
gToolbox.switchHost(devtools.Toolbox.HostType.WINDOW).then(focusMainWindow).then(null, console.error);
|
||||
}
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
Services.prefs.setCharPref("devtools.toolbox.host", devtools.Toolbox.HostType.BOTTOM);
|
||||
removeTab(gTab);
|
||||
removeTab(gTab2);
|
||||
gTab = null;
|
||||
gTab2 = null;
|
||||
gDebugger = null;
|
||||
gToolbox = null;
|
||||
gToolboxTab = null;
|
||||
gFocusedWindow = null;
|
||||
});
|
@ -1,32 +1,26 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that a chrome debugger can be created in a new process.
|
||||
*/
|
||||
|
||||
// Tests that a chrome debugger can be created in a new process.
|
||||
|
||||
var gProcess = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
let gProcess;
|
||||
|
||||
function test() {
|
||||
// Windows XP test slaves are terribly slow at this test.
|
||||
requestLongerTimeout(4);
|
||||
|
||||
debug_chrome(STACK_URL, aOnClosing, function(aTab, aDebuggee, aProcess) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
initChromeDebugger(aOnClose).then(aProcess => {
|
||||
gProcess = aProcess;
|
||||
|
||||
info("Starting test");
|
||||
testSimpleCall();
|
||||
info("Starting test...");
|
||||
performTest();
|
||||
});
|
||||
}
|
||||
|
||||
function testSimpleCall() {
|
||||
function performTest() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
ok(gProcess._dbgProcess,
|
||||
"The remote debugger process wasn't created properly!");
|
||||
ok(gProcess._dbgProcess.isRunning,
|
||||
@ -68,7 +62,7 @@ function testSimpleCall() {
|
||||
}}, 0);
|
||||
}
|
||||
|
||||
function aOnClosing() {
|
||||
function aOnClose() {
|
||||
ok(!gProcess._dbgProcess.isRunning,
|
||||
"The remote debugger process isn't closed as it should be!");
|
||||
is(gProcess._dbgProcess.exitValue, (Services.appinfo.OS == "WINNT" ? 0 : 256),
|
||||
@ -80,14 +74,9 @@ function aOnClosing() {
|
||||
info("profile rootDir: " + gProcess._dbgProfile.rootDir.path);
|
||||
info("profile name: " + gProcess._dbgProfile.name);
|
||||
|
||||
executeSoon(function() {
|
||||
finish();
|
||||
});
|
||||
finish();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gProcess = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
});
|
@ -1,68 +1,92 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that chrome debugging works.
|
||||
*/
|
||||
|
||||
// Tests that chrome debugging works.
|
||||
const TAB_URL = EXAMPLE_URL + "doc_inline-debugger-statement.html";
|
||||
|
||||
var gClient = null;
|
||||
var gTab = null;
|
||||
var gMozillaTab = null;
|
||||
var gThreadClient = null;
|
||||
var gNewGlobal = false;
|
||||
var gAttached = false;
|
||||
var gChromeSource = false;
|
||||
let gClient, gThreadClient;
|
||||
let gAttached = promise.defer();
|
||||
let gNewGlobal = promise.defer()
|
||||
let gNewChromeSource = promise.defer()
|
||||
|
||||
const DEBUGGER_TAB_URL = EXAMPLE_URL + "browser_dbg_debuggerstatement.html";
|
||||
function test() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init(() => true);
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect(function(aType, aTraits) {
|
||||
gTab = addTab(DEBUGGER_TAB_URL, function() {
|
||||
gClient.listTabs(function(aResponse) {
|
||||
let dbg = aResponse.chromeDebugger;
|
||||
ok(dbg, "Found a chrome debugging actor.");
|
||||
gClient.connect((aType, aTraits) => {
|
||||
is(aType, "browser",
|
||||
"Root actor should identify itself as a browser.");
|
||||
|
||||
gClient.addOneTimeListener("newGlobal", function() gNewGlobal = true);
|
||||
gClient.addListener("newSource", onNewSource);
|
||||
|
||||
gClient.attachThread(dbg, function(aResponse, aThreadClient) {
|
||||
gThreadClient = aThreadClient;
|
||||
ok(!aResponse.error, "Attached to the chrome debugger.");
|
||||
gAttached = true;
|
||||
|
||||
// Ensure that a new global will be created.
|
||||
gMozillaTab = gBrowser.addTab("about:mozilla");
|
||||
|
||||
finish_test();
|
||||
});
|
||||
promise.all([gAttached.promise, gNewGlobal.promise, gNewChromeSource.promise])
|
||||
.then(resumeAndCloseConnection)
|
||||
.then(finish)
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
testChromeActor();
|
||||
});
|
||||
}
|
||||
|
||||
function testChromeActor() {
|
||||
gClient.listTabs(aResponse => {
|
||||
ok(aResponse.chromeDebugger.contains("chromeDebugger"),
|
||||
"Chrome debugger actor should identify itself accordingly.");
|
||||
|
||||
gClient.addListener("newGlobal", onNewGlobal);
|
||||
gClient.addListener("newSource", onNewSource);
|
||||
|
||||
gClient.attachThread(aResponse.chromeDebugger, (aResponse, aThreadClient) => {
|
||||
gThreadClient = aThreadClient;
|
||||
|
||||
if (aResponse.error) {
|
||||
ok(false, "Couldn't attach to the chrome debugger.");
|
||||
gAttached.reject();
|
||||
} else {
|
||||
ok(true, "Attached to the chrome debugger.");
|
||||
gAttached.resolve();
|
||||
|
||||
// Ensure that a new chrome global will be created.
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:mozilla");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function onNewSource(aEvent, aPacket)
|
||||
{
|
||||
gChromeSource = aPacket.source.url.startsWith("chrome:");
|
||||
finish_test();
|
||||
function onNewGlobal() {
|
||||
ok(true, "Received a new chrome global.");
|
||||
|
||||
gClient.removeListener("newGlobal", onNewGlobal);
|
||||
gNewGlobal.resolve();
|
||||
}
|
||||
|
||||
function finish_test()
|
||||
{
|
||||
if (!gAttached || !gChromeSource) {
|
||||
return;
|
||||
function onNewSource(aEvent, aPacket) {
|
||||
if (aPacket.source.url.startsWith("chrome:")) {
|
||||
ok(true, "Received a new chrome source: " + aPacket.source.url);
|
||||
|
||||
gClient.removeListener("newSource", onNewSource);
|
||||
gNewChromeSource.resolve();
|
||||
}
|
||||
gClient.removeListener("newSource", onNewSource);
|
||||
gThreadClient.resume(function(aResponse) {
|
||||
removeTab(gMozillaTab);
|
||||
removeTab(gTab);
|
||||
gClient.close(function() {
|
||||
ok(gNewGlobal, "Received newGlobal event.");
|
||||
ok(gChromeSource, "Received newSource event for a chrome: script.");
|
||||
finish();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function resumeAndCloseConnection() {
|
||||
let deferred = promise.defer();
|
||||
gThreadClient.resume(() => gClient.close(deferred.resolve));
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gBrowser.selectedTab);
|
||||
gClient = null;
|
||||
gThreadClient = null;
|
||||
gAttached = null;
|
||||
gNewGlobal = null;
|
||||
gNewChromeSource = null;
|
||||
});
|
||||
|
@ -1,43 +1,39 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that closing a tab with the debugger in a paused state exits cleanly.
|
||||
*/
|
||||
|
||||
// Test that closing a tab with the debugger in a paused state exits cleanly.
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebugger = null;
|
||||
|
||||
const DEBUGGER_TAB_URL = EXAMPLE_URL + "browser_dbg_debuggerstatement.html";
|
||||
const TAB_URL = EXAMPLE_URL + "doc_inline-debugger-statement.html";
|
||||
|
||||
function test() {
|
||||
debug_tab_pane(DEBUGGER_TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
testCleanExit();
|
||||
});
|
||||
}
|
||||
|
||||
function testCleanExit() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 16).then(() => {
|
||||
is(gDebugger.gThreadClient.paused, true,
|
||||
"Should be paused after the debugger statement.");
|
||||
|
||||
is(gDebugger.DebuggerController.activeThread.paused, true,
|
||||
"Should be paused after the debugger statement.");
|
||||
|
||||
closeDebuggerAndFinish();
|
||||
}}, 0);
|
||||
closeDebuggerAndFinish(gPanel, { whilePaused: true });
|
||||
});
|
||||
|
||||
gTab.linkedBrowser.contentWindow.wrappedJSObject.runDebuggerStatement();
|
||||
gDebuggee.runDebuggerStatement();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
134
browser/devtools/debugger/test/browser_dbg_cmd-blackbox.js
Normal file
134
browser/devtools/debugger/test/browser_dbg_cmd-blackbox.js
Normal file
@ -0,0 +1,134 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the 'dbg blackbox' and 'dbg unblackbox' commands work as
|
||||
* they should.
|
||||
*/
|
||||
|
||||
const TEST_URL = EXAMPLE_URL + "doc_blackboxing.html";
|
||||
const BLACKBOXME_URL = EXAMPLE_URL + "code_blackboxing_blackboxme.js";
|
||||
const BLACKBOXONE_URL = EXAMPLE_URL + "code_blackboxing_one.js";
|
||||
const BLACKBOXTWO_URL = EXAMPLE_URL + "code_blackboxing_two.js";
|
||||
const BLACKBOXTHREE_URL = EXAMPLE_URL + "code_blackboxing_three.js";
|
||||
|
||||
let gPanel, gDebugger, gThreadClient;
|
||||
let gOptions;
|
||||
|
||||
function test() {
|
||||
helpers.addTabWithToolbar(TEST_URL, function(aOptions) {
|
||||
gOptions = aOptions;
|
||||
|
||||
return gDevTools.showToolbox(aOptions.target, "jsdebugger")
|
||||
.then(setupGlobals)
|
||||
.then(waitForDebuggerSources)
|
||||
.then(testBlackBoxSource)
|
||||
.then(testUnBlackBoxSource)
|
||||
.then(testBlackBoxGlob)
|
||||
.then(testUnBlackBoxGlob)
|
||||
.then(testBlackBoxInvert)
|
||||
.then(testUnBlackBoxInvert)
|
||||
.then(() => closeDebuggerAndFinish(gPanel, { noTabRemoval: true }))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function setupGlobals(aToolbox) {
|
||||
gPanel = aToolbox.getCurrentPanel();
|
||||
gDebugger = gPanel.panelWin;
|
||||
gThreadClient = gDebugger.gThreadClient;
|
||||
}
|
||||
|
||||
function waitForDebuggerSources() {
|
||||
return waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
|
||||
}
|
||||
|
||||
function testBlackBoxSource() {
|
||||
return cmd("dbg blackbox " + BLACKBOXME_URL).then(() => {
|
||||
const checkbox = getBlackBoxCheckbox(BLACKBOXME_URL);
|
||||
ok(!checkbox.checked,
|
||||
"Should be able to black box a specific source.");
|
||||
});
|
||||
}
|
||||
|
||||
function testUnBlackBoxSource() {
|
||||
return cmd("dbg unblackbox " + BLACKBOXME_URL).then(() => {
|
||||
const checkbox = getBlackBoxCheckbox(BLACKBOXME_URL);
|
||||
ok(checkbox.checked,
|
||||
"Should be able to stop black boxing a specific source.");
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBoxGlob() {
|
||||
return cmd("dbg blackbox --glob *blackboxing_t*.js", 2,
|
||||
[/blackboxing_three\.js/g, /blackboxing_two\.js/g]).then(() => {
|
||||
ok(getBlackBoxCheckbox(BLACKBOXME_URL).checked,
|
||||
"blackboxme should not be black boxed because it doesn't match the glob.");
|
||||
ok(getBlackBoxCheckbox(BLACKBOXONE_URL).checked,
|
||||
"blackbox_one should not be black boxed because it doesn't match the glob.");
|
||||
|
||||
ok(!getBlackBoxCheckbox(BLACKBOXTWO_URL).checked,
|
||||
"blackbox_two should be black boxed because it matches the glob.");
|
||||
ok(!getBlackBoxCheckbox(BLACKBOXTHREE_URL).checked,
|
||||
"blackbox_three should be black boxed because it matches the glob.");
|
||||
});
|
||||
}
|
||||
|
||||
function testUnBlackBoxGlob() {
|
||||
return cmd("dbg unblackbox --glob *blackboxing_t*.js", 2).then(() => {
|
||||
ok(getBlackBoxCheckbox(BLACKBOXTWO_URL).checked,
|
||||
"blackbox_two should be un-black boxed because it matches the glob.");
|
||||
ok(getBlackBoxCheckbox(BLACKBOXTHREE_URL).checked,
|
||||
"blackbox_three should be un-black boxed because it matches the glob.");
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBoxInvert() {
|
||||
return cmd("dbg blackbox --invert --glob *blackboxing_t*.js", 3,
|
||||
[/blackboxing_three\.js/g, /blackboxing_two\.js/g]).then(() => {
|
||||
ok(!getBlackBoxCheckbox(BLACKBOXME_URL).checked,
|
||||
"blackboxme should be black boxed because it doesn't match the glob.");
|
||||
ok(!getBlackBoxCheckbox(BLACKBOXONE_URL).checked,
|
||||
"blackbox_one should be black boxed because it doesn't match the glob.");
|
||||
ok(!getBlackBoxCheckbox(TEST_URL).checked,
|
||||
"TEST_URL should be black boxed because it doesn't match the glob.");
|
||||
|
||||
ok(getBlackBoxCheckbox(BLACKBOXTWO_URL).checked,
|
||||
"blackbox_two should not be black boxed because it matches the glob.");
|
||||
ok(getBlackBoxCheckbox(BLACKBOXTHREE_URL).checked,
|
||||
"blackbox_three should not be black boxed because it matches the glob.");
|
||||
});
|
||||
}
|
||||
|
||||
function testUnBlackBoxInvert() {
|
||||
return cmd("dbg unblackbox --invert --glob *blackboxing_t*.js", 3).then(() => {
|
||||
ok(getBlackBoxCheckbox(BLACKBOXME_URL).checked,
|
||||
"blackboxme should be un-black boxed because it does not match the glob.");
|
||||
ok(getBlackBoxCheckbox(BLACKBOXONE_URL).checked,
|
||||
"blackbox_one should be un-black boxed because it does not match the glob.");
|
||||
ok(getBlackBoxCheckbox(TEST_URL).checked,
|
||||
"TEST_URL should be un-black boxed because it doesn't match the glob.");
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gOptions = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gThreadClient = null;
|
||||
});
|
||||
|
||||
function cmd(aTyped, aEventRepeat = 1, aOutput = "") {
|
||||
return promise.all([
|
||||
waitForThreadEvents(gPanel, "blackboxchange", aEventRepeat),
|
||||
helpers.audit(gOptions, [{ setup: aTyped, output: aOutput, exec: {} }])
|
||||
]);
|
||||
}
|
||||
|
||||
function getBlackBoxCheckbox(url) {
|
||||
return gDebugger.document.querySelector(
|
||||
".side-menu-widget-item[tooltiptext=\"" + url + "\"] " +
|
||||
".side-menu-widget-item-checkbox");
|
||||
}
|
204
browser/devtools/debugger/test/browser_dbg_cmd-break.js
Normal file
204
browser/devtools/debugger/test/browser_dbg_cmd-break.js
Normal file
@ -0,0 +1,204 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the break commands works as they should.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_cmd-break.html";
|
||||
|
||||
function test() {
|
||||
let gPanel, gDebugger, gThreadClient;
|
||||
let gLineNumber;
|
||||
|
||||
helpers.addTabWithToolbar(TAB_URL, aOptions => {
|
||||
return helpers.audit(aOptions, [
|
||||
{
|
||||
setup: 'break',
|
||||
check: {
|
||||
input: 'break',
|
||||
hints: ' add line',
|
||||
markup: 'IIIII',
|
||||
status: 'ERROR',
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'break add',
|
||||
check: {
|
||||
input: 'break add',
|
||||
hints: ' line',
|
||||
markup: 'IIIIIVIII',
|
||||
status: 'ERROR'
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'break add line',
|
||||
check: {
|
||||
input: 'break add line',
|
||||
hints: ' <file> <line>',
|
||||
markup: 'VVVVVVVVVVVVVV',
|
||||
status: 'ERROR'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'open toolbox',
|
||||
setup: function() {
|
||||
return initDebugger(gBrowser.selectedTab).then(([aTab, aDebuggee, aPanel]) => {
|
||||
// Spin the event loop before causing the debuggee to pause, to allow
|
||||
// this function to return first.
|
||||
executeSoon(() => aDebuggee.firstCall());
|
||||
|
||||
return waitForSourceAndCaretAndScopes(aPanel, ".html", 17).then(() => {
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gThreadClient = gPanel.panelWin.gThreadClient;
|
||||
gLineNumber = '' + aOptions.window.wrappedJSObject.gLineNumber;
|
||||
});
|
||||
});
|
||||
},
|
||||
post: function() {
|
||||
ok(gThreadClient, "Debugger client exists.");
|
||||
is(gLineNumber, 14, "gLineNumber is correct.");
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'break add line .../doc_cmd-break.html 14',
|
||||
setup: function() {
|
||||
// We have to setup in a function to allow gLineNumber to be initialized.
|
||||
let line = 'break add line ' + TAB_URL + ' ' + gLineNumber;
|
||||
return helpers.setInput(aOptions, line);
|
||||
},
|
||||
check: {
|
||||
hints: '',
|
||||
status: 'VALID',
|
||||
message: '',
|
||||
args: {
|
||||
file: { value: TAB_URL, message: '' },
|
||||
line: { value: 14 }
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: 'Added breakpoint',
|
||||
completed: false
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'break add line ' + TAB_URL + ' 17',
|
||||
check: {
|
||||
hints: '',
|
||||
status: 'VALID',
|
||||
message: '',
|
||||
args: {
|
||||
file: { value: TAB_URL, message: '' },
|
||||
line: { value: 17 }
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: 'Added breakpoint',
|
||||
completed: false
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'break list',
|
||||
check: {
|
||||
input: 'break list',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVV',
|
||||
status: 'VALID'
|
||||
},
|
||||
exec: {
|
||||
output: [
|
||||
/Source/, /Remove/,
|
||||
/doc_cmd-break\.html:14/,
|
||||
/doc_cmd-break\.html:17/
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'cleanup',
|
||||
setup: function() {
|
||||
let deferred = promise.defer();
|
||||
gThreadClient.resume(deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'break del 14',
|
||||
check: {
|
||||
input: 'break del 14',
|
||||
hints: ' -> doc_cmd-break.html:14',
|
||||
markup: 'VVVVVVVVVVII',
|
||||
status: 'ERROR',
|
||||
args: {
|
||||
breakpoint: {
|
||||
status: 'INCOMPLETE',
|
||||
message: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'break del doc_cmd-break.html:14',
|
||||
check: {
|
||||
input: 'break del doc_cmd-break.html:14',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV',
|
||||
status: 'VALID',
|
||||
args: {
|
||||
breakpoint: { arg: ' doc_cmd-break.html:14' },
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: 'Breakpoint removed',
|
||||
completed: false
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'break list',
|
||||
check: {
|
||||
input: 'break list',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVV',
|
||||
status: 'VALID'
|
||||
},
|
||||
exec: {
|
||||
output: [
|
||||
/Source/, /Remove/,
|
||||
/doc_cmd-break\.html:17/
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'break del doc_cmd-break.html:17',
|
||||
check: {
|
||||
input: 'break del doc_cmd-break.html:17',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV',
|
||||
status: 'VALID',
|
||||
args: {
|
||||
breakpoint: { arg: ' doc_cmd-break.html:17' },
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: 'Breakpoint removed',
|
||||
completed: false
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'break list',
|
||||
check: {
|
||||
input: 'break list',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVV',
|
||||
status: 'VALID'
|
||||
},
|
||||
exec: {
|
||||
output: 'No breakpoints set'
|
||||
},
|
||||
post: function() {
|
||||
return teardown(gPanel, { noTabRemoval: true });
|
||||
}
|
||||
},
|
||||
]);
|
||||
}).then(finish);
|
||||
}
|
101
browser/devtools/debugger/test/browser_dbg_cmd-dbg.js
Normal file
101
browser/devtools/debugger/test/browser_dbg_cmd-dbg.js
Normal file
@ -0,0 +1,101 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the debugger commands work as they should.
|
||||
*/
|
||||
|
||||
const TEST_URI = EXAMPLE_URL + "doc_cmd-dbg.html";
|
||||
|
||||
function test() {
|
||||
return Task.spawn(function() {
|
||||
let options = yield helpers.openTab(TEST_URI);
|
||||
yield helpers.openToolbar(options);
|
||||
|
||||
yield helpers.audit(options, [{
|
||||
setup: "dbg open",
|
||||
exec: { output: "", completed: false }
|
||||
}]);
|
||||
|
||||
let [gTab, gDebuggee, gPanel] = yield initDebugger(gBrowser.selectedTab);
|
||||
let gDebugger = gPanel.panelWin;
|
||||
let gThreadClient = gDebugger.gThreadClient;
|
||||
|
||||
yield helpers.audit(options, [{
|
||||
setup: "dbg list",
|
||||
exec: { output: /doc_cmd-dbg.html/ }
|
||||
}]);
|
||||
|
||||
let button = gDebuggee.document.querySelector("input[type=button]");
|
||||
let output = gDebuggee.document.querySelector("input[type=text]");
|
||||
|
||||
let cmd = function(aTyped, aState) {
|
||||
return promise.all([
|
||||
waitForThreadEvents(gPanel, aState),
|
||||
helpers.audit(options, [{ setup: aTyped, exec: { output: "" } }])
|
||||
]);
|
||||
};
|
||||
|
||||
let click = function(aElement, aState) {
|
||||
return promise.all([
|
||||
waitForThreadEvents(gPanel, aState),
|
||||
executeSoon(() => EventUtils.sendMouseEvent({ type: "click" }, aElement, gDebuggee))
|
||||
]);
|
||||
}
|
||||
|
||||
yield cmd("dbg interrupt", "paused");
|
||||
is(gThreadClient.state, "paused", "Debugger is paused.");
|
||||
|
||||
yield cmd("dbg continue", "resumed");
|
||||
isnot(gThreadClient.state, "paused", "Debugger has continued.");
|
||||
|
||||
yield click(button, "paused");
|
||||
is(gThreadClient.state, "paused", "Debugger is paused again.");
|
||||
|
||||
yield cmd("dbg step in", "paused");
|
||||
yield cmd("dbg step in", "paused");
|
||||
yield cmd("dbg step in", "paused");
|
||||
is(output.value, "step in", "Debugger stepped in.");
|
||||
|
||||
yield cmd("dbg step over", "paused");
|
||||
is(output.value, "step over", "Debugger stepped over.");
|
||||
|
||||
yield cmd("dbg step out", "paused");
|
||||
is(output.value, "step out", "Debugger stepped out.");
|
||||
|
||||
yield cmd("dbg continue", "paused");
|
||||
is(output.value, "dbg continue", "Debugger continued.");
|
||||
|
||||
let closeDebugger = function() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
helpers.audit(options, [{
|
||||
setup: "dbg close",
|
||||
completed: false,
|
||||
exec: { output: "" }
|
||||
}])
|
||||
.then(() => {
|
||||
let toolbox = gDevTools.getToolbox(options.target);
|
||||
if (!toolbox) {
|
||||
ok(true, "Debugger is closed.");
|
||||
deferred.resolve();
|
||||
} else {
|
||||
toolbox.on("destroyed", () => {
|
||||
ok(true, "Debugger just closed.");
|
||||
deferred.resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
// We close the debugger twice to ensure 'dbg close' doesn't error when
|
||||
// toolbox is already closed. See bug 884638 for more info.
|
||||
yield closeDebugger();
|
||||
yield closeDebugger();
|
||||
yield helpers.closeToolbar(options);
|
||||
yield helpers.closeTab(options);
|
||||
|
||||
}).then(finish, helpers.handleError);
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="application/javascript;version=1.7"/>
|
||||
let output;
|
||||
|
||||
function init() {
|
||||
output = document.querySelector("input");
|
||||
output.value = "";
|
||||
}
|
||||
|
||||
function doit() {
|
||||
debugger;
|
||||
stepIntoMe(); // step in
|
||||
|
||||
output.value = "dbg continue";
|
||||
debugger;
|
||||
}
|
||||
|
||||
function stepIntoMe() {
|
||||
output.value = "step in"; // step in
|
||||
stepOverMe(); // step over
|
||||
let x = 0; // step out
|
||||
output.value = "step out";
|
||||
}
|
||||
|
||||
function stepOverMe() {
|
||||
output.value = "step over";
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
<input type="text" value=""/>
|
||||
<input type="button" value="DOIT" onclick="doit()"/>
|
||||
<br />
|
||||
Use this file to test the following commands:
|
||||
<ul>
|
||||
<li>dbg interrupt</li>
|
||||
<li>dbg continue</li>
|
||||
<li>dbg step over</li>
|
||||
<li>dbg step in</li>
|
||||
<li>dbg step out</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
@ -1,106 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
let Task = Cu.import("resource://gre/modules/Task.jsm", {}).Task;
|
||||
|
||||
return Task.spawn(function() {
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/debugger/" +
|
||||
"test/browser_dbg_cmd.html";
|
||||
|
||||
let options = yield helpers.openTab(TEST_URI);
|
||||
yield helpers.openToolbar(options);
|
||||
|
||||
yield helpers.audit(options, [{
|
||||
setup: "dbg open",
|
||||
exec: { output: "", completed: false }
|
||||
}]);
|
||||
|
||||
let toolbox = yield gDevTools.showToolbox(options.target, "jsdebugger");
|
||||
let dbg = toolbox.getCurrentPanel();
|
||||
ok(dbg, "DebuggerPanel exists");
|
||||
|
||||
// Wait for the initial resume...
|
||||
let resumeDeferred = promise.defer();
|
||||
dbg.panelWin.gClient.addOneTimeListener("resumed", () => {
|
||||
resumeDeferred.resolve();
|
||||
});
|
||||
yield resumeDeferred.promise;
|
||||
|
||||
yield helpers.audit(options, [{
|
||||
setup: "dbg list",
|
||||
exec: { output: /browser_dbg_cmd.html/ }
|
||||
}]);
|
||||
|
||||
// exec a command with GCLI to resume the debugger and wait until it stops
|
||||
let cmd = function(typed) {
|
||||
let cmdDeferred = promise.defer();
|
||||
dbg._controller.activeThread.addOneTimeListener("paused", ev => {
|
||||
cmdDeferred.resolve();
|
||||
});
|
||||
helpers.audit(options, [{
|
||||
setup: typed,
|
||||
exec: { output: "" }
|
||||
}]).then(null, cmdDeferred.reject);
|
||||
return cmdDeferred.promise;
|
||||
};
|
||||
|
||||
yield cmd("dbg interrupt");
|
||||
|
||||
let interruptDeferred = promise.defer();
|
||||
ok(true, "debugger is paused");
|
||||
dbg._controller.activeThread.addOneTimeListener("resumed", () => {
|
||||
ok(true, "debugger continued");
|
||||
dbg._controller.activeThread.addOneTimeListener("paused", () => {
|
||||
interruptDeferred.resolve();
|
||||
});
|
||||
let btnDoit = options.window.document.querySelector("input[type=button]");
|
||||
EventUtils.sendMouseEvent({ type:"click" }, btnDoit);
|
||||
});
|
||||
helpers.audit(options, [{
|
||||
setup: "dbg continue",
|
||||
exec: { output: "" }
|
||||
}]);
|
||||
yield interruptDeferred.promise;
|
||||
|
||||
yield cmd("dbg step in");
|
||||
yield cmd("dbg step in");
|
||||
yield cmd("dbg step in");
|
||||
let output = options.window.document.querySelector("input[type=text]");
|
||||
is(output.value, "step in", "debugger stepped in");
|
||||
yield cmd("dbg step over");
|
||||
is(output.value, "step over", "debugger stepped over");
|
||||
yield cmd("dbg step out");
|
||||
is(output.value, "step out", "debugger stepped out");
|
||||
yield cmd("dbg continue");
|
||||
is(output.value, "dbg continue", "debugger continued");
|
||||
|
||||
let closeDebugger = function() {
|
||||
let closeDeferred = promise.defer();
|
||||
helpers.audit(options, [{
|
||||
setup: "dbg close",
|
||||
completed: false,
|
||||
exec: { output: "" }
|
||||
}]).then(function() {
|
||||
let closeToolbox = gDevTools.getToolbox(options.target);
|
||||
if (!closeToolbox) {
|
||||
ok(true, "Debugger is closed.");
|
||||
closeDeferred.resolve();
|
||||
} else {
|
||||
closeToolbox.on("destroyed", () => {
|
||||
ok(true, "Debugger just closed.");
|
||||
closeDeferred.resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
return closeDeferred.promise;
|
||||
};
|
||||
|
||||
// We close the debugger twice to ensure 'dbg close' doesn't error when
|
||||
// toolbox is already closed. See bug 884638 for more info.
|
||||
yield closeDebugger();
|
||||
yield closeDebugger();
|
||||
yield helpers.closeToolbar(options);
|
||||
yield helpers.closeTab(options);
|
||||
}).then(finish, helpers.handleError);
|
||||
}
|
@ -1,173 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that the 'dbg blackbox' and 'dbg unblackbox' commands work as they
|
||||
// should.
|
||||
|
||||
const TEST_URL = EXAMPLE_URL + "browser_dbg_blackboxing.html";
|
||||
const BLACKBOXME_URL = EXAMPLE_URL + "blackboxing_blackboxme.js";
|
||||
const BLACKBOXONE_URL = EXAMPLE_URL + "blackboxing_one.js";
|
||||
const BLACKBOXTWO_URL = EXAMPLE_URL + "blackboxing_two.js";
|
||||
const BLACKBOXTHREE_URL = EXAMPLE_URL + "blackboxing_three.js";
|
||||
|
||||
let gcli = Cu.import("resource://gre/modules/devtools/gcli.jsm", {}).gcli;
|
||||
|
||||
let gTarget;
|
||||
let gPanel;
|
||||
let gOptions;
|
||||
let gDebugger;
|
||||
let gClient;
|
||||
let gThreadClient;
|
||||
let gTab;
|
||||
|
||||
function cmd(typed, expectedNumEvents=1, output=null) {
|
||||
const deferred = promise.defer();
|
||||
|
||||
let timesFired = 0;
|
||||
gThreadClient.addListener("blackboxchange", function _onBlackBoxChange() {
|
||||
if (++timesFired === expectedNumEvents) {
|
||||
gThreadClient.removeListener("blackboxchange", _onBlackBoxChange);
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
let audit = {
|
||||
setup: typed,
|
||||
exec: {}
|
||||
};
|
||||
|
||||
if (output) {
|
||||
audit.output = output;
|
||||
}
|
||||
|
||||
return helpers.audit(gOptions, [audit]).then(function() {
|
||||
return deferred.promise;
|
||||
});
|
||||
}
|
||||
|
||||
function test() {
|
||||
helpers.addTabWithToolbar(TEST_URL, function(options) {
|
||||
gOptions = options;
|
||||
gTarget = options.target;
|
||||
return gDevTools.showToolbox(options.target, "jsdebugger")
|
||||
.then(setupGlobals)
|
||||
.then(waitForDebuggerSources)
|
||||
.then(testBlackBoxSource)
|
||||
.then(testUnBlackBoxSource)
|
||||
.then(testBlackBoxGlob)
|
||||
.then(testUnBlackBoxGlob)
|
||||
.then(testBlackBoxInvert)
|
||||
.then(testUnBlackBoxInvert)
|
||||
.then(null, function (error) {
|
||||
ok(false, "Got an error: " + error.message + "\n" + error.stack);
|
||||
})
|
||||
.then(finishUp);
|
||||
});
|
||||
}
|
||||
|
||||
function setupGlobals(toolbox) {
|
||||
gTab = gBrowser.selectedTab;
|
||||
gPanel = toolbox.getCurrentPanel();
|
||||
gDebugger = gPanel.panelWin;
|
||||
gClient = gDebugger.gClient;
|
||||
gThreadClient = gClient.activeThread;
|
||||
}
|
||||
|
||||
function waitForDebuggerSources() {
|
||||
const deferred = promise.defer();
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onSourceShown() {
|
||||
gDebugger.removeEventListener("Debugger:SourceShown", _onSourceShown, false);
|
||||
deferred.resolve();
|
||||
}, false);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testBlackBoxSource() {
|
||||
return cmd("dbg blackbox " + BLACKBOXME_URL)
|
||||
.then(function () {
|
||||
const checkbox = getBlackBoxCheckbox(BLACKBOXME_URL);
|
||||
ok(!checkbox.checked,
|
||||
"Should be able to black box a specific source");
|
||||
});
|
||||
}
|
||||
|
||||
function testUnBlackBoxSource() {
|
||||
return cmd("dbg unblackbox " + BLACKBOXME_URL)
|
||||
.then(function () {
|
||||
const checkbox = getBlackBoxCheckbox(BLACKBOXME_URL);
|
||||
ok(checkbox.checked,
|
||||
"Should be able to stop black boxing a specific source");
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBoxGlob() {
|
||||
return cmd("dbg blackbox --glob *blackboxing_t*.js", 2,
|
||||
[/blackboxing_three\.js/g, /blackboxing_two\.js/g])
|
||||
.then(function () {
|
||||
ok(getBlackBoxCheckbox(BLACKBOXME_URL).checked,
|
||||
"blackboxme should not be black boxed because it doesn't match the glob");
|
||||
ok(getBlackBoxCheckbox(BLACKBOXONE_URL).checked,
|
||||
"blackbox_one should not be black boxed because it doesn't match the glob");
|
||||
|
||||
ok(!getBlackBoxCheckbox(BLACKBOXTWO_URL).checked,
|
||||
"blackbox_two should be black boxed because it matches the glob");
|
||||
ok(!getBlackBoxCheckbox(BLACKBOXTHREE_URL).checked,
|
||||
"blackbox_three should be black boxed because it matches the glob");
|
||||
});
|
||||
}
|
||||
|
||||
function testUnBlackBoxGlob() {
|
||||
return cmd("dbg unblackbox --glob *blackboxing_t*.js", 2)
|
||||
.then(function () {
|
||||
ok(getBlackBoxCheckbox(BLACKBOXTWO_URL).checked,
|
||||
"blackbox_two should be un-black boxed because it matches the glob");
|
||||
ok(getBlackBoxCheckbox(BLACKBOXTHREE_URL).checked,
|
||||
"blackbox_three should be un-black boxed because it matches the glob");
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBoxInvert() {
|
||||
return cmd("dbg blackbox --invert --glob *blackboxing_t*.js", 3,
|
||||
[/blackboxing_three\.js/g, /blackboxing_two\.js/g])
|
||||
.then(function () {
|
||||
ok(!getBlackBoxCheckbox(BLACKBOXME_URL).checked,
|
||||
"blackboxme should be black boxed because it doesn't match the glob");
|
||||
ok(!getBlackBoxCheckbox(BLACKBOXONE_URL).checked,
|
||||
"blackbox_one should be black boxed because it doesn't match the glob");
|
||||
ok(!getBlackBoxCheckbox(TEST_URL).checked,
|
||||
"TEST_URL should be black boxed because it doesn't match the glob");
|
||||
|
||||
ok(getBlackBoxCheckbox(BLACKBOXTWO_URL).checked,
|
||||
"blackbox_two should not be black boxed because it matches the glob");
|
||||
ok(getBlackBoxCheckbox(BLACKBOXTHREE_URL).checked,
|
||||
"blackbox_three should not be black boxed because it matches the glob");
|
||||
});
|
||||
}
|
||||
|
||||
function testUnBlackBoxInvert() {
|
||||
return cmd("dbg unblackbox --invert --glob *blackboxing_t*.js", 3)
|
||||
.then(function () {
|
||||
ok(getBlackBoxCheckbox(BLACKBOXME_URL).checked,
|
||||
"blackboxme should be un-black boxed because it does not match the glob");
|
||||
ok(getBlackBoxCheckbox(BLACKBOXONE_URL).checked,
|
||||
"blackbox_one should be un-black boxed because it does not match the glob");
|
||||
ok(getBlackBoxCheckbox(TEST_URL).checked,
|
||||
"TEST_URL should be un-black boxed because it doesn't match the glob");
|
||||
});
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
gTarget = null;
|
||||
gPanel = null;
|
||||
gOptions = null;
|
||||
gClient = null;
|
||||
gThreadClient = null;
|
||||
gDebugger = null;
|
||||
closeDebuggerAndFinish();
|
||||
}
|
||||
|
||||
function getBlackBoxCheckbox(url) {
|
||||
return gDebugger.document.querySelector(
|
||||
".side-menu-widget-item[tooltiptext=\""
|
||||
+ url + "\"] .side-menu-widget-item-checkbox");
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Browser GCLI break command test</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="text/javascript">
|
||||
function firstCall() {
|
||||
eval("window.line0 = Error().lineNumber; secondCall();");
|
||||
}
|
||||
function secondCall() {
|
||||
eval("debugger;");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -1,220 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that the break command works as it should
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/debugger/" +
|
||||
"test/browser_dbg_cmd_break.html";
|
||||
|
||||
function test() {
|
||||
helpers.addTabWithToolbar(TEST_URI, function(options) {
|
||||
// To help us run later commands, and clear up after ourselves
|
||||
let client, line0;
|
||||
|
||||
return helpers.audit(options, [
|
||||
{
|
||||
setup: 'break',
|
||||
check: {
|
||||
input: 'break',
|
||||
hints: ' add line',
|
||||
markup: 'IIIII',
|
||||
status: 'ERROR',
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: 'break add',
|
||||
check: {
|
||||
input: 'break add',
|
||||
hints: ' line',
|
||||
markup: 'IIIIIVIII',
|
||||
status: 'ERROR'
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: 'break add line',
|
||||
check: {
|
||||
input: 'break add line',
|
||||
hints: ' <file> <line>',
|
||||
markup: 'VVVVVVVVVVVVVV',
|
||||
status: 'ERROR'
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'open toolbox',
|
||||
setup: function() {
|
||||
var deferred = promise.defer();
|
||||
|
||||
var openDone = gDevTools.showToolbox(options.target, "jsdebugger");
|
||||
openDone.then(function(toolbox) {
|
||||
let dbg = toolbox.getCurrentPanel();
|
||||
ok(dbg, "DebuggerPanel exists");
|
||||
|
||||
// Wait for the initial resume...
|
||||
dbg.panelWin.gClient.addOneTimeListener("resumed", function() {
|
||||
info("Starting tests");
|
||||
|
||||
client = dbg.panelWin.gClient;
|
||||
client.activeThread.addOneTimeListener("framesadded", function() {
|
||||
line0 = '' + options.window.wrappedJSObject.line0;
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
// Trigger newScript notifications using eval.
|
||||
content.wrappedJSObject.firstCall();
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
post: function() {
|
||||
ok(client, "Debugger client exists");
|
||||
is(line0, 10, "line0 is 10");
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'break add line .../browser_dbg_cmd_break.html 10',
|
||||
setup: function() {
|
||||
// We have to setup in a function to allow line0 to be initialized
|
||||
let line = 'break add line ' + TEST_URI + ' ' + line0;
|
||||
return helpers.setInput(options, line);
|
||||
},
|
||||
check: {
|
||||
hints: '',
|
||||
status: 'VALID',
|
||||
message: '',
|
||||
args: {
|
||||
file: { value: TEST_URI, message: '' },
|
||||
line: { value: 10 }
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: 'Added breakpoint',
|
||||
completed: false
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: 'break add line http://example.com/browser/browser/devtools/debugger/test/browser_dbg_cmd_break.html 13',
|
||||
check: {
|
||||
hints: '',
|
||||
status: 'VALID',
|
||||
message: '',
|
||||
args: {
|
||||
file: { value: TEST_URI, message: '' },
|
||||
line: { value: 13 }
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: 'Added breakpoint',
|
||||
completed: false
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: 'break list',
|
||||
check: {
|
||||
input: 'break list',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVV',
|
||||
status: 'VALID'
|
||||
},
|
||||
exec: {
|
||||
output: [
|
||||
/Source/, /Remove/,
|
||||
/cmd_break\.html:10/,
|
||||
/cmd_break\.html:13/
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'cleanup',
|
||||
setup: function() {
|
||||
// a.k.a "return client.activeThread.resume();"
|
||||
var deferred = promise.defer();
|
||||
client.activeThread.resume(function() {
|
||||
deferred.resolve();
|
||||
});
|
||||
return deferred.promise;
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: 'break del 0',
|
||||
check: {
|
||||
input: 'break del 0',
|
||||
hints: ' -> browser_dbg_cmd_break.html:10',
|
||||
markup: 'VVVVVVVVVVI',
|
||||
status: 'ERROR',
|
||||
args: {
|
||||
breakpoint: {
|
||||
status: 'INCOMPLETE',
|
||||
message: ''
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: 'break del browser_dbg_cmd_break.html:10',
|
||||
check: {
|
||||
input: 'break del browser_dbg_cmd_break.html:10',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV',
|
||||
status: 'VALID',
|
||||
args: {
|
||||
breakpoint: { arg: ' browser_dbg_cmd_break.html:10' },
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: 'Breakpoint removed',
|
||||
completed: false
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: 'break list',
|
||||
check: {
|
||||
input: 'break list',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVV',
|
||||
status: 'VALID'
|
||||
},
|
||||
exec: {
|
||||
output: [
|
||||
/Source/, /Remove/,
|
||||
/browser_dbg_cmd_break\.html:13/
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: 'break del browser_dbg_cmd_break.html:13',
|
||||
check: {
|
||||
input: 'break del browser_dbg_cmd_break.html:13',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV',
|
||||
status: 'VALID',
|
||||
args: {
|
||||
breakpoint: { arg: ' browser_dbg_cmd_break.html:13' },
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: 'Breakpoint removed',
|
||||
completed: false
|
||||
},
|
||||
},
|
||||
{
|
||||
setup: 'break list',
|
||||
check: {
|
||||
input: 'break list',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVV',
|
||||
status: 'VALID'
|
||||
},
|
||||
exec: {
|
||||
output: 'No breakpoints set'
|
||||
},
|
||||
post: function() {
|
||||
client = undefined;
|
||||
|
||||
let toolbox = gDevTools.getToolbox(options.target);
|
||||
return toolbox.destroy();
|
||||
}
|
||||
},
|
||||
]);
|
||||
}).then(finish);
|
||||
}
|
@ -0,0 +1,218 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 740825: Test the debugger conditional breakpoints.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
|
||||
gBreakpointsAdded = gBreakpoints._added;
|
||||
gBreakpointsRemoving = gBreakpoints._removing;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
|
||||
.then(() => addBreakpoints())
|
||||
.then(() => initialChecks())
|
||||
.then(() => resumeAndTestBreakpoint(20))
|
||||
.then(() => resumeAndTestBreakpoint(21))
|
||||
.then(() => resumeAndTestBreakpoint(22))
|
||||
.then(() => resumeAndTestBreakpoint(23))
|
||||
.then(() => resumeAndTestBreakpoint(24))
|
||||
.then(() => resumeAndTestBreakpoint(25))
|
||||
.then(() => resumeAndTestBreakpoint(27))
|
||||
.then(() => resumeAndTestBreakpoint(28))
|
||||
.then(() => resumeAndTestBreakpoint(29))
|
||||
.then(() => resumeAndTestNoBreakpoint())
|
||||
.then(() => reloadActiveTab(gPanel, gDebugger.EVENTS.BREAKPOINT_SHOWN, 13))
|
||||
.then(() => ensureThreadClientState(gPanel, "resumed"))
|
||||
.then(() => testAfterReload())
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
gDebuggee.ermahgerd();
|
||||
});
|
||||
|
||||
function addBreakpoints() {
|
||||
return promise.resolve(null)
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 18 }))
|
||||
.then(aClient => aClient.conditionalExpression = "undefined")
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 19 }))
|
||||
.then(aClient => aClient.conditionalExpression = "null")
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 20 }))
|
||||
.then(aClient => aClient.conditionalExpression = "42")
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 21 }))
|
||||
.then(aClient => aClient.conditionalExpression = "true")
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 22 }))
|
||||
.then(aClient => aClient.conditionalExpression = "'nasu'")
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 23 }))
|
||||
.then(aClient => aClient.conditionalExpression = "/regexp/")
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 24 }))
|
||||
.then(aClient => aClient.conditionalExpression = "({})")
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 25 }))
|
||||
.then(aClient => aClient.conditionalExpression = "(function() {})")
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 26 }))
|
||||
.then(aClient => aClient.conditionalExpression = "(function() { return false; })()")
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 27 }))
|
||||
.then(aClient => aClient.conditionalExpression = "a")
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 28 }))
|
||||
.then(aClient => aClient.conditionalExpression = "a !== undefined")
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 29 }))
|
||||
.then(aClient => aClient.conditionalExpression = "a !== null")
|
||||
.then(() => gPanel.addBreakpoint({ url: gSources.selectedValue, line: 30 }))
|
||||
.then(aClient => aClient.conditionalExpression = "b")
|
||||
}
|
||||
|
||||
function initialChecks() {
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("ermahgerd"), 253,
|
||||
"The correct source was loaded initially.");
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The correct source is selected.");
|
||||
|
||||
is(gBreakpointsAdded.size, 13,
|
||||
"13 breakpoints currently added.");
|
||||
is(gBreakpointsRemoving.size, 0,
|
||||
"No breakpoints currently being removed.");
|
||||
is(gEditor.getBreakpoints().length, 13,
|
||||
"13 breakpoints currently shown in the editor.");
|
||||
|
||||
ok(!gBreakpoints._getAdded({ url: "foo", line: 3 }),
|
||||
"_getAdded('foo', 3) returns falsey.");
|
||||
ok(!gBreakpoints._getRemoving({ url: "bar", line: 3 }),
|
||||
"_getRemoving('bar', 3) returns falsey.");
|
||||
}
|
||||
|
||||
function resumeAndTestBreakpoint(aLine) {
|
||||
let finished = waitForCaretUpdated(gPanel, aLine).then(() => testBreakpoint(aLine));
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
function resumeAndTestNoBreakpoint() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("ermahgerd"), 253,
|
||||
"The correct source was loaded initially.");
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The correct source is selected.");
|
||||
|
||||
ok(gSources.selectedItem,
|
||||
"There should be a selected source in the sources pane.")
|
||||
ok(!gSources._selectedBreakpointItem,
|
||||
"There should be no selected breakpoint in the sources pane.")
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
|
||||
is(gDebugger.document.querySelectorAll(".dbg-stackframe").length, 0,
|
||||
"There should be no visible stackframes.");
|
||||
is(gDebugger.document.querySelectorAll(".dbg-breakpoint").length, 13,
|
||||
"There should be thirteen visible breakpoints.");
|
||||
});
|
||||
|
||||
gDebugger.gThreadClient.resume();
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testBreakpoint(aLine, aHighlightBreakpoint) {
|
||||
// Highlight the breakpoint only if required.
|
||||
if (aHighlightBreakpoint) {
|
||||
let finished = waitForCaretUpdated(gPanel, aLine).then(() => testBreakpoint(aLine));
|
||||
gSources.highlightBreakpoint({ url: gSources.selectedValue, line: aLine });
|
||||
return finished;
|
||||
}
|
||||
|
||||
let selectedUrl = gSources.selectedValue;
|
||||
let selectedBreakpoint = gSources._selectedBreakpointItem;
|
||||
|
||||
ok(selectedUrl,
|
||||
"There should be a selected item in the sources pane.");
|
||||
ok(selectedBreakpoint,
|
||||
"There should be a selected brekapoint in the sources pane.");
|
||||
|
||||
is(selectedBreakpoint.attachment.url, selectedUrl,
|
||||
"The breakpoint on line " + aLine + " wasn't added on the correct source.");
|
||||
is(selectedBreakpoint.attachment.line, aLine,
|
||||
"The breakpoint on line " + aLine + " wasn't found.");
|
||||
is(!!selectedBreakpoint.attachment.disabled, false,
|
||||
"The breakpoint on line " + aLine + " should be enabled.");
|
||||
is(!!selectedBreakpoint.attachment.openPopup, false,
|
||||
"The breakpoint on line " + aLine + " should not have opened a popup.");
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not have been shown.");
|
||||
|
||||
return gBreakpoints._getAdded(selectedBreakpoint.attachment).then(aBreakpointClient => {
|
||||
is(aBreakpointClient.location.url, selectedUrl,
|
||||
"The breakpoint's client url is correct");
|
||||
is(aBreakpointClient.location.line, aLine,
|
||||
"The breakpoint's client line is correct");
|
||||
isnot(aBreakpointClient.conditionalExpression, undefined,
|
||||
"The breakpoint on line " + aLine + " should have a conditional expression.");
|
||||
|
||||
ok(isCaretPos(gPanel, aLine),
|
||||
"The editor caret position is not properly set.");
|
||||
});
|
||||
}
|
||||
|
||||
function testAfterReload() {
|
||||
let selectedUrl = gSources.selectedValue;
|
||||
let selectedBreakpoint = gSources._selectedBreakpointItem;
|
||||
|
||||
ok(selectedUrl,
|
||||
"There should be a selected item in the sources pane after reload.");
|
||||
ok(!selectedBreakpoint,
|
||||
"There should be no selected brekapoint in the sources pane after reload.");
|
||||
|
||||
return promise.resolve(null)
|
||||
.then(() => testBreakpoint(18, true))
|
||||
.then(() => testBreakpoint(19, true))
|
||||
.then(() => testBreakpoint(20, true))
|
||||
.then(() => testBreakpoint(21, true))
|
||||
.then(() => testBreakpoint(22, true))
|
||||
.then(() => testBreakpoint(23, true))
|
||||
.then(() => testBreakpoint(24, true))
|
||||
.then(() => testBreakpoint(25, true))
|
||||
.then(() => testBreakpoint(26, true))
|
||||
.then(() => testBreakpoint(27, true))
|
||||
.then(() => testBreakpoint(28, true))
|
||||
.then(() => testBreakpoint(29, true))
|
||||
.then(() => testBreakpoint(30, true))
|
||||
.then(() => {
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("ermahgerd"), 253,
|
||||
"The correct source was loaded again.");
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The correct source is selected.");
|
||||
|
||||
ok(gSources.selectedItem,
|
||||
"There should be a selected source in the sources pane.")
|
||||
ok(gSources._selectedBreakpointItem,
|
||||
"There should be a selected breakpoint in the sources pane.")
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,196 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 740825: Test the debugger conditional breakpoints.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
|
||||
gBreakpointsAdded = gBreakpoints._added;
|
||||
gBreakpointsRemoving = gBreakpoints._removing;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
|
||||
.then(() => initialChecks())
|
||||
.then(() => addBreakpoint1())
|
||||
.then(() => testBreakpoint(18, false, false, undefined))
|
||||
.then(() => addBreakpoint2())
|
||||
.then(() => testBreakpoint(19, false, false, undefined))
|
||||
.then(() => modBreakpoint2())
|
||||
.then(() => testBreakpoint(19, false, true, undefined))
|
||||
.then(() => addBreakpoint3())
|
||||
.then(() => testBreakpoint(20, true, false, undefined))
|
||||
.then(() => modBreakpoint3())
|
||||
.then(() => testBreakpoint(20, true, false, "bamboocha"))
|
||||
.then(() => addBreakpoint4())
|
||||
.then(() => testBreakpoint(21, false, false, undefined))
|
||||
.then(() => delBreakpoint4())
|
||||
.then(() => setCaretPosition(18))
|
||||
.then(() => testBreakpoint(18, false, false, undefined))
|
||||
.then(() => setCaretPosition(19))
|
||||
.then(() => testBreakpoint(19, false, false, undefined))
|
||||
.then(() => setCaretPosition(20))
|
||||
.then(() => testBreakpoint(20, true, false, "bamboocha"))
|
||||
.then(() => setCaretPosition(17))
|
||||
.then(() => testNoBreakpoint(17))
|
||||
.then(() => setCaretPosition(21))
|
||||
.then(() => testNoBreakpoint(21))
|
||||
.then(() => clickOnBreakpoint(0))
|
||||
.then(() => testBreakpoint(18, false, false, undefined))
|
||||
.then(() => clickOnBreakpoint(1))
|
||||
.then(() => testBreakpoint(19, false, false, undefined))
|
||||
.then(() => clickOnBreakpoint(2))
|
||||
.then(() => testBreakpoint(20, true, true, "bamboocha"))
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
gDebuggee.ermahgerd();
|
||||
});
|
||||
|
||||
function initialChecks() {
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("ermahgerd"), 253,
|
||||
"The correct source was loaded initially.");
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The correct source is selected.");
|
||||
|
||||
is(gBreakpointsAdded.size, 0,
|
||||
"No breakpoints currently added.");
|
||||
is(gBreakpointsRemoving.size, 0,
|
||||
"No breakpoints currently being removed.");
|
||||
is(gEditor.getBreakpoints().length, 0,
|
||||
"No breakpoints currently shown in the editor.");
|
||||
|
||||
ok(!gBreakpoints._getAdded({ url: "foo", line: 3 }),
|
||||
"_getAdded('foo', 3) returns falsey.");
|
||||
ok(!gBreakpoints._getRemoving({ url: "bar", line: 3 }),
|
||||
"_getRemoving('bar', 3) returns falsey.");
|
||||
}
|
||||
|
||||
function addBreakpoint1() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
|
||||
gPanel.addBreakpoint({ url: gSources.selectedValue, line: 18 });
|
||||
return finished;
|
||||
}
|
||||
|
||||
function addBreakpoint2() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
|
||||
setContextPosition(19);
|
||||
gSources._onCmdAddBreakpoint();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function modBreakpoint2() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
|
||||
setContextPosition(19);
|
||||
gSources._onCmdAddConditionalBreakpoint();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function addBreakpoint3() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
|
||||
setContextPosition(20);
|
||||
gSources._onCmdAddConditionalBreakpoint();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function modBreakpoint3() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_HIDING);
|
||||
typeText(gSources._cbTextbox, "bamboocha");
|
||||
EventUtils.sendKey("RETURN", gDebugger);
|
||||
return finished;
|
||||
}
|
||||
|
||||
function addBreakpoint4() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
|
||||
setContextPosition(21);
|
||||
gSources._onCmdAddBreakpoint();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function delBreakpoint4() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED);
|
||||
setContextPosition(21);
|
||||
gSources._onCmdAddBreakpoint();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testBreakpoint(aLine, aOpenPopupFlag, aPopupVisible, aConditionalExpression) {
|
||||
let selectedUrl = gSources.selectedValue;
|
||||
let selectedBreakpoint = gSources._selectedBreakpointItem;
|
||||
|
||||
ok(selectedUrl,
|
||||
"There should be a selected item in the sources pane.");
|
||||
ok(selectedBreakpoint,
|
||||
"There should be a selected brekapoint in the sources pane.");
|
||||
|
||||
is(selectedBreakpoint.attachment.url, selectedUrl,
|
||||
"The breakpoint on line " + aLine + " wasn't added on the correct source.");
|
||||
is(selectedBreakpoint.attachment.line, aLine,
|
||||
"The breakpoint on line " + aLine + " wasn't found.");
|
||||
is(!!selectedBreakpoint.attachment.disabled, false,
|
||||
"The breakpoint on line " + aLine + " should be enabled.");
|
||||
is(!!selectedBreakpoint.attachment.openPopup, aOpenPopupFlag,
|
||||
"The breakpoint on line " + aLine + " should have a correct popup state (1).");
|
||||
is(gSources._conditionalPopupVisible, aPopupVisible,
|
||||
"The breakpoint on line " + aLine + " should have a correct popup state (2).");
|
||||
|
||||
return gBreakpoints._getAdded(selectedBreakpoint.attachment).then(aBreakpointClient => {
|
||||
is(aBreakpointClient.location.url, selectedUrl,
|
||||
"The breakpoint's client url is correct");
|
||||
is(aBreakpointClient.location.line, aLine,
|
||||
"The breakpoint's client line is correct");
|
||||
is(aBreakpointClient.conditionalExpression, aConditionalExpression,
|
||||
"The breakpoint on line " + aLine + " should have a correct conditional expression.");
|
||||
is("conditionalExpression" in aBreakpointClient, !!aConditionalExpression,
|
||||
"The breakpoint on line " + aLine + " should have a correct conditional state.");
|
||||
|
||||
ok(isCaretPos(gPanel, aLine),
|
||||
"The editor caret position is not properly set.");
|
||||
});
|
||||
}
|
||||
|
||||
function testNoBreakpoint(aLine) {
|
||||
let selectedUrl = gSources.selectedValue;
|
||||
let selectedBreakpoint = gSources._selectedBreakpointItem;
|
||||
|
||||
ok(selectedUrl,
|
||||
"There should be a selected item in the sources pane for line " + aLine + ".");
|
||||
ok(!selectedBreakpoint,
|
||||
"There should be no selected brekapoint in the sources pane for line " + aLine + ".");
|
||||
|
||||
ok(isCaretPos(gPanel, aLine),
|
||||
"The editor caret position is not properly set.");
|
||||
}
|
||||
|
||||
function setCaretPosition(aLine) {
|
||||
gEditor.setCaretPosition(aLine - 1);
|
||||
}
|
||||
|
||||
function setContextPosition(aLine) {
|
||||
gSources._editorContextMenuLineNumber = aLine - 1;
|
||||
}
|
||||
|
||||
function clickOnBreakpoint(aIndex) {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelectorAll(".dbg-breakpoint")[aIndex],
|
||||
gDebugger);
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests the behavior of the debugger statement.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_inline-debugger-statement.html";
|
||||
|
||||
let gClient;
|
||||
|
||||
function test() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init(() => true);
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect((aType, aTraits) => {
|
||||
is(aType, "browser",
|
||||
"Root actor should identify itself as a browser.");
|
||||
|
||||
addTab(TAB_URL)
|
||||
.then(() => attachTabActorForUrl(gClient, TAB_URL))
|
||||
.then(testEarlyDebuggerStatement)
|
||||
.then(testDebuggerStatement)
|
||||
.then(closeConnection)
|
||||
.then(finish)
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testEarlyDebuggerStatement([aGrip, aResponse]) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let onPaused = function(aEvent, aPacket) {
|
||||
ok(false, "Pause shouldn't be called before we've attached!");
|
||||
deferred.reject();
|
||||
};
|
||||
|
||||
gClient.addListener("paused", onPaused);
|
||||
|
||||
// This should continue without nesting an event loop and calling
|
||||
// the onPaused hook, because we haven't attached yet.
|
||||
let debuggee = gBrowser.selectedTab.linkedBrowser.contentWindow.wrappedJSObject;
|
||||
debuggee.runDebuggerStatement();
|
||||
|
||||
gClient.removeListener("paused", onPaused);
|
||||
|
||||
// Now attach and resume...
|
||||
gClient.request({ to: aResponse.threadActor, type: "attach" }, () => {
|
||||
gClient.request({ to: aResponse.threadActor, type: "resume" }, () => {
|
||||
ok(true, "Pause wasn't called before we've attached.");
|
||||
deferred.resolve([aGrip, aResponse]);
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testDebuggerStatement([aGrip, aResponse]) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gClient.addListener("paused", (aEvent, aPacket) => {
|
||||
gClient.request({ to: aResponse.threadActor, type: "resume" }, () => {
|
||||
ok(true, "The pause handler was triggered on a debugger statement.");
|
||||
deferred.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
// Reach around the debugging protocol and execute the debugger statement.
|
||||
let debuggee = gBrowser.selectedTab.linkedBrowser.contentWindow.wrappedJSObject;
|
||||
debuggee.runDebuggerStatement();
|
||||
}
|
||||
|
||||
function closeConnection() {
|
||||
let deferred = promise.defer();
|
||||
gClient.close(deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gBrowser.selectedTab);
|
||||
gClient = null;
|
||||
});
|
||||
|
@ -1,18 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head><meta charset='utf-8'/><title>Browser Debugger Test Tab</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="text/javascript">
|
||||
|
||||
function runDebuggerStatement()
|
||||
{
|
||||
debugger;
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body></body>
|
||||
|
||||
</html>
|
@ -1,70 +0,0 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Tests the behavior of the debugger statement.
|
||||
|
||||
var gClient = null;
|
||||
var gTab = null;
|
||||
const DEBUGGER_TAB_URL = EXAMPLE_URL + "browser_dbg_debuggerstatement.html";
|
||||
|
||||
function test()
|
||||
{
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect(function(aType, aTraits) {
|
||||
gTab = addTab(DEBUGGER_TAB_URL, function() {
|
||||
attach_tab_actor_for_url(gClient, DEBUGGER_TAB_URL, function(actor, response) {
|
||||
test_early_debugger_statement(response);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function test_early_debugger_statement(aActor)
|
||||
{
|
||||
let paused = function(aEvent, aPacket) {
|
||||
ok(false, "Pause shouldn't be called before we've attached!\n");
|
||||
finish_test();
|
||||
};
|
||||
gClient.addListener("paused", paused);
|
||||
// This should continue without nesting an event loop and calling
|
||||
// the onPaused hook, because we haven't attached yet.
|
||||
gTab.linkedBrowser.contentWindow.wrappedJSObject.runDebuggerStatement();
|
||||
|
||||
gClient.removeListener("paused", paused);
|
||||
|
||||
// Now attach and resume...
|
||||
gClient.request({ to: aActor.threadActor, type: "attach" }, function(aResponse) {
|
||||
gClient.request({ to: aActor.threadActor, type: "resume" }, function(aResponse) {
|
||||
test_debugger_statement(aActor);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function test_debugger_statement(aActor)
|
||||
{
|
||||
var stopped = false;
|
||||
gClient.addListener("paused", function(aEvent, aPacket) {
|
||||
stopped = true;
|
||||
|
||||
gClient.request({ to: aActor.threadActor, type: "resume" }, function() {
|
||||
finish_test();
|
||||
});
|
||||
});
|
||||
|
||||
// Reach around the debugging protocol and execute the debugger
|
||||
// statement.
|
||||
gTab.linkedBrowser.contentWindow.wrappedJSObject.runDebuggerStatement();
|
||||
ok(stopped, "Should trigger the pause handler on a debugger statement.");
|
||||
}
|
||||
|
||||
function finish_test()
|
||||
{
|
||||
removeTab(gTab);
|
||||
gClient.close(function() {
|
||||
finish();
|
||||
});
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head><meta charset='utf-8'/><title>Browser Debugger Test Tab</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="text/javascript">
|
||||
|
||||
var a = function() {
|
||||
return function() {
|
||||
debugger;
|
||||
}
|
||||
}
|
||||
|
||||
var anon = a();
|
||||
anon.displayName = "anonFunc";
|
||||
|
||||
var inferred = a();
|
||||
|
||||
function evalCall() {
|
||||
eval("anon();");
|
||||
eval("inferred();");
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body></body>
|
||||
|
||||
</html>
|
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Tests that anonymous functions appear in the stack frame list with either
|
||||
// their displayName property or a SpiderMonkey-inferred name.
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_displayName.html";
|
||||
|
||||
function test() {
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
|
||||
testAnonCall();
|
||||
});
|
||||
}
|
||||
|
||||
function testAnonCall() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let frames = gDebugger.DebuggerView.StackFrames.widget._list;
|
||||
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 3,
|
||||
"Should have three frames.");
|
||||
|
||||
is(frames.querySelector("#stackframe-0 .dbg-stackframe-title").getAttribute("value"),
|
||||
"anonFunc", "Frame name should be anonFunc");
|
||||
|
||||
testInferredName();
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.evalCall();
|
||||
}
|
||||
|
||||
function testInferredName() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let frames = gDebugger.DebuggerView.StackFrames.widget._list;
|
||||
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 3,
|
||||
"Should have three frames.");
|
||||
|
||||
is(frames.querySelector("#stackframe-0 .dbg-stackframe-title").getAttribute("value"),
|
||||
"a/<", "Frame name should be a/<");
|
||||
|
||||
resumeAndFinish();
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebugger.DebuggerController.activeThread.resume();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gDebuggee = null;
|
||||
finish();
|
||||
});
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 731394: Test the debugger source editor default context menu.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources, gContextMenu;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gContextMenu = gDebugger.document.getElementById("sourceEditorContextMenu");
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 6).then(performTest);
|
||||
gDebuggee.firstCall();
|
||||
});
|
||||
|
||||
function performTest() {
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
is(gSources.itemCount, 2,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("debugger"), 172,
|
||||
"The correct source was loaded initially.");
|
||||
is(gSources.selectedValue, gSources.values[1],
|
||||
"The correct source is selected.");
|
||||
|
||||
is(gEditor.getText().indexOf("\u263a"), 162,
|
||||
"Unicode characters are converted correctly.");
|
||||
|
||||
ok(gContextMenu,
|
||||
"The source editor's context menupopup is available.");
|
||||
ok(gEditor.readOnly,
|
||||
"The source editor is read only.");
|
||||
|
||||
gEditor.focus();
|
||||
gEditor.setSelection(0, 10);
|
||||
|
||||
once(gContextMenu, "popupshown").then(testContextMenu);
|
||||
gContextMenu.openPopup(gEditor.editorElement, "overlap", 0, 0, true, false);
|
||||
}
|
||||
|
||||
function testContextMenu() {
|
||||
let document = gDebugger.document;
|
||||
|
||||
ok(document.getElementById("editMenuCommands"),
|
||||
"#editMenuCommands found.");
|
||||
ok(!document.getElementById("editMenuKeys"),
|
||||
"#editMenuKeys not found.");
|
||||
ok(document.getElementById("sourceEditorCommands"),
|
||||
"#sourceEditorCommands found.");
|
||||
|
||||
// Map command ids to their expected disabled state.
|
||||
let commands = {"se-cmd-undo": true, "se-cmd-redo": true,
|
||||
"se-cmd-cut": true, "se-cmd-paste": true,
|
||||
"se-cmd-delete": true, "cmd_findAgain": true,
|
||||
"cmd_findPrevious": true, "cmd_find": false,
|
||||
"cmd_gotoLine": false, "cmd_copy": false,
|
||||
"se-cmd-selectAll": false};
|
||||
|
||||
for (let id in commands) {
|
||||
is(document.getElementById(id).hasAttribute("disabled"), commands[id],
|
||||
"The element with id: " + id + " hasAttribute('disabled').");
|
||||
}
|
||||
|
||||
gContextMenu.hidePopup();
|
||||
resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
}
|
||||
}
|
93
browser/devtools/debugger/test/browser_dbg_editor-mode.js
Normal file
93
browser/devtools/debugger/test/browser_dbg_editor-mode.js
Normal file
@ -0,0 +1,93 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that updating the editor mode sets the right highlighting engine,
|
||||
* and source URIs with extra query parameters also get the right engine.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_editor-mode.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, "code_test-editor-mode", 5)
|
||||
.then(testInitialSource)
|
||||
.then(testSwitch1)
|
||||
.then(testSwitch2)
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
gDebuggee.firstCall();
|
||||
});
|
||||
}
|
||||
|
||||
function testInitialSource() {
|
||||
is(gSources.itemCount, 3,
|
||||
"Found the expected number of sources.");
|
||||
|
||||
is(gEditor.getMode(), SourceEditor.MODES.TEXT,
|
||||
"Found the expected editor mode.");
|
||||
is(gEditor.getText().search(/firstCall/), -1,
|
||||
"The first source is not displayed.");
|
||||
is(gEditor.getText().search(/debugger/), 141,
|
||||
"The second source is displayed.");
|
||||
is(gEditor.getText().search(/banana/), -1,
|
||||
"The third source is not displayed.");
|
||||
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
|
||||
gSources.selectedLabel = "code_script-switching-01.js";
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testSwitch1() {
|
||||
is(gSources.itemCount, 3,
|
||||
"Found the expected number of sources.");
|
||||
|
||||
is(gEditor.getMode(), SourceEditor.MODES.JAVASCRIPT,
|
||||
"Found the expected editor mode.");
|
||||
is(gEditor.getText().search(/firstCall/), 118,
|
||||
"The first source is displayed.");
|
||||
is(gEditor.getText().search(/debugger/), -1,
|
||||
"The second source is not displayed.");
|
||||
is(gEditor.getText().search(/banana/), -1,
|
||||
"The third source is not displayed.");
|
||||
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
|
||||
gSources.selectedLabel = "doc_editor-mode.html";
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testSwitch2() {
|
||||
is(gSources.itemCount, 3,
|
||||
"Found the expected number of sources.");
|
||||
|
||||
is(gEditor.getMode(), SourceEditor.MODES.HTML,
|
||||
"Found the expected editor mode.");
|
||||
is(gEditor.getText().search(/firstCall/), -1,
|
||||
"The first source is not displayed.");
|
||||
is(gEditor.getText().search(/debugger/), -1,
|
||||
"The second source is not displayed.");
|
||||
is(gEditor.getText().search(/banana/), 443,
|
||||
"The third source is displayed.");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
});
|
@ -1,91 +1,126 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the eventListeners request works.
|
||||
*/
|
||||
|
||||
// Tests that the eventListeners request works.
|
||||
const TAB_URL = EXAMPLE_URL + "doc_event-listeners.html";
|
||||
|
||||
var gClient = null;
|
||||
var gTab = null;
|
||||
var gThreadClient = null;
|
||||
const DEBUGGER_TAB_URL = EXAMPLE_URL + "test-event-listeners.html";
|
||||
let gClient;
|
||||
|
||||
function test() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init(() => true);
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect(function(aType, aTraits) {
|
||||
gTab = addTab(DEBUGGER_TAB_URL, function() {
|
||||
attach_thread_actor_for_url(gClient,
|
||||
DEBUGGER_TAB_URL,
|
||||
function(threadClient) {
|
||||
gThreadClient = threadClient;
|
||||
testEventListeners();
|
||||
gClient.connect((aType, aTraits) => {
|
||||
is(aType, "browser",
|
||||
"Root actor should identify itself as a browser.");
|
||||
|
||||
addTab(TAB_URL)
|
||||
.then(() => attachThreadActorForUrl(gClient, TAB_URL))
|
||||
.then(pauseDebuggee)
|
||||
.then(testEventListeners)
|
||||
.then(closeConnection)
|
||||
.then(finish)
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testEventListeners()
|
||||
{
|
||||
gClient.addOneTimeListener("paused", function(aEvent, aPacket) {
|
||||
is(aPacket.why.type, "debuggerStatement", "debugger statement was hit.");
|
||||
gThreadClient.eventListeners(function(aPacket) {
|
||||
is(aPacket.listeners.length, 3, "Found all event listeners.");
|
||||
let types = [];
|
||||
for (let l of aPacket.listeners) {
|
||||
let node = l.node;
|
||||
ok(node, "There is a node property.");
|
||||
ok(node.object, "There is a node object property.");
|
||||
ok(node.selector == "window" ||
|
||||
content.document.querySelectorAll(node.selector).length == 1,
|
||||
"The node property is a unique CSS selector");
|
||||
ok(l.function, "There is a function property.");
|
||||
is(l.function.type, "object", "The function form is of type 'object'.");
|
||||
is(l.function.class, "Function", "The function form is of class 'Function'.");
|
||||
is(l.function.url, DEBUGGER_TAB_URL, "The function url is correct.");
|
||||
is(l.allowsUntrusted, true,
|
||||
"allowsUntrusted property has the right value.");
|
||||
is(l.inSystemEventGroup, false,
|
||||
"inSystemEventGroup property has the right value.");
|
||||
function pauseDebuggee(aThreadClient) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
types.push(l.type);
|
||||
gClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.type, "paused",
|
||||
"We should now be paused.");
|
||||
is(aPacket.why.type, "debuggerStatement",
|
||||
"The debugger statement was hit.");
|
||||
|
||||
if (l.type == "keyup") {
|
||||
is(l.capturing, true, "Capturing property has the right value.");
|
||||
is(l.isEventHandler, false,
|
||||
"isEventHandler property has the right value.");
|
||||
} else if (l.type == "load") {
|
||||
is(l.capturing, false, "Capturing property has the right value.");
|
||||
is(l.isEventHandler, false,
|
||||
"isEventHandler property has the right value.");
|
||||
} else {
|
||||
is(l.capturing, false, "Capturing property has the right value.");
|
||||
is(l.isEventHandler, true,
|
||||
"isEventHandler property has the right value.");
|
||||
}
|
||||
deferred.resolve(aThreadClient);
|
||||
});
|
||||
|
||||
// Spin the event loop before causing the debuggee to pause, to allow
|
||||
// this function to return first.
|
||||
executeSoon(() => {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
content.document.querySelector("button"),
|
||||
content);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testEventListeners(aThreadClient) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
aThreadClient.eventListeners(aPacket => {
|
||||
is(aPacket.listeners.length, 3,
|
||||
"Found all event listeners.");
|
||||
|
||||
let types = [];
|
||||
|
||||
for (let l of aPacket.listeners) {
|
||||
let node = l.node;
|
||||
ok(node, "There is a node property.");
|
||||
ok(node.object, "There is a node object property.");
|
||||
ok(node.selector == "window" ||
|
||||
content.document.querySelectorAll(node.selector).length == 1,
|
||||
"The node property is a unique CSS selector.");
|
||||
|
||||
let func = l.function;
|
||||
ok(func, "There is a function property.");
|
||||
is(func.type, "object", "The function form is of type 'object'.");
|
||||
is(func.class, "Function", "The function form is of class 'Function'.");
|
||||
is(func.url, TAB_URL, "The function url is correct.");
|
||||
|
||||
is(l.allowsUntrusted, true,
|
||||
"'allowsUntrusted' property has the right value.");
|
||||
is(l.inSystemEventGroup, false,
|
||||
"'inSystemEventGroup' property has the right value.");
|
||||
|
||||
types.push(l.type);
|
||||
|
||||
if (l.type == "keyup") {
|
||||
is(l.capturing, true,
|
||||
"Capturing property has the right value.");
|
||||
is(l.isEventHandler, false,
|
||||
"'isEventHandler' property has the right value.");
|
||||
} else if (l.type == "load") {
|
||||
is(l.capturing, false,
|
||||
"Capturing property has the right value.");
|
||||
is(l.isEventHandler, false,
|
||||
"'isEventHandler' property has the right value.");
|
||||
} else {
|
||||
is(l.capturing, false,
|
||||
"Capturing property has the right value.");
|
||||
is(l.isEventHandler, true,
|
||||
"'isEventHandler' property has the right value.");
|
||||
}
|
||||
ok(types.indexOf("click") != -1, "Found the click handler.");
|
||||
ok(types.indexOf("change") != -1, "Found the change handler.");
|
||||
ok(types.indexOf("keyup") != -1, "Found the keyup handler.");
|
||||
finish_test();
|
||||
});
|
||||
}
|
||||
|
||||
ok(types.indexOf("click") != -1, "Found the click handler.");
|
||||
ok(types.indexOf("change") != -1, "Found the change handler.");
|
||||
ok(types.indexOf("keyup") != -1, "Found the keyup handler.");
|
||||
|
||||
aThreadClient.resume(deferred.resolve);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
content.document.querySelector("button"));
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function finish_test()
|
||||
{
|
||||
gThreadClient.resume(function() {
|
||||
gClient.close(finish);
|
||||
});
|
||||
function closeConnection() {
|
||||
let deferred = promise.defer();
|
||||
gClient.close(deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gTab = null;
|
||||
removeTab(gBrowser.selectedTab);
|
||||
gClient = null;
|
||||
gThreadClient = null;
|
||||
});
|
||||
|
@ -1,36 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<title>Debugger Function Call Parameter Test</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="text/javascript">
|
||||
window.addEventListener("load", function() {
|
||||
function test(aArg, bArg, cArg, dArg, eArg, fArg) {
|
||||
var a = 1;
|
||||
var b = { a: a };
|
||||
var c = { a: 1, b: "beta", c: true, d: b };
|
||||
var myVar = {
|
||||
_prop: 42,
|
||||
get prop() { return this._prop; },
|
||||
set prop(val) { this._prop = val; }
|
||||
};
|
||||
|
||||
debugger;
|
||||
}
|
||||
function load() {
|
||||
var a = { a: 1, b: "beta", c: true };
|
||||
var e = eval("test(a, 'beta', 3, false, null)");
|
||||
}
|
||||
var button = document.querySelector("button");
|
||||
button.addEventListener("click", load, false);
|
||||
var buttonAsProto = Object.create(button);
|
||||
});
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<button>Click me!</button>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,63 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that anonymous functions appear in the stack frame list with either
|
||||
* their displayName property or a SpiderMonkey-inferred name.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_function-display-name.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
testAnonCall();
|
||||
});
|
||||
}
|
||||
|
||||
function testAnonCall() {
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 15).then(() => {
|
||||
ok(isCaretPos(gPanel, 15),
|
||||
"The source editor caret position was incorrect.");
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
is(gDebugger.document.querySelectorAll(".dbg-stackframe").length, 3,
|
||||
"Should have three frames.");
|
||||
is(gDebugger.document.querySelector("#stackframe-0 .dbg-stackframe-title").getAttribute("value"),
|
||||
"anonFunc", "Frame name should be 'anonFunc'.");
|
||||
|
||||
testInferredName();
|
||||
});
|
||||
|
||||
gDebuggee.evalCall();
|
||||
}
|
||||
|
||||
function testInferredName() {
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES).then(() => {
|
||||
ok(isCaretPos(gPanel, 15),
|
||||
"The source editor caret position was incorrect.");
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
is(gDebugger.document.querySelectorAll(".dbg-stackframe").length, 3,
|
||||
"Should have three frames.");
|
||||
is(gDebugger.document.querySelector("#stackframe-0 .dbg-stackframe-title").getAttribute("value"),
|
||||
"a/<", "Frame name should be 'a/<'.");
|
||||
|
||||
resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
});
|
||||
|
||||
gDebugger.gThreadClient.resume();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
@ -1,17 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<title>Browser Debugger Function Search</title>
|
||||
<script type="text/javascript" src="test-function-search-01.js"></script>
|
||||
<script type="text/javascript" src="test-function-search-02.js"></script>
|
||||
<script type="text/javascript" src="test-function-search-03.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>Peanut butter jelly time!</p>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,29 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<title>Browser Debugger Function Search</title>
|
||||
<script type="text/javascript" src="test-function-search-01.js"></script>
|
||||
<script type="text/javascript" src="test-function-search-02.js"></script>
|
||||
<script type="text/javascript" src="test-function-search-03.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>Peanut butter jelly time!</p>
|
||||
|
||||
<script type="text/javascript;version=1.8">
|
||||
function inline() {}
|
||||
let arrow = () => {}
|
||||
|
||||
let foo = bar => {}
|
||||
let foo2 = bar2 = baz2 => 42;
|
||||
|
||||
setTimeout((foo, bar, baz) => {});
|
||||
setTimeout((foo, bar, baz) => 42);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,499 +0,0 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_function-search-02.html";
|
||||
|
||||
/**
|
||||
* Tests if the function searching works properly.
|
||||
*/
|
||||
|
||||
let gPane = null;
|
||||
let gTab = null;
|
||||
let gDebuggee = null;
|
||||
let gDebugger = null;
|
||||
let gEditor = null;
|
||||
let gSources = null;
|
||||
let gSearchBox = null;
|
||||
let gFilteredFunctions = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
Services.tm.currentThread.dispatch({ run: testFunctionsFilter }, 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testFunctionsFilter()
|
||||
{
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
|
||||
gFilteredFunctions = gDebugger.DebuggerView.FilteredFunctions;
|
||||
|
||||
htmlSearch(function() {
|
||||
showSource("test-function-search-01.js", function() {
|
||||
firstSearch(function() {
|
||||
showSource("test-function-search-02.js", function() {
|
||||
secondSearch(function() {
|
||||
showSource("test-function-search-03.js", function() {
|
||||
thirdSearch(function() {
|
||||
saveSearch(function() {
|
||||
filterSearch(function() {
|
||||
bogusSearch(function() {
|
||||
anotherSearch(function() {
|
||||
emptySearch(function() {
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function htmlSearch(callback) {
|
||||
gDebugger.addEventListener("popupshown", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
info("Current script url:\n" + gSources.selectedValue + "\n");
|
||||
info("Debugger editor text:\n" + gEditor.getText() + "\n");
|
||||
|
||||
ok(gFilteredFunctions.selectedValue,
|
||||
"An item should be selected in the filtered functions view");
|
||||
ok(gFilteredFunctions.selectedLabel,
|
||||
"An item should be selected in the filtered functions view");
|
||||
|
||||
let url = gSources.selectedValue;
|
||||
if (url.indexOf("-02.html") != -1) {
|
||||
|
||||
executeSoon(function() {
|
||||
let expectedResults = [
|
||||
["inline", "-02.html", "", 16, 15],
|
||||
["arrow", "-02.html", "", 17, 10],
|
||||
["foo", "-02.html", "", 19, 10],
|
||||
["foo2", "-02.html", "", 20, 10],
|
||||
["bar2", "-02.html", "", 20, 17]
|
||||
];
|
||||
|
||||
for (let [label, value, description, line, col] of expectedResults) {
|
||||
is(gFilteredFunctions.selectedItem.label,
|
||||
gDebugger.SourceUtils.trimUrlLength(label + "()"),
|
||||
"The corect label (" + label + ") is currently selected.");
|
||||
ok(gFilteredFunctions.selectedItem.value.contains(value),
|
||||
"The corect value (" + value + ") is attached.");
|
||||
is(gFilteredFunctions.selectedItem.description, description,
|
||||
"The corect description (" + description + ") is currently shown.");
|
||||
|
||||
info("Editor caret position: " + gEditor.getCaretPosition().toSource());
|
||||
ok(gEditor.getCaretPosition().line == line &&
|
||||
gEditor.getCaretPosition().col == col,
|
||||
"The editor didn't jump to the correct line.");
|
||||
|
||||
ok(gSources.selectedLabel, label,
|
||||
"The current source isn't the correct one, according to the label.");
|
||||
ok(gSources.selectedValue, value,
|
||||
"The current source isn't the correct one, according to the value.");
|
||||
|
||||
EventUtils.sendKey("DOWN", gDebugger);
|
||||
}
|
||||
|
||||
ok(gEditor.getCaretPosition().line == expectedResults[0][3] &&
|
||||
gEditor.getCaretPosition().col == expectedResults[0][4],
|
||||
"The editor didn't jump to the correct line again.");
|
||||
|
||||
executeSoon(callback);
|
||||
});
|
||||
} else {
|
||||
ok(false, "How did you get here? Go away, you.");
|
||||
}
|
||||
});
|
||||
|
||||
write("@");
|
||||
}
|
||||
|
||||
function firstSearch(callback) {
|
||||
gDebugger.addEventListener("popupshown", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
info("Current script url:\n" + gSources.selectedValue + "\n");
|
||||
info("Debugger editor text:\n" + gEditor.getText() + "\n");
|
||||
|
||||
ok(gFilteredFunctions.selectedValue,
|
||||
"An item should be selected in the filtered functions view");
|
||||
ok(gFilteredFunctions.selectedLabel,
|
||||
"An item should be selected in the filtered functions view");
|
||||
|
||||
let url = gSources.selectedValue;
|
||||
if (url.indexOf("-01.js") != -1) {
|
||||
|
||||
executeSoon(function() {
|
||||
let s = " " + gDebugger.L10N.getStr("functionSearchSeparatorLabel") + " ";
|
||||
let expectedResults = [
|
||||
["test", "-01.js", "", 3, 9],
|
||||
["anonymousExpression", "-01.js", "test.prototype", 8, 2],
|
||||
["namedExpression" + s + "NAME", "-01.js", "test.prototype", 10, 2],
|
||||
["a_test", "-01.js", "foo", 21, 2],
|
||||
["n_test" + s + "x", "-01.js", "foo", 23, 2],
|
||||
["a_test", "-01.js", "foo.sub", 26, 4],
|
||||
["n_test" + s + "y", "-01.js", "foo.sub", 28, 4],
|
||||
["a_test", "-01.js", "foo.sub.sub", 31, 6],
|
||||
["n_test" + s + "z", "-01.js", "foo.sub.sub", 33, 6],
|
||||
["test_SAME_NAME", "-01.js", "foo.sub.sub.sub", 36, 8]
|
||||
];
|
||||
|
||||
for (let [label, value, description, line, col] of expectedResults) {
|
||||
is(gFilteredFunctions.selectedItem.label,
|
||||
gDebugger.SourceUtils.trimUrlLength(label + "()"),
|
||||
"The corect label (" + label + ") is currently selected.");
|
||||
ok(gFilteredFunctions.selectedItem.value.contains(value),
|
||||
"The corect value (" + value + ") is attached.");
|
||||
is(gFilteredFunctions.selectedItem.description, description,
|
||||
"The corect description (" + description + ") is currently shown.");
|
||||
|
||||
info("Editor caret position: " + gEditor.getCaretPosition().toSource());
|
||||
ok(gEditor.getCaretPosition().line == line &&
|
||||
gEditor.getCaretPosition().col == col,
|
||||
"The editor didn't jump to the correct line.");
|
||||
|
||||
ok(gSources.selectedLabel, label,
|
||||
"The current source isn't the correct one, according to the label.");
|
||||
ok(gSources.selectedValue, value,
|
||||
"The current source isn't the correct one, according to the value.");
|
||||
|
||||
EventUtils.sendKey("DOWN", gDebugger);
|
||||
}
|
||||
|
||||
ok(gEditor.getCaretPosition().line == expectedResults[0][3] &&
|
||||
gEditor.getCaretPosition().col == expectedResults[0][4],
|
||||
"The editor didn't jump to the correct line again.");
|
||||
|
||||
executeSoon(callback);
|
||||
});
|
||||
} else {
|
||||
ok(false, "How did you get here? Go away, you.");
|
||||
}
|
||||
});
|
||||
|
||||
write("@");
|
||||
}
|
||||
|
||||
function secondSearch(callback) {
|
||||
gDebugger.addEventListener("popupshown", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
info("Current script url:\n" + gSources.selectedValue + "\n");
|
||||
info("Debugger editor text:\n" + gEditor.getText() + "\n");
|
||||
|
||||
ok(gFilteredFunctions.selectedValue,
|
||||
"An item should be selected in the filtered functions view");
|
||||
ok(gFilteredFunctions.selectedLabel,
|
||||
"An item should be selected in the filtered functions view");
|
||||
|
||||
let url = gSources.selectedValue;
|
||||
if (url.indexOf("-02.js") != -1) {
|
||||
|
||||
executeSoon(function() {
|
||||
let s = " " + gDebugger.L10N.getStr("functionSearchSeparatorLabel") + " ";
|
||||
let expectedResults = [
|
||||
["test2", "-02.js", "", 3, 4],
|
||||
["test3" + s + "test3_NAME", "-02.js", "", 7, 4],
|
||||
["test4_SAME_NAME", "-02.js", "", 10, 4],
|
||||
["x" + s + "X", "-02.js", "test.prototype", 13, 0],
|
||||
["y" + s + "Y", "-02.js", "test.prototype.sub", 15, 0],
|
||||
["z" + s + "Z", "-02.js", "test.prototype.sub.sub", 17, 0],
|
||||
["t", "-02.js", "test.prototype.sub.sub.sub", 19, 0],
|
||||
["x", "-02.js", "", 19, 31],
|
||||
["y", "-02.js", "", 19, 40],
|
||||
["z", "-02.js", "", 19, 49]
|
||||
];
|
||||
|
||||
for (let [label, value, description, line, col] of expectedResults) {
|
||||
is(gFilteredFunctions.selectedItem.label,
|
||||
gDebugger.SourceUtils.trimUrlLength(label + "()"),
|
||||
"The corect label (" + label + ") is currently selected.");
|
||||
ok(gFilteredFunctions.selectedItem.value.contains(value),
|
||||
"The corect value (" + value + ") is attached.");
|
||||
is(gFilteredFunctions.selectedItem.description, description,
|
||||
"The corect description (" + description + ") is currently shown.");
|
||||
|
||||
info("Editor caret position: " + gEditor.getCaretPosition().toSource());
|
||||
ok(gEditor.getCaretPosition().line == line &&
|
||||
gEditor.getCaretPosition().col == col,
|
||||
"The editor didn't jump to the correct line.");
|
||||
|
||||
ok(gSources.selectedLabel, label,
|
||||
"The current source isn't the correct one, according to the label.");
|
||||
ok(gSources.selectedValue, value,
|
||||
"The current source isn't the correct one, according to the value.");
|
||||
|
||||
EventUtils.sendKey("DOWN", gDebugger);
|
||||
}
|
||||
|
||||
ok(gEditor.getCaretPosition().line == expectedResults[0][3] &&
|
||||
gEditor.getCaretPosition().col == expectedResults[0][4],
|
||||
"The editor didn't jump to the correct line again.");
|
||||
|
||||
executeSoon(callback);
|
||||
});
|
||||
} else {
|
||||
ok(false, "How did you get here? Go away, you.");
|
||||
}
|
||||
});
|
||||
|
||||
write("@");
|
||||
}
|
||||
|
||||
function thirdSearch(callback) {
|
||||
gDebugger.addEventListener("popupshown", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
info("Current script url:\n" + gSources.selectedValue + "\n");
|
||||
info("Debugger editor text:\n" + gEditor.getText() + "\n");
|
||||
|
||||
ok(gFilteredFunctions.selectedValue,
|
||||
"An item should be selected in the filtered functions view");
|
||||
ok(gFilteredFunctions.selectedLabel,
|
||||
"An item should be selected in the filtered functions view");
|
||||
|
||||
let url = gSources.selectedValue;
|
||||
if (url.indexOf("-03.js") != -1) {
|
||||
|
||||
executeSoon(function() {
|
||||
let s = " " + gDebugger.L10N.getStr("functionSearchSeparatorLabel") + " ";
|
||||
let expectedResults = [
|
||||
["namedEventListener", "-03.js", "", 3, 42],
|
||||
["a" + s + "A", "-03.js", "bar", 9, 4],
|
||||
["b" + s + "B", "-03.js", "bar.alpha", 14, 4],
|
||||
["c" + s + "C", "-03.js", "bar.alpha.beta", 19, 4],
|
||||
["d" + s + "D", "-03.js", "theta", 24, 4],
|
||||
["fun", "-03.js", "", 28, 6],
|
||||
["foo", "-03.js", "", 28, 12],
|
||||
["bar", "-03.js", "", 28, 18],
|
||||
["t_foo", "-03.js", "", 28, 24],
|
||||
["w_bar" + s + "baz", "-03.js", "window", 28, 37]
|
||||
];
|
||||
|
||||
for (let [label, value, description, line, col] of expectedResults) {
|
||||
is(gFilteredFunctions.selectedItem.label,
|
||||
gDebugger.SourceUtils.trimUrlLength(label + "()"),
|
||||
"The corect label (" + label + ") is currently selected.");
|
||||
ok(gFilteredFunctions.selectedItem.value.contains(value),
|
||||
"The corect value (" + value + ") is attached.");
|
||||
is(gFilteredFunctions.selectedItem.description, description,
|
||||
"The corect description (" + description + ") is currently shown.");
|
||||
|
||||
info("Editor caret position: " + gEditor.getCaretPosition().toSource());
|
||||
ok(gEditor.getCaretPosition().line == line &&
|
||||
gEditor.getCaretPosition().col == col,
|
||||
"The editor didn't jump to the correct line.");
|
||||
|
||||
ok(gSources.selectedLabel, label,
|
||||
"The current source isn't the correct one, according to the label.");
|
||||
ok(gSources.selectedValue, value,
|
||||
"The current source isn't the correct one, according to the value.");
|
||||
|
||||
EventUtils.sendKey("DOWN", gDebugger);
|
||||
}
|
||||
|
||||
ok(gEditor.getCaretPosition().line == expectedResults[0][3] &&
|
||||
gEditor.getCaretPosition().col == expectedResults[0][4],
|
||||
"The editor didn't jump to the correct line again.");
|
||||
|
||||
executeSoon(callback);
|
||||
});
|
||||
} else {
|
||||
ok(false, "How did you get here? Go away, you.");
|
||||
}
|
||||
});
|
||||
|
||||
write("@");
|
||||
}
|
||||
|
||||
function filterSearch(callback) {
|
||||
gDebugger.addEventListener("popupshown", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
info("Current script url:\n" + gSources.selectedValue + "\n");
|
||||
info("Debugger editor text:\n" + gEditor.getText() + "\n");
|
||||
|
||||
ok(gFilteredFunctions.selectedValue,
|
||||
"An item should be selected in the filtered functions view");
|
||||
ok(gFilteredFunctions.selectedLabel,
|
||||
"An item should be selected in the filtered functions view");
|
||||
|
||||
let url = gSources.selectedValue;
|
||||
if (url.indexOf("-03.js") != -1) {
|
||||
|
||||
executeSoon(function() {
|
||||
let s = " " + gDebugger.L10N.getStr("functionSearchSeparatorLabel") + " ";
|
||||
let expectedResults = [
|
||||
["namedEventListener", "-03.js", "", 3, 42],
|
||||
["a" + s + "A", "-03.js", "bar", 9, 4],
|
||||
["bar", "-03.js", "", 28, 18],
|
||||
["w_bar" + s + "baz", "-03.js", "window", 28, 37],
|
||||
["test3" + s + "test3_NAME", "-02.js", "", 7, 4],
|
||||
["test4_SAME_NAME", "-02.js", "", 10, 4],
|
||||
["anonymousExpression", "-01.js", "test.prototype", 8, 2],
|
||||
["namedExpression" + s + "NAME", "-01.js", "test.prototype", 10, 2],
|
||||
["a_test", "-01.js", "foo", 21, 2],
|
||||
["a_test", "-01.js", "foo.sub", 26, 4]
|
||||
];
|
||||
|
||||
for (let [label, value, description, line, col] of expectedResults) {
|
||||
is(gFilteredFunctions.selectedItem.label,
|
||||
gDebugger.SourceUtils.trimUrlLength(label + "()"),
|
||||
"The corect label (" + label + ") is currently selected.");
|
||||
ok(gFilteredFunctions.selectedItem.value.contains(value),
|
||||
"The corect value (" + value + ") is attached.");
|
||||
is(gFilteredFunctions.selectedItem.description, description,
|
||||
"The corect description (" + description + ") is currently shown.");
|
||||
|
||||
info("Editor caret position: " + gEditor.getCaretPosition().toSource());
|
||||
ok(gEditor.getCaretPosition().line == line &&
|
||||
gEditor.getCaretPosition().col == col,
|
||||
"The editor didn't jump to the correct line.");
|
||||
|
||||
ok(gSources.selectedLabel, label,
|
||||
"The current source isn't the correct one, according to the label.");
|
||||
ok(gSources.selectedValue, value,
|
||||
"The current source isn't the correct one, according to the value.");
|
||||
|
||||
EventUtils.sendKey("DOWN", gDebugger);
|
||||
}
|
||||
|
||||
ok(gEditor.getCaretPosition().line == expectedResults[0][3] &&
|
||||
gEditor.getCaretPosition().col == expectedResults[0][4],
|
||||
"The editor didn't jump to the correct line again.");
|
||||
|
||||
executeSoon(callback);
|
||||
});
|
||||
} else {
|
||||
ok(false, "How did you get here? Go away, you.");
|
||||
}
|
||||
});
|
||||
|
||||
write("@a");
|
||||
}
|
||||
|
||||
function bogusSearch(callback) {
|
||||
gDebugger.addEventListener("popuphidden", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
|
||||
ok(true, "Popup was successfully hidden after no matches were found!");
|
||||
executeSoon(callback);
|
||||
});
|
||||
|
||||
write("@bogus");
|
||||
}
|
||||
|
||||
function anotherSearch(callback) {
|
||||
gDebugger.addEventListener("popupshown", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
|
||||
ok(true, "Popup was successfully shown after some matches were found!");
|
||||
executeSoon(callback);
|
||||
});
|
||||
|
||||
write("@NAME");
|
||||
}
|
||||
|
||||
function emptySearch(callback) {
|
||||
gDebugger.addEventListener("popuphidden", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
|
||||
ok(true, "Popup was successfully hidden when nothing was searched!");
|
||||
executeSoon(callback);
|
||||
});
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
function showSource(label, callback) {
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
executeSoon(callback);
|
||||
});
|
||||
gSources.selectedLabel = label;
|
||||
}
|
||||
|
||||
function saveSearch(callback) {
|
||||
gDebugger.addEventListener("popuphidden", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
executeSoon(callback);
|
||||
});
|
||||
if (Math.random() >= 0.5) {
|
||||
EventUtils.sendKey("RETURN", gDebugger);
|
||||
} else {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gFilteredFunctions.selectedItem.target,
|
||||
gDebugger);
|
||||
}
|
||||
}
|
||||
|
||||
function waitForCaretPos(number, callback)
|
||||
{
|
||||
// Poll every few milliseconds until the source editor line is active.
|
||||
let count = 0;
|
||||
let intervalID = window.setInterval(function() {
|
||||
info("count: " + count + " ");
|
||||
info("caret: " + gEditor.getCaretPosition().line);
|
||||
if (++count > 50) {
|
||||
ok(false, "Timed out while polling for the line.");
|
||||
window.clearInterval(intervalID);
|
||||
return closeDebuggerAndFinish();
|
||||
}
|
||||
if (gEditor.getCaretPosition().line != number) {
|
||||
return;
|
||||
}
|
||||
// We got the source editor at the expected line, it's safe to callback.
|
||||
window.clearInterval(intervalID);
|
||||
callback();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function clear() {
|
||||
gSearchBox.focus();
|
||||
gSearchBox.value = "";
|
||||
}
|
||||
|
||||
function write(text) {
|
||||
clear();
|
||||
append(text);
|
||||
}
|
||||
|
||||
function backspace(times) {
|
||||
for (let i = 0; i < times; i++) {
|
||||
EventUtils.sendKey("BACK_SPACE", gDebugger);
|
||||
}
|
||||
}
|
||||
|
||||
function append(text) {
|
||||
gSearchBox.focus();
|
||||
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
EventUtils.sendChar(text[i], gDebugger);
|
||||
}
|
||||
info("Editor caret position: " + gEditor.getCaretPosition().toSource() + "\n");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
gSearchBox = null;
|
||||
gFilteredFunctions = null;
|
||||
});
|
@ -5,61 +5,69 @@
|
||||
* Check extension-added global actor API.
|
||||
*/
|
||||
|
||||
var gClient = null;
|
||||
const CHROME_URL = "chrome://mochitests/content/browser/browser/devtools/debugger/test/"
|
||||
const ACTORS_URL = CHROME_URL + "testactors.js";
|
||||
|
||||
function test()
|
||||
{
|
||||
DebuggerServer.addActors("chrome://mochitests/content/browser/browser/devtools/debugger/test/testactors.js");
|
||||
function test() {
|
||||
let gClient;
|
||||
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init(() => true);
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
DebuggerServer.addActors(ACTORS_URL);
|
||||
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect(function(aType, aTraits) {
|
||||
is(aType, "browser", "Root actor should identify itself as a browser.");
|
||||
gClient.listTabs(function(aResponse) {
|
||||
gClient.connect((aType, aTraits) => {
|
||||
is(aType, "browser",
|
||||
"Root actor should identify itself as a browser.");
|
||||
|
||||
gClient.listTabs(aResponse => {
|
||||
let globalActor = aResponse.testGlobalActor1;
|
||||
ok(globalActor, "Found the test tab actor.")
|
||||
ok(globalActor.indexOf("testone") >= 0,
|
||||
"testTabActor's actorPrefix should be used.");
|
||||
gClient.request({ to: globalActor, type: "ping" }, function(aResponse) {
|
||||
ok(globalActor.contains("test_one"),
|
||||
"testGlobalActor1's actorPrefix should be used.");
|
||||
|
||||
gClient.request({ to: globalActor, type: "ping" }, aResponse => {
|
||||
is(aResponse.pong, "pong", "Actor should respond to requests.");
|
||||
|
||||
// Send another ping to see if the same actor is used.
|
||||
gClient.request({ to: globalActor, type: "ping" }, function(aResponse) {
|
||||
gClient.request({ to: globalActor, type: "ping" }, aResponse => {
|
||||
is(aResponse.pong, "pong", "Actor should respond to requests.");
|
||||
|
||||
// Make sure that lazily-created actors are created only once.
|
||||
let conn = transport._serverConnection;
|
||||
|
||||
// First we look for the pool of global actors.
|
||||
let extraPools = conn._extraPools;
|
||||
|
||||
let globalPool;
|
||||
|
||||
for (let pool of extraPools) {
|
||||
if (Object.keys(pool._actors).some(function(elem) {
|
||||
if (Object.keys(pool._actors).some(e => {
|
||||
// Tab actors are in the global pool.
|
||||
let re = new RegExp(conn._prefix + "tab", "g");
|
||||
return elem.match(re) !== null;
|
||||
return e.match(re) !== null;
|
||||
})) {
|
||||
globalPool = pool;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Then we look if the global pool contains only one test actor.
|
||||
let actorPrefix = conn._prefix + "testone";
|
||||
let actorPrefix = conn._prefix + "test_one";
|
||||
let actors = Object.keys(globalPool._actors).join();
|
||||
info("Global actors: " + actors);
|
||||
isnot(actors.indexOf(actorPrefix), -1, "The test actor exists in the pool.");
|
||||
is(actors.indexOf(actorPrefix), actors.lastIndexOf(actorPrefix),
|
||||
"Only one actor exists in the pool.");
|
||||
|
||||
finish_test();
|
||||
isnot(actors.indexOf(actorPrefix), -1,
|
||||
"The test actor exists in the pool.");
|
||||
is(actors.indexOf(actorPrefix), actors.lastIndexOf(actorPrefix),
|
||||
"Only one actor exists in the pool.");
|
||||
|
||||
gClient.close(finish);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function finish_test()
|
||||
{
|
||||
gClient.close(function() {
|
||||
finish();
|
||||
});
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head><meta charset='utf-8'/><title>Browser Debugger IFrame Test Tab</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<iframe src="browser_dbg_debuggerstatement.html"></iframe>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,67 +1,67 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that iframes can be added as debuggees.
|
||||
*/
|
||||
|
||||
// Tests that iframes can be added as debuggees.
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebugger = null;
|
||||
|
||||
const TEST_URL = EXAMPLE_URL + "browser_dbg_iframes.html";
|
||||
const TAB_URL = EXAMPLE_URL + "doc_iframes.html";
|
||||
|
||||
function test() {
|
||||
debug_tab_pane(TEST_URL, function(aTab, aDebuggee, aPane) {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gIframe, gEditor, gSources, gFrames;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gIframe = gDebuggee.frames[0];
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gFrames = gDebugger.DebuggerView.StackFrames;
|
||||
|
||||
is(gDebugger.DebuggerController.activeThread.paused, false,
|
||||
"Should be running after debug_tab_pane.");
|
||||
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
let frames = gDebugger.DebuggerView.StackFrames.widget._list;
|
||||
let childNodes = frames.childNodes;
|
||||
|
||||
is(gDebugger.DebuggerController.activeThread.paused, true,
|
||||
"Should be paused after an interrupt request.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 1,
|
||||
"Should have one frame in the stack.");
|
||||
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("resumed", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
closeDebuggerAndFinish();
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
let iframe = gTab.linkedBrowser.contentWindow.wrappedJSObject.frames[0];
|
||||
is(iframe.document.title, "Browser Debugger Test Tab", "Found the iframe");
|
||||
|
||||
function handler() {
|
||||
if (iframe.document.readyState != "complete") {
|
||||
return;
|
||||
}
|
||||
iframe.window.removeEventListener("load", handler, false);
|
||||
executeSoon(iframe.runDebuggerStatement);
|
||||
};
|
||||
iframe.window.addEventListener("load", handler, false);
|
||||
handler();
|
||||
waitForSourceShown(gPanel, "inline-debugger-statement.html")
|
||||
.then(checkIframeSource)
|
||||
.then(checkIframePause)
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
function checkIframeSource() {
|
||||
is(gDebugger.gThreadClient.paused, false,
|
||||
"Should be running after starting the test.");
|
||||
|
||||
ok(isCaretPos(gPanel, 1),
|
||||
"The source editor caret position was incorrect.");
|
||||
is(gFrames.itemCount, 0,
|
||||
"Should have only no frames.");
|
||||
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of entries in the sources widget.");
|
||||
is(gEditor.getText().indexOf("debugger"), 348,
|
||||
"The correct source was loaded initially.");
|
||||
is(gSources.selectedLabel, "doc_inline-debugger-statement.html",
|
||||
"The currently selected source label is incorrect.");
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The currently selected source value is incorrect.");
|
||||
}
|
||||
|
||||
function checkIframePause() {
|
||||
// Spin the event loop before causing the debuggee to pause, to allow
|
||||
// this function to return first.
|
||||
executeSoon(() => gIframe.runDebuggerStatement());
|
||||
|
||||
return waitForCaretAndScopes(gPanel, 16).then(() => {
|
||||
is(gDebugger.gThreadClient.paused, true,
|
||||
"Should be paused after an interrupt request.");
|
||||
|
||||
ok(isCaretPos(gPanel, 16),
|
||||
"The source editor caret position was incorrect.");
|
||||
is(gFrames.itemCount, 1,
|
||||
"Should have only one frame.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,32 @@
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the debugger panes collapse properly.
|
||||
*/
|
||||
|
||||
// Tests that the debugger panes collapse properly.
|
||||
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
var gView = null;
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gPrefs, gOptions;
|
||||
|
||||
function test() {
|
||||
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
gView = gDebugger.DebuggerView;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gPrefs = gDebugger.Prefs;
|
||||
gOptions = gDebugger.DebuggerView.Options;
|
||||
|
||||
testPanesState();
|
||||
|
||||
gView.toggleInstrumentsPane({ visible: true, animated: false });
|
||||
gDebugger.DebuggerView.toggleInstrumentsPane({ visible: true, animated: false });
|
||||
|
||||
testInstrumentsPaneCollapse();
|
||||
testPanesStartupPref();
|
||||
|
||||
closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
}
|
||||
|
||||
@ -36,9 +39,9 @@ function testPanesState() {
|
||||
ok(instrumentsPane.hasAttribute("pane-collapsed") &&
|
||||
instrumentsPaneToggleButton.hasAttribute("pane-collapsed"),
|
||||
"The debugger view instruments pane should initially be hidden.");
|
||||
is(gDebugger.Prefs.panesVisibleOnStartup, false,
|
||||
is(gPrefs.panesVisibleOnStartup, false,
|
||||
"The debugger view instruments pane should initially be preffed as hidden.");
|
||||
isnot(gDebugger.DebuggerView.Options._showPanesOnStartupItem.getAttribute("checked"), "true",
|
||||
isnot(gOptions._showPanesOnStartupItem.getAttribute("checked"), "true",
|
||||
"The options menu item should not be checked.");
|
||||
}
|
||||
|
||||
@ -49,7 +52,7 @@ function testInstrumentsPaneCollapse() {
|
||||
gDebugger.document.getElementById("instruments-pane-toggle");
|
||||
|
||||
let width = parseInt(instrumentsPane.getAttribute("width"));
|
||||
is(width, gDebugger.Prefs.instrumentsWidth,
|
||||
is(width, gPrefs.instrumentsWidth,
|
||||
"The instruments pane has an incorrect width.");
|
||||
is(instrumentsPane.style.marginLeft, "0px",
|
||||
"The instruments pane has an incorrect left margin.");
|
||||
@ -61,15 +64,15 @@ function testInstrumentsPaneCollapse() {
|
||||
!instrumentsPaneToggleButton.hasAttribute("pane-collapsed"),
|
||||
"The instruments pane should at this point be visible.");
|
||||
|
||||
gView.toggleInstrumentsPane({ visible: false, animated: true });
|
||||
gDebugger.DebuggerView.toggleInstrumentsPane({ visible: false, animated: true });
|
||||
|
||||
is(gDebugger.Prefs.panesVisibleOnStartup, false,
|
||||
is(gPrefs.panesVisibleOnStartup, false,
|
||||
"The debugger view panes should still initially be preffed as hidden.");
|
||||
isnot(gDebugger.DebuggerView.Options._showPanesOnStartupItem.getAttribute("checked"), "true",
|
||||
isnot(gOptions._showPanesOnStartupItem.getAttribute("checked"), "true",
|
||||
"The options menu item should still not be checked.");
|
||||
|
||||
let margin = -(width + 1) + "px";
|
||||
is(width, gDebugger.Prefs.instrumentsWidth,
|
||||
is(width, gPrefs.instrumentsWidth,
|
||||
"The instruments pane has an incorrect width after collapsing.");
|
||||
is(instrumentsPane.style.marginLeft, margin,
|
||||
"The instruments pane has an incorrect left margin after collapsing.");
|
||||
@ -81,14 +84,14 @@ function testInstrumentsPaneCollapse() {
|
||||
instrumentsPaneToggleButton.hasAttribute("pane-collapsed"),
|
||||
"The instruments pane should not be visible after collapsing.");
|
||||
|
||||
gView.toggleInstrumentsPane({ visible: true, animated: false });
|
||||
gDebugger.DebuggerView.toggleInstrumentsPane({ visible: true, animated: false });
|
||||
|
||||
is(gDebugger.Prefs.panesVisibleOnStartup, false,
|
||||
is(gPrefs.panesVisibleOnStartup, false,
|
||||
"The debugger view panes should still initially be preffed as hidden.");
|
||||
isnot(gDebugger.DebuggerView.Options._showPanesOnStartupItem.getAttribute("checked"), "true",
|
||||
isnot(gOptions._showPanesOnStartupItem.getAttribute("checked"), "true",
|
||||
"The options menu item should still not be checked.");
|
||||
|
||||
is(width, gDebugger.Prefs.instrumentsWidth,
|
||||
is(width, gPrefs.instrumentsWidth,
|
||||
"The instruments pane has an incorrect width after uncollapsing.");
|
||||
is(instrumentsPane.style.marginLeft, "0px",
|
||||
"The instruments pane has an incorrect left margin after uncollapsing.");
|
||||
@ -107,53 +110,45 @@ function testPanesStartupPref() {
|
||||
let instrumentsPaneToggleButton =
|
||||
gDebugger.document.getElementById("instruments-pane-toggle");
|
||||
|
||||
is(gDebugger.Prefs.panesVisibleOnStartup, false,
|
||||
is(gPrefs.panesVisibleOnStartup, false,
|
||||
"The debugger view panes should still initially be preffed as hidden.");
|
||||
|
||||
ok(!instrumentsPane.hasAttribute("pane-collapsed") &&
|
||||
!instrumentsPaneToggleButton.hasAttribute("pane-collapsed"),
|
||||
"The debugger instruments pane should at this point be visible.");
|
||||
is(gDebugger.Prefs.panesVisibleOnStartup, false,
|
||||
is(gPrefs.panesVisibleOnStartup, false,
|
||||
"The debugger view panes should initially be preffed as hidden.");
|
||||
isnot(gDebugger.DebuggerView.Options._showPanesOnStartupItem.getAttribute("checked"), "true",
|
||||
isnot(gOptions._showPanesOnStartupItem.getAttribute("checked"), "true",
|
||||
"The options menu item should still not be checked.");
|
||||
|
||||
gDebugger.DebuggerView.Options._showPanesOnStartupItem.setAttribute("checked", "true");
|
||||
gDebugger.DebuggerView.Options._toggleShowPanesOnStartup();
|
||||
gOptions._showPanesOnStartupItem.setAttribute("checked", "true");
|
||||
gOptions._toggleShowPanesOnStartup();
|
||||
|
||||
executeSoon(function() {
|
||||
ok(!instrumentsPane.hasAttribute("pane-collapsed") &&
|
||||
!instrumentsPaneToggleButton.hasAttribute("pane-collapsed"),
|
||||
"The debugger instruments pane should at this point be visible.");
|
||||
is(gDebugger.Prefs.panesVisibleOnStartup, true,
|
||||
"The debugger view panes should now be preffed as visible.");
|
||||
is(gDebugger.DebuggerView.Options._showPanesOnStartupItem.getAttribute("checked"), "true",
|
||||
"The options menu item should now be checked.");
|
||||
ok(!instrumentsPane.hasAttribute("pane-collapsed") &&
|
||||
!instrumentsPaneToggleButton.hasAttribute("pane-collapsed"),
|
||||
"The debugger instruments pane should at this point be visible.");
|
||||
is(gPrefs.panesVisibleOnStartup, true,
|
||||
"The debugger view panes should now be preffed as visible.");
|
||||
is(gOptions._showPanesOnStartupItem.getAttribute("checked"), "true",
|
||||
"The options menu item should now be checked.");
|
||||
|
||||
gDebugger.DebuggerView.Options._showPanesOnStartupItem.setAttribute("checked", "false");
|
||||
gDebugger.DebuggerView.Options._toggleShowPanesOnStartup();
|
||||
gOptions._showPanesOnStartupItem.setAttribute("checked", "false");
|
||||
gOptions._toggleShowPanesOnStartup();
|
||||
|
||||
executeSoon(function() {
|
||||
ok(!instrumentsPane.hasAttribute("pane-collapsed") &&
|
||||
!instrumentsPaneToggleButton.hasAttribute("pane-collapsed"),
|
||||
"The debugger instruments pane should at this point be visible.");
|
||||
is(gDebugger.Prefs.panesVisibleOnStartup, false,
|
||||
"The debugger view panes should now be preffed as hidden.");
|
||||
isnot(gDebugger.DebuggerView.Options._showPanesOnStartupItem.getAttribute("checked"), "true",
|
||||
"The options menu item should now be unchecked.");
|
||||
|
||||
executeSoon(function() {
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
});
|
||||
});
|
||||
ok(!instrumentsPane.hasAttribute("pane-collapsed") &&
|
||||
!instrumentsPaneToggleButton.hasAttribute("pane-collapsed"),
|
||||
"The debugger instruments pane should at this point be visible.");
|
||||
is(gPrefs.panesVisibleOnStartup, false,
|
||||
"The debugger view panes should now be preffed as hidden.");
|
||||
isnot(gOptions._showPanesOnStartupItem.getAttribute("checked"), "true",
|
||||
"The options menu item should now be unchecked.");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gView = null;
|
||||
gPrefs = null;
|
||||
gOptions = null;
|
||||
});
|
@ -1,100 +1,114 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Make sure the listAddons request works as specified.
|
||||
/**
|
||||
* Make sure the listAddons request works as specified.
|
||||
*/
|
||||
const ADDON1_URL = EXAMPLE_URL + "addon1.xpi";
|
||||
const ADDON2_URL = EXAMPLE_URL + "addon2.xpi";
|
||||
|
||||
var gAddon1 = null;
|
||||
var gAddon1Actor = null;
|
||||
let gAddon1, gAddon1Actor, gAddon2, gAddon2Actor, gClient;
|
||||
|
||||
var gAddon2 = null;
|
||||
var gAddon2Actor = null;
|
||||
function test() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init(() => true);
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
var gClient = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect(function (aType, aTraits) {
|
||||
is(aType, "browser", "Root actor should identify itself as a browser.");
|
||||
test_first_addon();
|
||||
})
|
||||
gClient.connect((aType, aTraits) => {
|
||||
is(aType, "browser",
|
||||
"Root actor should identify itself as a browser.");
|
||||
|
||||
promise.resolve(null)
|
||||
.then(testFirstAddon)
|
||||
.then(testSecondAddon)
|
||||
.then(testRemoveFirstAddon)
|
||||
.then(testRemoveSecondAddon)
|
||||
.then(closeConnection)
|
||||
.then(finish)
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function test_first_addon()
|
||||
{
|
||||
function testFirstAddon() {
|
||||
let addonListChanged = false;
|
||||
gClient.addOneTimeListener("addonListChanged", function () {
|
||||
gClient.addOneTimeListener("addonListChanged", () => {
|
||||
addonListChanged = true;
|
||||
});
|
||||
addAddon(ADDON1_URL, function(aAddon) {
|
||||
|
||||
return addAddon(ADDON1_URL).then(aAddon => {
|
||||
gAddon1 = aAddon;
|
||||
gClient.listAddons(function(aResponse) {
|
||||
for each (let addon in aResponse.addons) {
|
||||
if (addon.url == ADDON1_URL) {
|
||||
gAddon1Actor = addon.actor;
|
||||
}
|
||||
}
|
||||
|
||||
return getAddonActorForUrl(gClient, ADDON1_URL).then(aGrip => {
|
||||
ok(!addonListChanged, "Should not yet be notified that list of addons changed.");
|
||||
ok(gAddon1Actor, "Should find an addon actor for addon1.");
|
||||
test_second_addon();
|
||||
ok(aGrip, "Should find an addon actor for addon1.");
|
||||
gAddon1Actor = aGrip.actor;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function test_second_addon()
|
||||
{
|
||||
function testSecondAddon() {
|
||||
let addonListChanged = false;
|
||||
gClient.addOneTimeListener("addonListChanged", function () {
|
||||
addonListChanged = true;
|
||||
});
|
||||
addAddon(ADDON2_URL, function(aAddon) {
|
||||
|
||||
return addAddon(ADDON2_URL).then(aAddon => {
|
||||
gAddon2 = aAddon;
|
||||
gClient.listAddons(function(aResponse) {
|
||||
let foundAddon1 = false;
|
||||
for each (let addon in aResponse.addons) {
|
||||
if (addon.url == ADDON1_URL) {
|
||||
is(addon.actor, gAddon1Actor, "Addon1's actor shouldn't have changed.");
|
||||
foundAddon1 = true;
|
||||
}
|
||||
if (addon.url == ADDON2_URL) {
|
||||
gAddon2Actor = addon.actor;
|
||||
}
|
||||
}
|
||||
ok(addonListChanged, "Should be notified that list of addons changed.");
|
||||
ok(foundAddon1, "Should find an addon actor for addon1.");
|
||||
ok(gAddon2Actor, "Should find an actor for addon2.");
|
||||
test_remove_addon();
|
||||
|
||||
return getAddonActorForUrl(gClient, ADDON1_URL).then(aFirstGrip => {
|
||||
return getAddonActorForUrl(gClient, ADDON2_URL).then(aSecondGrip => {
|
||||
ok(addonListChanged, "Should be notified that list of addons changed.");
|
||||
is(aFirstGrip.actor, gAddon1Actor, "First addon's actor shouldn't have changed.");
|
||||
ok(aSecondGrip, "Should find a addon actor for the second addon.");
|
||||
gAddon2Actor = aSecondGrip.actor;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function test_remove_addon()
|
||||
{
|
||||
function testRemoveFirstAddon() {
|
||||
let addonListChanged = false;
|
||||
gClient.addOneTimeListener("addonListChanged", function () {
|
||||
addonListChanged = true;
|
||||
});
|
||||
removeAddon(gAddon1, function() {
|
||||
gClient.listAddons(function(aResponse) {
|
||||
let foundAddon1 = false;
|
||||
for each (let addon in aResponse.addons) {
|
||||
if (addon.url == ADDON1_URL) {
|
||||
foundAddon1 = true;
|
||||
}
|
||||
}
|
||||
|
||||
removeAddon(gAddon1).then(() => {
|
||||
return getAddonActorForUrl(gClient, ADDON1_URL).then(aGrip => {
|
||||
ok(addonListChanged, "Should be notified that list of addons changed.");
|
||||
ok(!foundAddon1, "Addon1 should be gone");
|
||||
finish_test();
|
||||
ok(!aGrip, "Shouldn't find a addon actor for the first addon anymore.");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function finish_test()
|
||||
{
|
||||
removeAddon(gAddon2, function() {
|
||||
gClient.close(function() {
|
||||
finish();
|
||||
function testRemoveSecondAddon() {
|
||||
let addonListChanged = false;
|
||||
gClient.addOneTimeListener("addonListChanged", function () {
|
||||
addonListChanged = true;
|
||||
});
|
||||
|
||||
removeAddon(gAddon2).then(() => {
|
||||
return getAddonActorForUrl(gClient, ADDON2_URL).then(aGrip => {
|
||||
ok(addonListChanged, "Should be notified that list of addons changed.");
|
||||
ok(!aGrip, "Shouldn't find a addon actor for the second addon anymore.");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function closeConnection() {
|
||||
let deferred = promise.defer();
|
||||
gClient.close(deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gAddon1 = null;
|
||||
gAddon1Actor = null;
|
||||
gAddon2 = null;
|
||||
gAddon2Actor = null;
|
||||
gClient = null;
|
||||
});
|
||||
|
@ -1,102 +1,101 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Make sure the listTabs request works as specified.
|
||||
/**
|
||||
* Make sure the listTabs request works as specified.
|
||||
*/
|
||||
|
||||
var gTab1 = null;
|
||||
var gTab1Actor = null;
|
||||
const TAB1_URL = EXAMPLE_URL + "doc_empty-tab-01.html";
|
||||
const TAB2_URL = EXAMPLE_URL + "doc_empty-tab-02.html";
|
||||
|
||||
var gTab2 = null;
|
||||
var gTab2Actor = null;
|
||||
let gTab1, gTab1Actor, gTab2, gTab2Actor, gClient;
|
||||
|
||||
var gClient = null;
|
||||
function test() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init(() => true);
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect(function(aType, aTraits) {
|
||||
is(aType, "browser", "Root actor should identify itself as a browser.");
|
||||
test_first_tab();
|
||||
gClient.connect((aType, aTraits) => {
|
||||
is(aType, "browser",
|
||||
"Root actor should identify itself as a browser.");
|
||||
|
||||
promise.resolve(null)
|
||||
.then(testFirstTab)
|
||||
.then(testSecondTab)
|
||||
.then(testRemoveTab)
|
||||
.then(testAttachRemovedTab)
|
||||
.then(closeConnection)
|
||||
.then(finish)
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that a new tab shows up in a listTabs call.
|
||||
*/
|
||||
function test_first_tab()
|
||||
{
|
||||
gTab1 = addTab(TAB1_URL, function() {
|
||||
gClient.listTabs(function(aResponse) {
|
||||
for each (let tab in aResponse.tabs) {
|
||||
if (tab.url == TAB1_URL) {
|
||||
gTab1Actor = tab.actor;
|
||||
}
|
||||
}
|
||||
ok(gTab1Actor, "Should find a tab actor for tab1.");
|
||||
test_second_tab();
|
||||
function testFirstTab() {
|
||||
return addTab(TAB1_URL).then(aTab => {
|
||||
gTab1 = aTab;
|
||||
|
||||
return getTabActorForUrl(gClient, TAB1_URL).then(aGrip => {
|
||||
ok(aGrip, "Should find a tab actor for the first tab.");
|
||||
gTab1Actor = aGrip.actor;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function test_second_tab()
|
||||
{
|
||||
gTab2 = addTab(TAB2_URL, function() {
|
||||
gClient.listTabs(function(aResponse) {
|
||||
// Verify that tab1 has the same actor it used to.
|
||||
let foundTab1 = false;
|
||||
for each (let tab in aResponse.tabs) {
|
||||
if (tab.url == TAB1_URL) {
|
||||
is(tab.actor, gTab1Actor, "Tab1's actor shouldn't have changed.");
|
||||
foundTab1 = true;
|
||||
}
|
||||
if (tab.url == TAB2_URL) {
|
||||
gTab2Actor = tab.actor;
|
||||
}
|
||||
}
|
||||
ok(foundTab1, "Should have found an actor for tab 1.");
|
||||
ok(gTab2Actor != null, "Should find an actor for tab2.");
|
||||
function testSecondTab() {
|
||||
return addTab(TAB2_URL).then(aTab => {
|
||||
gTab2 = aTab;
|
||||
|
||||
test_remove_tab();
|
||||
return getTabActorForUrl(gClient, TAB1_URL).then(aFirstGrip => {
|
||||
return getTabActorForUrl(gClient, TAB2_URL).then(aSecondGrip => {
|
||||
is(aFirstGrip.actor, gTab1Actor, "First tab's actor shouldn't have changed.");
|
||||
ok(aSecondGrip, "Should find a tab actor for the second tab.");
|
||||
gTab2Actor = aSecondGrip.actor;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function test_remove_tab()
|
||||
{
|
||||
removeTab(gTab1);
|
||||
function testRemoveTab() {
|
||||
return removeTab(gTab1).then(() => {
|
||||
return getTabActorForUrl(gClient, TAB1_URL).then(aGrip => {
|
||||
ok(!aGrip, "Shouldn't find a tab actor for the first tab anymore.");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testAttachRemovedTab() {
|
||||
return removeTab(gTab2).then(() => {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gClient.addListener("paused", (aEvent, aPacket) => {
|
||||
ok(false, "Attaching to an exited tab actor shouldn't generate a pause.");
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
gClient.request({ to: gTab2Actor, type: "attach" }, aResponse => {
|
||||
is(aResponse.type, "exited", "Tab should consider itself exited.");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
});
|
||||
}
|
||||
|
||||
function closeConnection() {
|
||||
let deferred = promise.defer();
|
||||
gClient.close(deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab1 = null;
|
||||
gClient.listTabs(function(aResponse) {
|
||||
// Verify that tab1 is no longer included in listTabs.
|
||||
let foundTab1 = false;
|
||||
for each (let tab in aResponse.tabs) {
|
||||
if (tab.url == TAB1_URL) {
|
||||
ok(false, "Tab1 should be gone.");
|
||||
}
|
||||
}
|
||||
ok(!foundTab1, "Tab1 should be gone.");
|
||||
test_attach_removed_tab();
|
||||
});
|
||||
}
|
||||
|
||||
function test_attach_removed_tab()
|
||||
{
|
||||
removeTab(gTab2);
|
||||
gTab1Actor = null;
|
||||
gTab2 = null;
|
||||
gClient.addListener("paused", function(aEvent, aPacket) {
|
||||
ok(false, "Attaching to an exited tab actor shouldn't generate a pause.");
|
||||
finish_test();
|
||||
});
|
||||
|
||||
gClient.request({ to: gTab2Actor, type: "attach" }, function(aResponse) {
|
||||
is(aResponse.type, "exited", "Tab should consider itself exited.");
|
||||
finish_test();
|
||||
});
|
||||
}
|
||||
|
||||
function finish_test()
|
||||
{
|
||||
gClient.close(function() {
|
||||
finish();
|
||||
});
|
||||
}
|
||||
gTab2Actor = null;
|
||||
gClient = null;
|
||||
});
|
||||
|
@ -1,17 +1,19 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Make sure the root actor's live tab list implementation works as specified.
|
||||
/**
|
||||
* Make sure the root actor's live tab list implementation works as specified.
|
||||
*/
|
||||
|
||||
let gTestPage = "data:text/html;charset=utf-8," + encodeURIComponent(
|
||||
"<title>JS Debugger BrowserTabList test page</title><body>Yo.</body>");
|
||||
|
||||
let testPage = ("data:text/html;charset=utf-8,"
|
||||
+ encodeURIComponent("<title>JS Debugger BrowserTabList test page</title>" +
|
||||
"<body>Yo.</body>"));
|
||||
// The tablist object whose behavior we observe.
|
||||
let tabList;
|
||||
let firstActor, actorA;
|
||||
let tabA, tabB, tabC;
|
||||
let newWin;
|
||||
let gTabList;
|
||||
let gFirstActor, gActorA;
|
||||
let gTabA, gTabB, gTabC;
|
||||
let gNewWindow;
|
||||
|
||||
// Stock onListChanged handler.
|
||||
let onListChangedCount = 0;
|
||||
function onListChangedHandler() {
|
||||
@ -19,144 +21,190 @@ function onListChangedHandler() {
|
||||
}
|
||||
|
||||
function test() {
|
||||
tabList = new DebuggerServer.BrowserTabList("fake DebuggerServerConnection");
|
||||
tabList._testing = true;
|
||||
tabList.onListChanged = onListChangedHandler;
|
||||
checkSingleTab(function () {
|
||||
is(onListChangedCount, 0, "onListChanged handler call count");
|
||||
tabA = addTab(testPage, onTabA);
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init(() => true);
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
gTabList = new DebuggerServer.BrowserTabList("fake DebuggerServerConnection");
|
||||
gTabList._testing = true;
|
||||
gTabList.onListChanged = onListChangedHandler;
|
||||
|
||||
checkSingleTab()
|
||||
.then(addTabA)
|
||||
.then(testTabA)
|
||||
.then(addTabB)
|
||||
.then(testTabB)
|
||||
.then(removeTabA)
|
||||
.then(testTabClosed)
|
||||
.then(addTabC)
|
||||
.then(testTabC)
|
||||
.then(removeTabC)
|
||||
.then(testNewWindow)
|
||||
.then(removeNewWindow)
|
||||
.then(testWindowClosed)
|
||||
.then(removeTabB)
|
||||
.then(checkSingleTab)
|
||||
.then(finish);
|
||||
}
|
||||
|
||||
function checkSingleTab() {
|
||||
return gTabList.getList().then(aTabActors => {
|
||||
is(aTabActors.length, 1, "initial tab list: contains initial tab");
|
||||
gFirstActor = aTabActors[0];
|
||||
is(gFirstActor.url, "about:blank", "initial tab list: initial tab URL is 'about:blank'");
|
||||
is(gFirstActor.title, "New Tab", "initial tab list: initial tab title is 'New Tab'");
|
||||
});
|
||||
}
|
||||
|
||||
function checkSingleTab(callback) {
|
||||
tabList.getList().then(function (tabActors) {
|
||||
is(tabActors.length, 1, "initial tab list: contains initial tab");
|
||||
firstActor = tabActors[0];
|
||||
is(firstActor.url, "about:blank", "initial tab list: initial tab URL is 'about:blank'");
|
||||
is(firstActor.title, "New Tab", "initial tab list: initial tab title is 'New Tab'");
|
||||
callback();
|
||||
function addTabA() {
|
||||
return addTab(gTestPage).then(aTab => {
|
||||
gTabA = aTab;
|
||||
});
|
||||
}
|
||||
|
||||
function onTabA() {
|
||||
function testTabA() {
|
||||
is(onListChangedCount, 1, "onListChanged handler call count");
|
||||
|
||||
tabList.getList().then(function (tabActors) {
|
||||
tabActors = new Set(tabActors);
|
||||
is(tabActors.size, 2, "tabA opened: two tabs in list");
|
||||
ok(tabActors.has(firstActor), "tabA opened: initial tab present");
|
||||
return gTabList.getList().then(aTabActors => {
|
||||
let tabActors = new Set(aTabActors);
|
||||
is(tabActors.size, 2, "gTabA opened: two tabs in list");
|
||||
ok(tabActors.has(gFirstActor), "gTabA opened: initial tab present");
|
||||
|
||||
info("actors: " + [a.url for (a of tabActors)]);
|
||||
actorA = [a for (a of tabActors) if (a !== firstActor)][0];
|
||||
ok(actorA.url.match(/^data:text\/html;/), "tabA opened: new tab URL");
|
||||
is(actorA.title, "JS Debugger BrowserTabList test page", "tabA opened: new tab title");
|
||||
|
||||
tabB = addTab(testPage, onTabB);
|
||||
gActorA = [a for (a of tabActors) if (a !== gFirstActor)][0];
|
||||
ok(gActorA.url.match(/^data:text\/html;/), "gTabA opened: new tab URL");
|
||||
is(gActorA.title, "JS Debugger BrowserTabList test page", "gTabA opened: new tab title");
|
||||
});
|
||||
}
|
||||
|
||||
function onTabB() {
|
||||
function addTabB() {
|
||||
return addTab(gTestPage).then(aTab => {
|
||||
gTabB = aTab;
|
||||
});
|
||||
}
|
||||
|
||||
function testTabB() {
|
||||
is(onListChangedCount, 2, "onListChanged handler call count");
|
||||
|
||||
tabList.getList().then(function (tabActors) {
|
||||
tabActors = new Set(tabActors);
|
||||
is(tabActors.size, 3, "tabB opened: three tabs in list");
|
||||
|
||||
// Test normal close.
|
||||
gBrowser.tabContainer.addEventListener("TabClose", function onClose(aEvent) {
|
||||
gBrowser.tabContainer.removeEventListener("TabClose", onClose, false);
|
||||
ok(!aEvent.detail, "This was a normal tab close");
|
||||
// Let the actor's TabClose handler finish first.
|
||||
executeSoon(testTabClose);
|
||||
}, false);
|
||||
gBrowser.removeTab(tabA);
|
||||
return gTabList.getList().then(aTabActors => {
|
||||
let tabActors = new Set(aTabActors);
|
||||
is(tabActors.size, 3, "gTabB opened: three tabs in list");
|
||||
});
|
||||
}
|
||||
|
||||
function testTabClose() {
|
||||
function removeTabA() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
once(gBrowser.tabContainer, "TabClose").then(aEvent => {
|
||||
ok(!aEvent.detail, "This was a normal tab close");
|
||||
|
||||
// Let the actor's TabClose handler finish first.
|
||||
executeSoon(deferred.resolve);
|
||||
}, false);
|
||||
|
||||
removeTab(gTabA);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testTabClosed() {
|
||||
is(onListChangedCount, 3, "onListChanged handler call count");
|
||||
|
||||
tabList.getList().then(function (tabActors) {
|
||||
tabActors = new Set(tabActors);
|
||||
is(tabActors.size, 2, "tabA closed: two tabs in list");
|
||||
ok(tabActors.has(firstActor), "tabA closed: initial tab present");
|
||||
gTabList.getList().then(aTabActors => {
|
||||
let tabActors = new Set(aTabActors);
|
||||
is(tabActors.size, 2, "gTabA closed: two tabs in list");
|
||||
ok(tabActors.has(gFirstActor), "gTabA closed: initial tab present");
|
||||
|
||||
info("actors: " + [a.url for (a of tabActors)]);
|
||||
actorA = [a for (a of tabActors) if (a !== firstActor)][0];
|
||||
ok(actorA.url.match(/^data:text\/html;/), "tabA closed: new tab URL");
|
||||
is(actorA.title, "JS Debugger BrowserTabList test page", "tabA closed: new tab title");
|
||||
|
||||
// Test tab close by moving tab to a window.
|
||||
tabC = addTab(testPage, onTabC);
|
||||
gActorA = [a for (a of tabActors) if (a !== gFirstActor)][0];
|
||||
ok(gActorA.url.match(/^data:text\/html;/), "gTabA closed: new tab URL");
|
||||
is(gActorA.title, "JS Debugger BrowserTabList test page", "gTabA closed: new tab title");
|
||||
});
|
||||
}
|
||||
|
||||
function onTabC() {
|
||||
function addTabC() {
|
||||
return addTab(gTestPage).then(aTab => {
|
||||
gTabC = aTab;
|
||||
});
|
||||
}
|
||||
|
||||
function testTabC() {
|
||||
is(onListChangedCount, 4, "onListChanged handler call count");
|
||||
|
||||
tabList.getList().then(function (tabActors) {
|
||||
tabActors = new Set(tabActors);
|
||||
is(tabActors.size, 3, "tabC opened: three tabs in list");
|
||||
|
||||
gBrowser.tabContainer.addEventListener("TabClose", function onClose2(aEvent) {
|
||||
gBrowser.tabContainer.removeEventListener("TabClose", onClose2, false);
|
||||
ok(aEvent.detail, "This was a tab closed by moving");
|
||||
// Let the actor's TabClose handler finish first.
|
||||
executeSoon(testWindowClose);
|
||||
}, false);
|
||||
newWin = gBrowser.replaceTabWithWindow(tabC);
|
||||
gTabList.getList().then(aTabActors => {
|
||||
let tabActors = new Set(aTabActors);
|
||||
is(tabActors.size, 3, "gTabC opened: three tabs in list");
|
||||
});
|
||||
}
|
||||
|
||||
function testWindowClose() {
|
||||
function removeTabC() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
once(gBrowser.tabContainer, "TabClose").then(aEvent => {
|
||||
ok(aEvent.detail, "This was a tab closed by moving");
|
||||
|
||||
// Let the actor's TabClose handler finish first.
|
||||
executeSoon(deferred.resolve);
|
||||
}, false);
|
||||
|
||||
gNewWindow = gBrowser.replaceTabWithWindow(gTabC);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testNewWindow() {
|
||||
is(onListChangedCount, 5, "onListChanged handler call count");
|
||||
|
||||
tabList.getList().then(function (tabActors) {
|
||||
tabActors = new Set(tabActors);
|
||||
is(tabActors.size, 3, "tabC closed: three tabs in list");
|
||||
ok(tabActors.has(firstActor), "tabC closed: initial tab present");
|
||||
return gTabList.getList().then(aTabActors => {
|
||||
let tabActors = new Set(aTabActors);
|
||||
is(tabActors.size, 3, "gTabC closed: three tabs in list");
|
||||
ok(tabActors.has(gFirstActor), "gTabC closed: initial tab present");
|
||||
|
||||
info("actors: " + [a.url for (a of tabActors)]);
|
||||
actorA = [a for (a of tabActors) if (a !== firstActor)][0];
|
||||
ok(actorA.url.match(/^data:text\/html;/), "tabC closed: new tab URL");
|
||||
is(actorA.title, "JS Debugger BrowserTabList test page", "tabC closed: new tab title");
|
||||
|
||||
// Cleanup.
|
||||
newWin.addEventListener("unload", function onUnload(aEvent) {
|
||||
newWin.removeEventListener("unload", onUnload, false);
|
||||
ok(!aEvent.detail, "This was a normal window close");
|
||||
// Let the actor's TabClose handler finish first.
|
||||
executeSoon(checkWindowClose);
|
||||
}, false);
|
||||
newWin.close();
|
||||
gActorA = [a for (a of tabActors) if (a !== gFirstActor)][0];
|
||||
ok(gActorA.url.match(/^data:text\/html;/), "gTabC closed: new tab URL");
|
||||
is(gActorA.title, "JS Debugger BrowserTabList test page", "gTabC closed: new tab title");
|
||||
});
|
||||
}
|
||||
|
||||
function checkWindowClose() {
|
||||
function removeNewWindow() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
once(gNewWindow, "unload").then(aEvent => {
|
||||
ok(!aEvent.detail, "This was a normal window close");
|
||||
|
||||
// Let the actor's TabClose handler finish first.
|
||||
executeSoon(deferred.resolve);
|
||||
}, false);
|
||||
|
||||
gNewWindow.close();
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testWindowClosed() {
|
||||
is(onListChangedCount, 6, "onListChanged handler call count");
|
||||
|
||||
// Check that closing a XUL window leaves the other actors intact.
|
||||
tabList.getList().then(function (tabActors) {
|
||||
tabActors = new Set(tabActors);
|
||||
is(tabActors.size, 2, "newWin closed: two tabs in list");
|
||||
ok(tabActors.has(firstActor), "newWin closed: initial tab present");
|
||||
return gTabList.getList().then(aTabActors => {
|
||||
let tabActors = new Set(aTabActors);
|
||||
is(tabActors.size, 2, "gNewWindow closed: two tabs in list");
|
||||
ok(tabActors.has(gFirstActor), "gNewWindow closed: initial tab present");
|
||||
|
||||
info("actors: " + [a.url for (a of tabActors)]);
|
||||
actorA = [a for (a of tabActors) if (a !== firstActor)][0];
|
||||
ok(actorA.url.match(/^data:text\/html;/), "newWin closed: new tab URL");
|
||||
is(actorA.title, "JS Debugger BrowserTabList test page", "newWin closed: new tab title");
|
||||
|
||||
// Test normal close.
|
||||
gBrowser.tabContainer.addEventListener("TabClose", function onClose(aEvent) {
|
||||
gBrowser.tabContainer.removeEventListener("TabClose", onClose, false);
|
||||
ok(!aEvent.detail, "This was a normal tab close");
|
||||
// Let the actor's TabClose handler finish first.
|
||||
executeSoon(finishTest);
|
||||
}, false);
|
||||
gBrowser.removeTab(tabB);
|
||||
gActorA = [a for (a of tabActors) if (a !== gFirstActor)][0];
|
||||
ok(gActorA.url.match(/^data:text\/html;/), "gNewWindow closed: new tab URL");
|
||||
is(gActorA.title, "JS Debugger BrowserTabList test page", "gNewWindow closed: new tab title");
|
||||
});
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
checkSingleTab(finish);
|
||||
function removeTabB() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
once(gBrowser.tabContainer, "TabClose").then(aEvent => {
|
||||
ok(!aEvent.detail, "This was a normal tab close");
|
||||
|
||||
// Let the actor's TabClose handler finish first.
|
||||
executeSoon(deferred.resolve);
|
||||
}, false);
|
||||
|
||||
removeTab(gTabB);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
@ -0,0 +1,78 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that changing the tab location URL works.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources, gFrames;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gFrames = gDebugger.DebuggerView.StackFrames;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 14).then(performTest);
|
||||
gDebuggee.simpleCall();
|
||||
});
|
||||
}
|
||||
|
||||
function performTest() {
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(gFrames.itemCount, 1,
|
||||
"Should have only one frame.");
|
||||
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of entries in the sources widget.");
|
||||
|
||||
isnot(gSources.selectedLabel, null,
|
||||
"There should be a selected source label.");
|
||||
isnot(gSources.selectedValue, null,
|
||||
"There should be a selected source value.");
|
||||
isnot(gEditor.getText().length, 0,
|
||||
"The source editor should have some text displayed.");
|
||||
isnot(gEditor.getText(), gDebugger.L10N.getStr("loadingText"),
|
||||
"The source editor text should not be 'Loading...'");
|
||||
|
||||
is(gSources.widget.getAttribute("label"), "doc_recursion-stack.html",
|
||||
"The sources widget should have a correct label attribute.");
|
||||
is(gSources.widget.getAttribute("tooltiptext"), "example.com test",
|
||||
"The sources widget should have a correct tooltip text attribute.");
|
||||
|
||||
is(gDebugger.document.querySelectorAll(".side-menu-widget-empty-notice-container").length, 0,
|
||||
"The sources widget should not display any notice at this point (1).");
|
||||
is(gDebugger.document.querySelectorAll(".side-menu-widget-empty-notice").length, 0,
|
||||
"The sources widget should not display any notice at this point (2).");
|
||||
is(gDebugger.document.querySelector(".side-menu-widget-empty-notice > label"), null,
|
||||
"The sources widget should not display a notice at this point (3).");
|
||||
|
||||
gDebugger.gThreadClient.resume(() => {
|
||||
testLocationChange();
|
||||
});
|
||||
}
|
||||
|
||||
function testLocationChange() {
|
||||
navigateActiveTabTo(gPanel, "about:blank", gDebugger.EVENTS.SOURCES_ADDED).then(() => {
|
||||
closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
gFrames = null;
|
||||
});
|
@ -0,0 +1,71 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that changing the tab location URL to a page with no sources works.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources, gFrames;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gFrames = gDebugger.DebuggerView.StackFrames;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 14).then(testLocationChange);
|
||||
gDebuggee.simpleCall();
|
||||
});
|
||||
}
|
||||
|
||||
function testLocationChange() {
|
||||
navigateActiveTabTo(gPanel, "about:blank", gDebugger.EVENTS.SOURCES_ADDED).then(() => {
|
||||
isnot(gDebugger.gThreadClient.state, "paused",
|
||||
"Should not be paused after a tab navigation.");
|
||||
|
||||
is(gFrames.itemCount, 0,
|
||||
"Should have no frames.");
|
||||
|
||||
is(gSources.itemCount, 0,
|
||||
"Found no entries in the sources widget.");
|
||||
|
||||
is(gSources.selectedLabel, "",
|
||||
"There should be no selected source label.");
|
||||
is(gSources.selectedValue, "",
|
||||
"There should be no selected source value.");
|
||||
is(gEditor.getText().length, 0,
|
||||
"The source editor should not have any text displayed.");
|
||||
|
||||
is(gSources.widget.getAttribute("label"), gDebugger.L10N.getStr("noSourcesText"),
|
||||
"The sources widget should display a notice that there are no sources availalble.");
|
||||
is(gSources.widget.getAttribute("tooltiptext"), "",
|
||||
"The sources widget shouldn't have any tooltip text attribute when there are no sources available.");
|
||||
|
||||
is(gDebugger.document.querySelectorAll(".side-menu-widget-empty-notice-container").length, 1,
|
||||
"The sources widget should now display a notice (1).");
|
||||
is(gDebugger.document.querySelectorAll(".side-menu-widget-empty-notice").length, 1,
|
||||
"The sources widget should now display a notice (2).");
|
||||
is(gDebugger.document.querySelector(".side-menu-widget-empty-notice").getAttribute("value"),
|
||||
gSources.widget.getAttribute("label"),
|
||||
"The sources widget should now display a notice (3).");
|
||||
|
||||
closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
gFrames = null;
|
||||
});
|
@ -0,0 +1,73 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that changing the tab location URL to a page with other sources works.
|
||||
*/
|
||||
|
||||
const TAB_URL_1 = EXAMPLE_URL + "doc_recursion-stack.html";
|
||||
const TAB_URL_2 = EXAMPLE_URL + "doc_iframes.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources, gFrames;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL_1).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gFrames = gDebugger.DebuggerView.StackFrames;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 14).then(testLocationChange);
|
||||
gDebuggee.simpleCall();
|
||||
});
|
||||
}
|
||||
|
||||
function testLocationChange() {
|
||||
navigateActiveTabTo(gPanel, TAB_URL_2, gDebugger.EVENTS.SOURCES_ADDED).then(() => {
|
||||
isnot(gDebugger.gThreadClient.state, "paused",
|
||||
"Should not be paused after a tab navigation.");
|
||||
|
||||
is(gFrames.itemCount, 0,
|
||||
"Should have no frames.");
|
||||
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of entries in the sources widget.");
|
||||
|
||||
is(gSources.selectedLabel, "doc_inline-debugger-statement.html",
|
||||
"There should be a selected source label.");
|
||||
is(gSources.selectedValue, EXAMPLE_URL + "doc_inline-debugger-statement.html",
|
||||
"There should be a selected source value.");
|
||||
isnot(gEditor.getText().length, 0,
|
||||
"The source editor should have some text displayed.");
|
||||
is(gEditor.getText(), gDebugger.L10N.getStr("loadingText"),
|
||||
"The source editor text should not be 'Loading...'");
|
||||
|
||||
is(gSources.widget.getAttribute("label"), "doc_inline-debugger-statement.html",
|
||||
"The sources widget should have a correct label attribute.");
|
||||
is(gSources.widget.getAttribute("tooltiptext"), "example.com test",
|
||||
"The sources widget should have a correct tooltip text attribute.");
|
||||
|
||||
is(gDebugger.document.querySelectorAll(".side-menu-widget-empty-notice-container").length, 0,
|
||||
"The sources widget should not display any notice at this point (1).");
|
||||
is(gDebugger.document.querySelectorAll(".side-menu-widget-empty-notice").length, 0,
|
||||
"The sources widget should not display any notice at this point (2).");
|
||||
is(gDebugger.document.querySelector(".side-menu-widget-empty-notice > label"), null,
|
||||
"The sources widget should not display a notice at this point (3).");
|
||||
|
||||
closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
gFrames = null;
|
||||
});
|
@ -0,0 +1,197 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that reloading a page with a breakpoint set does not cause it to
|
||||
* fire more than once.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_included-script.html";
|
||||
const SOURCE_URL = EXAMPLE_URL + "code_location-changes.js";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gEditor, gSources;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 17).then(addBreakpoint);
|
||||
gDebuggee.runDebuggerStatement();
|
||||
});
|
||||
}
|
||||
|
||||
function addBreakpoint() {
|
||||
waitForSourceAndCaret(gPanel, ".js", 5).then(() => {
|
||||
ok(true,
|
||||
"Switched to the desired function when adding a breakpoint " +
|
||||
"but not passing { noEditorUpdate: true } as an option.");
|
||||
|
||||
testResume();
|
||||
});
|
||||
|
||||
gPanel.addBreakpoint({ url: SOURCE_URL, line: 5 });
|
||||
}
|
||||
|
||||
function testResume() {
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"The breakpoint wasn't hit yet (1).");
|
||||
is(gSources.selectedValue, SOURCE_URL,
|
||||
"The currently shown source is incorrect (1).");
|
||||
ok(isCaretPos(gPanel, 5),
|
||||
"The source editor caret position is incorrect (1).");
|
||||
|
||||
gDebugger.gThreadClient.resume(testClick);
|
||||
}
|
||||
|
||||
function testClick() {
|
||||
isnot(gDebugger.gThreadClient.state, "paused",
|
||||
"The breakpoint wasn't hit yet (2).");
|
||||
is(gSources.selectedValue, SOURCE_URL,
|
||||
"The currently shown source is incorrect (2).");
|
||||
ok(isCaretPos(gPanel, 5),
|
||||
"The source editor caret position is incorrect (2).");
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.why.type, "breakpoint",
|
||||
"Execution has advanced to the breakpoint.");
|
||||
isnot(aPacket.why.type, "debuggerStatement",
|
||||
"The breakpoint was hit before the debugger statement.");
|
||||
|
||||
afterBreakpointHit();
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
}
|
||||
|
||||
function afterBreakpointHit() {
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"The breakpoint was hit (3).");
|
||||
is(gSources.selectedValue, SOURCE_URL,
|
||||
"The currently shown source is incorrect (3).");
|
||||
ok(isCaretPos(gPanel, 5),
|
||||
"The source editor caret position is incorrect (3).");
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.why.type, "debuggerStatement",
|
||||
"Execution has advanced to the next line.");
|
||||
isnot(aPacket.why.type, "breakpoint",
|
||||
"No ghost breakpoint was hit.");
|
||||
|
||||
ensureCaretAt(gPanel, 6, 1, true).then(afterDebuggerStatementHit);
|
||||
});
|
||||
|
||||
gDebugger.gThreadClient.resume();
|
||||
}
|
||||
|
||||
function afterDebuggerStatementHit() {
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"The debugger statement was hit (4).");
|
||||
is(gSources.selectedValue, SOURCE_URL,
|
||||
"The currently shown source is incorrect (4).");
|
||||
ok(isCaretPos(gPanel, 6),
|
||||
"The source editor caret position is incorrect (4).");
|
||||
|
||||
reloadActiveTab(gPanel, gDebugger.EVENTS.SOURCE_SHOWN)
|
||||
.then(() => ensureThreadClientState(gPanel, "resumed"))
|
||||
.then(() => testClickAgain());
|
||||
}
|
||||
|
||||
function testClickAgain() {
|
||||
isnot(gDebugger.gThreadClient.state, "paused",
|
||||
"The breakpoint wasn't hit yet (5).");
|
||||
is(gSources.selectedValue, SOURCE_URL,
|
||||
"The currently shown source is incorrect (5).");
|
||||
ok(isCaretPos(gPanel, 1),
|
||||
"The source editor caret position is incorrect (5).");
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.why.type, "breakpoint",
|
||||
"Execution has advanced to the breakpoint.");
|
||||
isnot(aPacket.why.type, "debuggerStatement",
|
||||
"The breakpoint was hit before the debugger statement.");
|
||||
|
||||
ensureCaretAt(gPanel, 5, 1, true).then(afterBreakpointHitAgain);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
}
|
||||
|
||||
function afterBreakpointHitAgain() {
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"The breakpoint was hit (6).");
|
||||
is(gSources.selectedValue, SOURCE_URL,
|
||||
"The currently shown source is incorrect (6).");
|
||||
ok(isCaretPos(gPanel, 5),
|
||||
"The source editor caret position is incorrect (6).");
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.why.type, "debuggerStatement",
|
||||
"Execution has advanced to the next line.");
|
||||
isnot(aPacket.why.type, "breakpoint",
|
||||
"No ghost breakpoint was hit.");
|
||||
|
||||
ensureCaretAt(gPanel, 6, 1, true).then(afterDebuggerStatementHitAgain);
|
||||
});
|
||||
|
||||
gDebugger.gThreadClient.resume();
|
||||
}
|
||||
|
||||
function afterDebuggerStatementHitAgain() {
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"The debugger statement was hit (7).");
|
||||
is(gSources.selectedValue, SOURCE_URL,
|
||||
"The currently shown source is incorrect (7).");
|
||||
ok(isCaretPos(gPanel, 6),
|
||||
"The source editor caret position is incorrect (7).");
|
||||
|
||||
showSecondSource();
|
||||
}
|
||||
|
||||
function showSecondSource() {
|
||||
gDebugger.once(gDebugger.EVENTS.SOURCE_SHOWN, () => {
|
||||
is(gEditor.getText().indexOf("debugger"), 447,
|
||||
"The correct source is shown in the source editor.")
|
||||
is(gEditor.getBreakpoints().length, 0,
|
||||
"No breakpoints should be shown for the second source.");
|
||||
|
||||
ensureCaretAt(gPanel, 1, 1, true).then(showFirstSourceAgain);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.querySelectorAll(".side-menu-widget-item-contents")[1],
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function showFirstSourceAgain() {
|
||||
gDebugger.once(gDebugger.EVENTS.SOURCE_SHOWN, () => {
|
||||
is(gEditor.getText().indexOf("debugger"), 148,
|
||||
"The correct source is shown in the source editor.")
|
||||
is(gEditor.getBreakpoints().length, 1,
|
||||
"One breakpoint should be shown for the first source.");
|
||||
|
||||
ensureCaretAt(gPanel, 6, 1, true).then(() => resumeDebuggerThenCloseAndFinish(gPanel));
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.querySelectorAll(".side-menu-widget-item-contents")[0],
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
});
|
@ -1,108 +0,0 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that changing the tab location URL to a page with no scripts works.
|
||||
*/
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
|
||||
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
|
||||
let url = aEvent.detail.url;
|
||||
if (url.indexOf("browser_dbg_stack") != -1) {
|
||||
scriptShown = true;
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
runTest();
|
||||
}
|
||||
});
|
||||
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
framesAdded = true;
|
||||
runTest();
|
||||
});
|
||||
|
||||
gDebuggee.simpleCall();
|
||||
});
|
||||
|
||||
function runTest()
|
||||
{
|
||||
if (scriptShown && framesAdded) {
|
||||
Services.tm.currentThread.dispatch({ run: testSimpleCall }, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testSimpleCall() {
|
||||
var frames = gDebugger.DebuggerView.StackFrames.widget._list,
|
||||
childNodes = frames.childNodes;
|
||||
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 1,
|
||||
"Should have only one frame.");
|
||||
|
||||
is(childNodes.length, frames.querySelectorAll(".dbg-stackframe").length,
|
||||
"All children should be frames.");
|
||||
|
||||
isnot(gDebugger.DebuggerView.Sources.selectedValue, null,
|
||||
"There should be a selected script.");
|
||||
isnot(gDebugger.editor.getText().length, 0,
|
||||
"The source editor should have some text displayed.");
|
||||
isnot(gDebugger.editor.getText(), gDebugger.L10N.getStr("loadingText"),
|
||||
"The source editor text should not be 'Loading...'");
|
||||
|
||||
testLocationChange();
|
||||
}
|
||||
|
||||
function testLocationChange()
|
||||
{
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController._target.once("navigate", function onTabNavigated(aEvent, aPacket) {
|
||||
ok(true, "tabNavigated event was fired.");
|
||||
info("Still attached to the tab.");
|
||||
|
||||
gDebugger.addEventListener("Debugger:AfterSourcesAdded", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
|
||||
is(gDebugger.DebuggerView.Sources.selectedValue, "",
|
||||
"There should be no selected script.");
|
||||
is(gDebugger.editor.getText().length, 0,
|
||||
"The source editor not have any text displayed.");
|
||||
|
||||
let menulist = gDebugger.DebuggerView.Sources.widget;
|
||||
let noScripts = gDebugger.L10N.getStr("noSourcesText");
|
||||
is(menulist.getAttribute("label"), noScripts,
|
||||
"The menulist should display a notice that there are no scripts availalble.");
|
||||
is(menulist.getAttribute("tooltiptext"), "",
|
||||
"The menulist shouldn't have any tooltip text attributed when there are no scripts available.");
|
||||
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
});
|
||||
gDebugger.DebuggerController.client.activeTab.navigateTo("about:blank");
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
@ -1,163 +0,0 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that reloading a page with a breakpoint set does not cause it to
|
||||
* fire more than once.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "test-location-changes-bp.html";
|
||||
const SCRIPT_URL = EXAMPLE_URL + "test-location-changes-bp.js";
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
var sourcesShown = false;
|
||||
var tabNavigated = false;
|
||||
|
||||
function test()
|
||||
{
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
|
||||
testAddBreakpoint();
|
||||
});
|
||||
}
|
||||
|
||||
function testAddBreakpoint()
|
||||
{
|
||||
let controller = gDebugger.DebuggerController;
|
||||
controller.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
|
||||
var frames = gDebugger.DebuggerView.StackFrames.widget._list;
|
||||
|
||||
is(controller.activeThread.state, "paused",
|
||||
"The debugger statement was reached.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 1,
|
||||
"Should have one frame.");
|
||||
|
||||
gPane.addBreakpoint({ url: SCRIPT_URL, line: 5 }, testResume);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.runDebuggerStatement();
|
||||
}
|
||||
|
||||
function testResume()
|
||||
{
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"The breakpoint wasn't hit yet.");
|
||||
|
||||
let thread = gDebugger.DebuggerController.activeThread;
|
||||
thread.addOneTimeListener("resumed", function() {
|
||||
thread.addOneTimeListener("paused", function() {
|
||||
executeSoon(testBreakpointHit);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
content.document.querySelector("button"));
|
||||
});
|
||||
|
||||
thread.resume();
|
||||
}
|
||||
|
||||
function testBreakpointHit()
|
||||
{
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"The breakpoint was hit.");
|
||||
|
||||
let thread = gDebugger.DebuggerController.activeThread;
|
||||
thread.addOneTimeListener("paused", function test(aEvent, aPacket) {
|
||||
thread.addOneTimeListener("resumed", function() {
|
||||
executeSoon(testReloadPage);
|
||||
});
|
||||
|
||||
is(aPacket.why.type, "debuggerStatement", "Execution has advanced to the next line.");
|
||||
isnot(aPacket.why.type, "breakpoint", "No ghost breakpoint was hit.");
|
||||
thread.resume();
|
||||
});
|
||||
|
||||
thread.resume();
|
||||
}
|
||||
|
||||
function testReloadPage()
|
||||
{
|
||||
let controller = gDebugger.DebuggerController;
|
||||
controller._target.once("navigate", function onTabNavigated(aEvent, aPacket) {
|
||||
tabNavigated = true;
|
||||
ok(true, "tabNavigated event was fired.");
|
||||
info("Still attached to the tab.");
|
||||
clickAgain();
|
||||
});
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function onSourcesShown() {
|
||||
sourcesShown = true;
|
||||
gDebugger.removeEventListener("Debugger:SourceShown", onSourcesShown);
|
||||
clickAgain();
|
||||
});
|
||||
|
||||
gDebugger.DebuggerController.client.activeTab.reload();
|
||||
}
|
||||
|
||||
function clickAgain()
|
||||
{
|
||||
if (!sourcesShown || !tabNavigated) {
|
||||
return;
|
||||
}
|
||||
|
||||
let controller = gDebugger.DebuggerController;
|
||||
controller.activeThread.addOneTimeListener("paused", function(aEvent, aPacket) {
|
||||
is(aPacket.why.type, "breakpoint",
|
||||
"The breakpoint was hit.");
|
||||
|
||||
let thread = gDebugger.DebuggerController.activeThread;
|
||||
thread.addOneTimeListener("paused", function test(aEvent, aPacket) {
|
||||
thread.addOneTimeListener("resumed", function() {
|
||||
executeSoon(closeDebuggerAndFinish);
|
||||
});
|
||||
|
||||
is(aPacket.why.type, "debuggerStatement", "Execution has advanced to the next line.");
|
||||
isnot(aPacket.why.type, "breakpoint", "No ghost breakpoint was hit.");
|
||||
thread.resume();
|
||||
});
|
||||
|
||||
thread.resume();
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
content.document.querySelector("button"));
|
||||
}
|
||||
|
||||
function testBreakpointHitAfterReload()
|
||||
{
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"The breakpoint was hit.");
|
||||
|
||||
let thread = gDebugger.DebuggerController.activeThread;
|
||||
thread.addOneTimeListener("paused", function test(aEvent, aPacket) {
|
||||
thread.addOneTimeListener("resumed", function() {
|
||||
executeSoon(closeDebuggerAndFinish);
|
||||
});
|
||||
|
||||
is(aPacket.why.type, "debuggerStatement", "Execution has advanced to the next line.");
|
||||
isnot(aPacket.why.type, "breakpoint", "No ghost breakpoint was hit.");
|
||||
thread.resume();
|
||||
});
|
||||
|
||||
thread.resume();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
@ -1,109 +0,0 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that changing the tab location URL to a page with other scripts works.
|
||||
*/
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
let scriptShown = false;
|
||||
let framesAdded = false;
|
||||
|
||||
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
|
||||
let url = aEvent.detail.url;
|
||||
if (url.indexOf("browser_dbg_stack") != -1) {
|
||||
scriptShown = true;
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
runTest();
|
||||
}
|
||||
});
|
||||
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
framesAdded = true;
|
||||
runTest();
|
||||
});
|
||||
|
||||
gDebuggee.simpleCall();
|
||||
});
|
||||
|
||||
function runTest()
|
||||
{
|
||||
if (scriptShown && framesAdded) {
|
||||
Services.tm.currentThread.dispatch({ run: testSimpleCall }, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testSimpleCall() {
|
||||
var frames = gDebugger.DebuggerView.StackFrames.widget._list,
|
||||
childNodes = frames.childNodes;
|
||||
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 1,
|
||||
"Should have only one frame.");
|
||||
|
||||
is(childNodes.length, frames.querySelectorAll(".dbg-stackframe").length,
|
||||
"All children should be frames.");
|
||||
|
||||
isnot(gDebugger.DebuggerView.Sources.selectedValue, null,
|
||||
"There should be a selected script.");
|
||||
isnot(gDebugger.editor.getText().length, 0,
|
||||
"The source editor should have some text displayed.");
|
||||
isnot(gDebugger.editor.getText(), gDebugger.L10N.getStr("loadingText"),
|
||||
"The source editor text should not be 'Loading...'");
|
||||
|
||||
testLocationChange();
|
||||
}
|
||||
|
||||
function testLocationChange()
|
||||
{
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController._target.once("navigate", function onTabNavigated(aEvent, aPacket) {
|
||||
ok(true, "tabNavigated event was fired.");
|
||||
info("Still attached to the tab.");
|
||||
|
||||
gDebugger.addEventListener("Debugger:SourceShown", function _onEvent(aEvent) {
|
||||
gDebugger.removeEventListener(aEvent.type, _onEvent);
|
||||
|
||||
isnot(gDebugger.DebuggerView.Sources.selectedValue, null,
|
||||
"There should be a selected script.");
|
||||
isnot(gDebugger.editor.getText().length, 0,
|
||||
"The source editor should have some text displayed.");
|
||||
|
||||
let menulist = gDebugger.DebuggerView.Sources.widget;
|
||||
let noScripts = gDebugger.L10N.getStr("noSourcesText");
|
||||
isnot(menulist.getAttribute("label"), noScripts,
|
||||
"The menulist should not display a notice that there are no scripts availalble.");
|
||||
isnot(menulist.getAttribute("tooltiptext"), "",
|
||||
"The menulist should have a tooltip text attributed.");
|
||||
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
});
|
||||
let newLocation = EXAMPLE_URL + "browser_dbg_iframes.html";
|
||||
gDebugger.DebuggerController.client.activeTab.navigateTo(newLocation);
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
@ -1,69 +0,0 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that changing the tab location URL works.
|
||||
*/
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.panelWin;
|
||||
|
||||
testSimpleCall();
|
||||
});
|
||||
}
|
||||
|
||||
function testSimpleCall() {
|
||||
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({
|
||||
run: function() {
|
||||
var frames = gDebugger.DebuggerView.StackFrames.widget._list,
|
||||
childNodes = frames.childNodes;
|
||||
|
||||
is(gDebugger.DebuggerController.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 1,
|
||||
"Should have only one frame.");
|
||||
|
||||
is(childNodes.length, frames.querySelectorAll(".dbg-stackframe").length,
|
||||
"All children should be frames.");
|
||||
|
||||
testLocationChange();
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.simpleCall();
|
||||
}
|
||||
|
||||
function testLocationChange()
|
||||
{
|
||||
gDebugger.DebuggerController.activeThread.resume(function() {
|
||||
gDebugger.DebuggerController._target.once("navigate", function onTabNavigated(aEvent, aPacket) {
|
||||
ok(true, "tabNavigated event was fired.");
|
||||
info("Still attached to the tab.");
|
||||
|
||||
closeDebuggerAndFinish();
|
||||
});
|
||||
gDebugger.DebuggerController.client.activeTab.navigateTo(TAB1_URL);
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
@ -1,45 +0,0 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// We make sure the menuitems in the application menubar
|
||||
// are checked.
|
||||
|
||||
function test() {
|
||||
var tab1 = addTab("about:blank", function() {
|
||||
var tab2 = addTab("about:blank", function() {
|
||||
gBrowser.selectedTab = tab2;
|
||||
|
||||
let pane = DebuggerUI.toggleDebugger();
|
||||
ok(pane, "toggleDebugger() should return a pane.");
|
||||
let frame = pane._frame;
|
||||
|
||||
wait_for_connect_and_resume(function() {
|
||||
let cmd = document.getElementById("Tools:Debugger");
|
||||
is(cmd.getAttribute("checked"), "true", "<command Tools:Debugger> is checked.");
|
||||
|
||||
gBrowser.selectedTab = tab1;
|
||||
|
||||
is(cmd.getAttribute("checked"), "false", "<command Tools:Debugger> is unchecked after tab switch.");
|
||||
|
||||
gBrowser.selectedTab = tab2;
|
||||
|
||||
is(cmd.getAttribute("checked"), "true", "<command Tools:Debugger> is checked.");
|
||||
|
||||
let pane = DebuggerUI.toggleDebugger();
|
||||
|
||||
is(cmd.getAttribute("checked"), "false", "<command Tools:Debugger> is unchecked once closed.");
|
||||
});
|
||||
|
||||
window.addEventListener("Debugger:Shutdown", function dbgShutdown() {
|
||||
window.removeEventListener("Debugger:Shutdown", dbgShutdown, true);
|
||||
removeTab(tab1);
|
||||
removeTab(tab2);
|
||||
|
||||
finish();
|
||||
}, true);
|
||||
});
|
||||
});
|
||||
}
|
@ -1,142 +1,164 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Make sure that the debugger attaches to the right tab when multiple windows
|
||||
// are open.
|
||||
/**
|
||||
* Make sure that the debugger attaches to the right tab when multiple windows
|
||||
* are open.
|
||||
*/
|
||||
|
||||
var gTab1 = null;
|
||||
var gTab1Actor = null;
|
||||
const TAB1_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
const TAB2_URL = EXAMPLE_URL + "doc_script-switching-02.html";
|
||||
|
||||
var gSecondWindow = null;
|
||||
let gNewTab, gNewWindow;
|
||||
let gClient;
|
||||
|
||||
var gClient = null;
|
||||
var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Ci.nsIWindowMediator);
|
||||
function test() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init(() => true);
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect(function(aType, aTraits) {
|
||||
is(aType, "browser", "Root actor should identify itself as a browser.");
|
||||
test_first_tab();
|
||||
gClient.connect((aType, aTraits) => {
|
||||
is(aType, "browser",
|
||||
"Root actor should identify itself as a browser.");
|
||||
|
||||
promise.resolve(null)
|
||||
.then(() => addTab(TAB1_URL))
|
||||
.then(testFirstTab)
|
||||
.then(() => addWindow(TAB2_URL))
|
||||
.then(testNewWindow)
|
||||
.then(testFocusFirst)
|
||||
.then(testRemoveTab)
|
||||
.then(closeConnection)
|
||||
.then(finish)
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function test_first_tab()
|
||||
{
|
||||
gTab1 = addTab(TAB1_URL, function() {
|
||||
gClient.listTabs(function(aResponse) {
|
||||
for each (let tab in aResponse.tabs) {
|
||||
if (tab.url == TAB1_URL) {
|
||||
gTab1Actor = tab.actor;
|
||||
}
|
||||
}
|
||||
ok(gTab1Actor, "Should find a tab actor for tab1.");
|
||||
is(aResponse.selected, 1, "Tab1 is selected.");
|
||||
test_open_window();
|
||||
function testFirstTab(aTab) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gNewTab = aTab;
|
||||
ok(!!gNewTab, "Second tab created.");
|
||||
|
||||
gClient.listTabs(aResponse => {
|
||||
let tabActor = aResponse.tabs.filter(aGrip => aGrip.url == TAB1_URL).pop();
|
||||
ok(tabActor,
|
||||
"Should find a tab actor for the first tab.");
|
||||
|
||||
is(aResponse.selected, 1,
|
||||
"The first tab is selected.");
|
||||
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testNewWindow(aWindow) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gNewWindow = aWindow;
|
||||
ok(!!gNewWindow, "Second window created.");
|
||||
|
||||
gNewWindow.focus();
|
||||
|
||||
let topWindow = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
is(topWindow, gNewWindow,
|
||||
"The second window is on top.");
|
||||
|
||||
let isActive = promise.defer();
|
||||
let isLoaded = promise.defer();
|
||||
|
||||
promise.all([isActive.promise, isLoaded.promise]).then(() => {
|
||||
gNewWindow.BrowserChromeTest.runWhenReady(() => {
|
||||
gClient.listTabs(aResponse => {
|
||||
is(aResponse.selected, 2,
|
||||
"The second tab is selected.");
|
||||
|
||||
deferred.resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function test_open_window()
|
||||
{
|
||||
gSecondWindow = window.open(TAB2_URL, "secondWindow");
|
||||
ok(!!gSecondWindow, "Second window created.");
|
||||
gSecondWindow.focus();
|
||||
let top = windowMediator.getMostRecentWindow("navigator:browser");
|
||||
var main2 = gSecondWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindow);
|
||||
is(top, main2, "The second window is on top.");
|
||||
let gotLoad = false;
|
||||
let gotActivate = (Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager).activeWindow == main2);
|
||||
function maybeWindowLoadedAndActive() {
|
||||
if (gotLoad && gotActivate) {
|
||||
top.BrowserChromeTest.runWhenReady(function() {
|
||||
executeSoon(function() {
|
||||
gClient.listTabs(function(aResponse) {
|
||||
is(aResponse.selected, 2, "Tab2 is selected.");
|
||||
test_focus_first();
|
||||
});
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (!gotActivate) {
|
||||
main2.addEventListener("activate", function() {
|
||||
main2.removeEventListener("activate", arguments.callee, true);
|
||||
gotActivate = true;
|
||||
maybeWindowLoadedAndActive();
|
||||
},
|
||||
true
|
||||
);
|
||||
}
|
||||
main2.document.addEventListener("load", function(e) {
|
||||
if (e.target.documentURI != TAB2_URL) {
|
||||
let focusManager = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
|
||||
if (focusManager.activeWindow != gNewWindow) {
|
||||
gNewWindow.addEventListener("activate", function onActivate(aEvent) {
|
||||
if (aEvent.target != gNewWindow) {
|
||||
return;
|
||||
}
|
||||
main2.document.removeEventListener("load", arguments.callee, true);
|
||||
gotLoad = true;
|
||||
maybeWindowLoadedAndActive();
|
||||
},
|
||||
true
|
||||
);
|
||||
}
|
||||
gNewWindow.removeEventListener("activate", onActivate, true);
|
||||
isActive.resolve();
|
||||
}, true);
|
||||
} else {
|
||||
isActive.resolve();
|
||||
}
|
||||
|
||||
function test_focus_first()
|
||||
{
|
||||
window.content.addEventListener("focus", function onFocus() {
|
||||
window.content.removeEventListener("focus", onFocus, false);
|
||||
let top = windowMediator.getMostRecentWindow("navigator:browser");
|
||||
var main1 = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindow);
|
||||
is(top, main1, "The first window is on top.");
|
||||
|
||||
gClient.listTabs(function(aResponse) {
|
||||
is(aResponse.selected, 1, "Tab1 is selected after focusing on it.");
|
||||
|
||||
test_remove_tab();
|
||||
});
|
||||
}, false);
|
||||
window.content.focus();
|
||||
}
|
||||
|
||||
function test_remove_tab()
|
||||
{
|
||||
gSecondWindow.close();
|
||||
gSecondWindow = null;
|
||||
removeTab(gTab1);
|
||||
gTab1 = null;
|
||||
gClient.listTabs(function(aResponse) {
|
||||
// Verify that tabs are no longer included in listTabs.
|
||||
let foundTab1 = false;
|
||||
let foundTab2 = false;
|
||||
for (let tab of aResponse.tabs) {
|
||||
if (tab.url == TAB1_URL) {
|
||||
foundTab1 = true;
|
||||
} else if (tab.url == TAB2_URL) {
|
||||
foundTab2 = true;
|
||||
let contentLocation = gNewWindow.content.location.href;
|
||||
if (contentLocation != TAB2_URL) {
|
||||
gNewWindow.document.addEventListener("load", function onLoad(aEvent) {
|
||||
if (aEvent.target.documentURI != TAB2_URL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
gNewWindow.document.removeEventListener("load", onLoad, true);
|
||||
isLoaded.resolve();
|
||||
}, true);
|
||||
} else {
|
||||
isLoaded.resolve();
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testFocusFirst() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
once(window.content, "focus").then(() => {
|
||||
let topWindow = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
is(top, getDOMWindow(window),
|
||||
"The first window is on top.");
|
||||
|
||||
gClient.listTabs(aResponse => {
|
||||
is(aResponse.selected, 1,
|
||||
"The first tab is selected after focusing on it.");
|
||||
|
||||
deferred.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
window.content.focus();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testRemoveTab() {
|
||||
gNewWindow.close();
|
||||
removeTab(gNewTab);
|
||||
|
||||
gClient.listTabs(aResponse => {
|
||||
// Verify that tabs are no longer included in listTabs.
|
||||
let foundTab1 = aResponse.tabs.some(aGrip => aGrip.url == TAB1_URL);
|
||||
let foundTab2 = aResponse.tabs.some(aGrip => aGrip.url == TAB2_URL);
|
||||
ok(!foundTab1, "Tab1 should be gone.");
|
||||
ok(!foundTab2, "Tab2 should be gone.");
|
||||
is(aResponse.selected, 0, "The original tab is selected.");
|
||||
finish_test();
|
||||
|
||||
is(aResponse.selected, 0,
|
||||
"The original tab is selected.");
|
||||
});
|
||||
}
|
||||
|
||||
function finish_test()
|
||||
{
|
||||
gClient.close(function() {
|
||||
finish();
|
||||
});
|
||||
function closeConnection() {
|
||||
let deferred = promise.defer();
|
||||
gClient.close(deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gNewTab = null;
|
||||
gNewWindow = null;
|
||||
gClient = null;
|
||||
});
|
||||
|
@ -1,54 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Check tab attach/navigation.
|
||||
*/
|
||||
|
||||
var gTab1 = null;
|
||||
var gTab1Actor = null;
|
||||
|
||||
var gClient = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect(function(aType, aTraits) {
|
||||
is(aType, "browser", "Root actor should identify itself as a browser.");
|
||||
get_tab();
|
||||
});
|
||||
}
|
||||
|
||||
function get_tab()
|
||||
{
|
||||
gTab1 = addTab(TAB1_URL, function() {
|
||||
get_tab_actor_for_url(gClient, TAB1_URL, function(aGrip) {
|
||||
gTab1Actor = aGrip.actor;
|
||||
gClient.request({ to: aGrip.actor, type: "attach" }, function(aResponse) {
|
||||
gClient.addListener("tabNavigated", function onTabNavigated(aEvent, aPacket) {
|
||||
dump("onTabNavigated state " + aPacket.state + "\n");
|
||||
if (aPacket.state == "start") {
|
||||
return;
|
||||
}
|
||||
gClient.removeListener("tabNavigated", onTabNavigated);
|
||||
|
||||
is(aPacket.url, TAB2_URL, "Got a tab navigation notification.");
|
||||
gClient.addOneTimeListener("tabDetached", function (aEvent, aPacket) {
|
||||
ok(true, "Got a tab detach notification.");
|
||||
finish_test();
|
||||
});
|
||||
removeTab(gTab1);
|
||||
});
|
||||
gTab1.linkedBrowser.loadURI(TAB2_URL);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function finish_test()
|
||||
{
|
||||
gClient.close(function() {
|
||||
finish();
|
||||
});
|
||||
}
|
71
browser/devtools/debugger/test/browser_dbg_navigation.js
Normal file
71
browser/devtools/debugger/test/browser_dbg_navigation.js
Normal file
@ -0,0 +1,71 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Check tab attach/navigation.
|
||||
*/
|
||||
|
||||
const TAB1_URL = EXAMPLE_URL + "doc_empty-tab-01.html";
|
||||
const TAB2_URL = EXAMPLE_URL + "doc_empty-tab-02.html";
|
||||
|
||||
let gClient;
|
||||
|
||||
function test() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init(() => true);
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect((aType, aTraits) => {
|
||||
is(aType, "browser",
|
||||
"Root actor should identify itself as a browser.");
|
||||
|
||||
addTab(TAB1_URL)
|
||||
.then(() => attachTabActorForUrl(gClient, TAB1_URL))
|
||||
.then(testNavigate)
|
||||
.then(testDetach)
|
||||
.then(finish)
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testNavigate() {
|
||||
let outstanding = [promise.defer(), promise.defer()];
|
||||
|
||||
gClient.addListener("tabNavigated", function onTabNavigated(aEvent, aPacket) {
|
||||
is(aPacket.url, TAB2_URL,
|
||||
"Got a tab navigation notification.");
|
||||
|
||||
if (aPacket.state == "start") {
|
||||
ok(true, "Tab started to navigate.");
|
||||
outstanding[0].resolve();
|
||||
} else {
|
||||
ok(true, "Tab finished navigating.");
|
||||
gClient.removeListener("tabNavigated", onTabNavigated);
|
||||
outstanding[1].resolve();
|
||||
}
|
||||
});
|
||||
|
||||
gBrowser.selectedTab.linkedBrowser.loadURI(TAB2_URL);
|
||||
return promise.all(outstanding.map(e => e.promise));
|
||||
}
|
||||
|
||||
function testDetach() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gClient.addOneTimeListener("tabDetached", () => {
|
||||
ok(true, "Got a tab detach notification.");
|
||||
gClient.close(deferred.resolve);
|
||||
});
|
||||
|
||||
removeTab(gBrowser.selectedTab);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gClient = null;
|
||||
});
|
@ -0,0 +1,75 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that debugger's tab is highlighted when it is paused and not the
|
||||
* currently selected tool.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gToolbox, gToolboxTab;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gToolbox = gPanel._toolbox;
|
||||
gToolboxTab = gToolbox.doc.getElementById("toolbox-tab-jsdebugger");
|
||||
|
||||
waitForSourceShown(gPanel, ".html").then(testPause);
|
||||
});
|
||||
}
|
||||
|
||||
function testPause() {
|
||||
is(gDebugger.gThreadClient.paused, false,
|
||||
"Should be running after starting test.");
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("paused", () => {
|
||||
gToolbox.selectTool("webconsole").then(() => {
|
||||
ok(gToolboxTab.classList.contains("highlighted"),
|
||||
"The highlighted class is present");
|
||||
ok(!gToolboxTab.hasAttribute("selected") ||
|
||||
gToolboxTab.getAttribute("selected") != "true",
|
||||
"The tab is not selected");
|
||||
}).then(() => gToolbox.selectTool("jsdebugger")).then(() => {
|
||||
ok(gToolboxTab.classList.contains("highlighted"),
|
||||
"The highlighted class is present");
|
||||
ok(gToolboxTab.hasAttribute("selected") &&
|
||||
gToolboxTab.getAttribute("selected") == "true",
|
||||
"...and the tab is selected, so the glow will not be present.");
|
||||
}).then(testResume);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function testResume() {
|
||||
gDebugger.gThreadClient.addOneTimeListener("resumed", () => {
|
||||
gToolbox.selectTool("webconsole").then(() => {
|
||||
ok(!gToolboxTab.classList.contains("highlighted"),
|
||||
"The highlighted class is not present now after the resume");
|
||||
ok(!gToolboxTab.hasAttribute("selected") ||
|
||||
gToolboxTab.getAttribute("selected") != "true",
|
||||
"The tab is not selected");
|
||||
}).then(() => closeDebuggerAndFinish(gPanel));
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gToolbox = null;
|
||||
gToolboxTab = null;
|
||||
});
|
141
browser/devtools/debugger/test/browser_dbg_on-pause-raise.js
Normal file
141
browser/devtools/debugger/test/browser_dbg_on-pause-raise.js
Normal file
@ -0,0 +1,141 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the toolbox is raised when the debugger gets paused.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gNewTab, gFocusedWindow, gToolbox, gToolboxTab;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gToolbox = gPanel._toolbox;
|
||||
gToolboxTab = gToolbox.doc.getElementById("toolbox-tab-jsdebugger");
|
||||
|
||||
waitForSourceShown(gPanel, ".html").then(performTest);
|
||||
});
|
||||
}
|
||||
|
||||
function performTest() {
|
||||
addTab(TAB_URL).then(aTab => {
|
||||
isnot(aTab, gTab,
|
||||
"The newly added tab is different from the debugger's tab.");
|
||||
is(gBrowser.selectedTab, aTab,
|
||||
"Debugger's tab is not the selected tab.");
|
||||
|
||||
gNewTab = aTab;
|
||||
gFocusedWindow = window;
|
||||
testPause();
|
||||
});
|
||||
}
|
||||
|
||||
function focusMainWindow() {
|
||||
// Make sure toolbox is not focused.
|
||||
window.addEventListener("focus", onFocus, true);
|
||||
info("Focusing main window.")
|
||||
|
||||
// Execute soon to avoid any race conditions between toolbox and main window
|
||||
// getting focused.
|
||||
executeSoon(() => {
|
||||
window.focus();
|
||||
});
|
||||
}
|
||||
|
||||
function onFocus() {
|
||||
window.removeEventListener("focus", onFocus, true);
|
||||
info("Main window focused.")
|
||||
|
||||
gFocusedWindow = window;
|
||||
testPause();
|
||||
}
|
||||
|
||||
function testPause() {
|
||||
is(gDebugger.gThreadClient.paused, false,
|
||||
"Should be running after starting the test.");
|
||||
|
||||
is(gFocusedWindow, window,
|
||||
"Main window is the top level window before pause.");
|
||||
|
||||
if (gToolbox.hostType == devtools.Toolbox.HostType.WINDOW) {
|
||||
gToolbox._host._window.onfocus = () => {
|
||||
gFocusedWindow = gToolbox._host._window;
|
||||
};
|
||||
}
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("paused", () => {
|
||||
if (gToolbox.hostType == devtools.Toolbox.HostType.WINDOW) {
|
||||
is(gFocusedWindow, gToolbox._host._window,
|
||||
"Toolbox window is the top level window on pause.");
|
||||
} else {
|
||||
is(gBrowser.selectedTab, gTab,
|
||||
"Debugger's tab got selected.");
|
||||
}
|
||||
gToolbox.selectTool("webconsole").then(() => {
|
||||
ok(gToolboxTab.classList.contains("highlighted"),
|
||||
"The highlighted class is present");
|
||||
ok(!gToolboxTab.hasAttribute("selected") ||
|
||||
gToolboxTab.getAttribute("selected") != "true",
|
||||
"The tab is not selected");
|
||||
}).then(() => gToolbox.selectTool("jsdebugger")).then(() => {
|
||||
ok(gToolboxTab.classList.contains("highlighted"),
|
||||
"The highlighted class is present");
|
||||
ok(gToolboxTab.hasAttribute("selected") &&
|
||||
gToolboxTab.getAttribute("selected") == "true",
|
||||
"...and the tab is selected, so the glow will not be present.");
|
||||
}).then(testResume);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function testResume() {
|
||||
gDebugger.gThreadClient.addOneTimeListener("resumed", () => {
|
||||
gToolbox.selectTool("webconsole").then(() => {
|
||||
ok(!gToolboxTab.classList.contains("highlighted"),
|
||||
"The highlighted class is not present now after the resume");
|
||||
ok(!gToolboxTab.hasAttribute("selected") ||
|
||||
gToolboxTab.getAttribute("selected") != "true",
|
||||
"The tab is not selected");
|
||||
}).then(maybeEndTest);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function maybeEndTest() {
|
||||
if (gToolbox.hostType == devtools.Toolbox.HostType.BOTTOM) {
|
||||
info("Switching to a toolbox window host.");
|
||||
gToolbox.switchHost(devtools.Toolbox.HostType.WINDOW).then(focusMainWindow);
|
||||
} else {
|
||||
info("Switching to main window host.");
|
||||
gToolbox.switchHost(devtools.Toolbox.HostType.BOTTOM).then(() => closeDebuggerAndFinish(gPanel));
|
||||
}
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
// Revert to the default toolbox host, so that the following tests proceed
|
||||
// normally and not inside a non-default host.
|
||||
Services.prefs.setCharPref("devtools.toolbox.host", devtools.Toolbox.HostType.BOTTOM);
|
||||
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
|
||||
removeTab(gNewTab);
|
||||
gNewTab = null;
|
||||
gFocusedWindow = null;
|
||||
gToolbox = null;
|
||||
gToolboxTab = null;
|
||||
});
|
83
browser/devtools/debugger/test/browser_dbg_panel-size.js
Normal file
83
browser/devtools/debugger/test/browser_dbg_panel-size.js
Normal file
@ -0,0 +1,83 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that the sources and instruments panels widths are properly
|
||||
* remembered when the debugger closes.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gPrefs, gSources, gInstruments;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gPrefs = gDebugger.Prefs;
|
||||
gSources = gDebugger.document.getElementById("sources-pane");
|
||||
gInstruments = gDebugger.document.getElementById("instruments-pane");
|
||||
|
||||
waitForSourceShown(gPanel, ".html").then(performTest);
|
||||
});
|
||||
|
||||
function performTest() {
|
||||
let preferredSw = Services.prefs.getIntPref("devtools.debugger.ui.panes-sources-width");
|
||||
let preferredIw = Services.prefs.getIntPref("devtools.debugger.ui.panes-instruments-width");
|
||||
let someWidth1, someWidth2;
|
||||
|
||||
do {
|
||||
someWidth1 = parseInt(Math.random() * 200) + 100;
|
||||
someWidth2 = parseInt(Math.random() * 300) + 100;
|
||||
} while ((someWidth1 == preferredSw) || (someWidth2 == preferredIw));
|
||||
|
||||
info("Preferred sources width: " + preferredSw);
|
||||
info("Preferred instruments width: " + preferredIw);
|
||||
info("Generated sources width: " + someWidth1);
|
||||
info("Generated instruments width: " + someWidth2);
|
||||
|
||||
ok(gPrefs.sourcesWidth,
|
||||
"The debugger preferences should have a saved sourcesWidth value.");
|
||||
ok(gPrefs.instrumentsWidth,
|
||||
"The debugger preferences should have a saved instrumentsWidth value.");
|
||||
|
||||
is(gPrefs.sourcesWidth, preferredSw,
|
||||
"The debugger preferences should have a correct sourcesWidth value.");
|
||||
is(gPrefs.instrumentsWidth, preferredIw,
|
||||
"The debugger preferences should have a correct instrumentsWidth value.");
|
||||
|
||||
is(gSources.getAttribute("width"), gPrefs.sourcesWidth,
|
||||
"The sources pane width should be the same as the preferred value.");
|
||||
is(gInstruments.getAttribute("width"), gPrefs.instrumentsWidth,
|
||||
"The instruments pane width should be the same as the preferred value.");
|
||||
|
||||
gSources.setAttribute("width", someWidth1);
|
||||
gInstruments.setAttribute("width", someWidth2);
|
||||
|
||||
is(gPrefs.sourcesWidth, preferredSw,
|
||||
"The sources pane width pref should still be the same as the preferred value.");
|
||||
is(gPrefs.instrumentsWidth, preferredIw,
|
||||
"The instruments pane width pref should still be the same as the preferred value.");
|
||||
|
||||
isnot(gSources.getAttribute("width"), gPrefs.sourcesWidth,
|
||||
"The sources pane width should not be the preferred value anymore.");
|
||||
isnot(gInstruments.getAttribute("width"), gPrefs.instrumentsWidth,
|
||||
"The instruments pane width should not be the preferred value anymore.");
|
||||
|
||||
teardown(gPanel).then(() => {
|
||||
is(gPrefs.sourcesWidth, someWidth1,
|
||||
"The sources pane width should have been saved by now.");
|
||||
is(gPrefs.instrumentsWidth, someWidth2,
|
||||
"The instruments pane width should have been saved by now.");
|
||||
|
||||
// Cleanup after ourselves!
|
||||
Services.prefs.setIntPref("devtools.debugger.ui.panes-sources-width", preferredSw);
|
||||
Services.prefs.setIntPref("devtools.debugger.ui.panes-instruments-width", preferredIw);
|
||||
|
||||
finish();
|
||||
});
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
function test() {
|
||||
var tab1 = addTab(TAB1_URL, function() {
|
||||
gBrowser.selectedTab = tab1;
|
||||
let target1 = TargetFactory.forTab(tab1);
|
||||
|
||||
ok(!gDevTools.getToolbox(target1),
|
||||
"Shouldn't have a debugger panel for this tab yet.");
|
||||
|
||||
gDevTools.showToolbox(target1, "jsdebugger").then(function(toolbox) {
|
||||
let dbg = toolbox.getCurrentPanel();
|
||||
ok(dbg, "We should have a debugger panel.");
|
||||
|
||||
let preferredSw = Services.prefs.getIntPref("devtools.debugger.ui.panes-sources-width");
|
||||
let preferredIw = Services.prefs.getIntPref("devtools.debugger.ui.panes-instruments-width");
|
||||
let someWidth1, someWidth2;
|
||||
|
||||
do {
|
||||
someWidth1 = parseInt(Math.random() * 200) + 100;
|
||||
someWidth2 = parseInt(Math.random() * 200) + 100;
|
||||
} while (someWidth1 == preferredSw ||
|
||||
someWidth2 == preferredIw)
|
||||
|
||||
let someWidth1 = parseInt(Math.random() * 200) + 100;
|
||||
let someWidth2 = parseInt(Math.random() * 200) + 100;
|
||||
|
||||
info("Preferred sources width: " + preferredSw);
|
||||
info("Preferred instruments width: " + preferredIw);
|
||||
info("Generated sources width: " + someWidth1);
|
||||
info("Generated instruments width: " + someWidth2);
|
||||
|
||||
let content = dbg.panelWin;
|
||||
let sources;
|
||||
let instruments;
|
||||
|
||||
wait_for_connect_and_resume(function() {
|
||||
ok(content.Prefs.sourcesWidth,
|
||||
"The debugger preferences should have a saved sourcesWidth value.");
|
||||
ok(content.Prefs.instrumentsWidth,
|
||||
"The debugger preferences should have a saved instrumentsWidth value.");
|
||||
|
||||
sources = content.document.getElementById("sources-pane");
|
||||
instruments = content.document.getElementById("instruments-pane");
|
||||
|
||||
is(content.Prefs.sourcesWidth, sources.getAttribute("width"),
|
||||
"The sources pane width should be the same as the preferred value.");
|
||||
is(content.Prefs.instrumentsWidth, instruments.getAttribute("width"),
|
||||
"The instruments pane width should be the same as the preferred value.");
|
||||
|
||||
sources.setAttribute("width", someWidth1);
|
||||
instruments.setAttribute("width", someWidth2);
|
||||
|
||||
removeTab(tab1);
|
||||
}, tab1);
|
||||
|
||||
window.addEventListener("Debugger:Shutdown", function dbgShutdown() {
|
||||
window.removeEventListener("Debugger:Shutdown", dbgShutdown, true);
|
||||
|
||||
is(content.Prefs.sourcesWidth, sources.getAttribute("width"),
|
||||
"The sources pane width should have been saved by now.");
|
||||
is(content.Prefs.instrumentsWidth, instruments.getAttribute("width"),
|
||||
"The instruments pane width should have been saved by now.");
|
||||
|
||||
// Cleanup after ourselves!
|
||||
Services.prefs.setIntPref("devtools.debugger.ui.panes-sources-width", preferredSw);
|
||||
Services.prefs.setIntPref("devtools.debugger.ui.panes-instruments-width", preferredIw);
|
||||
|
||||
finish();
|
||||
}, true);
|
||||
});
|
||||
});
|
||||
}
|
@ -0,0 +1,245 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that pausing on exceptions works.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_pause-exceptions.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gFrames, gVariables, gPrefs, gOptions;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gFrames = gDebugger.DebuggerView.StackFrames;
|
||||
gVariables = gDebugger.DebuggerView.Variables;
|
||||
gPrefs = gDebugger.Prefs;
|
||||
gOptions = gDebugger.DebuggerView.Options;
|
||||
|
||||
is(gPrefs.pauseOnExceptions, false,
|
||||
"The pause-on-exceptions pref should be disabled by default.");
|
||||
isnot(gOptions._pauseOnExceptionsItem.getAttribute("checked"), "true",
|
||||
"The pause-on-exceptions menu item should not be checked.");
|
||||
|
||||
testPauseOnExceptionsDisabled()
|
||||
.then(enablePauseOnExceptions)
|
||||
.then(disableIgnoreCaughtExceptions)
|
||||
.then(testPauseOnExceptionsEnabled)
|
||||
.then(disablePauseOnExceptions)
|
||||
.then(enableIgnoreCaughtExceptions)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testPauseOnExceptionsDisabled() {
|
||||
let finished = waitForCaretAndScopes(gPanel, 26).then(() => {
|
||||
info("Testing disabled pause-on-exceptions.");
|
||||
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused (1).");
|
||||
ok(isCaretPos(gPanel, 26),
|
||||
"Should be paused on the debugger statement (1).");
|
||||
|
||||
let innerScope = gVariables.getScopeAtIndex(0);
|
||||
let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes;
|
||||
|
||||
is(gFrames.itemCount, 1,
|
||||
"Should have one frame.");
|
||||
is(gVariables._store.length, 3,
|
||||
"Should have three scopes.");
|
||||
|
||||
is(innerNodes[0].querySelector(".name").getAttribute("value"), "this",
|
||||
"Should have the right property name for 'this'.");
|
||||
is(innerNodes[0].querySelector(".value").getAttribute("value"), "HTMLButtonElement",
|
||||
"Should have the right property value for 'this'.");
|
||||
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
|
||||
isnot(gDebugger.gThreadClient.state, "paused",
|
||||
"Should not be paused after resuming.");
|
||||
ok(isCaretPos(gPanel, 26),
|
||||
"Should be idle on the debugger statement.");
|
||||
|
||||
ok(true, "Frames were cleared, debugger didn't pause again.");
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
|
||||
return finished;
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testPauseOnExceptionsEnabled() {
|
||||
let finished = waitForCaretAndScopes(gPanel, 19).then(() => {
|
||||
info("Testing enabled pause-on-exceptions.");
|
||||
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
ok(isCaretPos(gPanel, 19),
|
||||
"Should be paused on the debugger statement.");
|
||||
|
||||
let innerScope = gVariables.getScopeAtIndex(0);
|
||||
let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes;
|
||||
|
||||
is(gFrames.itemCount, 1,
|
||||
"Should have one frame.");
|
||||
is(gVariables._store.length, 3,
|
||||
"Should have three scopes.");
|
||||
|
||||
is(innerNodes[0].querySelector(".name").getAttribute("value"), "<exception>",
|
||||
"Should have the right property name for <exception>.");
|
||||
is(innerNodes[0].querySelector(".value").getAttribute("value"), "Error",
|
||||
"Should have the right property value for <exception>.");
|
||||
|
||||
let finished = waitForCaretAndScopes(gPanel, 26).then(() => {
|
||||
info("Testing enabled pause-on-exceptions and resumed after pause.");
|
||||
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
ok(isCaretPos(gPanel, 26),
|
||||
"Should be paused on the debugger statement.");
|
||||
|
||||
let innerScope = gVariables.getScopeAtIndex(0);
|
||||
let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes;
|
||||
|
||||
is(gFrames.itemCount, 1,
|
||||
"Should have one frame.");
|
||||
is(gVariables._store.length, 3,
|
||||
"Should have three scopes.");
|
||||
|
||||
is(innerNodes[0].querySelector(".name").getAttribute("value"), "this",
|
||||
"Should have the right property name for 'this'.");
|
||||
is(innerNodes[0].querySelector(".value").getAttribute("value"), "HTMLButtonElement",
|
||||
"Should have the right property value for 'this'.");
|
||||
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
|
||||
isnot(gDebugger.gThreadClient.state, "paused",
|
||||
"Should not be paused after resuming.");
|
||||
ok(isCaretPos(gPanel, 26),
|
||||
"Should be idle on the debugger statement.");
|
||||
|
||||
ok(true, "Frames were cleared, debugger didn't pause again.");
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
|
||||
return finished;
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
|
||||
return finished;
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
function enablePauseOnExceptions() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("resumed", () => {
|
||||
is(gPrefs.pauseOnExceptions, true,
|
||||
"The pause-on-exceptions pref should now be enabled.");
|
||||
is(gOptions._pauseOnExceptionsItem.getAttribute("checked"), "true",
|
||||
"The pause-on-exceptions menu item should now be checked.");
|
||||
|
||||
ok(true, "Pausing on exceptions was enabled.");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
gOptions._pauseOnExceptionsItem.setAttribute("checked", "true");
|
||||
gOptions._togglePauseOnExceptions();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function disablePauseOnExceptions() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("resumed", () => {
|
||||
is(gPrefs.pauseOnExceptions, false,
|
||||
"The pause-on-exceptions pref should now be disabled.");
|
||||
isnot(gOptions._pauseOnExceptionsItem.getAttribute("checked"), "true",
|
||||
"The pause-on-exceptions menu item should now be unchecked.");
|
||||
|
||||
ok(true, "Pausing on exceptions was disabled.");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
gOptions._pauseOnExceptionsItem.setAttribute("checked", "false");
|
||||
gOptions._togglePauseOnExceptions();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function enableIgnoreCaughtExceptions() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("resumed", () => {
|
||||
is(gPrefs.ignoreCaughtExceptions, true,
|
||||
"The ignore-caught-exceptions pref should now be enabled.");
|
||||
is(gOptions._ignoreCaughtExceptionsItem.getAttribute("checked"), "true",
|
||||
"The ignore-caught-exceptions menu item should now be checked.");
|
||||
|
||||
ok(true, "Ignore caught exceptions was enabled.");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
gOptions._ignoreCaughtExceptionsItem.setAttribute("checked", "true");
|
||||
gOptions._toggleIgnoreCaughtExceptions();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function disableIgnoreCaughtExceptions() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("resumed", () => {
|
||||
is(gPrefs.ignoreCaughtExceptions, false,
|
||||
"The ignore-caught-exceptions pref should now be disabled.");
|
||||
isnot(gOptions._ignoreCaughtExceptionsItem.getAttribute("checked"), "true",
|
||||
"The ignore-caught-exceptions menu item should now be unchecked.");
|
||||
|
||||
ok(true, "Ignore caught exceptions was disabled.");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
gOptions._ignoreCaughtExceptionsItem.setAttribute("checked", "false");
|
||||
gOptions._toggleIgnoreCaughtExceptions();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gFrames = null;
|
||||
gVariables = null;
|
||||
gPrefs = null;
|
||||
gOptions = null;
|
||||
});
|
@ -0,0 +1,201 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that pausing on exceptions works after reload.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_pause-exceptions.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gFrames, gVariables, gPrefs, gOptions;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gFrames = gDebugger.DebuggerView.StackFrames;
|
||||
gVariables = gDebugger.DebuggerView.Variables;
|
||||
gPrefs = gDebugger.Prefs;
|
||||
gOptions = gDebugger.DebuggerView.Options;
|
||||
|
||||
is(gPrefs.pauseOnExceptions, false,
|
||||
"The pause-on-exceptions pref should be disabled by default.");
|
||||
isnot(gOptions._pauseOnExceptionsItem.getAttribute("checked"), "true",
|
||||
"The pause-on-exceptions menu item should not be checked.");
|
||||
|
||||
enablePauseOnExceptions()
|
||||
.then(disableIgnoreCaughtExceptions)
|
||||
.then(() => reloadActiveTab(gPanel, gDebugger.EVENTS.SOURCE_SHOWN))
|
||||
.then(() => ensureThreadClientState(gPanel, "resumed"))
|
||||
.then(testPauseOnExceptionsAfterReload)
|
||||
.then(disablePauseOnExceptions)
|
||||
.then(enableIgnoreCaughtExceptions)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testPauseOnExceptionsAfterReload() {
|
||||
let finished = waitForCaretAndScopes(gPanel, 19).then(() => {
|
||||
info("Testing enabled pause-on-exceptions.");
|
||||
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
ok(isCaretPos(gPanel, 19),
|
||||
"Should be paused on the debugger statement.");
|
||||
|
||||
let innerScope = gVariables.getScopeAtIndex(0);
|
||||
let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes;
|
||||
|
||||
is(gFrames.itemCount, 1,
|
||||
"Should have one frame.");
|
||||
is(gVariables._store.length, 3,
|
||||
"Should have three scopes.");
|
||||
|
||||
is(innerNodes[0].querySelector(".name").getAttribute("value"), "<exception>",
|
||||
"Should have the right property name for <exception>.");
|
||||
is(innerNodes[0].querySelector(".value").getAttribute("value"), "Error",
|
||||
"Should have the right property value for <exception>.");
|
||||
|
||||
let finished = waitForCaretAndScopes(gPanel, 26).then(() => {
|
||||
info("Testing enabled pause-on-exceptions and resumed after pause.");
|
||||
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
ok(isCaretPos(gPanel, 26),
|
||||
"Should be paused on the debugger statement.");
|
||||
|
||||
let innerScope = gVariables.getScopeAtIndex(0);
|
||||
let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes;
|
||||
|
||||
is(gFrames.itemCount, 1,
|
||||
"Should have one frame.");
|
||||
is(gVariables._store.length, 3,
|
||||
"Should have three scopes.");
|
||||
|
||||
is(innerNodes[0].querySelector(".name").getAttribute("value"), "this",
|
||||
"Should have the right property name for 'this'.");
|
||||
is(innerNodes[0].querySelector(".value").getAttribute("value"), "HTMLButtonElement",
|
||||
"Should have the right property value for 'this'.");
|
||||
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
|
||||
isnot(gDebugger.gThreadClient.state, "paused",
|
||||
"Should not be paused after resuming.");
|
||||
ok(isCaretPos(gPanel, 26),
|
||||
"Should be idle on the debugger statement.");
|
||||
|
||||
ok(true, "Frames were cleared, debugger didn't pause again.");
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
|
||||
return finished;
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
|
||||
return finished;
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee.window);
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
function enablePauseOnExceptions() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("resumed", () => {
|
||||
is(gPrefs.pauseOnExceptions, true,
|
||||
"The pause-on-exceptions pref should now be enabled.");
|
||||
is(gOptions._pauseOnExceptionsItem.getAttribute("checked"), "true",
|
||||
"The pause-on-exceptions menu item should now be checked.");
|
||||
|
||||
ok(true, "Pausing on exceptions was enabled.");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
gOptions._pauseOnExceptionsItem.setAttribute("checked", "true");
|
||||
gOptions._togglePauseOnExceptions();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function disablePauseOnExceptions() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("resumed", () => {
|
||||
is(gPrefs.pauseOnExceptions, false,
|
||||
"The pause-on-exceptions pref should now be disabled.");
|
||||
isnot(gOptions._pauseOnExceptionsItem.getAttribute("checked"), "true",
|
||||
"The pause-on-exceptions menu item should now be unchecked.");
|
||||
|
||||
ok(true, "Pausing on exceptions was disabled.");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
gOptions._pauseOnExceptionsItem.setAttribute("checked", "false");
|
||||
gOptions._togglePauseOnExceptions();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function enableIgnoreCaughtExceptions() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("resumed", () => {
|
||||
is(gPrefs.ignoreCaughtExceptions, true,
|
||||
"The ignore-caught-exceptions pref should now be enabled.");
|
||||
is(gOptions._ignoreCaughtExceptionsItem.getAttribute("checked"), "true",
|
||||
"The ignore-caught-exceptions menu item should now be checked.");
|
||||
|
||||
ok(true, "Ignore caught exceptions was enabled.");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
gOptions._ignoreCaughtExceptionsItem.setAttribute("checked", "true");
|
||||
gOptions._toggleIgnoreCaughtExceptions();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function disableIgnoreCaughtExceptions() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("resumed", () => {
|
||||
is(gPrefs.ignoreCaughtExceptions, false,
|
||||
"The ignore-caught-exceptions pref should now be disabled.");
|
||||
isnot(gOptions._ignoreCaughtExceptionsItem.getAttribute("checked"), "true",
|
||||
"The ignore-caught-exceptions menu item should now be unchecked.");
|
||||
|
||||
ok(true, "Ignore caught exceptions was disabled.");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
gOptions._ignoreCaughtExceptionsItem.setAttribute("checked", "false");
|
||||
gOptions._toggleIgnoreCaughtExceptions();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gFrames = null;
|
||||
gVariables = null;
|
||||
gPrefs = null;
|
||||
gOptions = null;
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user