Back out 34c9087517ea (bug 1200798) for e10s bustage in browser_dbg_reload-same-script.js

CLOSED TREE
This commit is contained in:
Phil Ringnalda 2015-11-25 21:39:05 -08:00
Родитель ffa084a90a
Коммит feae2f167e
131 изменённых файлов: 6766 добавлений и 6469 удалений

Просмотреть файл

@ -1,169 +0,0 @@
/* 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/. */
"use strict";
const constants = require('../constants');
const promise = require('promise');
const { asPaused, rdpInvoke } = require('../utils');
const { PROMISE } = require('devtools/client/shared/redux/middleware/promise');
const {
getSource, getBreakpoint, getBreakpoints, makeLocationId
} = require('../queries');
// Because breakpoints are just simple data structures, we still need
// a way to lookup the actual client instance to talk to the server.
// We keep an internal database of clients based off of actor ID.
const BREAKPOINT_CLIENT_STORE = new Map();
function setBreakpointClient(actor, client) {
BREAKPOINT_CLIENT_STORE.set(actor, client);
}
function getBreakpointClient(actor) {
return BREAKPOINT_CLIENT_STORE.get(actor);
}
function enableBreakpoint(location) {
// Enabling is exactly the same as adding. It will use the existing
// breakpoint that still stored.
return addBreakpoint(location);
}
function _breakpointExists(state, location) {
const currentBp = getBreakpoint(state, location);
return currentBp && !currentBp.disabled;
}
function _getOrCreateBreakpoint(state, location, condition) {
return getBreakpoint(state, location) || { location, condition };
}
function addBreakpoint(location, condition) {
return (dispatch, getState) => {
if(_breakpointExists(getState(), location)) {
return;
}
const bp = _getOrCreateBreakpoint(getState(), location, condition);
return dispatch({
type: constants.ADD_BREAKPOINT,
breakpoint: bp,
condition: condition,
[PROMISE]: Task.spawn(function*() {
const sourceClient = gThreadClient.source(
getSource(getState(), bp.location.actor)
);
const [response, bpClient] = yield rdpInvoke(sourceClient, sourceClient.setBreakpoint, {
line: bp.location.line,
column: bp.location.column,
condition: bp.condition
});
const { isPending, actualLocation } = response;
// Save the client instance
setBreakpointClient(bpClient.actor, bpClient);
return {
text: DebuggerView.editor.getText(bp.location.line - 1).trim(),
// If the breakpoint response has an "actualLocation" attached, then
// the original requested placement for the breakpoint wasn't
// accepted.
actualLocation: isPending ? null : actualLocation,
actor: bpClient.actor
};
})
});
}
}
function disableBreakpoint(location) {
return _removeOrDisableBreakpoint(location, true);
}
function removeBreakpoint(location) {
return _removeOrDisableBreakpoint(location);
}
function _removeOrDisableBreakpoint(location, isDisabled) {
return (dispatch, getState) => {
let bp = getBreakpoint(getState(), location);
if (!bp) {
throw new Error('attempt to remove breakpoint that does not exist');
}
if (bp.loading) {
// TODO(jwl): make this wait until the breakpoint is saved if it
// is still loading
throw new Error('attempt to remove unsaved breakpoint');
}
const bpClient = getBreakpointClient(bp.actor);
return dispatch({
type: constants.REMOVE_BREAKPOINT,
breakpoint: bp,
disabled: isDisabled,
[PROMISE]: rdpInvoke(bpClient, bpClient.remove)
});
}
}
function removeAllBreakpoints() {
return (dispatch, getState) => {
const breakpoints = getBreakpoints(getState());
const activeBreakpoints = breakpoints.filter(bp => !bp.disabled);
activeBreakpoints.forEach(bp => removeBreakpoint(bp.location));
}
}
/**
* Update the condition of a breakpoint.
*
* @param object aLocation
* @see DebuggerController.Breakpoints.addBreakpoint
* @param string aClients
* The condition to set on the breakpoint
* @return object
* A promise that will be resolved with the breakpoint client
*/
function setBreakpointCondition(location, condition) {
return (dispatch, getState) => {
const bp = getBreakpoint(getState(), location);
if (!bp) {
throw new Error("Breakpoint does not exist at the specified location");
}
if (bp.loading){
// TODO(jwl): when this function is called, make sure the action
// creator waits for the breakpoint to exist
throw new Error("breakpoint must be saved");
}
const bpClient = getBreakpointClient(bp.actor);
return dispatch({
type: constants.SET_BREAKPOINT_CONDITION,
breakpoint: bp,
condition: condition,
[PROMISE]: Task.spawn(function*() {
const newClient = yield bpClient.setCondition(gThreadClient, condition);
// Remove the old instance and save the new one
setBreakpointClient(bpClient.actor, null);
setBreakpointClient(newClient.actor, newClient);
return { actor: newClient.actor };
})
});
};
}
module.exports = {
enableBreakpoint,
addBreakpoint,
disableBreakpoint,
removeBreakpoint,
removeAllBreakpoints,
setBreakpointCondition
}

Просмотреть файл

@ -4,7 +4,5 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'breakpoints.js',
'event-listeners.js',
'sources.js'
)

Просмотреть файл

@ -1,283 +0,0 @@
/* 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/. */
"use strict";
const constants = require('../constants');
const promise = require('promise');
const { rdpInvoke } = require('../utils');
const { dumpn } = require("devtools/shared/DevToolsUtils");
const { PROMISE, HISTOGRAM_ID } = require('devtools/client/shared/redux/middleware/promise');
const { getSource, getSourceText } = require('../queries');
const NEW_SOURCE_IGNORED_URLS = ["debugger eval code", "XStringBundle"];
const FETCH_SOURCE_RESPONSE_DELAY = 200; // ms
function getSourceClient(source) {
return gThreadClient.source(source);
}
/**
* Handler for the debugger client's unsolicited newSource notification.
*/
function newSource(source) {
return dispatch => {
// Ignore bogus scripts, e.g. generated from 'clientEvaluate' packets.
if (NEW_SOURCE_IGNORED_URLS.indexOf(source.url) != -1) {
return;
}
// Signal that a new source has been added.
window.emit(EVENTS.NEW_SOURCE);
return dispatch({
type: constants.ADD_SOURCE,
source: source
});
};
}
function selectSource(source, opts) {
return (dispatch, getState) => {
if(!gThreadClient) {
// No connection, do nothing. This happens when the debugger is
// shut down too fast and it tries to display a default source.
return;
}
source = getSource(getState(), source.actor);
// Make sure to start a request to load the source text.
dispatch(loadSourceText(source));
dispatch({
type: constants.SELECT_SOURCE,
source: source,
opts: opts
});
};
}
function loadSources() {
return {
type: constants.LOAD_SOURCES,
[PROMISE]: Task.spawn(function*() {
const response = yield rdpInvoke(gThreadClient, gThreadClient.getSources);
// Top-level breakpoints may pause the entire loading process
// because scripts are executed as they are loaded, so the
// engine may pause in the middle of loading all the sources.
// This is relatively harmless, as individual `newSource`
// notifications are fired for each script and they will be
// added to the UI through that.
if(!response.sources) {
dumpn(
"Error getting sources, probably because a top-level " +
"breakpoint was hit while executing them"
);
return;
}
// Ignore bogus scripts, e.g. generated from 'clientEvaluate' packets.
return response.sources.filter(source => {
return NEW_SOURCE_IGNORED_URLS.indexOf(source.url) === -1;
});
})
}
}
/**
* Set the black boxed status of the given source.
*
* @param Object aSource
* The source form.
* @param bool aBlackBoxFlag
* True to black box the source, false to un-black box it.
* @returns Promise
* A promize that resolves to [aSource, isBlackBoxed] or rejects to
* [aSource, error].
*/
function blackbox(source, shouldBlackBox) {
const client = getSourceClient(source);
return {
type: constants.BLACKBOX,
source: source,
[PROMISE]: Task.spawn(function*() {
yield rdpInvoke(client,
shouldBlackBox ? client.blackBox : client.unblackBox);
return {
isBlackBoxed: shouldBlackBox
}
})
};
}
/**
* Toggle the pretty printing of a source's text. All subsequent calls to
* |getText| will return the pretty-toggled text. Nothing will happen for
* non-javascript files.
*
* @param Object aSource
* The source form from the RDP.
* @returns Promise
* A promise that resolves to [aSource, prettyText] or rejects to
* [aSource, error].
*/
function togglePrettyPrint(source) {
return (dispatch, getState) => {
const sourceClient = getSourceClient(source);
const wantPretty = !source.isPrettyPrinted;
return dispatch({
type: constants.TOGGLE_PRETTY_PRINT,
source: source,
[PROMISE]: Task.spawn(function*() {
let response;
// Only attempt to pretty print JavaScript sources.
const sourceText = getSourceText(getState(), source.actor);
const contentType = sourceText ? sourceText.contentType : null;
if (!SourceUtils.isJavaScript(source.url, contentType)) {
throw new Error("Can't prettify non-javascript files.");
}
if(wantPretty) {
response = yield rdpInvoke(sourceClient,
sourceClient.prettyPrint,
Prefs.editorTabSize);
}
else {
response = yield rdpInvoke(sourceClient,
sourceClient.disablePrettyPrint);
}
// Remove the cached source AST from the Parser, to avoid getting
// wrong locations when searching for functions.
DebuggerController.Parser.clearSource(source.url);
return {
isPrettyPrinted: wantPretty,
text: response.source,
contentType: response.contentType
};
})
});
};
}
function loadSourceText(source) {
return (dispatch, getState) => {
// Fetch the source text only once.
let textInfo = getSourceText(getState(), source.actor);
if (textInfo) {
// It's already loaded or is loading
return promise.resolve(textInfo);
}
const sourceClient = getSourceClient(source);
return dispatch({
type: constants.LOAD_SOURCE_TEXT,
source: source,
[PROMISE]: Task.spawn(function*() {
let transportType = gClient.localTransport ? "_LOCAL" : "_REMOTE";
let histogramId = "DEVTOOLS_DEBUGGER_DISPLAY_SOURCE" + transportType + "_MS";
let histogram = Services.telemetry.getHistogramById(histogramId);
let startTime = Date.now();
const response = yield rdpInvoke(sourceClient, sourceClient.source);
histogram.add(Date.now() - startTime);
// Automatically pretty print if enabled and the test is
// detected to be "minified"
if (Prefs.autoPrettyPrint &&
!source.isPrettyPrinted &&
SourceUtils.isMinified(source.actor, response.source)) {
dispatch(togglePrettyPrint(source));
}
return { text: response.source,
contentType: response.contentType };
})
});
}
}
/**
* Starts fetching all the sources, silently.
*
* @param array aUrls
* The urls for the sources to fetch. If fetching a source's text
* takes too long, it will be discarded.
* @return object
* A promise that is resolved after source texts have been fetched.
*/
function getTextForSources(actors) {
return (dispatch, getState) => {
let deferred = promise.defer();
let pending = new Set(actors);
let fetched = [];
// Can't use promise.all, because if one fetch operation is rejected, then
// everything is considered rejected, thus no other subsequent source will
// be getting fetched. We don't want that. Something like Q's allSettled
// would work like a charm here.
// Try to fetch as many sources as possible.
for (let actor of actors) {
let source = getSource(getState(), actor);
dispatch(loadSourceText(source)).then(({ text, contentType }) => {
onFetch([source, text, contentType]);
}, err => {
onError(source, err);
});
}
setTimeout(onTimeout, FETCH_SOURCE_RESPONSE_DELAY);
/* Called if fetching a source takes too long. */
function onTimeout() {
pending = new Set();
maybeFinish();
}
/* Called if fetching a source finishes successfully. */
function onFetch([aSource, aText, aContentType]) {
// If fetching the source has previously timed out, discard it this time.
if (!pending.has(aSource.actor)) {
return;
}
pending.delete(aSource.actor);
fetched.push([aSource.actor, aText, aContentType]);
maybeFinish();
}
/* Called if fetching a source failed because of an error. */
function onError([aSource, aError]) {
pending.delete(aSource.actor);
maybeFinish();
}
/* Called every time something interesting happens while fetching sources. */
function maybeFinish() {
if (pending.size == 0) {
// Sort the fetched sources alphabetically by their url.
deferred.resolve(fetched.sort(([aFirst], [aSecond]) => aFirst > aSecond));
}
}
return deferred.promise;
};
}
module.exports = {
newSource,
selectSource,
loadSources,
blackbox,
togglePrettyPrint,
loadSourceText,
getTextForSources
};

Просмотреть файл

@ -5,19 +5,3 @@
exports.UPDATE_EVENT_BREAKPOINTS = 'UPDATE_EVENT_BREAKPOINTS';
exports.FETCH_EVENT_LISTENERS = 'FETCH_EVENT_LISTENERS';
exports.TOGGLE_PRETTY_PRINT = 'TOGGLE_PRETTY_PRINT';
exports.BLACKBOX = 'BLACKBOX';
exports.ADD_BREAKPOINT = 'ADD_BREAKPOINT';
exports.REMOVE_BREAKPOINT = 'REMOVE_BREAKPOINT';
exports.ENABLE_BREAKPOINT = 'ENABLE_BREAKPOINT';
exports.DISABLE_BREAKPOINT = 'DISABLE_BREAKPOINT';
exports.SET_BREAKPOINT_CONDITION = 'SET_BREAKPOINT_CONDITION'
exports.ADD_SOURCE = 'ADD_SOURCE';
exports.LOAD_SOURCES = 'LOAD_SOURCES';
exports.LOAD_SOURCE_TEXT = 'LOAD_SOURCE_TEXT';
exports.SELECT_SOURCE = 'SELECT_SOURCE';
exports.UNLOAD = 'UNLOAD';
exports.RELOAD = 'RELOAD';

Просмотреть файл

@ -5,12 +5,5 @@
const constants = require('./constants');
// Fired when the page is being unloaded, for example when it's being
// navigated away from.
function unload() {
return {
type: constants.UNLOAD
}
}
module.exports = { unload };
// No global actions right now, but I'm sure there will be soon.
module.exports = {};

Просмотреть файл

@ -12,6 +12,5 @@ DIRS += [
DevToolsModules(
'constants.js',
'globalActions.js',
'queries.js',
'utils.js'
)

Просмотреть файл

@ -1,70 +0,0 @@
function getSource(state, actor) {
return state.sources.sources[actor];
}
function getSources(state) {
return state.sources.sources;
}
function getSourceCount(state) {
return Object.keys(state.sources.sources).length;
}
function getSourceByURL(state, url) {
for(let k in state.sources.sources) {
const source = state.sources.sources[k];
if(source.url === url) {
return source;
}
}
}
function getSourceByActor(state, actor) {
for(let k in state.sources.sources) {
const source = state.sources.sources[k];
if(source.actor === actor) {
return source;
}
}
}
function getSelectedSource(state) {
return state.sources.sources[state.sources.selectedSource];
}
function getSelectedSourceOpts(state) {
return state.sources.selectedSourceOpts;
}
function getSourceText(state, actor) {
return state.sources.sourcesText[actor];
}
function getBreakpoints(state) {
return Object.keys(state.breakpoints.breakpoints).map(k => {
return state.breakpoints.breakpoints[k];
});
}
function getBreakpoint(state, location) {
return state.breakpoints.breakpoints[makeLocationId(location)];
}
function makeLocationId(location) {
return location.actor + ':' + location.line.toString();
}
module.exports = {
getSource,
getSources,
getSourceCount,
getSourceByURL,
getSourceByActor,
getSelectedSource,
getSelectedSourceOpts,
getSourceText,
getBreakpoint,
getBreakpoints,
makeLocationId
};

Просмотреть файл

@ -1,27 +0,0 @@
/* 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/. */
"use strict";
const initialState = {
openRequests: []
};
function update(state = initialState, action, emitChange) {
const { seqId } = action;
if(seqId) {
if(action.status === 'start') {
state.openRequests.push(seqId);
}
else if(action.status === 'error' || action.status === 'done') {
state.openRequests = state.openRequests.filter(id => id !== seqId);
}
emitChange('open-requests', state.openRequests);
}
return state;
}
module.exports = update;

Просмотреть файл

@ -1,128 +0,0 @@
/* 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/. */
"use strict";
const constants = require('../constants');
const Immutable = require('devtools/client/shared/vendor/seamless-immutable');
const { mergeIn, setIn, deleteIn } = require('../utils');
const { makeLocationId } = require('../queries');
const initialState = Immutable({
breakpoints: {}
});
function update(state = initialState, action, emitChange) {
switch(action.type) {
case constants.ADD_BREAKPOINT: {
const id = makeLocationId(action.breakpoint.location);
if(action.status === 'start') {
const existingBp = state.breakpoints[id];
const bp = existingBp || Immutable(action.breakpoint);
state = setIn(state, ['breakpoints', id], bp.merge({
disabled: false,
loading: true,
condition: action.condition || bp.condition || undefined
}));
emitChange(existingBp ? "breakpoint-enabled" : "breakpoint-added",
state.breakpoints[id]);
return state;
}
else if(action.status === 'done') {
const { actor, text } = action.value;
let { actualLocation } = action.value;
// If the breakpoint moved, update the map
if(actualLocation) {
// XXX Bug 1227417: The `setBreakpoint` RDP request rdp
// request returns an `actualLocation` field that doesn't
// conform to the regular { actor, line } location shape, but
// it has a `source` field. We should fix that.
actualLocation = { actor: actualLocation.source.actor,
line: actualLocation.line };
state = deleteIn(state, ['breakpoints', id]);
const movedId = makeLocationId(actualLocation);
const currentBp = state.breakpoints[movedId] || Immutable(action.breakpoint);
const prevLocation = action.breakpoint.location;
const newBp = currentBp.merge({ location: actualLocation });
state = setIn(state, ['breakpoints', movedId], newBp);
emitChange('breakpoint-moved', {
breakpoint: newBp,
prevLocation: prevLocation
});
}
const finalLocation = (
actualLocation ? actualLocation : action.breakpoint.location
);
const finalLocationId = makeLocationId(finalLocation);
state = mergeIn(state, ['breakpoints', finalLocationId], {
disabled: false,
loading: false,
actor: actor,
text: text
});
emitChange('breakpoint-updated', state.breakpoints[finalLocationId]);
return state;
}
else if(action.status === 'error') {
// Remove the optimistic update
emitChange('breakpoint-removed', state.breakpoints[id]);
return deleteIn(state, ['breakpoints', id]);
}
break;
}
case constants.REMOVE_BREAKPOINT: {
if(action.status === 'done') {
const id = makeLocationId(action.breakpoint.location);
const bp = state.breakpoints[id];
if(action.disabled) {
state = mergeIn(state, ['breakpoints', id],
{ loading: false, disabled: true });
emitChange('breakpoint-disabled', state.breakpoints[id]);
return state;
}
state = deleteIn(state, ['breakpoints', id]);
emitChange('breakpoint-removed', bp);
return state;
}
break;
}
case constants.SET_BREAKPOINT_CONDITION: {
const id = makeLocationId(action.breakpoint.location);
const bp = state.breakpoints[id];
if(action.status === 'start') {
return mergeIn(state, ['breakpoints', id], {
loading: true,
condition: action.condition
});
}
else if(action.status === 'done') {
return mergeIn(state, ['breakpoints', id], {
loading: false,
// Setting a condition creates a new breakpoint client as of
// now, so we need to update the actor
actor: action.value.actor
});
}
else if(action.status === 'error') {
return deleteIn(state, ['breakpoints', id]);
}
break;
}}
return state;
}
module.exports = update;

Просмотреть файл

@ -17,7 +17,7 @@ function update(state = initialState, action, emit) {
switch(action.type) {
case constants.UPDATE_EVENT_BREAKPOINTS:
state.activeEventNames = action.eventNames;
emit("activeEventNames", state.activeEventNames);
emit("@redux:activeEventNames", state.activeEventNames);
break;
case constants.FETCH_EVENT_LISTENERS:
if (action.status === "begin") {
@ -26,7 +26,7 @@ function update(state = initialState, action, emit) {
else if (action.status === "done") {
state.fetchingListeners = false;
state.listeners = action.listeners;
emit("event-listeners", state.listeners);
emit("@redux:listeners", state.listeners);
}
break;
}

Просмотреть файл

@ -4,13 +4,5 @@
"use strict";
const eventListeners = require('./event-listeners');
const sources = require('./sources');
const breakpoints = require('./breakpoints');
const asyncRequests = require('./async-requests');
module.exports = {
eventListeners,
sources,
breakpoints,
asyncRequests
};
exports.eventListeners = eventListeners;

Просмотреть файл

@ -4,9 +4,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'async-requests.js',
'breakpoints.js',
'event-listeners.js',
'index.js',
'sources.js'
'index.js'
)

Просмотреть файл

@ -1,117 +0,0 @@
/* 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/. */
"use strict";
const constants = require('../constants');
const Immutable = require('devtools/client/shared/vendor/seamless-immutable');
const { mergeIn, setIn } = require('../utils');
const initialState = Immutable({
sources: {},
selectedSource: null,
selectedSourceOpts: null,
sourcesText: {}
});
function update(state = initialState, action, emitChange) {
switch(action.type) {
case constants.ADD_SOURCE:
emitChange('source', action.source);
return mergeIn(state, ['sources', action.source.actor], action.source);
case constants.LOAD_SOURCES:
if(action.status === 'done') {
// We don't need to actually load the sources into the state.
// Loading sources actually forces the server to emit several
// individual newSources packets which will eventually fire
// ADD_SOURCE actions.
//
// We still emit this event so that the UI can show an "empty
// text" label if no sources were loaded.
emitChange('sources', state.sources);
}
break;
case constants.SELECT_SOURCE:
emitChange('source-selected', action.source);
return state.merge({
selectedSource: action.source.actor,
selectedSourceOpts: action.opts
});
case constants.LOAD_SOURCE_TEXT: {
const s = _updateText(state, action);
emitChange('source-text-loaded', s.sources[action.source.actor]);
return s;
}
case constants.BLACKBOX:
if(action.status === 'done') {
const s = mergeIn(state,
['sources', action.source.actor, 'isBlackBoxed'],
action.value.isBlackBoxed);
emitChange('blackboxed', s.sources[action.source.actor]);
return s;
}
break;
case constants.TOGGLE_PRETTY_PRINT:
let s = state;
if(action.status === "error") {
s = mergeIn(state, ['sourcesText', action.source.actor], {
loading: false
});
// If it errored, just display the source as it way before.
emitChange('prettyprinted', s.sources[action.source.actor]);
}
else {
s = _updateText(state, action);
// Don't do this yet, the progress bar is still imperatively shown
// from the source view. We will fix in the next iteration.
// emitChange('source-text-loaded', s.sources[action.source.actor]);
if(action.status === 'done') {
s = mergeIn(s,
['sources', action.source.actor, 'isPrettyPrinted'],
action.value.isPrettyPrinted);
emitChange('prettyprinted', s.sources[action.source.actor]);
}
}
return s;
case constants.UNLOAD:
// Reset the entire state to just the initial state, a blank state
// if you will.
return initialState;
}
return state;
}
function _updateText(state, action) {
const { source } = action;
if(action.status === 'start') {
// Merge this in, don't set it. That way the previous value is
// still stored here, and we can retrieve it if whatever we're
// doing fails.
return mergeIn(state, ['sourcesText', source.actor], {
loading: true
});
}
else if(action.status === 'error') {
return setIn(state, ['sourcesText', source.actor], {
error: action.error
});
}
else {
return setIn(state, ['sourcesText', source.actor], {
text: action.value.text,
contentType: action.value.contentType
});
}
}
module.exports = update;

Просмотреть файл

@ -6,21 +6,16 @@
const { promiseInvoke } = require("devtools/shared/async-utils");
const { reportException } = require("devtools/shared/DevToolsUtils");
// RDP utils
function rdpInvoke(client, method, ...args) {
return (promiseInvoke(client, method, ...args)
return promiseInvoke(client, method, ...args)
.then((packet) => {
if (packet.error) {
let { error, message } = packet;
const err = new Error(error + ": " + message);
err.rdpError = error;
err.rdpMessage = message;
throw err;
let { error, message } = packet;
if (error) {
throw new Error(error + ": " + message);
}
return packet;
}));
});
}
function asPaused(client, func) {
@ -47,58 +42,4 @@ function asPaused(client, func) {
}
}
function handleError(err) {
reportException("promise", err.toString());
}
function onReducerEvents(controller, listeners, thisContext) {
Object.keys(listeners).forEach(name => {
const listener = listeners[name];
controller.onChange(name, payload => {
listener.call(thisContext, payload);
});
});
}
function _getIn(destObj, path) {
return path.reduce(function(acc, name) {
return acc[name];
}, destObj);
}
function mergeIn(destObj, path, value) {
path = [...path];
path.reverse();
var obj = path.reduce(function(acc, name) {
return { [name]: acc };
}, value);
return destObj.merge(obj, { deep: true });
}
function setIn(destObj, path, value) {
destObj = mergeIn(destObj, path, null);
return mergeIn(destObj, path, value);
}
function updateIn(destObj, path, fn) {
return setIn(destObj, path, fn(_getIn(destObj, path)));
}
function deleteIn(destObj, path) {
const objPath = path.slice(0, -1);
const propName = path[path.length - 1];
const obj = _getIn(destObj, objPath);
return setIn(destObj, objPath, obj.without(propName));
}
module.exports = {
rdpInvoke,
asPaused,
handleError,
onReducerEvents,
mergeIn,
setIn,
updateIn,
deleteIn
};
module.exports = { rdpInvoke, asPaused };

Просмотреть файл

@ -9,16 +9,19 @@ const { bindActionCreators } = require('devtools/client/shared/vendor/redux');
/**
* Functions handling the event listeners UI.
*/
function EventListenersView(controller) {
function EventListenersView(store, DebuggerController) {
dumpn("EventListenersView was instantiated");
this.actions = bindActionCreators(actions, controller.dispatch);
this.getState = () => controller.getState().eventListeners;
this.actions = bindActionCreators(actions, store.dispatch);
this.getState = () => store.getState().eventListeners;
this._onCheck = this._onCheck.bind(this);
this._onClick = this._onClick.bind(this);
this._onListeners = this._onListeners.bind(this);
controller.onChange("event-listeners", this.renderListeners.bind(this));
this.Breakpoints = DebuggerController.Breakpoints;
this.controller = DebuggerController;
this.controller.on("@redux:listeners", this._onListeners);
}
EventListenersView.prototype = Heritage.extend(WidgetMethods, {
@ -49,8 +52,10 @@ EventListenersView.prototype = Heritage.extend(WidgetMethods, {
destroy: function() {
dumpn("Destroying the EventListenersView");
this.controller.off("@redux:listeners", this._onListeners);
this.widget.removeEventListener("check", this._onCheck, false);
this.widget.removeEventListener("click", this._onClick, false);
this.controller = this.Breakpoints = null;
},
renderListeners: function(listeners) {
@ -281,6 +286,13 @@ EventListenersView.prototype = Heritage.extend(WidgetMethods, {
}
},
/**
* Called when listeners change.
*/
_onListeners: function(_, listeners) {
this.renderListeners(listeners);
},
_eventCheckboxTooltip: "",
_onSelectorString: "",
_inSourceString: "",

Просмотреть файл

@ -4,6 +4,5 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'event-listeners-view.js',
'sources-view.js'
'event-listeners-view.js'
)

Просмотреть файл

@ -537,15 +537,17 @@ exports.items.push({
const blackBoxed = [];
for (let source of toBlackBox) {
dbg.blackbox(source, cmd.clientMethod === "blackBox").then(() => {
blackBoxed.push(source.url);
}, err => {
blackBoxed.push(lookup("ErrorDesc") + " " + source.url);
}).then(() => {
activeThread.source(source)[cmd.clientMethod](function({ error }) {
if (error) {
blackBoxed.push(lookup("ErrorDesc") + " " + source.url);
} else {
blackBoxed.push(source.url);
}
if (toBlackBox.length === blackBoxed.length) {
displayResults();
}
})
});
}
// List the results for the user.

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -10,6 +10,10 @@ 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_SCROLL_DELAY = 100; // ms
const BREAKPOINT_LINE_TOOLTIP_MAX_LENGTH = 1000; // chars
const BREAKPOINT_CONDITIONAL_POPUP_POSITION = "before_start";
const BREAKPOINT_CONDITIONAL_POPUP_OFFSET_X = 7; // px
const BREAKPOINT_CONDITIONAL_POPUP_OFFSET_Y = -3; // px
const BREAKPOINT_SMALL_WINDOW_WIDTH = 850; // px
const RESULTS_PANEL_POPUP_POSITION = "before_end";
const RESULTS_PANEL_MAX_RESULTS = 10;
@ -27,21 +31,37 @@ const SEARCH_AUTOFILL = [SEARCH_GLOBAL_FLAG, SEARCH_FUNCTION_FLAG, SEARCH_TOKEN_
const EDITOR_VARIABLE_HOVER_DELAY = 750; // ms
const EDITOR_VARIABLE_POPUP_POSITION = "topcenter bottomleft";
const TOOLBAR_ORDER_POPUP_POSITION = "topcenter bottomleft";
const FUNCTION_SEARCH_POPUP_POSITION = "topcenter bottomleft";
const RESIZE_REFRESH_RATE = 50; // ms
const PROMISE_DEBUGGER_URL =
"chrome://devtools/content/promisedebugger/promise-debugger.xhtml";
const debuggerControllerEmit = DebuggerController.emit.bind(DebuggerController);
const createStore = require("devtools/client/shared/redux/create-store")();
const { combineEmittingReducers } = require("devtools/client/shared/redux/reducers");
const reducers = require("./content/reducers/index");
const store = createStore(combineEmittingReducers(reducers, debuggerControllerEmit));
const { NAME: WAIT_UNTIL_NAME } = require("devtools/client/shared/redux/middleware/wait-service");
const services = {
WAIT_UNTIL: WAIT_UNTIL_NAME
};
const EventListenersView = require('./content/views/event-listeners-view');
const SourcesView = require('./content/views/sources-view');
var actions = Object.assign(
{},
require('./content/globalActions'),
require('./content/actions/breakpoints'),
require('./content/actions/sources'),
require('./content/actions/event-listeners')
);
var queries = require('./content/queries');
var constants = require('./content/constants');
const actions = require('./content/actions/event-listeners');
Object.defineProperties(this, {
"store": {
value: store,
enumerable: true,
writable: false
},
"services": {
value: services,
enumerable: true,
writable: false
}
});
/**
* Object defining the debugger view components.
@ -54,10 +74,12 @@ var DebuggerView = {
* A promise that is resolved when the view finishes initializing.
*/
initialize: function() {
if (this._hasStartup) {
return;
if (this._startup) {
return this._startup;
}
this._hasStartup = true;
let deferred = promise.defer();
this._startup = deferred.promise;
this._initializePanes();
this.Toolbar.initialize();
@ -72,36 +94,11 @@ var DebuggerView = {
this.EventListeners.initialize();
this.GlobalSearch.initialize();
this._initializeVariablesView();
this._initializeEditor();
this._editorSource = {};
this._initializeEditor(deferred.resolve);
document.title = L10N.getStr("DebuggerWindowTitle");
this.editor.on("cursorActivity", this.Sources._onEditorCursorActivity);
this.controller = DebuggerController;
const getState = this.controller.getState;
onReducerEvents(this.controller, {
"source-text-loaded": this.renderSourceText,
"source-selected": this.renderSourceText,
"blackboxed": this.renderBlackBoxed,
"prettyprinted": this.renderPrettyPrinted,
"breakpoint-added": this.addEditorBreakpoint,
"breakpoint-enabled": this.addEditorBreakpoint,
"breakpoint-disabled": this.removeEditorBreakpoint,
"breakpoint-removed": this.removeEditorBreakpoint,
"breakpoint-moved": ({ breakpoint, prevLocation }) => {
const selectedSource = queries.getSelectedSource(getState());
const { location } = breakpoint;
if(selectedSource &&
selectedSource.actor === location.actor) {
this.editor.moveBreakpoint(prevLocation.line - 1,
location.line - 1);
}
}
}, this);
return deferred.promise;
},
/**
@ -111,13 +108,14 @@ var DebuggerView = {
* A promise that is resolved when the view finishes destroying.
*/
destroy: function() {
if (this._hasShutdown) {
return;
if (this._shutdown) {
return this._shutdown;
}
this._hasShutdown = true;
window.removeEventListener("resize", this._onResize, false);
this.editor.off("cursorActivity", this.Sources._onEditorCursorActivity);
let deferred = promise.defer();
this._shutdown = deferred.promise;
this.Toolbar.destroy();
this.Options.destroy();
@ -131,11 +129,9 @@ var DebuggerView = {
this.GlobalSearch.destroy();
this._destroyPromiseDebugger();
this._destroyPanes();
this._destroyEditor(deferred.resolve);
this.editor.destroy();
this.editor = null;
this.controller.dispatch(actions.removeAllBreakpoints());
return deferred.promise;
},
/**
@ -154,6 +150,7 @@ var DebuggerView = {
this.showEditor = this.showEditor.bind(this);
this.showBlackBoxMessage = this.showBlackBoxMessage.bind(this);
this.showProgressBar = this.showProgressBar.bind(this);
this.maybeShowBlackBoxMessage = this.maybeShowBlackBoxMessage.bind(this);
this._onTabSelect = this._onInstrumentsPaneTabSelect.bind(this);
this._instrumentsPane.tabpanels.addEventListener("select", this._onTabSelect);
@ -273,7 +270,7 @@ var DebuggerView = {
* @param function aCallback
* Called after the editor finishes initializing.
*/
_initializeEditor: function() {
_initializeEditor: function(aCallback) {
dumpn("Initializing the DebuggerView editor");
let extraKeys = {};
@ -305,6 +302,7 @@ var DebuggerView = {
this.editor.appendTo(document.getElementById("editor")).then(() => {
this.editor.extend(DebuggerEditor);
this._loadingText = L10N.getStr("loadingText");
this._onEditorLoad(aCallback);
});
this.editor.on("gutterClick", (ev, line, button) => {
@ -313,52 +311,51 @@ var DebuggerView = {
if (button == 2) {
this.clickedLine = line;
}
else {
const source = queries.getSelectedSource(this.controller.getState());
if(source) {
const location = { actor: source.actor, line: line + 1 };
if (this.editor.hasBreakpoint(line)) {
this.controller.dispatch(actions.removeBreakpoint(location));
} else {
this.controller.dispatch(actions.addBreakpoint(location));
}
// Bug 1201008: Only add the breakpoint to the editor if we're currently
// looking at a source. Even if no source is loaded, you can
// interact with line 1 of the editor.
else if (DebuggerView.Sources.selectedValue) {
if (this.editor.hasBreakpoint(line)) {
this.editor.removeBreakpoint(line);
} else {
this.editor.addBreakpoint(line);
}
}
});
},
updateEditorBreakpoints: function(source) {
const breakpoints = queries.getBreakpoints(this.controller.getState());
const sources = queries.getSources(this.controller.getState());
/**
* 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(aCallback) {
dumpn("Finished loading the DebuggerView editor");
for (let bp of breakpoints) {
if (sources[bp.location.actor] && !bp.disabled) {
this.addEditorBreakpoint(bp);
}
else {
this.removeEditorBreakpoint(bp);
}
}
DebuggerController.Breakpoints.initialize().then(() => {
window.emit(EVENTS.EDITOR_LOADED, this.editor);
aCallback();
});
},
addEditorBreakpoint: function(breakpoint) {
const { location } = breakpoint;
const source = queries.getSelectedSource(this.controller.getState());
/**
* Destroys the Editor instance and also executes any necessary
* post-unload operations.
*
* @param function aCallback
* Called after the editor finishes destroying.
*/
_destroyEditor: function(aCallback) {
dumpn("Destroying the DebuggerView editor");
if(source &&
source.actor === location.actor &&
!breakpoint.disabled) {
this.editor.addBreakpoint(location.line - 1);
}
},
removeEditorBreakpoint: function (breakpoint) {
const { location } = breakpoint;
const source = queries.getSelectedSource(this.controller.getState());
if(source && source.actor === location.actor) {
this.editor.removeBreakpoint(location.line - 1);
}
DebuggerController.Breakpoints.destroy().then(() => {
window.emit(EVENTS.EDITOR_UNLOADED, this.editor);
this.editor.destroy();
this.editor = null;
aCallback();
});
},
/**
@ -382,6 +379,19 @@ var DebuggerView = {
this._editorDeck.selectedIndex = 2;
},
/**
* Show or hide the black box message vs. source editor depending on if the
* selected source is black boxed or not.
*/
maybeShowBlackBoxMessage: function() {
let { source } = DebuggerView.Sources.selectedItem.attachment;
if (gThreadClient.source(source).isBlackBoxed) {
this.showBlackBoxMessage();
} else {
this.showEditor();
}
},
/**
* Sets the currently displayed text contents in the source editor.
* This resets the mode and undo stack.
@ -429,119 +439,69 @@ var DebuggerView = {
this.editor.setMode(Editor.modes.text);
},
renderBlackBoxed: function(source) {
this._renderSourceText(
source,
queries.getSourceText(this.controller.getState(), source.actor)
);
},
renderPrettyPrinted: function(source) {
this._renderSourceText(
source,
queries.getSourceText(this.controller.getState(), source.actor)
);
},
renderSourceText: function(source) {
this._renderSourceText(
source,
queries.getSourceText(this.controller.getState(), source.actor),
queries.getSelectedSourceOpts(this.controller.getState())
);
},
_renderSourceText: function(source, textInfo, opts = {}) {
const selectedSource = queries.getSelectedSource(this.controller.getState());
if(!selectedSource || selectedSource.actor !== source.actor) {
return;
/**
* Sets the currently displayed source text in the editor.
*
* 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.
* @param object aFlags
* Additional options for setting the source. Supported options:
* - force: boolean forcing all text to be reshown in the editor
* @return object
* A promise that is resolved after the source text has been set.
*/
_setEditorSource: function(aSource, aFlags={}) {
// Avoid setting the same source text in the editor again.
if (this._editorSource.actor == aSource.actor && !aFlags.force) {
return this._editorSource.promise;
}
let transportType = gClient.localTransport ? "_LOCAL" : "_REMOTE";
let histogramId = "DEVTOOLS_DEBUGGER_DISPLAY_SOURCE" + transportType + "_MS";
let histogram = Services.telemetry.getHistogramById(histogramId);
let startTime = Date.now();
if(source.isBlackBoxed) {
this.showBlackBoxMessage();
setTimeout(() => {
window.emit(EVENTS.SOURCE_SHOWN, source);
}, 0);
return;
}
else {
this.showEditor();
}
let deferred = promise.defer();
if(textInfo.loading) {
this._setEditorText(L10N.getStr("loadingText"));
return;
}
else if(textInfo.error) {
let url = textInfo.error;
this._setEditorText(L10N.getStr("loadingText"));
this._editorSource = { actor: aSource.actor, promise: deferred.promise };
DebuggerController.SourceScripts.getText(aSource).then(([, aText, aContentType]) => {
// Avoid setting an unexpected source. This may happen when switching
// very fast between sources that haven't been fetched yet.
if (this._editorSource.actor != aSource.actor) {
return;
}
this._setEditorText(aText);
this._setEditorMode(aSource.url, aContentType, aText);
// Synchronize any other components with the currently displayed
// source.
DebuggerView.Sources.selectedValue = aSource.actor;
DebuggerController.Breakpoints.updateEditorBreakpoints();
histogram.add(Date.now() - startTime);
// Resolve and notify that a source file was shown.
window.emit(EVENTS.SOURCE_SHOWN, aSource);
deferred.resolve([aSource, aText, aContentType]);
},
([, aError]) => {
let url = aError;
let msg = L10N.getFormatStr("errorLoadingText2", url);
this._setEditorText(msg);
Cu.reportError(msg);
dumpn(msg);
this.showEditor();
window.emit(EVENTS.SOURCE_ERROR_SHOWN, source);
return;
}
// Reject and notify that there was an error showing the source file.
window.emit(EVENTS.SOURCE_ERROR_SHOWN, aSource);
deferred.reject([aSource, aError]);
});
// 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 (!('line' in opts)) {
let cachedFrames = DebuggerController.activeThread.cachedFrames;
let currentDepth = DebuggerController.StackFrames.currentFrameDepth;
let frame = cachedFrames[currentDepth];
if (frame && frame.source.actor == source.actor) {
opts.line = frame.where.line;
}
}
if (this._editorSource.actor === source.actor &&
this._editorSource.prettyPrinted === source.isPrettyPrinted &&
this._editorSource.blackboxed === source.isBlackBoxed) {
this.updateEditorPosition(opts);
return;
}
this._editorSource.actor = source.actor;
this._editorSource.prettyPrinted = source.isPrettyPrinted;
this._editorSource.blackboxed = source.isBlackBoxed;
let { text, contentType } = textInfo;
this._setEditorText(text);
this._setEditorMode(source.url, contentType, text);
this.updateEditorBreakpoints(source);
setTimeout(() => {
window.emit(EVENTS.SOURCE_SHOWN, source);
}, 0);
this.updateEditorPosition(opts);
},
updateEditorPosition: function(opts) {
let line = opts.line || 0;
// Line numbers in the source editor should start from 1. If
// invalid or not specified, then don't do anything.
if (line < 1) {
window.emit(EVENTS.EDITOR_LOCATION_SET);
return;
}
if (opts.charOffset) {
line += this.editor.getPosition(opts.charOffset).line;
}
if (opts.lineOffset) {
line += opts.lineOffset;
}
if (opts.moveCursor) {
let location = { line: line - 1, ch: opts.columnOffset || 0 };
this.editor.setCursor(location);
}
if (!opts.noDebug) {
this.editor.setDebugLocation(line - 1);
}
window.emit(EVENTS.EDITOR_LOCATION_SET);
return deferred.promise;
},
/**
@ -565,27 +525,58 @@ var DebuggerView = {
* @return object
* A promise that is resolved after the source text has been set.
*/
setEditorLocation: function(aActor, aLine, aFlags = {}) {
setEditorLocation: function(aActor, aLine = 0, aFlags = {}) {
// Avoid trying to set a source for a url that isn't known yet.
if (!this.Sources.containsValue(aActor)) {
throw new Error("Unknown source for the specified URL.");
return promise.reject(new Error("Unknown source for the specified URL."));
}
// 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 currentDepth = DebuggerController.StackFrames.currentFrameDepth;
let frame = cachedFrames[currentDepth];
if (frame && frame.source.actor == aActor) {
aLine = frame.where.line;
}
}
let sourceItem = this.Sources.getItemByValue(aActor);
let source = sourceItem.attachment.source;
let sourceForm = sourceItem.attachment.source;
// Make sure the requested source client is shown in the editor,
// then update the source editor's caret position and debug
// location.
this.controller.dispatch(actions.selectSource(source, {
line: aLine,
charOffset: aFlags.charOffset,
lineOffset: aFlags.lineOffset,
columnOffset: aFlags.columnOffset,
moveCursor: !aFlags.noCaret,
noDebug: aFlags.noDebug,
forceUpdate: aFlags.force
}));
this._editorLoc = { actor: sourceForm.actor };
// 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, aFlags).then(([,, aContentType]) => {
if (this._editorLoc.actor !== sourceForm.actor) {
return;
}
// Record the contentType learned from fetching
sourceForm.contentType = aContentType;
// Line numbers in the source editor should start from 1. If invalid
// or not specified, then don't do anything.
if (aLine < 1) {
window.emit(EVENTS.EDITOR_LOCATION_SET);
return;
}
if (aFlags.charOffset) {
aLine += this.editor.getPosition(aFlags.charOffset).line;
}
if (aFlags.lineOffset) {
aLine += aFlags.lineOffset;
}
if (!aFlags.noCaret) {
let location = { line: aLine -1, ch: aFlags.columnOffset || 0 };
this.editor.setCursor(location, aFlags.align);
}
if (!aFlags.noDebug) {
this.editor.setDebugLocation(aLine - 1);
}
window.emit(EVENTS.EDITOR_LOCATION_SET);
}).then(null, console.error);
},
/**
@ -655,7 +646,7 @@ var DebuggerView = {
*/
_onInstrumentsPaneTabSelect: function() {
if (this._instrumentsPane.selectedTab.id == "events-tab") {
this.controller.dispatch(actions.fetchEventListeners());
store.dispatch(actions.fetchEventListeners());
}
},
@ -780,6 +771,8 @@ var DebuggerView = {
this.Sources.emptyText = L10N.getStr("loadingSourcesText");
},
_startup: null,
_shutdown: null,
Toolbar: null,
Options: null,
Filtering: null,
@ -791,6 +784,7 @@ var DebuggerView = {
WatchExpressions: null,
EventListeners: null,
editor: null,
_editorSource: {},
_loadingText: "",
_body: null,
_editorDeck: null,
@ -954,5 +948,4 @@ ResultsPanelContainer.prototype = Heritage.extend(WidgetMethods, {
top: 0
});
DebuggerView.EventListeners = new EventListenersView(DebuggerController);
DebuggerView.Sources = new SourcesView(DebuggerController, DebuggerView);
DebuggerView.EventListeners = new EventListenersView(store, DebuggerController);

Просмотреть файл

@ -59,11 +59,3 @@
#source-progress {
flex: none;
}
#redux-devtools * {
display: block;
}
#redux-devtools span {
display: inline
}

Просмотреть файл

@ -495,6 +495,4 @@
</vbox>
</panel>
<script type="text/javascript" src="resource://gre/browser/modules/devtools/debugger/mocks.js"/>
<script type="text/javascript" src="resource://gre/browser/modules/devtools/debugger/mock-init.js"/>
</window>

Просмотреть файл

@ -101,44 +101,12 @@ DebuggerPanel.prototype = {
// DebuggerPanel API
addBreakpoint: function(location) {
const { actions } = this.panelWin;
const { dispatch } = this._controller;
// const deferred = promise.defer();
// dispatch({
// type: this.panelWin.services.WAIT_UNTIL,
// predicate: action => (
// action.type === this.panelWin.constants.ADD_BREAKPOINT &&
// action.status === "done"
// ),
// run: deferred.resolve
// });
return dispatch(actions.addBreakpoint(location));
// return deferred.promise;
addBreakpoint: function(aLocation, aOptions) {
return this._controller.Breakpoints.addBreakpoint(aLocation, aOptions);
},
removeBreakpoint: function(location) {
const { actions } = this.panelWin;
const { dispatch } = this._controller;
// const deferred = promise.defer();
// dispatch({
// type: this.panelWin.services.WAIT_UNTIL,
// predicate: action => (
// action.type === this.panelWin.constants.REMOVE_BREAKPOINT &&
// action.status === "done"
// ),
// run: deferred.resolve
// });
return dispatch(actions.removeBreakpoint(location));
// return deferred.promise;
},
blackbox: function(source, flag) {
const { actions } = this.panelWin;
const { dispatch } = this._controller;
return dispatch(actions.blackbox(source, flag))
removeBreakpoint: function(aLocation) {
return this._controller.Breakpoints.removeBreakpoint(aLocation);
},
handleHostChanged: function() {

Просмотреть файл

@ -40,7 +40,7 @@ function test(){
.then(testPrettyPrintButtonOn)
.then(() => {
// Switch to the second source.
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN, 2);
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
gSources.selectedIndex = 1;
return finished;
})
@ -96,6 +96,8 @@ function disableAutoPrettyPrint(){
gOptions._toggleAutoPrettyPrint();
gOptions._onPopupHidden();
info("Disabled auto pretty printing.");
// Wait for the pref update to be communicated to the server.
return waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
}
function testSourceIsPretty() {

Просмотреть файл

@ -29,8 +29,8 @@ function testBlackBoxSource() {
const bbButton = getBlackBoxButton(gPanel);
ok(!bbButton.checked, "Should not be black boxed by default");
return toggleBlackBoxing(gPanel).then(source => {
ok(source.isBlackBoxed, "The source should be black boxed now.");
return toggleBlackBoxing(gPanel).then(aSource => {
ok(aSource.isBlackBoxed, "The source should be black boxed now.");
ok(bbButton.checked, "The checkbox should no longer be checked.");
});
}

Просмотреть файл

@ -30,8 +30,8 @@ function test() {
}
function testBlackBoxSource() {
return toggleBlackBoxing(gPanel).then(source => {
ok(source.isBlackBoxed, "The source should be black boxed now.");
return toggleBlackBoxing(gPanel).then(aSource => {
ok(aSource.isBlackBoxed, "The source should be black boxed now.");
});
}

Просмотреть файл

@ -44,7 +44,7 @@ function testBlackBoxMessageShown() {
function clickStopBlackBoxingButton() {
// Give the test a chance to finish before triggering the click event.
executeSoon(() => getEditorBlackboxMessageButton().click());
return waitForDispatch(gPanel, gDebugger.constants.BLACKBOX);
return waitForThreadEvents(gPanel, "blackboxchange");
}
function testSourceEditorShownAgain() {

Просмотреть файл

@ -33,13 +33,11 @@ function test() {
function checkNavigationWhileNotFocused() {
checkState({ frame: 1, source: 1, line: 6 });
return Task.spawn(function*() {
EventUtils.sendKey("DOWN", gDebugger);
checkState({ frame: 1, source: 1, line: 7 });
EventUtils.sendKey("DOWN", gDebugger);
checkState({ frame: 1, source: 1, line: 7 });
EventUtils.sendKey("UP", gDebugger);
checkState({ frame: 1, source: 1, line: 6 });
});
EventUtils.sendKey("UP", gDebugger);
checkState({ frame: 1, source: 1, line: 6 });
}
function focusCurrentStackFrame() {
@ -53,6 +51,7 @@ function test() {
yield promise.all([
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
waitForSourceAndCaret(gPanel, "-01.js", 5),
waitForEditorLocationSet(gPanel),
EventUtils.sendKey("UP", gDebugger)
]);
checkState({ frame: 0, source: 0, line: 5 });
@ -64,6 +63,7 @@ function test() {
yield promise.all([
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
waitForSourceAndCaret(gPanel, "-02.js", 6),
waitForEditorLocationSet(gPanel),
EventUtils.sendKey("END", gDebugger)
]);
checkState({ frame: 1, source: 1, line: 6 });
@ -75,6 +75,7 @@ function test() {
yield promise.all([
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
waitForSourceAndCaret(gPanel, "-01.js", 5),
waitForEditorLocationSet(gPanel),
EventUtils.sendKey("HOME", gDebugger)
]);
checkState({ frame: 0, source: 0, line: 5 });

Просмотреть файл

@ -9,18 +9,23 @@
const TAB_URL = EXAMPLE_URL + "doc_script-eval.html";
function test() {
let gTab, gPanel, gDebugger;
let gSources, gBreakpoints;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gSources = gDebugger.DebuggerView.Sources;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
return Task.spawn(function*() {
yield waitForSourceShown(gPanel, "-eval.js");
is(gSources.values.length, 1, "Should have 1 source");
let hasFrames = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_REFILLED);
callInTab(gTab, "evalSourceWithDebugger");
yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
yield hasFrames;
is(gSources.values.length, 2, "Should have 2 sources");

Просмотреть файл

@ -12,8 +12,6 @@ function test() {
let gDebugger = aPanel.panelWin;
let gView = gDebugger.DebuggerView;
let gEvents = gView.EventListeners;
let gController = gDebugger.DebuggerController;
let constants = gDebugger.require('./content/constants');
gDebugger.on(gDebugger.EVENTS.EVENT_LISTENERS_FETCHED, () => {
ok(false, "Shouldn't have fetched any event listeners.");
@ -46,7 +44,7 @@ function test() {
function waitForSourcesAfterReload() {
return promise.all([
waitForDebuggerEvents(aPanel, gDebugger.EVENTS.NEW_SOURCE),
waitForDispatch(aPanel, gDebugger.constants.LOAD_SOURCES),
waitForDebuggerEvents(aPanel, gDebugger.EVENTS.SOURCES_ADDED),
waitForDebuggerEvents(aPanel, gDebugger.EVENTS.SOURCE_SHOWN)
]);
}

Просмотреть файл

@ -13,7 +13,7 @@ function test() {
let gDebugger = aPanel.panelWin;
let gView = gDebugger.DebuggerView;
let gEvents = gView.EventListeners;
let gController = gDebugger.DebuggerController;
let gStore = gDebugger.store;
let constants = gDebugger.require('./content/constants');
Task.spawn(function*() {
@ -26,7 +26,7 @@ function test() {
function testFetchOnFocus() {
return Task.spawn(function*() {
let fetched = waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
let fetched = afterDispatch(gStore, constants.FETCH_EVENT_LISTENERS);
gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
is(gView.instrumentsPaneHidden, false,
@ -45,7 +45,7 @@ function test() {
function testFetchOnReloadWhenFocused() {
return Task.spawn(function*() {
let fetched = waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
let fetched = afterDispatch(gStore, constants.FETCH_EVENT_LISTENERS);
let reloading = once(gDebugger.gTarget, "will-navigate");
let reloaded = waitForSourcesAfterReload();
@ -76,7 +76,7 @@ function test() {
function testFetchOnReloadWhenNotFocused() {
return Task.spawn(function*() {
gController.dispatch({
gStore.dispatch({
type: gDebugger.services.WAIT_UNTIL,
predicate: action => {
return (action.type === constants.FETCH_EVENT_LISTENERS ||
@ -129,7 +129,7 @@ function test() {
function waitForSourcesAfterReload() {
return promise.all([
waitForDebuggerEvents(aPanel, gDebugger.EVENTS.NEW_SOURCE),
waitForDispatch(aPanel, constants.LOAD_SOURCES),
waitForDebuggerEvents(aPanel, gDebugger.EVENTS.SOURCES_ADDED),
waitForDebuggerEvents(aPanel, gDebugger.EVENTS.SOURCE_SHOWN)
]);
}

Просмотреть файл

@ -12,13 +12,13 @@ function test() {
let gDebugger = aPanel.panelWin;
let gView = gDebugger.DebuggerView;
let gEvents = gView.EventListeners;
let gController = gDebugger.DebuggerController;
let gStore = gDebugger.store;
let constants = gDebugger.require('./content/constants');
Task.spawn(function*() {
yield waitForSourceShown(aPanel, ".html");
let fetched = waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
let fetched = afterDispatch(gStore, constants.FETCH_EVENT_LISTENERS);
gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
yield fetched;

Просмотреть файл

@ -14,12 +14,14 @@ function test() {
let gView = gDebugger.DebuggerView;
let gController = gDebugger.DebuggerController
let gEvents = gView.EventListeners;
let gStore = gDebugger.store;
let getState = gStore.getState;
let constants = gDebugger.require('./content/constants');
Task.spawn(function*() {
yield waitForSourceShown(aPanel, ".html");
let fetched = waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
let fetched = afterDispatch(gStore, constants.FETCH_EVENT_LISTENERS);
gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
yield fetched;
@ -32,7 +34,7 @@ function test() {
testEventGroup("mouseEvents", false);
testEventArrays("change,click,keydown,keyup", "");
let updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
let updated = afterDispatch(gStore, constants.UPDATE_EVENT_BREAKPOINTS);
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(0), gDebugger);
yield updated;
@ -45,7 +47,7 @@ function test() {
testEventGroup("mouseEvents", false);
testEventArrays("change,click,keydown,keyup", "change");
updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
updated = afterDispatch(gStore, constants.UPDATE_EVENT_BREAKPOINTS);
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(0), gDebugger);
yield updated;
@ -90,7 +92,7 @@ function test() {
"The getAllEvents() method returns the correct stuff.");
is(gEvents.getCheckedEvents().toString(), checked,
"The getCheckedEvents() method returns the correct stuff.");
is(gController.getState().eventListeners.activeEventNames.toString(), checked,
is(getState().eventListeners.activeEventNames.toString(), checked,
"The correct event names are listed as being active breakpoints.");
}
});

Просмотреть файл

@ -15,12 +15,14 @@ function test() {
let gView = gDebugger.DebuggerView;
let gController = gDebugger.DebuggerController
let gEvents = gView.EventListeners;
let gStore = gDebugger.store;
let getState = gStore.getState;
let constants = gDebugger.require('./content/constants');
Task.spawn(function*() {
yield waitForSourceShown(aPanel, ".html");
let fetched = waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
let fetched = afterDispatch(gStore, constants.FETCH_EVENT_LISTENERS);
gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
yield fetched;
@ -33,7 +35,7 @@ function test() {
testEventGroup("mouseEvents", false);
testEventArrays("change,click,keydown,keyup", "");
let updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
let updated = afterDispatch(gStore, constants.UPDATE_EVENT_BREAKPOINTS);
EventUtils.sendMouseEvent({ type: "click" }, getGroupCheckboxNode("interactionEvents"), gDebugger);
yield updated;
@ -46,7 +48,7 @@ function test() {
testEventGroup("mouseEvents", false);
testEventArrays("change,click,keydown,keyup", "change");
updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
updated = afterDispatch(gStore, constants.UPDATE_EVENT_BREAKPOINTS);
EventUtils.sendMouseEvent({ type: "click" }, getGroupCheckboxNode("interactionEvents"), gDebugger);
yield updated;
@ -59,7 +61,7 @@ function test() {
testEventGroup("mouseEvents", false);
testEventArrays("change,click,keydown,keyup", "");
updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
updated = afterDispatch(gStore, constants.UPDATE_EVENT_BREAKPOINTS);
EventUtils.sendMouseEvent({ type: "click" }, getGroupCheckboxNode("keyboardEvents"), gDebugger);
yield updated;
@ -72,7 +74,7 @@ function test() {
testEventGroup("mouseEvents", false);
testEventArrays("change,click,keydown,keyup", "keydown,keyup");
updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
updated = afterDispatch(gStore, constants.UPDATE_EVENT_BREAKPOINTS);
EventUtils.sendMouseEvent({ type: "click" }, getGroupCheckboxNode("keyboardEvents"), gDebugger);
yield updated;
@ -117,7 +119,7 @@ function test() {
"The getAllEvents() method returns the correct stuff.");
is(gEvents.getCheckedEvents().toString(), checked,
"The getCheckedEvents() method returns the correct stuff.");
is(gController.getState().eventListeners.activeEventNames.toString(), checked,
is(getState().eventListeners.activeEventNames.toString(), checked,
"The correct event names are listed as being active breakpoints.");
}
});

Просмотреть файл

@ -15,12 +15,14 @@ function test() {
let gController = gDebugger.DebuggerController
let gEvents = gView.EventListeners;
let gBreakpoints = gController.Breakpoints;
let gStore = gDebugger.store;
let getState = gStore.getState;
let constants = gDebugger.require('./content/constants');
Task.spawn(function*() {
yield waitForSourceShown(aPanel, ".html");
let fetched = waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
let fetched = afterDispatch(gStore, constants.FETCH_EVENT_LISTENERS);
gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
yield fetched;
@ -33,7 +35,7 @@ function test() {
testEventGroup("mouseEvents", false);
testEventArrays("change,click,keydown,keyup", "");
let updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
let updated = afterDispatch(gStore, constants.UPDATE_EVENT_BREAKPOINTS);
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(0), gDebugger);
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(1), gDebugger);
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(2), gDebugger);
@ -49,7 +51,7 @@ function test() {
testEventArrays("change,click,keydown,keyup", "change,click,keydown");
reload(aPanel);
yield waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
yield afterDispatch(gStore, constants.FETCH_EVENT_LISTENERS);
testEventItem(0, true);
testEventItem(1, true);
@ -60,7 +62,7 @@ function test() {
testEventGroup("mouseEvents", false);
testEventArrays("change,click,keydown,keyup", "change,click,keydown");
updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
updated = afterDispatch(gStore, constants.UPDATE_EVENT_BREAKPOINTS);
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(0), gDebugger);
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(1), gDebugger);
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(2), gDebugger);
@ -76,7 +78,7 @@ function test() {
testEventArrays("change,click,keydown,keyup", "");
reload(aPanel);
yield waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
yield afterDispatch(gStore, constants.FETCH_EVENT_LISTENERS);
testEventItem(0, false);
testEventItem(1, false);
@ -119,7 +121,7 @@ function test() {
"The getAllEvents() method returns the correct stuff.");
is(gEvents.getCheckedEvents().toString(), checked,
"The getCheckedEvents() method returns the correct stuff.");
is(gController.getState().eventListeners.activeEventNames.toString(), checked,
is(getState().eventListeners.activeEventNames.toString(), checked,
"The correct event names are listed as being active breakpoints.");
}
});

Просмотреть файл

@ -13,14 +13,15 @@ function test() {
let gDebugger = aPanel.panelWin;
let gView = gDebugger.DebuggerView;
let gEvents = gView.EventListeners;
let gController = gDebugger.DebuggerController;
let gStore = gDebugger.store;
let getState = gStore.getState;
let constants = gDebugger.require('./content/constants');
Task.spawn(function*() {
yield waitForSourceShown(aPanel, ".html");
yield callInTab(gTab, "addBodyClickEventListener");
let fetched = waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
let fetched = afterDispatch(gStore, constants.FETCH_EVENT_LISTENERS);
gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
yield fetched;
yield ensureThreadClientState(aPanel, "attached");
@ -30,7 +31,7 @@ function test() {
is(gView.instrumentsPaneTab, "events-tab",
"The events tab should be selected.");
let updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
let updated = afterDispatch(gStore, constants.UPDATE_EVENT_BREAKPOINTS);
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(1), gDebugger);
yield updated;
yield ensureThreadClientState(aPanel, "attached");

Просмотреть файл

@ -17,6 +17,7 @@ function test() {
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
gTarget = gDebugger.gTarget;
gThreadClient = gDebugger.gThreadClient;
gResumeButton = gDebugger.document.getElementById("resume");

Просмотреть файл

@ -17,6 +17,7 @@ function test() {
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
gTarget = gDebugger.gTarget;
gThreadClient = gDebugger.gThreadClient;
gResumeButton = gDebugger.document.getElementById("resume");
@ -45,7 +46,7 @@ function test() {
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
yield oncePaused;
yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
let updatedFrame = yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
let variables = gDebugger.DebuggerView.Variables;
is(variables._store.length, 4, "Correct number of scopes available");
@ -74,7 +75,7 @@ function test() {
});
yield oncePaused;
yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
let updatedFrame = yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
let variables = gDebugger.DebuggerView.Variables;
is(variables._store.length, 6, "Correct number of scopes available");

Просмотреть файл

@ -9,43 +9,83 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() {
let gTab, gPanel, gDebugger;
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const gController = gDebugger.DebuggerController;
const constants = gDebugger.require('./content/constants');
const queries = gDebugger.require('./content/queries');
const actions = bindActionCreators(gPanel);
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1);
is(queries.getBreakpoints(gController.getState()).length, 0,
"There are no breakpoints in the editor");
const response = yield actions.addBreakpoint({
actor: gSources.selectedValue, line: 4
});
ok(response.actualLocation, "has an actualLocation");
is(response.actualLocation.line, 6, "moved to line 6");
console.log(queries.getBreakpoints(gController.getState()))
is(queries.getBreakpoints(gController.getState()).length, 1,
"There is only one breakpoint in the editor");
ok(!queries.getBreakpoint(gController.getState(), { actor: gSources.selectedValue, line: 4 }),
"There isn't any breakpoint added on an invalid line.");
ok(queries.getBreakpoint(gController.getState(), { actor: gSources.selectedValue, line: 6 }),
"There isn't any breakpoint added on an invalid line.");
resumeDebuggerThenCloseAndFinish(gPanel);
})
gTab = aTab;
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", 1).then(performTest);
callInTab(gTab, "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.on("breakpointAdded", onEditorBreakpointAdd);
gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 4 }).then(onBreakpointAdd);
}
let onBpDebuggerAdd = false;
let onBpEditorAdd = false;
function onBreakpointAdd(aBreakpointClient) {
ok(aBreakpointClient,
"Breakpoint added, client received.");
is(aBreakpointClient.location.actor, gSources.selectedValue,
"Breakpoint client url is the same.");
is(aBreakpointClient.location.line, 6,
"Breakpoint client line is new.");
onBpDebuggerAdd = true;
maybeFinish();
}
function onEditorBreakpointAdd() {
gEditor.off("breakpointAdded", onEditorBreakpointAdd);
is(gEditor.getBreakpoints().length, 1,
"There is only one breakpoint in the editor");
ok(!gBreakpoints._getAdded({ actor: gSources.selectedValue, line: 4 }),
"There isn't any breakpoint added on an invalid line.");
ok(!gBreakpoints._getRemoving({ actor: gSources.selectedValue, line: 4 }),
"There isn't any breakpoint removed from an invalid line.");
ok(gBreakpoints._getAdded({ actor: gSources.selectedValue, line: 6 }),
"There is a breakpoint added on the actual line.");
ok(!gBreakpoints._getRemoving({ actor: gSources.selectedValue, line: 6 }),
"There isn't any breakpoint removed from the actual line.");
gBreakpoints._getAdded({ actor: gSources.selectedValue, line: 6 }).then(aBreakpointClient => {
is(aBreakpointClient.location.actor, gSources.selectedValue,
"Breakpoint client location actor 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);
}
}
}

Просмотреть файл

@ -10,59 +10,51 @@
const TAB_URL = EXAMPLE_URL + "doc_breakpoint-move.html";
function test() {
let gTab, gPanel, gDebugger;
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const gController = gDebugger.DebuggerController;
const actions = bindActionCreators(gPanel);
const constants = gDebugger.require('./content/constants');
const queries = gDebugger.require('./content/queries');
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
gBreakpointsAdded = gBreakpoints._added;
gBreakpointsRemoving = gBreakpoints._removing;
function resumeAndTestBreakpoint(line) {
return Task.spawn(function*() {
let event = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
doResume(gPanel);
yield event;
testBreakpoint(line);
});
};
waitForSourceAndCaretAndScopes(gPanel, ".html", 1).then(performTest);
callInTab(gTab, "ermahgerd");
});
function testBreakpoint(line) {
let bp = gSources._selectedBreakpoint;
ok(bp, "There should be a selected breakpoint on line " + line);
is(bp.location.line, line,
"The breakpoint on line " + line + " was not hit");
}
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.");
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 1);
is(queries.getBreakpoints(gController.getState()).length, 0,
"There are no breakpoints in the editor");
yield actions.addBreakpoint({
let bpClient = yield gPanel.addBreakpoint({
actor: gSources.selectedValue,
line: 19
});
yield actions.addBreakpoint({
yield gPanel.addBreakpoint({
actor: gSources.selectedValue,
line: 20
});
const response = yield actions.addBreakpoint({
let movedBpClient = yield gPanel.addBreakpoint({
actor: gSources.selectedValue,
line: 17
});
is(response.actualLocation.line, 19,
"Breakpoint client line is new.");
testMovedLocation(movedBpClient);
yield resumeAndTestBreakpoint(19);
yield actions.removeBreakpoint({
yield gPanel.removeBreakpoint({
actor: gSources.selectedValue,
line: 19
});
@ -76,7 +68,31 @@ function test() {
yield resumeAndTestBreakpoint(20);
resumeDebuggerThenCloseAndFinish(gPanel);
});
}
callInTab(gTab, "ermahgerd");
});
function resumeAndTestBreakpoint(line) {
return Task.spawn(function*() {
let event = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
doResume(gPanel);
yield event;
testBreakpoint(line);
});
};
function testBreakpoint(line) {
let selectedBreakpoint = gSources._selectedBreakpointItem;
ok(selectedBreakpoint,
"There should be a selected breakpoint on line " + line);
is(selectedBreakpoint.attachment.line, line,
"The breakpoint on line " + line + " was not hit");
}
function testMovedLocation(breakpointClient) {
ok(breakpointClient,
"Breakpoint added, client received.");
is(breakpointClient.location.actor, gSources.selectedValue,
"Breakpoint client url is the same.");
is(breakpointClient.location.line, 19,
"Breakpoint client line is new.");
}
}

Просмотреть файл

@ -21,7 +21,6 @@ function test() {
gThreadClient = gDebugger.gThreadClient;
gEvents = gDebugger.EVENTS;
gSources = gDebugger.DebuggerView.Sources;
const actions = bindActionCreators(gPanel);
Task.spawn(function* () {
try {
@ -39,18 +38,17 @@ function test() {
is(paused.why.type, "debuggerStatement");
// Set our breakpoints.
const sourceActor = getSourceActor(gSources, CODE_URL);
yield promise.all([
actions.addBreakpoint({
actor: sourceActor,
const [bp1, bp2, bp3] = yield promise.all([
setBreakpoint({
url: CODE_URL,
line: 3
}),
actions.addBreakpoint({
actor: sourceActor,
setBreakpoint({
url: CODE_URL,
line: 4
}),
actions.addBreakpoint({
actor: sourceActor,
setBreakpoint({
url: CODE_URL,
line: 5
})
]);
@ -77,9 +75,9 @@ function test() {
// Clean up the breakpoints.
yield promise.all([
actions.removeBreakpoint({ actor: sourceActor, line: 3 }),
actions.removeBreakpoint({ actor: sourceActor, line: 4 }),
actions.removeBreakpoint({ actor: sourceActor, line: 5 })
rdpInvoke(bp1, bp1.remove),
rdpInvoke(bp2, bp1.remove),
rdpInvoke(bp3, bp1.remove),
]);
yield resumeDebuggerThenCloseAndFinish(gPanel);

Просмотреть файл

@ -8,42 +8,53 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() {
let gTab, gPanel, gDebugger;
let gSources, gBreakpoints;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gSources = gDebugger.DebuggerView.Sources;
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
function checkBreakpointsDisabled(isDisabled, total = 3) {
let breakpoints = gDebugger.queries.getBreakpoints(getState());
is(breakpoints.length, total,
"Breakpoints should still be set.");
is(breakpoints.filter(bp => bp.disabled === isDisabled).length, total,
"Breakpoints should be " + (isDisabled ? "disabled" : "enabled") + ".");
}
Task.spawn(function*() {
yield waitForSourceShown(gPanel, "-01.js");
yield actions.addBreakpoint({ actor: gSources.values[0], line: 5 });
yield actions.addBreakpoint({ actor: gSources.values[1], line: 6 });
yield actions.addBreakpoint({ actor: gSources.values[1], line: 7 });
yield ensureThreadClientState(gPanel, "resumed");
gSources.toggleBreakpoints();
yield waitForDispatch(gPanel, gDebugger.constants.REMOVE_BREAKPOINT, 3);
checkBreakpointsDisabled(true)
const finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED, 3);
gSources.toggleBreakpoints();
yield waitForDispatch(gPanel, gDebugger.constants.ADD_BREAKPOINT, 3);
checkBreakpointsDisabled(false);
yield ensureThreadClientState(gPanel, "resumed");
closeDebuggerAndFinish(gPanel)
});
waitForSourceShown(gPanel, "-01.js")
.then(addBreakpoints)
.then(testDisableBreakpoints)
.then(testEnableBreakpoints)
.then(() => ensureThreadClientState(gPanel, "resumed"))
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
});
function addBreakpoints() {
return promise.resolve(null)
.then(() => gPanel.addBreakpoint({ actor: gSources.values[0], line: 5 }))
.then(() => gPanel.addBreakpoint({ actor: gSources.values[1], line: 6 }))
.then(() => gPanel.addBreakpoint({ actor: gSources.values[1], line: 7 }))
.then(() => ensureThreadClientState(gPanel, "resumed"));
}
function testDisableBreakpoints() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED, 3);
gSources.toggleBreakpoints();
return finished.then(() => checkBreakpointsDisabled(true));
}
function testEnableBreakpoints() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED, 3);
gSources.toggleBreakpoints();
return finished.then(() => checkBreakpointsDisabled(false));
}
function checkBreakpointsDisabled(aState, aTotal = 3) {
let breakpoints = gSources.getAllBreakpoints();
is(breakpoints.length, aTotal,
"Breakpoints should still be set.");
is(breakpoints.filter(e => e.attachment.disabled == aState).length, aTotal,
"Breakpoints should be " + (aState ? "disabled" : "enabled") + ".");
}
}

Просмотреть файл

@ -9,48 +9,61 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() {
let gTab, gPanel, gDebugger;
let gSources, gBreakpoints;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gSources = gDebugger.DebuggerView.Sources;
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
function checkBreakpointsDisabled(isDisabled, total = 3) {
let breakpoints = gDebugger.queries.getBreakpoints(getState());
is(breakpoints.length, total,
"Breakpoints should still be set.");
is(breakpoints.filter(bp => bp.disabled === isDisabled).length, total,
"Breakpoints should be " + (isDisabled ? "disabled" : "enabled") + ".");
}
Task.spawn(function*() {
yield waitForSourceShown(gPanel, "-01.js");
yield promise.all([
actions.addBreakpoint({ actor: gSources.values[0], line: 5 }),
actions.addBreakpoint({ actor: gSources.values[1], line: 6 }),
actions.addBreakpoint({ actor: gSources.values[1], line: 7 })
]);
yield ensureThreadClientState(gPanel, "resumed");
yield promise.all([
actions.disableBreakpoint({ actor: gSources.values[0], line: 5 }),
actions.disableBreakpoint({ actor: gSources.values[1], line: 6 })
]);
gSources.toggleBreakpoints();
yield waitForDispatch(gPanel, gDebugger.constants.REMOVE_BREAKPOINT, 1);
checkBreakpointsDisabled(true);
gSources.toggleBreakpoints();
yield waitForDispatch(gPanel, gDebugger.constants.ADD_BREAKPOINT, 3);
checkBreakpointsDisabled(false);
yield ensureThreadClientState(gPanel, "resumed");
closeDebuggerAndFinish(gPanel);
});
waitForSourceShown(gPanel, "-01.js")
.then(addBreakpoints)
.then(disableSomeBreakpoints)
.then(testToggleBreakpoints)
.then(testEnableBreakpoints)
.then(() => ensureThreadClientState(gPanel, "resumed"))
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
});
function addBreakpoints() {
return promise.resolve(null)
.then(() => gPanel.addBreakpoint({ actor: gSources.values[0], line: 5 }))
.then(() => gPanel.addBreakpoint({ actor: gSources.values[1], line: 6 }))
.then(() => gPanel.addBreakpoint({ actor: gSources.values[1], line: 7 }))
.then(() => ensureThreadClientState(gPanel, "resumed"));
}
function disableSomeBreakpoints() {
return promise.all([
gSources.disableBreakpoint({ actor: gSources.values[0], line: 5 }),
gSources.disableBreakpoint({ actor: gSources.values[1], line: 6 })
]);
}
function testToggleBreakpoints() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED, 1);
gSources.toggleBreakpoints();
return finished.then(() => checkBreakpointsDisabled(true));
}
function testEnableBreakpoints() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED, 3);
gSources.toggleBreakpoints();
return finished.then(() => checkBreakpointsDisabled(false));
}
function checkBreakpointsDisabled(aState, aTotal = 3) {
let breakpoints = gSources.getAllBreakpoints();
is(breakpoints.length, aTotal,
"Breakpoints should still be set.");
is(breakpoints.filter(e => e.attachment.disabled == aState).length, aTotal,
"Breakpoints should be " + (aState ? "disabled" : "enabled") + ".");
}
}

Просмотреть файл

@ -9,93 +9,98 @@
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
function test() {
let gTab, gPanel, gDebugger, gEditor;
let gSources, gLocation;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
function initialCheck(aCaretLine) {
let bp = gDebugger.queries.getBreakpoint(getState(),
{ actor: gSources.values[0], line: aCaretLine });
ok(bp, "There should be a breakpoint on line " + aCaretLine);
let attachment = gSources._getBreakpoint(bp).attachment;
ok(attachment,
"There should be a breakpoint on line " + aCaretLine + " in the sources pane.");
let thrownNode = attachment.view.container.querySelector(".dbg-breakpoint-condition-thrown-message");
ok(thrownNode,
"The breakpoint item should contain a thrown message node.")
ok(!attachment.view.container.classList.contains("dbg-breakpoint-condition-thrown"),
"The thrown message on line " + aCaretLine + " should be hidden when condition has not been evaluated.")
}
function resumeAndTestThrownMessage(line) {
doResume(gPanel);
return waitForCaretUpdated(gPanel, line).then(() => {
// Test that the thrown message is correctly shown.
let bp = gDebugger.queries.getBreakpoint(
getState(),
{ actor: gSources.values[0], line: line }
);
let attachment = gSources._getBreakpoint(bp).attachment;
ok(attachment.view.container.classList.contains('dbg-breakpoint-condition-thrown'),
"Message on line " + line + " should be shown when condition throws.");
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
.then(addBreakpoints)
.then(() => resumeAndTestThrownMessage(18))
.then(() => resumeAndTestNoThrownMessage(19))
.then(() => resumeAndTestThrownMessage(22))
.then(() => resumeAndFinishTest())
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
}
function resumeAndTestNoThrownMessage(line) {
doResume(gPanel);
return waitForCaretUpdated(gPanel, line).then(() => {
//test that the thrown message is correctly shown
let bp = gDebugger.queries.getBreakpoint(
getState(),
{ actor: gSources.values[0], line: line }
);
let attachment = gSources._getBreakpoint(bp).attachment;
ok(!attachment.view.container.classList.contains("dbg-breakpoint-condition-thrown"),
"Message on line " + line + " should be hidden if condition doesn't throw.");
});
}
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 17);
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 18 }, " 1afff");
// Close the popup because a SET_BREAKPOINT_CONDITION action is
// fired when it's closed, and it sets it on the currently
// selected breakpoint and we want to make sure it uses the
// current breakpoint. This isn't a problem outside of tests
// because any UI interaction will close the popup before the
// new breakpoint is added.
gSources._hideConditionalPopup();
initialCheck(18);
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 19 }, "true");
gSources._hideConditionalPopup();
initialCheck(19);
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 20 }, "false");
gSources._hideConditionalPopup();
initialCheck(20);
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 22 }, "randomVar");
gSources._hideConditionalPopup();
initialCheck(22)
yield resumeAndTestThrownMessage(18);
yield resumeAndTestNoThrownMessage(19);
yield resumeAndTestThrownMessage(22);
resumeDebuggerThenCloseAndFinish(gPanel);
});
callInTab(gTab, "ermahgerd");
});
function resumeAndTestThrownMessage(aLine) {
EventUtils.sendMouseEvent({ type: "mousedown" },
gDebugger.document.getElementById("resume"),
gDebugger);
let finished = waitForCaretUpdated(gPanel, aLine).then(() => {
//test that the thrown message is correctly shown
let attachment = gSources.getBreakpoint({ actor: gSources.values[0], line: aLine}).attachment;
ok(attachment.view.container.classList.contains('dbg-breakpoint-condition-thrown'),
"Message on line " + aLine + " should be shown when condition throws.");
});
return finished;
}
function resumeAndTestNoThrownMessage(aLine) {
EventUtils.sendMouseEvent({ type: "mousedown" },
gDebugger.document.getElementById("resume"),
gDebugger);
let finished = waitForCaretUpdated(gPanel, aLine).then(() => {
//test that the thrown message is correctly shown
let attachment = gSources.getBreakpoint({ actor: gSources.values[0], line: aLine}).attachment;
ok(!attachment.view.container.classList.contains("dbg-breakpoint-condition-thrown"),
"Message on line " + aLine + " should be hidden if condition doesn't throw.");
});
return finished;
}
function resumeAndFinishTest() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED)
gDebugger.gThreadClient.resume();
return finished;
}
function addBreakpoints() {
return promise.resolve(null)
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 18,
condition: " 1a"}))
.then(() => initialCheck(18))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 19,
condition: "true"}))
.then(() => initialCheck(19))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 20,
condition: "false"}))
.then(() => initialCheck(20))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 22,
condition: "randomVar"}))
.then(() => initialCheck(22));
}
function initialCheck(aCaretLine) {
let bp = gSources.getBreakpoint({ actor: gSources.values[0], line: aCaretLine})
let attachment = bp.attachment;
ok(attachment,
"There should be an item for line " + aCaretLine + " in the sources pane.");
let thrownNode = attachment.view.container.querySelector(".dbg-breakpoint-condition-thrown-message");
ok(thrownNode,
"The breakpoint item should contain a thrown message node.")
ok(!attachment.view.container.classList.contains("dbg-breakpoint-condition-thrown"),
"The thrown message on line " + aCaretLine + " should be hidden when condition has not been evaluated.")
}
}

Просмотреть файл

@ -8,71 +8,88 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() {
let gTab, gPanel, gDebugger;
let gEditor, gSources, gContextMenu, gBreakpoints, gBreakpointsAdded;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const gContextMenu = gDebugger.document.getElementById("sourceEditorContextMenu");
const queries = gDebugger.require('./content/queries');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
gBreakpointsAdded = gBreakpoints._added;
gContextMenu = gDebugger.document.getElementById("sourceEditorContextMenu");
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1);
is(gDebugger.gThreadClient.state, "paused",
"Should only be getting stack frames while paused.");
is(queries.getSourceCount(getState()), 2,
"Found the expected number of sources.");
isnot(gEditor.getText().indexOf("debugger"), -1,
"The correct source was loaded initially.");
is(gSources.selectedValue, gSources.values[1],
"The correct source is selected.");
ok(gContextMenu,
"The source editor's context menupopup is available.");
gEditor.focus();
gEditor.setSelection({ line: 1, ch: 0 }, { line: 1, ch: 10 });
gContextMenu.openPopup(gEditor.container, "overlap", 0, 0, true, false);
gEditor.emit("gutterClick", 6, 2);
yield once(gContextMenu, "popupshown");
is(queries.getBreakpoints(getState()).length, 0, "no breakpoints added");
let cmd = gContextMenu.querySelector('menuitem[command=addBreakpointCommand]');
EventUtils.synthesizeMouseAtCenter(cmd, {}, gDebugger);
yield waitForDispatch(gPanel, gDebugger.constants.ADD_BREAKPOINT);
is(queries.getBreakpoints(getState()).length, 1,
"1 breakpoint correctly added");
ok(queries.getBreakpoint(getState(),
{ actor: gSources.values[1], line: 7 }),
"Breakpoint on line 7 exists");
gContextMenu.openPopup(gEditor.container, "overlap", 0, 0, true, false);
gEditor.emit("gutterClick", 7, 2);
yield once(gContextMenu, "popupshown");
is(queries.getBreakpoints(getState()).length, 1,
"1 breakpoint correctly added");
cmd = gContextMenu.querySelector('menuitem[command=addConditionalBreakpointCommand]');
EventUtils.synthesizeMouseAtCenter(cmd, {}, gDebugger);
yield waitForDispatch(gPanel, gDebugger.constants.ADD_BREAKPOINT);
is(queries.getBreakpoints(getState()).length, 2,
"2 breakpoints correctly added");
ok(queries.getBreakpoint(getState(),
{ actor: gSources.values[1], line: 8 }),
"Breakpoint on line 8 exists");
resumeDebuggerThenCloseAndFinish(gPanel);
});
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1)
.then(performTest)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
callInTab(gTab, "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.");
isnot(gEditor.getText().indexOf("debugger"), -1,
"The correct source was loaded initially.");
is(gSources.selectedValue, gSources.values[1],
"The correct source is selected.");
ok(gContextMenu,
"The source editor's context menupopup is available.");
gEditor.focus();
gEditor.setSelection({ line: 1, ch: 0 }, { line: 1, ch: 10 });
return testAddBreakpoint().then(testAddConditionalBreakpoint);
}
function testAddBreakpoint() {
gContextMenu.openPopup(gEditor.container, "overlap", 0, 0, true, false);
gEditor.emit("gutterClick", 6, 2);
return once(gContextMenu, "popupshown").then(() => {
is(gBreakpointsAdded.size, 0, "no breakpoints added");
let cmd = gContextMenu.querySelector('menuitem[command=addBreakpointCommand]');
let bpShown = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_SHOWN_IN_EDITOR);
EventUtils.synthesizeMouseAtCenter(cmd, {}, gDebugger);
return bpShown;
}).then(() => {
is(gBreakpointsAdded.size, 1,
"1 breakpoint correctly added");
is(gEditor.getBreakpoints().length, 1,
"1 breakpoint currently shown in the editor.");
ok(gBreakpoints._getAdded({ actor: gSources.values[1], line: 7 }),
"Breakpoint on line 7 exists");
});
}
function testAddConditionalBreakpoint() {
gContextMenu.openPopup(gEditor.container, "overlap", 0, 0, true, false);
gEditor.emit("gutterClick", 7, 2);
return once(gContextMenu, "popupshown").then(() => {
is(gBreakpointsAdded.size, 1,
"1 breakpoint correctly added");
let cmd = gContextMenu.querySelector('menuitem[command=addConditionalBreakpointCommand]');
let bpShown = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
EventUtils.synthesizeMouseAtCenter(cmd, {}, gDebugger);
return bpShown;
}).then(() => {
is(gBreakpointsAdded.size, 2,
"2 breakpoints correctly added");
is(gEditor.getBreakpoints().length, 2,
"2 breakpoints currently shown in the editor.");
ok(gBreakpoints._getAdded({ actor: gSources.values[1], line: 8 }),
"Breakpoint on line 8 exists");
});
}
}

Просмотреть файл

@ -11,62 +11,118 @@ function test() {
// Debug test slaves are a bit slow at this test.
requestLongerTimeout(2);
Task.spawn(function*() {
const [gTab,, gPanel ] = yield initDebugger(TAB_URL);
const gDebugger = gPanel.panelWin;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
let gTab, gPanel, gDebugger;
let gSources, gBreakpoints;
const addBreakpoints = Task.async(function*() {
yield actions.addBreakpoint({ actor: gSources.values[0], line: 5 });
yield actions.addBreakpoint({ actor: gSources.values[1], line: 6 });
yield actions.addBreakpoint({ actor: gSources.values[1], line: 7 });
yield actions.addBreakpoint({ actor: gSources.values[1], line: 8 });
yield actions.addBreakpoint({ actor: gSources.values[1], line: 9 });
yield ensureThreadClientState(gPanel, "resumed");
gSources.highlightBreakpoint({ actor: gSources.values[1], line: 9 });
});
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
const pauseAndCheck = Task.async(function*() {
let source = queries.getSelectedSource(getState());
is(source.url, EXAMPLE_URL + "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.");
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
return waitForSourceAndCaretAndScopes(gPanel, "-01.js", 5).then(() => {
let source = queries.getSelectedSource(getState());
is(source.url, EXAMPLE_URL + "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.");
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({ actor: gSources.values[0], line: 5 }))
.then(() => gPanel.addBreakpoint({ actor: gSources.values[1], line: 6 }))
.then(() => gPanel.addBreakpoint({ actor: gSources.values[1], line: 7 }))
.then(() => gPanel.addBreakpoint({ actor: gSources.values[1], line: 8 }))
.then(() => gPanel.addBreakpoint({ actor: gSources.values[1], line: 9 }))
.then(() => ensureThreadClientState(gPanel, "resumed"));
}
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(() => {
let source = gSources.selectedItem.attachment.source;
is(source.url, EXAMPLE_URL + "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.");
});
let initialChecks = Task.async(function*() {
for (let bp of queries.getBreakpoints(getState())) {
ok(bp.actor, "All breakpoint items should have an actor");
ok(!bp.disabled, "All breakpoints should initially be enabled.");
let source = gSources.selectedItem.attachment.source;
is(source.url, EXAMPLE_URL + "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.");
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
return finished;
}
let initialChecks = Task.async(function*() {
for (let source of gSources) {
for (let breakpoint of 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 prefix = "bp-cMenu-"; // "breakpoints context menu"
let identifier = queries.makeLocationId(bp.location);
let identifier = gBreakpoints.getIdentifier(breakpoint.attachment);
let enableSelfId = prefix + "enableSelf-" + identifier + "-menuitem";
let disableSelfId = prefix + "disableSelf-" + identifier + "-menuitem";
// Check to make sure that only the bp context menu is shown when right clicking
// this node (Bug 1159276).
let breakpointItem = gSources._getBreakpoint(bp);
let menu = gDebugger.document.getElementById("bp-mPop-" + identifier);
let contextMenuShown = once(gDebugger.document, "popupshown");
EventUtils.synthesizeMouseAtCenter(breakpointItem.prebuiltNode, {type: 'contextmenu', button: 2}, gDebugger);
EventUtils.synthesizeMouseAtCenter(breakpoint.prebuiltNode, {type: 'contextmenu', button: 2}, gDebugger);
let event = yield contextMenuShown;
is (event.originalTarget.id, menu.id, "The correct context menu was shown");
let contextMenuHidden = once(gDebugger.document, "popuphidden");
@ -74,175 +130,204 @@ function test() {
yield contextMenuHidden;
is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true",
"The 'Enable breakpoint' context menu item should initially be hidden'.");
"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(breakpointItem.attachment.view.checkbox.getAttribute("checked"), "true",
"All breakpoints should initially have a checked checkbox.");
"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.");
});
const checkBreakpointToggleSelf = Task.async(function*(index) {
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelectorAll(".dbg-breakpoint")[index],
gDebugger);
let prefix = "bp-cMenu-"; // "breakpoints context menu"
let identifier = gBreakpoints.getIdentifier(selectedBreakpoint.attachment);
let enableSelfId = prefix + "enableSelf-" + identifier + "-menuitem";
let disableSelfId = prefix + "disableSelf-" + identifier + "-menuitem";
let selectedBreakpoint = gSources._selectedBreakpoint;
let selectedBreakpointItem = gSources._getBreakpoint(selectedBreakpoint);
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.actor,
"Selected breakpoint should have an actor.");
ok(!selectedBreakpoint.disabled,
"The breakpoint should not be disabled yet (" + index + ").");
ok(isCaretPos(gPanel, selectedBreakpoint.attachment.line),
"The source editor caret position was incorrect (" + aIndex + ").");
let prefix = "bp-cMenu-"; // "breakpoints context menu"
let identifier = queries.makeLocationId(selectedBreakpoint.location);
let enableSelfId = prefix + "enableSelf-" + identifier + "-menuitem";
let disableSelfId = prefix + "disableSelf-" + identifier + "-menuitem";
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);
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'.");
"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.location.line),
"The source editor caret position was incorrect (" + index + ").");
// Test disabling this breakpoint.
gSources._onDisableSelf(selectedBreakpoint.location);
yield waitForDispatch(gPanel, gDebugger.constants.REMOVE_BREAKPOINT);
ok(!!queries.getBreakpoint(getState(), selectedBreakpoint.location).disabled,
"The breakpoint should 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(!selectedBreakpointItem.attachment.view.checkbox.hasAttribute("checked"),
"The breakpoint should now be unchecked.");
gSources._onEnableSelf(selectedBreakpoint.location);
yield waitForDispatch(gPanel, gDebugger.constants.ADD_BREAKPOINT);
ok(!queries.getBreakpoint(getState(), selectedBreakpoint.location).disabled,
"The breakpoint should 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(selectedBreakpointItem.attachment.view.checkbox.hasAttribute("checked"),
"The breakpoint should now be checked.");
"The 'Disable breakpoint' context menu item should not be hidden'.");
ok(selectedBreakpoint.attachment.view.checkbox.hasAttribute("checked"),
"The breakpoint should now be checked.");
});
const checkBreakpointToggleOthers = Task.async(function*(index) {
EventUtils.sendMouseEvent(
{ type: "click" },
gDebugger.document.querySelectorAll(".dbg-breakpoint")[index],
gDebugger
);
// Test disabling this breakpoint.
gSources._onDisableSelf(selectedBreakpoint.attachment);
is(selectedBreakpoint.attachment.disabled, true,
"The current breakpoint should now be disabled.")
// Test disabling other breakpoints.
disableOthers();
yield waitForDispatch(gPanel, gDebugger.constants.REMOVE_BREAKPOINT, 4);
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.");
let selectedBreakpoint = queries.getBreakpoint(getState(), gSources._selectedBreakpoint.location);
return deferred.promise;
}
ok(selectedBreakpoint.actor,
"There should be a breakpoint actor.");
ok(!selectedBreakpoint.disabled,
"The targetted breakpoint should not have been disabled (" + index + ").");
function checkBreakpointToggleOthers(aIndex) {
let deferred = promise.defer();
for (let bp of queries.getBreakpoints(getState())) {
if (bp !== selectedBreakpoint) {
ok(bp.disabled,
"Non-targetted breakpoints should have been disabled.");
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 of gSources) {
for (let otherBreakpoint of 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 of gSources) {
for (let someBreakpoint of 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 of gSources) {
for (let someBreakpoint of 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 of gSources) {
for (let someBreakpoint of 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();
yield waitForDispatch(gPanel, gDebugger.constants.ADD_BREAKPOINT, 4);
for (let bp of queries.getBreakpoints(getState())) {
ok(!bp.disabled, "All breakpoints should be enabled.");
}
// Test disabling all breakpoints.
disableAll();
yield waitForDispatch(gPanel, gDebugger.constants.REMOVE_BREAKPOINT, 5);
for (let bp of queries.getBreakpoints(getState())) {
ok(!!bp.disabled, "All breakpoints should be disabled.");
}
// // Test re-enabling all breakpoints.
enableAll();
yield waitForDispatch(gPanel, gDebugger.constants.ADD_BREAKPOINT, 5);
for (let bp of queries.getBreakpoints(getState())) {
ok(!bp.disabled, "All breakpoints should be enabled.");
}
});
const testDeleteAll = Task.async(function*() {
// Test deleting all breakpoints.
deleteAll();
yield waitForDispatch(gPanel, gDebugger.constants.REMOVE_BREAKPOINT, 5);
// Test disabling other breakpoints.
disableOthers();
ok(!gSources._selectedBreakpoint,
"There should be no breakpoint available after removing all breakpoints.");
return deferred.promise;
}
for (let bp of queries.getBreakpoints(getState())) {
ok(false, "It's a trap!");
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 of gSources) {
for (let otherBreakpoint of source) {
ok(false, "It's a trap!");
}
}
// Done.
deferred.resolve()
});
function disableOthers() {
gSources._onDisableOthers(gSources._selectedBreakpoint.location);
}
function enableOthers() {
gSources._onEnableOthers(gSources._selectedBreakpoint.location);
}
function disableAll() {
gSources._onDisableAll();
}
function enableAll() {
gSources._onEnableAll();
}
function deleteAll() {
gSources._onDeleteAll();
}
// Test deleting all breakpoints.
deleteAll();
yield waitForSourceShown(gPanel, "-01.js");
return deferred.promise;
}
yield addBreakpoints();
yield initialChecks();
yield checkBreakpointToggleSelf(0);
yield checkBreakpointToggleOthers(0);
yield checkBreakpointToggleSelf(1);
yield checkBreakpointToggleOthers(1);
yield checkBreakpointToggleSelf(2);
yield checkBreakpointToggleOthers(2);
yield checkBreakpointToggleSelf(3);
yield checkBreakpointToggleOthers(3);
yield checkBreakpointToggleSelf(4);
yield checkBreakpointToggleOthers(4);
yield testDeleteAll();
yield addBreakpoints()
yield initialChecks();
yield pauseAndCheck();
yield checkBreakpointToggleSelf(0);
yield checkBreakpointToggleOthers(0);
yield checkBreakpointToggleSelf(1);
yield checkBreakpointToggleOthers(1);
yield checkBreakpointToggleSelf(2);
yield checkBreakpointToggleOthers(2);
yield checkBreakpointToggleSelf(3);
yield checkBreakpointToggleOthers(3);
yield checkBreakpointToggleSelf(4);
yield checkBreakpointToggleOthers(4);
yield testDeleteAll();
resumeDebuggerThenCloseAndFinish(gPanel);
});
function disableOthers() {
gSources._onDisableOthers(gSources._selectedBreakpointItem.attachment);
}
function enableOthers() {
gSources._onEnableOthers(gSources._selectedBreakpointItem.attachment);
}
function disableAll() {
gSources._onDisableAll();
}
function enableAll() {
gSources._onEnableAll();
}
function deleteAll() {
gSources._onDeleteAll();
}
}

Просмотреть файл

@ -9,56 +9,55 @@ const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gPanel = aPanel;
const gTab = aTab;
const gDebugger = gPanel.panelWin;
const gEvents = gDebugger.EVENTS;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
let gTab = aTab;
let gDebugger = aPanel.panelWin;
let gEvents = gDebugger.EVENTS;
let gEditor = gDebugger.DebuggerView.editor;
let gSources = gDebugger.DebuggerView.Sources;
let gBreakpoints = gDebugger.DebuggerController.Breakpoints;
let gBreakpointLocation;
Task.spawn(function*() {
yield waitForSourceShown(gPanel, "-01.js");
yield waitForSourceShown(aPanel, "-01.js");
gBreakpointLocation = { actor: getSourceActor(gSources, EXAMPLE_URL + "code_script-switching-01.js"),
line: 5 };
yield actions.addBreakpoint(gBreakpointLocation);
yield aPanel.addBreakpoint(gBreakpointLocation);
yield ensureThreadClientState(gPanel, "resumed");
yield ensureThreadClientState(aPanel, "resumed");
yield testWhenBreakpointEnabledAndFirstSourceShown();
gSources._preferredSourceURL = EXAMPLE_URL + "code_script-switching-02.js";
yield reloadActiveTab(gPanel, gEvents.SOURCE_SHOWN);
yield reloadActiveTab(aPanel, gEvents.SOURCE_SHOWN);
yield testWhenBreakpointEnabledAndSecondSourceShown();
yield actions.disableBreakpoint(gBreakpointLocation);
yield reloadActiveTab(gPanel, gEvents.SOURCE_SHOWN);
yield gSources.disableBreakpoint(gBreakpointLocation);
yield reloadActiveTab(aPanel, gEvents.SOURCE_SHOWN);
yield testWhenBreakpointDisabledAndSecondSourceShown();
yield actions.enableBreakpoint(gBreakpointLocation);
yield reloadActiveTab(gPanel, gEvents.SOURCE_SHOWN);
yield gSources.enableBreakpoint(gBreakpointLocation);
yield reloadActiveTab(aPanel, gEvents.SOURCE_SHOWN);
yield testWhenBreakpointEnabledAndSecondSourceShown();
yield resumeDebuggerThenCloseAndFinish(gPanel);
yield resumeDebuggerThenCloseAndFinish(aPanel);
});
function verifyView({ disabled }) {
function verifyView({ disabled, visible }) {
return Task.spawn(function*() {
// It takes a tick for the checkbox in the SideMenuWidget and the
// gutter in the editor to get updated.
yield waitForTick();
let breakpoint = queries.getBreakpoint(getState(), gBreakpointLocation);
let breakpointItem = gSources._getBreakpoint(breakpoint);
is(!!breakpoint.disabled, disabled,
"The selected breakpoint state was correct.");
let breakpointItem = gSources.getBreakpoint(gBreakpointLocation);
let visibleBreakpoints = gEditor.getBreakpoints();
is(!!breakpointItem.attachment.disabled, disabled,
"The selected brekapoint state was correct.");
is(breakpointItem.attachment.view.checkbox.hasAttribute("checked"), !disabled,
"The selected breakpoint's checkbox state was correct.");
"The selected brekapoint's checkbox state was correct.");
// Source editor starts counting line and column numbers from 0.
let breakpointLine = breakpointItem.attachment.line - 1;
let matchedBreakpoints = visibleBreakpoints.filter(e => e.line == breakpointLine);
is(!!matchedBreakpoints.length, visible,
"The selected breakpoint's visibility in the editor was correct.");
});
}
@ -67,52 +66,52 @@ function test() {
function testWhenBreakpointEnabledAndFirstSourceShown() {
return Task.spawn(function*() {
yield ensureSourceIs(gPanel, "-01.js");
yield verifyView({ disabled: false });
yield ensureSourceIs(aPanel, "-01.js");
yield verifyView({ disabled: false, visible: true });
callInTab(gTab, "firstCall");
yield waitForDebuggerEvents(gPanel, gEvents.FETCHED_SCOPES);
yield ensureSourceIs(gPanel, "-01.js");
yield ensureCaretAt(gPanel, 5);
yield verifyView({ disabled: false });
yield waitForDebuggerEvents(aPanel, gEvents.FETCHED_SCOPES);
yield ensureSourceIs(aPanel, "-01.js");
yield ensureCaretAt(aPanel, 5);
yield verifyView({ disabled: false, visible: true });
executeSoon(() => gDebugger.gThreadClient.resume());
yield waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1);
yield verifyView({ disabled: false });
yield waitForSourceAndCaretAndScopes(aPanel, "-02.js", 1);
yield verifyView({ disabled: false, visible: false });
});
}
function testWhenBreakpointEnabledAndSecondSourceShown() {
return Task.spawn(function*() {
yield ensureSourceIs(gPanel, "-02.js", true);
yield verifyView({ disabled: false });
yield ensureSourceIs(aPanel, "-02.js", true);
yield verifyView({ disabled: false, visible: false });
callInTab(gTab, "firstCall");
yield waitForSourceAndCaretAndScopes(gPanel, "-01.js", 1);
yield verifyView({ disabled: false });
yield waitForSourceAndCaretAndScopes(aPanel, "-01.js", 1);
yield verifyView({ disabled: false, visible: true });
executeSoon(() => gDebugger.gThreadClient.resume());
yield waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1);
yield verifyView({ disabled: false });
yield waitForSourceAndCaretAndScopes(aPanel, "-02.js", 1);
yield verifyView({ disabled: false, visible: false });
});
}
function testWhenBreakpointDisabledAndSecondSourceShown() {
return Task.spawn(function*() {
yield ensureSourceIs(gPanel, "-02.js", true);
yield verifyView({ disabled: true });
yield ensureSourceIs(aPanel, "-02.js", true);
yield verifyView({ disabled: true, visible: false });
callInTab(gTab, "firstCall");
yield waitForDebuggerEvents(gPanel, gEvents.FETCHED_SCOPES);
yield ensureSourceIs(gPanel, "-02.js");
yield ensureCaretAt(gPanel, 6);
yield verifyView({ disabled: true });
yield waitForDebuggerEvents(aPanel, gEvents.FETCHED_SCOPES);
yield ensureSourceIs(aPanel, "-02.js");
yield ensureCaretAt(aPanel, 6);
yield verifyView({ disabled: true, visible: false });
executeSoon(() => gDebugger.gThreadClient.resume());
yield waitForDebuggerEvents(gPanel, gEvents.AFTER_FRAMES_CLEARED);
yield ensureSourceIs(gPanel, "-02.js");
yield ensureCaretAt(gPanel, 6);
yield verifyView({ disabled: true });
yield waitForDebuggerEvents(aPanel, gEvents.AFTER_FRAMES_CLEARED);
yield ensureSourceIs(aPanel, "-02.js");
yield ensureCaretAt(aPanel, 6);
yield verifyView({ disabled: true, visible: false });
});
}
});

Просмотреть файл

@ -9,227 +9,293 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() {
let gTab, gPanel, gDebugger;
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
gBreakpointsAdded = gBreakpoints._added;
gBreakpointsRemoving = gBreakpoints._removing;
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1);
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest);
callInTab(gTab, "firstCall");
});
is(gDebugger.gThreadClient.state, "paused",
"Should only be getting stack frames while paused.");
is(queries.getSourceCount(getState()), 2,
"Found the expected number of sources.");
is(gEditor.getText().indexOf("debugger"), 166,
"The correct source was loaded initially.");
is(queries.getSelectedSource(getState()).actor, gSources.values[1],
"The correct source is selected.");
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"), 166,
"The correct source was loaded initially.");
is(gSources.selectedValue, gSources.values[1],
"The correct source is selected.");
is(queries.getBreakpoints(getState()).length, 0,
"No breakpoints currently added.");
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.");
info("Add the first breakpoint.");
gEditor.once("breakpointAdded", onEditorBreakpointAddFirst);
let location = { actor: gSources.selectedValue, line: 6 };
yield actions.addBreakpoint(location);
checkFirstBreakpoint(location);
ok(!gBreakpoints._getAdded({ url: "foo", line: 3 }),
"_getAdded('foo', 3) returns falsey.");
ok(!gBreakpoints._getRemoving({ url: "bar", line: 3 }),
"_getRemoving('bar', 3) returns falsey.");
info("Remove the first breakpoint.");
gEditor.once("breakpointRemoved", onEditorBreakpointRemoveFirst);
yield actions.removeBreakpoint(location);
checkFirstBreakpointRemoved(location);
checkBackgroundBreakpoint(yield testBreakpointAddBackground());
is(gSources.values[1], gSources.selectedValue,
"The second source should be currently selected.");
info("Switch to the first source, which is not yet selected");
gEditor.once("breakpointAdded", onEditorBreakpointAddSwitch);
gEditor.once("change", onEditorTextChanged);
actions.selectSource(gSources.items[0].attachment.source);
yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
onReadyForClick();
info("Add the first breakpoint.");
let location = { actor: gSources.selectedValue, line: 6 };
gEditor.once("breakpointAdded", onEditorBreakpointAddFirst);
gPanel.addBreakpoint(location).then(onBreakpointAddFirst);
}
let breakpointsAdded = 0;
let breakpointsRemoved = 0;
let editorBreakpointChanges = 0;
function onEditorBreakpointAddFirst(aEvent, aLine) {
editorBreakpointChanges++;
ok(aEvent,
"breakpoint1 added to the editor.");
is(aLine, 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.actor, 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.");
});
callInTab(gTab, "firstCall");
is(gSources.values[1], gSources.selectedValue,
"The second source should be currently selected.");
let breakpointsAdded = 0;
let breakpointsRemoved = 0;
let editorBreakpointChanges = 0;
info("Remove the first breakpoint.");
gEditor.once("breakpointRemoved", onEditorBreakpointRemoveFirst);
gPanel.removeBreakpoint(aBreakpointClient.location).then(onBreakpointRemoveFirst);
}
function onEditorBreakpointAddFirst(aEvent, aLine) {
editorBreakpointChanges++;
function onEditorBreakpointRemoveFirst(aEvent, aLine) {
editorBreakpointChanges++;
ok(aEvent,
"breakpoint1 added to the editor.");
is(aLine, 5,
"Editor breakpoint line is correct.");
ok(aEvent,
"breakpoint1 removed from the editor.");
is(aLine, 5,
"Editor breakpoint line is correct.");
is(gEditor.getBreakpoints().length, 1,
"editor.getBreakpoints().length is correct.");
}
is(gEditor.getBreakpoints().length, 0,
"editor.getBreakpoints().length is correct.");
}
function onEditorBreakpointRemoveFirst(aEvent, aLine) {
editorBreakpointChanges++;
function onBreakpointRemoveFirst(aLocation) {
breakpointsRemoved++;
ok(aEvent,
"breakpoint1 removed from the editor.");
is(aLine, 5,
"Editor breakpoint line is correct.");
ok(aLocation,
"breakpoint1 removed");
is(aLocation.actor, gSources.selectedValue,
"breakpoint1 removal url is correct.");
is(aLocation.line, 6,
"breakpoint1 removal line is correct.");
is(gEditor.getBreakpoints().length, 0,
"editor.getBreakpoints().length is correct.");
}
testBreakpointAddBackground();
}
function checkFirstBreakpoint(location) {
breakpointsAdded++;
const bp = queries.getBreakpoint(getState(), location);
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(bp,
"breakpoint1 exists");
is(bp.location.actor, queries.getSelectedSource(getState()).actor,
"breakpoint1 actor is correct.");
is(bp.location.line, 6,
"breakpoint1 line is correct.");
ok(!gBreakpoints._getAdded({ actor: gSources.selectedValue, line: 6 }),
"_getAdded('gSources.selectedValue', 6) returns falsey.");
ok(!gBreakpoints._getRemoving({ actor: gSources.selectedValue, line: 6 }),
"_getRemoving('gSources.selectedValue', 6) returns falsey.");
is(queries.getBreakpoints(getState()).length, 1,
"The list of added breakpoints holds only one breakpoint.");
is(gSources.values[1], gSources.selectedValue,
"The second source should be currently selected.");
is(queries.getSelectedSource(getState()).actor, gSources.values[1],
"The second source should be currently selected.");
}
info("Add a breakpoint to the first source, which is not selected.");
let location = { actor: gSources.values[0], line: 5 };
let options = { noEditorUpdate: true };
gEditor.on("breakpointAdded", onEditorBreakpointAddBackgroundTrap);
gPanel.addBreakpoint(location, options).then(onBreakpointAddBackground);
}
function checkFirstBreakpointRemoved(location) {
breakpointsRemoved++;
const bp = queries.getBreakpoint(getState(), location);
ok(!bp, "breakpoint1 removed");
}
function onEditorBreakpointAddBackgroundTrap() {
// Trap listener: no breakpoint must be added to the editor when a
// breakpoint is added to a source that is not currently selected.
editorBreakpointChanges++;
ok(false, "breakpoint2 must not be added to the editor.");
}
function testBreakpointAddBackground() {
is(queries.getBreakpoints(getState()).length, 0,
"No breakpoints currently added.");
function onBreakpointAddBackground(aBreakpointClient, aResponseError) {
breakpointsAdded++;
is(gSources.values[1], gSources.selectedValue,
"The second source should be currently selected.");
ok(aBreakpointClient,
"breakpoint2 added, client received");
is(aBreakpointClient.location.actor, gSources.values[0],
"breakpoint2 client url is correct.");
is(aBreakpointClient.location.line, 5,
"breakpoint2 client line is correct.");
info("Add a breakpoint to the first source, which is not selected.");
let location = { actor: gSources.values[0], line: 5 };
gEditor.on("breakpointAdded", onEditorBreakpointAddBackgroundTrap);
return actions.addBreakpoint(location).then(() => location);
}
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.");
function onEditorBreakpointAddBackgroundTrap() {
// Trap listener: no breakpoint must be added to the editor when a
// breakpoint is added to a source that is not currently selected.
editorBreakpointChanges++;
ok(false, "breakpoint2 must not be added to the editor.");
}
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.");
function checkBackgroundBreakpoint(location) {
breakpointsAdded++;
const bp = queries.getBreakpoint(getState(), location);
gBreakpoints._getAdded(aBreakpointClient.location).then(aClient => {
is(aClient, aBreakpointClient,
"_getAdded() returns the correct breakpoint.");
});
ok(bp,
"breakpoint2 added, client received");
is(bp.location.actor, gSources.values[0],
"breakpoint2 client url is correct.");
is(bp.location.line, 5,
"breakpoint2 client line is correct.");
is(gSources.values[1], gSources.selectedValue,
"The second source should be currently selected.");
ok(queries.getBreakpoint(getState(), bp.location),
"breakpoint2 found in the list of added breakpoints.");
// Remove the trap listener.
gEditor.off("breakpointAdded", onEditorBreakpointAddBackgroundTrap);
is(queries.getBreakpoints(getState()).length, 1,
"The list of added breakpoints holds only one breakpoint.");
info("Switch to the first source, which is not yet selected");
gEditor.once("breakpointAdded", onEditorBreakpointAddSwitch);
gEditor.once("change", onEditorTextChanged);
gSources.selectedIndex = 0;
}
is(queries.getSelectedSource(getState()).actor, gSources.values[1],
"The second source should be currently selected.");
function onEditorBreakpointAddSwitch(aEvent, aLine) {
editorBreakpointChanges++;
// Remove the trap listener.
gEditor.off("breakpointAdded", onEditorBreakpointAddBackgroundTrap);
}
ok(aEvent,
"breakpoint2 added to the editor.");
is(aLine, 4,
"Editor breakpoint line is correct.");
function onEditorBreakpointAddSwitch(aEvent, aLine) {
editorBreakpointChanges++;
is(gEditor.getBreakpoints().length, 1,
"editor.getBreakpoints().length is correct");
}
ok(aEvent,
"breakpoint2 added to the editor.");
is(aLine, 4,
"Editor breakpoint line is correct.");
function onEditorTextChanged() {
// Wait for the actual text to be shown.
if (gEditor.getText() == gDebugger.L10N.getStr("loadingText"))
return void gEditor.once("change", onEditorTextChanged);
is(gEditor.getBreakpoints().length, 1,
"editor.getBreakpoints().length is correct");
}
is(gEditor.getText().indexOf("debugger"), -1,
"The second source is no longer displayed.");
is(gEditor.getText().indexOf("firstCall"), 118,
"The first source is displayed.");
function onEditorTextChanged() {
// Wait for the actual text to be shown.
if (gEditor.getText() == gDebugger.L10N.getStr("loadingText"))
return void gEditor.once("change", onEditorTextChanged);
is(gSources.values[0], gSources.selectedValue,
"The first source should be currently selected.");
is(gEditor.getText().indexOf("debugger"), -1,
"The second source is no longer displayed.");
is(gEditor.getText().indexOf("firstCall"), 118,
"The first source is displayed.");
let window = gEditor.container.contentWindow;
executeSoon(() => window.requestAnimationFrame(onReadyForClick));
}
is(gSources.values[0], gSources.selectedValue,
"The first source should be currently selected.");
}
function onReadyForClick() {
info("Remove the second breakpoint using the mouse.");
gEditor.once("breakpointRemoved", onEditorBreakpointRemoveSecond);
function onReadyForClick() {
info("Remove the second breakpoint using the mouse.");
gEditor.once("breakpointRemoved", onEditorBreakpointRemoveSecond);
let iframe = gEditor.container;
let testWin = iframe.ownerDocument.defaultView;
let iframe = gEditor.container;
let testWin = iframe.ownerDocument.defaultView;
// Flush the layout for the iframe.
info("rect " + iframe.contentDocument.documentElement.getBoundingClientRect());
// Flush the layout for the iframe.
info("rect " + iframe.contentDocument.documentElement.getBoundingClientRect());
let utils = testWin
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let utils = testWin
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let coords = gEditor.getCoordsFromPosition({ line: 4, ch: 0 });
let rect = iframe.getBoundingClientRect();
let left = rect.left + 10;
let top = rect.top + coords.top + 4;
utils.sendMouseEventToWindow("mousedown", left, top, 0, 1, 0, false, 0, 0);
utils.sendMouseEventToWindow("mouseup", left, top, 0, 1, 0, false, 0, 0);
}
let coords = gEditor.getCoordsFromPosition({ line: 4, ch: 0 });
let rect = iframe.getBoundingClientRect();
let left = rect.left + 10;
let top = rect.top + coords.top + 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, aLine) {
editorBreakpointChanges++;
function onEditorBreakpointRemoveSecond(aEvent, aLine) {
editorBreakpointChanges++;
ok(aEvent,
"breakpoint2 removed from the editor.");
is(aLine, 4,
"Editor breakpoint line is correct.");
ok(aEvent,
"breakpoint2 removed from the editor.");
is(aLine, 4,
"Editor breakpoint line is correct.");
is(gEditor.getBreakpoints().length, 0,
"editor.getBreakpoints().length is correct.");
is(gEditor.getBreakpoints().length, 0,
"editor.getBreakpoints().length is correct.");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
finalCheck();
closeDebuggerAndFinish(gPanel);
});
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
finalCheck();
closeDebuggerAndFinish(gPanel);
});
gDebugger.gThreadClient.resume();
}
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.");
function finalCheck() {
is(queries.getBreakpoints(getState()).length, 0,
"No breakpoints currently added.");
ok(!gBreakpoints._getAdded({ actor: gSources.values[0], line: 5 }),
"_getAdded('gSources.values[0]', 5) returns falsey.");
ok(!gBreakpoints._getRemoving({ actor: gSources.values[0], line: 5 }),
"_getRemoving('gSources.values[0]', 5) 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.");
}
});
ok(!gBreakpoints._getAdded({ actor: gSources.values[1], line: 6 }),
"_getAdded('gSources.values[1]', 6) returns falsey.");
ok(!gBreakpoints._getRemoving({ actor: gSources.values[1], line: 6 }),
"_getRemoving('gSources.values[1]', 6) returns falsey.");
ok(!gBreakpoints._getAdded({ actor: "foo", line: 3 }),
"_getAdded('foo', 3) returns falsey.");
ok(!gBreakpoints._getRemoving({ actor: "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.");
}
}

Просмотреть файл

@ -8,36 +8,39 @@
const TAB_URL = EXAMPLE_URL + "doc_script-eval.html";
function test() {
let gTab, gPanel, gDebugger;
let gSources, gBreakpoints;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gSources = gDebugger.DebuggerView.Sources;
const actions = bindActionCreators(gPanel);
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
Task.spawn(function*() {
yield waitForSourceShown(gPanel, "-eval.js");
waitForSourceShown(gPanel, "-eval.js")
.then(run)
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
});
function run() {
return Task.spawn(function*() {
let newSource = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.NEW_SOURCE);
callInTab(gTab, "evalSourceWithSourceURL");
yield newSource;
// Wait for it to be added to the UI
yield waitForTick();
const newSourceActor = getSourceActor(gSources, EXAMPLE_URL + 'bar.js');
yield actions.addBreakpoint({
actor: newSourceActor,
line: 2
});
yield gPanel.addBreakpoint({ actor: gSources.values[0], line: 2 });
yield ensureThreadClientState(gPanel, "resumed");
const paused = waitForThreadEvents(gPanel, "paused");
callInTab(gTab, "bar");
let frame = (yield paused).frame;
is(frame.where.source.actor, newSourceActor, "Should have broken on the eval'ed source");
is(frame.where.source.actor, gSources.values[0], "Should have broken on the eval'ed source");
is(frame.where.line, 2, "Should break on line 2");
yield resumeDebuggerThenCloseAndFinish(gPanel);
});
});
}
}

Просмотреть файл

@ -8,79 +8,96 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() {
let gTab, gPanel, gDebugger;
let gEditor, gSources;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
const addBreakpoints = Task.async(function*() {
yield actions.addBreakpoint({ actor: gSources.values[0], line: 5 });
yield actions.addBreakpoint({ actor: gSources.values[1], line: 6 });
yield actions.addBreakpoint({ actor: gSources.values[1], line: 7 });
yield actions.addBreakpoint({ actor: gSources.values[1], line: 8 });
yield actions.addBreakpoint({ actor: gSources.values[1], line: 9 })
});
function clickBreakpointAndCheck(aBreakpointIndex, aSourceIndex, aCaretLine) {
let finished = waitForCaretUpdated(gPanel, aCaretLine).then(() => {
checkHighlight(gSources.values[aSourceIndex], aCaretLine);
checkEditorContents(aSourceIndex);
is(queries.getSelectedSource(getState()).actor,
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).");
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(() => ensureThreadClientState(gPanel, "resumed"))
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
EventUtils.sendMouseEvent(
{ type: "click" },
gDebugger.document.querySelectorAll(".dbg-breakpoint")[aBreakpointIndex],
gDebugger
);
return finished;
}
function checkHighlight(actor, line) {
let breakpoint = gSources._selectedBreakpoint;
let breakpointItem = gSources._getBreakpoint(breakpoint);
is(breakpoint.location.actor, actor,
"The currently selected breakpoint actor is incorrect.");
is(breakpoint.location.line, line,
"The currently selected breakpoint line is incorrect.");
is(breakpointItem.attachment.actor, actor,
"The selected breakpoint item's source location attachment is incorrect.");
ok(breakpointItem.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"), 166,
"The second source is correctly displayed.");
}
}
Task.spawn(function*() {
yield waitForSourceShown(gPanel, "-01.js");
yield addBreakpoints();
yield clickBreakpointAndCheck(0, 0, 5);
yield clickBreakpointAndCheck(1, 1, 6);
yield clickBreakpointAndCheck(2, 1, 7);
yield clickBreakpointAndCheck(3, 1, 8);
yield clickBreakpointAndCheck(4, 1, 9);
closeDebuggerAndFinish(gPanel);
});
});
function addBreakpoints() {
return promise.resolve(null)
.then(() => initialChecks(0, 1))
.then(() => gPanel.addBreakpoint({ actor: gSources.values[0], line: 5 }))
.then(() => initialChecks(0, 5))
.then(() => gPanel.addBreakpoint({ actor: gSources.values[1], line: 6 }))
.then(() => waitForSourceShown(gPanel, "-02.js"))
.then(() => waitForCaretUpdated(gPanel, 6))
.then(() => initialChecks(1, 6))
.then(() => gPanel.addBreakpoint({ actor: gSources.values[1], line: 7 }))
.then(() => initialChecks(1, 7))
.then(() => gPanel.addBreakpoint({ actor: gSources.values[1], line: 8 }))
.then(() => initialChecks(1, 8))
.then(() => gPanel.addBreakpoint({ actor: 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(aActor, aLine) {
is(gSources._selectedBreakpointItem, gSources.getBreakpoint({ actor: aActor, line: aLine }),
"The currently selected breakpoint item is incorrect.");
is(gSources._selectedBreakpointItem.attachment.actor, aActor,
"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"), 166,
"The second source is correctly displayed.");
}
}
}

Просмотреть файл

@ -8,78 +8,81 @@
const TAB_URL = EXAMPLE_URL + "doc_inline-script.html";
var gTab, gPanel, gDebugger, gSources;
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
function testResume() {
const deferred = promise.defer();
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).");
deferred.resolve();
});
});
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
});
return deferred.promise;
}
function testBreakpointHit() {
const deferred = promise.defer();
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).");
deferred.resolve();
});
});
EventUtils.sendMouseEvent({ type: "mousedown" },
gDebugger.document.getElementById("resume"),
gDebugger);
return deferred.promise;
}
Task.spawn(function(){
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 16);
is(gDebugger.gThreadClient.state, "paused",
"The debugger statement was reached.");
ok(isCaretPos(gPanel, 16),
"The source editor caret position is incorrect (1).");
yield actions.addBreakpoint({ actor: getSourceActor(gSources, TAB_URL), line: 20 });
yield testResume();
yield testBreakpointHit();
resumeDebuggerThenCloseAndFinish(gPanel);
});
callInTab(gTab, "runDebuggerStatement");
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({ actor: getSourceActor(gSources, TAB_URL), line: 20 }).then(() => {
testResume();
});
});
callInTab(gTab, "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();
});
});
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
});
}
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;
gPanel = null;
gDebugger = null;
gSources = null;
});

Просмотреть файл

@ -11,16 +11,13 @@ const TAB_URL = EXAMPLE_URL + "doc_breakpoints-other-tabs.html";
var test = Task.async(function* () {
const [tab1,, panel1] = yield initDebugger(TAB_URL);
const [tab2,, panel2] = yield initDebugger(TAB_URL);
const queries = panel1.panelWin.require('./content/queries');
const actions = bindActionCreators(panel1);
const getState = panel1.panelWin.DebuggerController.getState;
yield ensureSourceIs(panel1, "code_breakpoints-other-tabs.js", true);
const sources = panel1.panelWin.DebuggerView.Sources;
yield actions.addBreakpoint({
actor: queries.getSelectedSource(getState()).actor,
yield panel1.addBreakpoint({
actor: sources.selectedValue,
line: 2
});

Просмотреть файл

@ -9,48 +9,161 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() {
let gTab, gPanel, gDebugger;
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
const { getBreakpoint } = queries;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
gBreakpointsAdded = gBreakpoints._added;
gBreakpointsRemoving = gBreakpoints._removing;
let breakpointsAdded = 0;
let breakpointsDisabled = 0;
let breakpointsRemoved = 0;
let breakpointsList;
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest);
callInTab(gTab, "firstCall");
});
const addBreakpoints = Task.async(function*(aIncrementFlag) {
const loc1 = { actor: gSources.selectedValue, line: 6 };
yield actions.addBreakpoint(loc1);
onBreakpointAdd(getBreakpoint(getState(), loc1), {
increment: aIncrementFlag,
line: 6,
text: "debugger;"
});
let breakpointsAdded = 0;
let breakpointsDisabled = 0;
let breakpointsRemoved = 0;
const loc2 = { actor: gSources.selectedValue, line: 7 };
yield actions.addBreakpoint(loc2);
onBreakpointAdd(getBreakpoint(getState(), loc2), {
increment: aIncrementFlag,
line: 7,
text: "function foo() {}"
});
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"), 166,
"The correct source was loaded initially.");
is(gSources.selectedValue, gSources.values[1],
"The correct source is selected.");
const loc3 = {actor: gSources.selectedValue, line: 9 }
yield actions.addBreakpoint(loc3);
onBreakpointAdd(getBreakpoint(getState(), loc3), {
increment: aIncrementFlag,
line: 9,
text: "foo();"
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({ actor: gSources.selectedValue, line: 6 }).then(aClient => {
onBreakpointAdd(aClient, {
increment: aIncrementFlag,
line: 6,
text: "debugger;"
});
gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 7 }).then(aClient => {
onBreakpointAdd(aClient, {
increment: aIncrementFlag,
line: 7,
text: "function foo() {}"
});
gPanel.addBreakpoint({ actor: 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();
@ -58,7 +171,7 @@ function test() {
info("Nodes to disable: " + breakpointsAdded.length);
is(nodes.length, breakpointsAdded,
"The number of nodes to disable is incorrect.");
"The number of nodes to disable is incorrect.");
for (let node of nodes) {
info("Disabling breakpoint: " + node.id);
@ -67,7 +180,7 @@ function test() {
let breakpointItem = gSources.getItemForElement.call(sourceItem, node);
info("Found data: " + breakpointItem.attachment.toSource());
actions.disableBreakpoint(breakpointItem.attachment).then(() => {
gSources.disableBreakpoint(breakpointItem.attachment).then(() => {
if (++breakpointsDisabled == breakpointsAdded) {
deferred.resolve();
}
@ -84,7 +197,7 @@ function test() {
info("Nodes to remove: " + breakpointsAdded.length);
is(nodes.length, breakpointsAdded,
"The number of nodes to remove is incorrect.");
"The number of nodes to remove is incorrect.");
for (let node of nodes) {
info("Removing breakpoint: " + node.id);
@ -93,7 +206,7 @@ function test() {
let breakpointItem = gSources.getItemForElement.call(sourceItem, node);
info("Found data: " + breakpointItem.attachment.toSource());
actions.removeBreakpoint(breakpointItem.attachment).then(() => {
gPanel.removeBreakpoint(breakpointItem.attachment).then(() => {
if (++breakpointsRemoved == breakpointsAdded) {
deferred.resolve();
}
@ -103,130 +216,39 @@ function test() {
return deferred.promise;
}
function onBreakpointAdd(bp, testData) {
if (testData.increment) {
function onBreakpointAdd(aBreakpointClient, aTestData) {
if (aTestData.increment) {
breakpointsAdded++;
}
is(breakpointsList.querySelectorAll(".dbg-breakpoint").length, breakpointsAdded,
testData.increment
? "Should have added a breakpoint in the pane."
: "Should have the same number of breakpoints in the pane.");
aTestData.increment
? "Should have added a breakpoint in the pane."
: "Should have the same number of breakpoints in the pane.");
let identifier = queries.makeLocationId(bp.location);
let identifier = gBreakpoints.getIdentifier(aBreakpointClient.location);
let node = gDebugger.document.getElementById("breakpoint-" + identifier);
let line = node.getElementsByClassName("dbg-breakpoint-line")[0];
let text = node.getElementsByClassName("dbg-breakpoint-text")[0];
let check = node.querySelector("checkbox");
ok(node,
"Breakpoint element found successfully.");
is(line.getAttribute("value"), testData.line,
"The expected information wasn't found in the breakpoint element.");
is(text.getAttribute("value"), testData.text,
"The expected line text wasn't found in the breakpoint element.");
"Breakpoint element 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.");
"The breakpoint enable checkbox is checked as expected.");
}
}
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1);
is(gDebugger.gThreadClient.state, "paused",
"Should only be getting stack frames while paused.");
is(queries.getSourceCount(getState()), 2,
"Found the expected number of sources.");
is(gEditor.getText().indexOf("debugger"), 166,
"The correct source was loaded initially.");
is(gSources.selectedValue, gSources.values[1],
"The correct source is selected.");
is(queries.getBreakpoints(getState()).length, 0,
"No breakpoints currently added.");
let breakpointsParent = gSources.widget._parent;
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.");
yield addBreakpoints(true);
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.");
yield disableBreakpoints();
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.");
yield addBreakpoints();
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.");
yield removeBreakpoints();
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.");
const cleared = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED);
gDebugger.gThreadClient.resume();
yield cleared;
is(queries.getBreakpoints(getState()).length, 0,
"No breakpoints currently added.");
closeDebuggerAndFinish(gPanel);
});
callInTab(gTab, "firstCall");
});
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.");
}
}

Просмотреть файл

@ -12,12 +12,11 @@ var test = Task.async(function* () {
requestLongerTimeout(4);
const [tab,, panel] = yield initDebugger(TAB_URL);
const actions = bindActionCreators(panel);
yield ensureSourceIs(panel, "doc_breakpoints-reload.html", true);
const sources = panel.panelWin.DebuggerView.Sources;
yield actions.addBreakpoint({
yield panel.addBreakpoint({
actor: sources.selectedValue,
line: 10 // "break on me" string
});

Просмотреть файл

@ -22,13 +22,12 @@ function* spawnTest() {
let toolbox = yield gDevTools.showToolbox(options.target, "jsdebugger");
let panel = toolbox.getCurrentPanel();
let constants = panel.panelWin.require('./content/constants');
yield waitForDebuggerEvents(panel, panel.panelWin.EVENTS.SOURCE_SHOWN);
function cmd(aTyped, aEventRepeat = 1, aOutput = "") {
return promise.all([
waitForDispatch(panel, constants.BLACKBOX, aEventRepeat),
waitForThreadEvents(panel, "blackboxchange", aEventRepeat),
helpers.audit(options, [{ setup: aTyped, output: aOutput, exec: {} }])
]);
}

Просмотреть файл

@ -11,201 +11,233 @@ function test() {
// Linux debug test slaves are a bit slow at this test sometimes.
requestLongerTimeout(2);
let gTab, gPanel, gDebugger;
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
gBreakpointsAdded = gBreakpoints._added;
gBreakpointsRemoving = gBreakpoints._removing;
// This test forces conditional breakpoints to be evaluated on the
// client-side
var client = gPanel.target.client;
client.mainRoot.traits.conditionalBreakpoints = false;
const addBreakpoints = Task.async(function*() {
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 18 },
"undefined");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 19 },
"null");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 20 },
"42");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 21 },
"true");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 22 },
"'nasu'");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 23 },
"/regexp/");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 24 },
"({})");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 25 },
"(function() {})");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 26 },
"(function() { return false; })()");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 27 },
"a");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 28 },
"a !== undefined");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 29 },
"b");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 30 },
"a !== null");
});
function resumeAndTestBreakpoint(line) {
let finished = waitForCaretUpdated(gPanel, line).then(() => testBreakpoint(line));
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._selectedBreakpoint,
"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.");
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(() => {
// Note: the breakpoint on line 29 should not be hit since the
// conditional expression evaluates to undefined. It used to
// be on line 30, but it can't be the last breakpoint because
// there is a race condition (the "frames cleared" event might
// fire from the conditional expression evaluation if it's too
// slow, which is what we wait for to reload the page)
return resumeAndTestBreakpoint(30);
})
.then(() => resumeAndTestNoBreakpoint())
.then(() => {
return promise.all([
reloadActiveTab(gPanel, gDebugger.EVENTS.BREAKPOINT_SHOWN_IN_EDITOR, 13),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_SHOWN_IN_PANE, 13)
]);
})
.then(() => testAfterReload())
.then(() => {
// Reset traits back to default value
client.mainRoot.traits.conditionalBreakpoints = true;
})
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
gDebugger.gThreadClient.resume();
return finished;
}
function testBreakpoint(line, highlightBreakpoint) {
// Highlight the breakpoint only if required.
if (highlightBreakpoint) {
let finished = waitForCaretUpdated(gPanel, line).then(() => testBreakpoint(line));
gSources.highlightBreakpoint({ actor: gSources.selectedValue, line: line });
return finished;
}
let selectedActor = gSources.selectedValue;
let selectedBreakpoint = gSources._selectedBreakpoint;
let selectedBreakpointItem = gSources._getBreakpoint(selectedBreakpoint);
ok(selectedActor,
"There should be a selected item in the sources pane.");
ok(selectedBreakpoint,
"There should be a selected breakpoint in the sources pane.");
let source = gSources.selectedItem.attachment.source;
let bp = queries.getBreakpoint(getState(), selectedBreakpoint.location);
ok(bp, "The selected breakpoint exists");
is(bp.location.actor, source.actor,
"The breakpoint on line " + line + " wasn't added on the correct source.");
is(bp.location.line, line,
"The breakpoint on line " + line + " wasn't found.");
is(!!bp.disabled, false,
"The breakpoint on line " + line + " should be enabled.");
is(!!selectedBreakpointItem.attachment.openPopup, false,
"The breakpoint on line " + line + " should not have opened a popup.");
is(gSources._conditionalPopupVisible, false,
"The breakpoint conditional expression popup should not have been shown.");
isnot(bp.condition, undefined,
"The breakpoint on line " + line + " should have a conditional expression.");
ok(isCaretPos(gPanel, line),
"The editor caret position is not properly set.");
}
const testAfterReload = Task.async(function*() {
let selectedActor = gSources.selectedValue;
let selectedBreakpoint = gSources._selectedBreakpoint;
ok(selectedActor,
"There should be a selected item in the sources pane after reload.");
ok(!selectedBreakpoint,
"There should be no selected breakpoint in the sources pane after reload.");
yield testBreakpoint(18, true);
yield testBreakpoint(19, true);
yield testBreakpoint(20, true);
yield testBreakpoint(21, true);
yield testBreakpoint(22, true);
yield testBreakpoint(23, true);
yield testBreakpoint(24, true);
yield testBreakpoint(25, true);
yield testBreakpoint(26, true);
yield testBreakpoint(27, true);
yield testBreakpoint(28, true);
yield testBreakpoint(29, true);
yield testBreakpoint(30, true);
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._selectedBreakpoint,
"There should be a selected breakpoint in the sources pane.")
is(gSources._conditionalPopupVisible, false,
"The breakpoint conditional expression popup should not be shown.");
});
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 17);
yield addBreakpoints();
is(gDebugger.gThreadClient.state, "paused",
"Should only be getting stack frames while paused.");
is(queries.getSourceCount(getState()), 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(queries.getBreakpoints(getState()).length, 13,
"13 breakpoints currently added.");
yield resumeAndTestBreakpoint(20);
yield resumeAndTestBreakpoint(21);
yield resumeAndTestBreakpoint(22);
yield resumeAndTestBreakpoint(23);
yield resumeAndTestBreakpoint(24);
yield resumeAndTestBreakpoint(25);
yield resumeAndTestBreakpoint(27);
yield resumeAndTestBreakpoint(28);
yield resumeAndTestBreakpoint(29);
yield resumeAndTestBreakpoint(30);
yield resumeAndTestNoBreakpoint();
let sourceShown = waitForSourceShown(gPanel, ".html");
reload(gPanel),
yield sourceShown;
testAfterReload();
// Reset traits back to default value
client.mainRoot.traits.conditionalBreakpoints = true;
closeDebuggerAndFinish(gPanel);
});
callInTab(gTab, "ermahgerd");
});
function addBreakpoints() {
return promise.resolve(null)
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 18 }))
.then(aClient => aClient.conditionalExpression = "undefined")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 19 }))
.then(aClient => aClient.conditionalExpression = "null")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 20 }))
.then(aClient => aClient.conditionalExpression = "42")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 21 }))
.then(aClient => aClient.conditionalExpression = "true")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 22 }))
.then(aClient => aClient.conditionalExpression = "'nasu'")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 23 }))
.then(aClient => aClient.conditionalExpression = "/regexp/")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 24 }))
.then(aClient => aClient.conditionalExpression = "({})")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 25 }))
.then(aClient => aClient.conditionalExpression = "(function() {})")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 26 }))
.then(aClient => aClient.conditionalExpression = "(function() { return false; })()")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 27 }))
.then(aClient => aClient.conditionalExpression = "a")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 28 }))
.then(aClient => aClient.conditionalExpression = "a !== undefined")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 29 }))
.then(aClient => aClient.conditionalExpression = "b")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 30 }))
.then(aClient => aClient.conditionalExpression = "a !== null");
}
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({ actor: gSources.selectedValue, line: aLine });
return finished;
}
let selectedActor = gSources.selectedValue;
let selectedBreakpoint = gSources._selectedBreakpointItem;
ok(selectedActor,
"There should be a selected item in the sources pane.");
ok(selectedBreakpoint,
"There should be a selected breakpoint in the sources pane.");
let source = gSources.selectedItem.attachment.source;
is(selectedBreakpoint.attachment.actor, source.actor,
"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, source.url,
"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 selectedActor = gSources.selectedValue;
let selectedBreakpoint = gSources._selectedBreakpointItem;
ok(selectedActor,
"There should be a selected item in the sources pane after reload.");
ok(!selectedBreakpoint,
"There should be no selected breakpoint 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.");
});
}
}

Просмотреть файл

@ -8,187 +8,197 @@
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
function test() {
let gTab, gPanel, gDebugger;
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
gBreakpointsAdded = gBreakpoints._added;
gBreakpointsRemoving = gBreakpoints._removing;
// This test forces conditional breakpoints to be evaluated on the
// client-side
var client = gPanel.target.client;
client.mainRoot.traits.conditionalBreakpoints = false;
function addBreakpoint1() {
return actions.addBreakpoint({ actor: gSources.selectedValue, line: 18 });
}
function addBreakpoint2() {
let finished = waitForDispatch(gPanel, constants.ADD_BREAKPOINT);
setCaretPosition(19);
gSources._onCmdAddBreakpoint();
return finished;
}
function modBreakpoint2() {
setCaretPosition(19);
gSources._onCmdAddConditionalBreakpoint();
}
function addBreakpoint3() {
let finished = waitForDispatch(gPanel, constants.ADD_BREAKPOINT);
setCaretPosition(20);
gSources._onCmdAddConditionalBreakpoint();
return finished;
}
function modBreakpoint3() {
let finished = waitForDispatch(gPanel, constants.SET_BREAKPOINT_CONDITION);
setCaretPosition(20);
gSources._onCmdAddConditionalBreakpoint();
typeText(gSources._cbTextbox, "bamboocha");
EventUtils.sendKey("RETURN", gDebugger);
return finished;
}
function addBreakpoint4() {
let finished = waitForDispatch(gPanel, constants.ADD_BREAKPOINT);
setCaretPosition(21);
gSources._onCmdAddBreakpoint();
return finished;
}
function delBreakpoint4() {
let finished = waitForDispatch(gPanel, constants.REMOVE_BREAKPOINT);
setCaretPosition(21);
gSources._onCmdAddBreakpoint();
return finished;
}
function testBreakpoint(aLine, aPopupVisible, aConditionalExpression) {
const source = queries.getSelectedSource(getState());
ok(source,
"There should be a selected item in the sources pane.");
const bp = queries.getBreakpoint(getState(), {
actor: source.actor,
line: aLine
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(() => {
// Reset traits back to default value
client.mainRoot.traits.conditionalBreakpoints = true;
})
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
const bpItem = gSources._getBreakpoint(bp);
ok(bp, "There should be a breakpoint.");
ok(bpItem, "There should be a breakpoint in the sources pane.");
is(bp.location.actor, source.actor,
"The breakpoint on line " + aLine + " wasn't added on the correct source.");
is(bp.location.line, aLine,
"The breakpoint on line " + aLine + " wasn't found.");
is(!!bp.disabled, false,
"The breakpoint on line " + aLine + " should be enabled.");
is(gSources._conditionalPopupVisible, aPopupVisible,
"The breakpoint on line " + aLine + " should have a correct popup state (2).");
is(bp.condition, aConditionalExpression,
"The breakpoint on line " + aLine + " should have a correct conditional expression.");
}
function testNoBreakpoint(aLine) {
let selectedActor = gSources.selectedValue;
let selectedBreakpoint = gSources._selectedBreakpoint;
ok(selectedActor,
"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.setCursor({ line: aLine - 1, ch: 0 });
}
function clickOnBreakpoint(aIndex) {
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelectorAll(".dbg-breakpoint")[aIndex],
gDebugger);
}
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 17);
is(gDebugger.gThreadClient.state, "paused",
"Should only be getting stack frames while paused.");
is(queries.getSourceCount(getState()), 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(queries.getBreakpoints(getState()).length, 0,
"No breakpoints currently added.");
yield addBreakpoint1();
testBreakpoint(18, false, undefined)
yield addBreakpoint2();
testBreakpoint(19, false, undefined);
yield modBreakpoint2();
testBreakpoint(19, true, undefined);
yield addBreakpoint3();
testBreakpoint(20, false, undefined);
yield modBreakpoint3();
testBreakpoint(20, false, "bamboocha");
yield addBreakpoint4();
testBreakpoint(21, false, undefined);
yield delBreakpoint4();
setCaretPosition(18);
is(gSources._selectedBreakpoint.location.line, 18,
"The selected breakpoint is line 18");
yield testBreakpoint(18, false, undefined);
setCaretPosition(19);
is(gSources._selectedBreakpoint.location.line, 19,
"The selected breakpoint is line 19");
yield testBreakpoint(19, false, "");
setCaretPosition(20);
is(gSources._selectedBreakpoint.location.line, 20,
"The selected breakpoint is line 20");
yield testBreakpoint(20, false, "bamboocha");
setCaretPosition(17);
yield testNoBreakpoint(17);
setCaretPosition(21);
yield testNoBreakpoint(21);
clickOnBreakpoint(0);
is(gSources._selectedBreakpoint.location.line, 18,
"The selected breakpoint is line 18");
yield testBreakpoint(18, false, undefined);
clickOnBreakpoint(1);
is(gSources._selectedBreakpoint.location.line, 19,
"The selected breakpoint is line 19");
yield testBreakpoint(19, false, "");
clickOnBreakpoint(2);
is(gSources._selectedBreakpoint.location.line, 20,
"The selected breakpoint is line 20");
testBreakpoint(20, true, "bamboocha");
// Reset traits back to default value
client.mainRoot.traits.conditionalBreakpoints = true;
resumeDebuggerThenCloseAndFinish(gPanel);
});
callInTab(gTab, "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({ actor: "foo", line: 3 }),
"_getAdded('foo', 3) returns falsey.");
ok(!gBreakpoints._getRemoving({ actor: "bar", line: 3 }),
"_getRemoving('bar', 3) returns falsey.");
}
function addBreakpoint1() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 18 });
return finished;
}
function addBreakpoint2() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
setCaretPosition(19);
gSources._onCmdAddBreakpoint();
return finished;
}
function modBreakpoint2() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
setCaretPosition(19);
gSources._onCmdAddConditionalBreakpoint();
return finished;
}
function addBreakpoint3() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
setCaretPosition(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);
setCaretPosition(21);
gSources._onCmdAddBreakpoint();
return finished;
}
function delBreakpoint4() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED);
setCaretPosition(21);
gSources._onCmdAddBreakpoint();
return finished;
}
function testBreakpoint(aLine, aOpenPopupFlag, aPopupVisible, aConditionalExpression) {
let selectedActor = gSources.selectedValue;
let selectedBreakpoint = gSources._selectedBreakpointItem;
ok(selectedActor,
"There should be a selected item in the sources pane.");
ok(selectedBreakpoint,
"There should be a selected brekapoint in the sources pane.");
let source = gSources.selectedItem.attachment.source;
is(selectedBreakpoint.attachment.actor, source.actor,
"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.actor, selectedActor,
"The breakpoint's client actor 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 selectedActor = gSources.selectedValue;
let selectedBreakpoint = gSources._selectedBreakpointItem;
ok(selectedActor,
"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.setCursor({ line: aLine - 1, ch: 0 });
}
function clickOnBreakpoint(aIndex) {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_CLICKED);
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelectorAll(".dbg-breakpoint")[aIndex],
gDebugger);
return finished;
}
}

Просмотреть файл

@ -8,46 +8,83 @@
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
function test() {
let gTab, gPanel, gDebugger;
let gSources, gBreakpoints, gLocation;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
// This test forces conditional breakpoints to be evaluated on the
// client-side
var client = gPanel.target.client;
client.mainRoot.traits.conditionalBreakpoints = false;
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 17);
const location = { actor: gSources.selectedValue, line: 18 };
gLocation = { actor: gSources.selectedValue, line: 18 };
yield actions.addBreakpoint(location, "hello");
yield actions.disableBreakpoint(location);
yield actions.addBreakpoint(location);
const bp = queries.getBreakpoint(getState(), location);
is(bp.condition, "hello", "The conditional expression is correct.");
const finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelector(".dbg-breakpoint"),
gDebugger);
yield finished;
const textbox = gDebugger.document.getElementById("conditional-breakpoint-panel-textbox");
is(textbox.value, "hello", "The expression is correct (2).")
// Reset traits back to default value
client.mainRoot.traits.conditionalBreakpoints = true;
resumeDebuggerThenCloseAndFinish(gPanel);
});
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
.then(addBreakpoint)
.then(setConditional)
.then(() => {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED);
toggleBreakpoint();
return finished;
})
.then(() => {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
toggleBreakpoint();
return finished;
})
.then(testConditionalExpressionOnClient)
.then(() => {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
openConditionalPopup();
return finished;
})
.then(testConditionalExpressionInPopup)
.then(() => {
// Reset traits back to default value
client.mainRoot.traits.conditionalBreakpoints = true;
})
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
callInTab(gTab, "ermahgerd");
});
function addBreakpoint() {
return gPanel.addBreakpoint(gLocation);
}
function setConditional(aClient) {
aClient.conditionalExpression = "hello";
}
function toggleBreakpoint() {
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelector(".dbg-breakpoint-checkbox"),
gDebugger);
}
function openConditionalPopup() {
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelector(".dbg-breakpoint"),
gDebugger);
}
function testConditionalExpressionOnClient() {
return gBreakpoints._getAdded(gLocation).then(aClient => {
is(aClient.conditionalExpression, "hello", "The expression is correct (1).");
});
}
function testConditionalExpressionInPopup() {
let textbox = gDebugger.document.getElementById("conditional-breakpoint-panel-textbox");
is(textbox.value, "hello", "The expression is correct (2).")
}
}

Просмотреть файл

@ -2,44 +2,91 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that conditional breakpoints with blank expressions
* Make sure that conditional breakpoints with undefined expressions
* are stored as plain breakpoints when re-enabling them.
*/
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
function test() {
let gTab, gPanel, gDebugger;
let gSources, gBreakpoints, gLocation;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
// This test forces conditional breakpoints to be evaluated on the
// client-side
var client = gPanel.target.client;
client.mainRoot.traits.conditionalBreakpoints = false;
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 17);
const location = { actor: gSources.selectedValue, line: 18 };
gLocation = { actor: gSources.selectedValue, line: 18 };
yield actions.addBreakpoint(location, "");
yield actions.disableBreakpoint(location);
yield actions.addBreakpoint(location);
const bp = queries.getBreakpoint(getState(), location);
is(bp.condition, undefined, "The conditional expression is correct.");
// Reset traits back to default value
client.mainRoot.traits.conditionalBreakpoints = true;
resumeDebuggerThenCloseAndFinish(gPanel);
});
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
.then(addBreakpoint)
.then(setDummyConditional)
.then(() => {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED);
toggleBreakpoint();
return finished;
})
.then(() => {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
toggleBreakpoint();
return finished;
})
.then(testConditionalExpressionOnClient)
.then(() => {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
openConditionalPopup();
finished.then(() => ok(false, "The popup shouldn't have opened."));
return waitForTime(1000);
})
.then(() => {
// Reset traits back to default value
client.mainRoot.traits.conditionalBreakpoints = true;
})
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
callInTab(gTab, "ermahgerd");
});
function addBreakpoint() {
return gPanel.addBreakpoint(gLocation);
}
function setDummyConditional(aClient) {
// This happens when a conditional expression input popup is shown
// but the user doesn't type anything into it.
aClient.conditionalExpression = "";
}
function toggleBreakpoint() {
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelector(".dbg-breakpoint-checkbox"),
gDebugger);
}
function openConditionalPopup() {
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelector(".dbg-breakpoint"),
gDebugger);
}
function testConditionalExpressionOnClient() {
return gBreakpoints._getAdded(gLocation).then(aClient => {
if ("conditionalExpression" in aClient) {
ok(false, "A conditional expression shouldn't have been set.");
} else {
ok(true, "The conditional expression wasn't set, as expected.");
}
});
}
}

Просмотреть файл

@ -9,127 +9,133 @@
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
function test() {
let gTab, gPanel, gDebugger, gEditor;
let gSources, gBreakpoints, gLocation;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
// This test forces conditional breakpoints to be evaluated on the
// client-side
var client = gPanel.target.client;
client.mainRoot.traits.conditionalBreakpoints = false;
function resumeAndTestBreakpoint(line) {
let finished = waitForCaretUpdated(gPanel, line).then(() => testBreakpoint(line));
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._selectedBreakpoint,
"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, 6,
"There should be thirteen visible breakpoints.");
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
.then(addBreakpoints)
.then(() => resumeAndTestBreakpoint(18))
.then(() => resumeAndTestBreakpoint(19))
.then(() => resumeAndTestBreakpoint(20))
.then(() => resumeAndTestBreakpoint(23))
.then(() => resumeAndTestNoBreakpoint())
.then(() => {
// Reset traits back to default value
client.mainRoot.traits.conditionalBreakpoints = true;
})
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
gDebugger.gThreadClient.resume();
return finished;
}
function testBreakpoint(line, highlightBreakpoint) {
// Highlight the breakpoint only if required.
if (highlightBreakpoint) {
let finished = waitForCaretUpdated(gPanel, line).then(() => testBreakpoint(line));
gSources.highlightBreakpoint({ actor: gSources.selectedValue, line: line });
return finished;
}
let selectedActor = gSources.selectedValue;
let selectedBreakpoint = gSources._selectedBreakpoint;
let selectedBreakpointItem = gSources._getBreakpoint(selectedBreakpoint);
let source = queries.getSource(getState(), selectedActor);
ok(selectedActor,
"There should be a selected item in the sources pane.");
ok(selectedBreakpoint,
"There should be a selected breakpoint.");
ok(selectedBreakpointItem,
"There should be a selected breakpoint item in the sources pane.");
is(selectedBreakpoint.location.actor, source.actor,
"The breakpoint on line " + line + " wasn't added on the correct source.");
is(selectedBreakpoint.location.line, line,
"The breakpoint on line " + line + " wasn't found.");
is(!!selectedBreakpoint.location.disabled, false,
"The breakpoint on line " + line + " should be enabled.");
is(gSources._conditionalPopupVisible, false,
"The breakpoint conditional expression popup should not have been shown.");
isnot(selectedBreakpoint.condition, undefined,
"The breakpoint on line " + line + " should have a conditional expression.");
ok(isCaretPos(gPanel, line),
"The editor caret position is not properly set.");
}
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
yield actions.addBreakpoint(
{ actor: gSources.selectedValue, line: 18 }, " 1a"
);
yield actions.addBreakpoint(
{ actor: gSources.selectedValue, line: 19 }, "new Error()"
);
yield actions.addBreakpoint(
{ actor: gSources.selectedValue, line: 20 }, "true"
);
yield actions.addBreakpoint(
{ actor: gSources.selectedValue, line: 21 }, "false"
);
yield actions.addBreakpoint(
{ actor: gSources.selectedValue, line: 22 }, "0"
);
yield actions.addBreakpoint(
{ actor: gSources.selectedValue, line: 23 }, "randomVar"
);
yield resumeAndTestBreakpoint(18);
yield resumeAndTestBreakpoint(19);
yield resumeAndTestBreakpoint(20);
yield resumeAndTestBreakpoint(23);
yield resumeAndTestNoBreakpoint();
// Reset traits back to default value
client.mainRoot.traits.conditionalBreakpoints = true;
closeDebuggerAndFinish(gPanel);
});
callInTab(gTab, "ermahgerd");
});
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, 6,
"There should be thirteen visible breakpoints.");
});
gDebugger.gThreadClient.resume();
return finished;
}
function addBreakpoints() {
return promise.resolve(null)
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 18 }))
.then(aClient => aClient.conditionalExpression = " 1a")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 19 }))
.then(aClient => aClient.conditionalExpression = "new Error()")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 20 }))
.then(aClient => aClient.conditionalExpression = "true")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 21 }))
.then(aClient => aClient.conditionalExpression = "false")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 22 }))
.then(aClient => aClient.conditionalExpression = "0")
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 23 }))
.then(aClient => aClient.conditionalExpression = "randomVar");
}
function testBreakpoint(aLine, aHighlightBreakpoint) {
// Highlight the breakpoint only if required.
if (aHighlightBreakpoint) {
let finished = waitForCaretUpdated(gPanel, aLine).then(() => testBreakpoint(aLine));
gSources.highlightBreakpoint({ actor: gSources.selectedValue, line: aLine });
return finished;
}
let selectedActor = gSources.selectedValue;
let selectedBreakpoint = gSources._selectedBreakpointItem;
ok(selectedActor,
"There should be a selected item in the sources pane.");
ok(selectedBreakpoint,
"There should be a selected breakpoint in the sources pane.");
let source = gSources.selectedItem.attachment.source;
is(selectedBreakpoint.attachment.actor, source.actor,
"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, source.url,
"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.");
});
}
}

Просмотреть файл

@ -7,34 +7,36 @@
*/
function test() {
Task.spawn(function*() {
let TAB_URL = EXAMPLE_URL + "doc_empty-tab-01.html";
let [,, panel] = yield initDebugger(TAB_URL);
let dbgWin = panel.panelWin;
let sources = dbgWin.DebuggerView.Sources;
let frames = dbgWin.DebuggerView.StackFrames;
let editor = dbgWin.DebuggerView.editor;
let toolbox = gDevTools.getToolbox(panel.target);
let paused = promise.all([
waitForEditorEvents(panel, "cursorActivity"),
waitForDebuggerEvents(panel, dbgWin.EVENTS.SOURCE_SHOWN)
]);
toolbox.once("webconsole-ready", () => {
ok(toolbox.splitConsole, "Split console is shown.");
let jsterm = toolbox.getPanel("webconsole").hud.jsterm;
jsterm.execute('debugger');
});
EventUtils.synthesizeKey("VK_ESCAPE", {}, dbgWin);
yield paused;
is(sources.selectedItem.attachment.label, 'SCRIPT0',
'Anonymous source is selected in sources');
dump('text ::' + editor.getText() + '::\n');
ok(editor.getText() === 'debugger', 'Editor has correct text');
yield toolbox.closeSplitConsole();
yield resumeDebuggerThenCloseAndFinish(panel);
});
Task.spawn(runTests);
}
function* runTests() {
let TAB_URL = EXAMPLE_URL + "doc_empty-tab-01.html";
let [,, panel] = yield initDebugger(TAB_URL);
let dbgWin = panel.panelWin;
let sources = dbgWin.DebuggerView.Sources;
let frames = dbgWin.DebuggerView.StackFrames;
let editor = dbgWin.DebuggerView.editor;
let toolbox = gDevTools.getToolbox(panel.target);
let paused = promise.all([
waitForEditorEvents(panel, "cursorActivity"),
waitForDebuggerEvents(panel, dbgWin.EVENTS.SOURCE_SHOWN)
]);
toolbox.once("webconsole-ready", () => {
ok(toolbox.splitConsole, "Split console is shown.");
let jsterm = toolbox.getPanel("webconsole").hud.jsterm;
jsterm.execute('debugger');
});
EventUtils.synthesizeKey("VK_ESCAPE", {}, dbgWin);
yield paused;
is(sources.selectedItem.attachment.label, 'SCRIPT0',
'Anonymous source is selected in sources');
dump('text ::' + editor.getText() + '::\n');
ok(editor.getText() === 'debugger', 'Editor has correct text');
yield toolbox.closeSplitConsole();
yield resumeDebuggerThenCloseAndFinish(panel);
}

Просмотреть файл

@ -9,17 +9,14 @@ const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() {
Task.spawn(function*() {
const [tab,, panel] = yield initDebugger(TAB_URL);
const win = panel.panelWin;
const frames = win.DebuggerController.StackFrames;
const framesView = win.DebuggerView.StackFrames;
const sourcesView = win.DebuggerView.Sources;
const editorView = win.DebuggerView.editor;
const events = win.EVENTS;
const queries = win.require('./content/queries');
const constants = win.require('./content/constants');
const actions = bindActionCreators(panel);
const getState = win.DebuggerController.getState;
let [tab,, panel] = yield initDebugger(TAB_URL);
let win = panel.panelWin;
let frames = win.DebuggerController.StackFrames;
let framesView = win.DebuggerView.StackFrames;
let sources = win.DebuggerController.SourceScripts;
let sourcesView = win.DebuggerView.Sources;
let editorView = win.DebuggerView.editor;
let events = win.EVENTS;
function checkView(frameDepth, selectedSource, caretLine, editorText) {
is(win.gThreadClient.state, "paused",
@ -36,15 +33,9 @@ function test() {
"The correct source is not displayed.");
}
// Cache the sources text to avoid having to wait for their
// retrieval.
const sources = queries.getSources(getState());
yield promise.all(Object.keys(sources).map(k => {
return actions.loadSourceText(sources[k]);
}));
is(Object.keys(getState().sources.sourcesText).length, 2,
"There should be two cached sources in the cache.");
// Cache the sources text to avoid having to wait for their retrieval.
yield promise.all(sourcesView.attachments.map(e => sources.getText(e.source)));
is(sources._cache.size, 2, "There should be two cached sources in the cache.");
// Eval while not paused.
try {

Просмотреть файл

@ -9,17 +9,14 @@ const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() {
Task.spawn(function*() {
const [tab,, panel] = yield initDebugger(TAB_URL);
const win = panel.panelWin;
const frames = win.DebuggerController.StackFrames;
const framesView = win.DebuggerView.StackFrames;
const sourcesView = win.DebuggerView.Sources;
const editorView = win.DebuggerView.editor;
const events = win.EVENTS;
const queries = win.require('./content/queries');
const constants = win.require('./content/constants');
const actions = bindActionCreators(panel);
const getState = win.DebuggerController.getState;
let [tab,, panel] = yield initDebugger(TAB_URL);
let win = panel.panelWin;
let frames = win.DebuggerController.StackFrames;
let framesView = win.DebuggerView.StackFrames;
let sources = win.DebuggerController.SourceScripts;
let sourcesView = win.DebuggerView.Sources;
let editorView = win.DebuggerView.editor;
let events = win.EVENTS;
function checkView(selectedFrame, selectedSource, caretLine, editorText) {
is(win.gThreadClient.state, "paused",
@ -36,12 +33,9 @@ function test() {
"The correct source is not displayed.");
}
// Cache the sources text to avoid having to wait for their
// retrieval.
const sources = queries.getSources(getState());
yield promise.all(Object.keys(sources).map(k => {
return actions.loadSourceText(sources[k]);
}));
// Cache the sources text to avoid having to wait for their retrieval.
yield promise.all(sourcesView.attachments.map(e => sources.getText(e.source)));
is(sources._cache.size, 2, "There should be two cached sources in the cache.");
// Allow this generator function to yield first.
callInTab(tab, "firstCall");

Просмотреть файл

@ -14,36 +14,33 @@
const TAB_URL = EXAMPLE_URL + "doc_event-listeners-01.html";
function test() {
Task.spawn(function*() {
let tab = yield addTab(TAB_URL);
add_task(function* () {
let tab = yield addTab(TAB_URL);
// Create a sandboxed content script the Add-on SDK way. Inspired by bug
// 1145996.
let tabs = require('sdk/tabs');
let sdkTab = [...tabs].find(tab => tab.url === TAB_URL);
ok(sdkTab, "Add-on SDK found the loaded tab.");
// Create a sandboxed content script the Add-on SDK way. Inspired by bug
// 1145996.
let tabs = require('sdk/tabs');
let sdkTab = [...tabs].find(tab => tab.url === TAB_URL);
ok(sdkTab, "Add-on SDK found the loaded tab.");
info("Attaching an event handler via add-on sdk content scripts.");
let worker = sdkTab.attach({
contentScript: "document.body.addEventListener('click', e => alert(e))",
onError: ok.bind(this, false)
});
let [,, panel, win] = yield initDebugger(tab);
let dbg = panel.panelWin;
let controller = dbg.DebuggerController;
let constants = dbg.require('./content/constants');
let actions = dbg.require('./content/actions/event-listeners');
let fetched = waitForDispatch(panel, constants.FETCH_EVENT_LISTENERS);
info("Scheduling event listener fetch.");
controller.dispatch(actions.fetchEventListeners());
info("Waiting for updated event listeners to arrive.");
yield fetched;
ok(true, "The listener update did not hang.");
closeDebuggerAndFinish(panel);
info("Attaching an event handler via add-on sdk content scripts.");
let worker = sdkTab.attach({
contentScript: "document.body.addEventListener('click', e => alert(e))",
onError: ok.bind(this, false)
});
}
let [,, panel, win] = yield initDebugger(tab);
let gDebugger = panel.panelWin;
let gStore = gDebugger.store;
let constants = gDebugger.require('./content/constants');
let actions = gDebugger.require('./content/actions/event-listeners');
let fetched = afterDispatch(gStore, constants.FETCH_EVENT_LISTENERS);
info("Scheduling event listener fetch.");
gStore.dispatch(actions.fetchEventListeners());
info("Waiting for updated event listeners to arrive.");
yield fetched;
ok(true, "The listener update did not hang.");
});

Просмотреть файл

@ -10,28 +10,24 @@ const JS_URL = EXAMPLE_URL + "sjs_random-javascript.sjs";
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gPanel = aPanel;
const gDebugger = aPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
let gDebugger = aPanel.panelWin;
let gEditor = gDebugger.DebuggerView.editor;
let gSources = gDebugger.DebuggerView.Sources;
let gControllerSources = gDebugger.DebuggerController.SourceScripts;
Task.spawn(function*() {
yield waitForSourceShown(gPanel, JS_URL);
let source = queries.getSelectedSource(getState());
yield waitForSourceShown(aPanel, JS_URL);
is(queries.getSourceCount(getState()), 1,
is(gSources.itemCount, 1,
"There should be one source displayed in the view.")
is(source.url, JS_URL,
is(getSelectedSourceURL(gSources), JS_URL,
"The correct source is currently selected in the view.");
ok(gEditor.getText().includes("bacon"),
"The currently shown source contains bacon. Mmm, delicious!");
const { text: firstText } = yield queries.getSourceText(getState(), source.actor);
const firstNumber = parseFloat(firstText.match(/\d\.\d+/)[0]);
let { source } = gSources.selectedItem.attachment;
let [, firstText] = yield gControllerSources.getText(source);
let firstNumber = parseFloat(firstText.match(/\d\.\d+/)[0]);
is(firstText, gEditor.getText(),
"gControllerSources.getText() returned the expected contents.");
@ -40,16 +36,16 @@ function test() {
yield reloadActiveTab(aPanel, gDebugger.EVENTS.SOURCE_SHOWN);
is(queries.getSourceCount(getState()), 1,
"There should be one source displayed in the view.")
is(source.url, JS_URL,
"The correct source is currently selected in the view.");
is(gSources.itemCount, 1,
"There should be one source displayed in the view after reloading.")
is(getSelectedSourceURL(gSources), JS_URL,
"The correct source is currently selected in the view after reloading.");
ok(gEditor.getText().includes("bacon"),
"The newly shown source contains bacon. Mmm, delicious!");
source = queries.getSelectedSource(getState());
const { text: secondText } = yield queries.getSourceText(getState(), source.actor);
const secondNumber = parseFloat(secondText.match(/\d\.\d+/)[0]);
({ source } = gSources.selectedItem.attachment);
let [, secondText] = yield gControllerSources.getText(source);
let secondNumber = parseFloat(secondText.match(/\d\.\d+/)[0]);
is(secondText, gEditor.getText(),
"gControllerSources.getText() returned the expected contents.");

Просмотреть файл

@ -11,6 +11,9 @@ const TAB_URL = EXAMPLE_URL + "doc_auto-pretty-print-01.html";
var { RootActor } = require("devtools/server/actors/root");
function test() {
let gTab, gDebuggee, gPanel, gDebugger;
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
RootActor.prototype.traits.noBlackBoxing = true;
RootActor.prototype.traits.noPrettyPrinting = true;

Просмотреть файл

@ -2,7 +2,7 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Test resuming from button and keyboard shortcuts.
* Test if the breakpoints toggle button works as advertised.
*/
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
@ -71,7 +71,7 @@ function test() {
evalInTab(gTab, "1+1;");
});
return waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN)
return oncePaused
.then(() => {
ok (!gResumeButton.hasAttribute("break-on-next"), "Resume button isn't waiting for next execution");
is (gResumeButton.getAttribute("checked"), "true", "Resume button is checked");
@ -88,6 +88,7 @@ function test() {
ok (!gResumeButton.hasAttribute("disabled"), "Resume button is not disabled");
ok (!gResumeButton.hasAttribute("break-on-next"), "Resume button isn't waiting for next execution");
ok (!gResumeButton.hasAttribute("checked"), "Resume button is not checked");
let oncePaused = gTarget.once("thread-paused");
// Press the key to break on next execution
EventUtils.synthesizeKey(key, { }, gDebugger);
@ -100,7 +101,7 @@ function test() {
evalInTab(gTab, "1+1;");
});
return waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN)
return oncePaused
.then(() => {
ok (!gResumeButton.hasAttribute("break-on-next"), "Resume button isn't waiting for next execution");
is (gResumeButton.getAttribute("checked"), "true", "Resume button is checked");

Просмотреть файл

@ -7,48 +7,63 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
var gTab, gPanel, gDebugger;
var gEditor, gSources, gFrames;
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const gFrames = gDebugger.DebuggerView.StackFrames;
const constants = gDebugger.require('./content/constants');
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 14);
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.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(gDebugger.document.querySelectorAll("#sources .side-menu-widget-empty-notice-container").length, 0,
"The sources widget should not display any notice at this point (1).");
is(gDebugger.document.querySelectorAll("#sources .side-menu-widget-empty-notice").length, 0,
"The sources widget should not display any notice at this point (2).");
is(gDebugger.document.querySelector("#sources .side-menu-widget-empty-notice > label"), null,
"The sources widget should not display a notice at this point (3).");
yield doResume(gPanel);
navigateActiveTabTo(gPanel, "about:blank");
yield waitForDispatch(gPanel, constants.LOAD_SOURCES);
closeDebuggerAndFinish(gPanel);
});
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gFrames = gDebugger.DebuggerView.StackFrames;
waitForSourceAndCaretAndScopes(gPanel, ".html", 14).then(performTest);
callInTab(gTab, "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.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(gDebugger.document.querySelectorAll("#sources .side-menu-widget-empty-notice-container").length, 0,
"The sources widget should not display any notice at this point (1).");
is(gDebugger.document.querySelectorAll("#sources .side-menu-widget-empty-notice").length, 0,
"The sources widget should not display any notice at this point (2).");
is(gDebugger.document.querySelector("#sources .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;
gPanel = null;
gDebugger = null;
gEditor = null;
gSources = null;
gFrames = null;
});

Просмотреть файл

@ -7,45 +7,54 @@
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
var gTab, gPanel, gDebugger;
var gEditor, gSources, gFrames;
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const gFrames = gDebugger.DebuggerView.StackFrames;
const constants = gDebugger.require('./content/constants');
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 14);
navigateActiveTabTo(gPanel, "about:blank");
yield waitForDispatch(gPanel, constants.LOAD_SOURCES);
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.selectedValue, "",
"There should be no selected source value.");
is(gEditor.getText().length, 0,
"The source editor should not have any text displayed.");
is(gDebugger.document.querySelectorAll("#sources .side-menu-widget-empty-text").length, 1,
"The sources widget should now display a notice (1).");
is(gDebugger.document.querySelectorAll("#sources .side-menu-widget-empty-text")[0].getAttribute("value"),
gDebugger.L10N.getStr("noSourcesText"),
"The sources widget should now display a notice (2).");
closeDebuggerAndFinish(gPanel);
});
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gFrames = gDebugger.DebuggerView.StackFrames;
waitForSourceAndCaretAndScopes(gPanel, ".html", 14).then(testLocationChange);
callInTab(gTab, "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.selectedValue, "",
"There should be no selected source value.");
is(gEditor.getText().length, 0,
"The source editor should not have any text displayed.");
is(gDebugger.document.querySelectorAll("#sources .side-menu-widget-empty-text").length, 1,
"The sources widget should now display a notice (1).");
is(gDebugger.document.querySelectorAll("#sources .side-menu-widget-empty-text")[0].getAttribute("value"),
gDebugger.L10N.getStr("noSourcesText"),
"The sources widget should now display a notice (2).");
closeDebuggerAndFinish(gPanel);
});
}
registerCleanupFunction(function() {
gTab = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gSources = null;
gFrames = null;
});

Просмотреть файл

@ -8,46 +8,55 @@
const TAB_URL_1 = EXAMPLE_URL + "doc_recursion-stack.html";
const TAB_URL_2 = EXAMPLE_URL + "doc_iframes.html";
var gTab, gDebuggee, gPanel, gDebugger;
var gEditor, gSources, gFrames;
function test() {
initDebugger(TAB_URL_1).then(([aTab, aDebuggee, aPanel]) => {
const gTab = aTab;
const gDebuggee = aDebuggee;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const gFrames = gDebugger.DebuggerView.StackFrames;
const constants = gDebugger.require('./content/constants');
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 14);
const startedLoading = waitForNextDispatch(gDebugger.DebuggerController,
constants.LOAD_SOURCE_TEXT);
navigateActiveTabTo(gPanel, TAB_URL_2);
yield startedLoading;
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(getSelectedSourceURL(gSources), 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 be 'Loading...'");
is(gDebugger.document.querySelectorAll("#sources .side-menu-widget-empty-text").length, 0,
"The sources widget should not display any notice at this point.");
yield waitForDispatch(gPanel, constants.LOAD_SOURCE_TEXT);
closeDebuggerAndFinish(gPanel);
});
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(getSelectedSourceURL(gSources), 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(gDebugger.document.querySelectorAll("#sources .side-menu-widget-empty-text").length, 0,
"The sources widget should not display any notice at this point.");
closeDebuggerAndFinish(gPanel);
});
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gSources = null;
gFrames = null;
});

Просмотреть файл

@ -9,154 +9,193 @@
const TAB_URL = EXAMPLE_URL + "doc_included-script.html";
const SOURCE_URL = EXAMPLE_URL + "code_location-changes.js";
var gTab, gDebuggee, gPanel, gDebugger;
var gEditor, gSources;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
const gTab = aTab;
const gDebuggee = aDebuggee;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
function clickButtonAndPause() {
const paused = waitForPause(gDebugger.gThreadClient);
BrowserTestUtils.synthesizeMouse("button", 2, 2, {}, gBrowser.selectedBrowser);
return paused;
}
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 17);
const location = { actor: getSourceActor(gSources, SOURCE_URL), line: 5 };
yield actions.addBreakpoint(location);
const caretUpdated = waitForSourceAndCaret(gPanel, ".js", 5);
gSources.highlightBreakpoint(location);
yield caretUpdated;
ok(true, "Switched to the desired function when adding a breakpoint");
is(gDebugger.gThreadClient.state, "paused",
"The breakpoint was hit (1).");
is(getSelectedSourceURL(gSources), SOURCE_URL,
"The currently shown source is correct (1).");
ok(isCaretPos(gPanel, 5),
"The source editor caret position is correct (1).");
yield doResume(gPanel);
isnot(gDebugger.gThreadClient.state, "paused",
"The breakpoint was not hit yet (2).");
is(getSelectedSourceURL(gSources), SOURCE_URL,
"The currently shown source is correct (2).");
ok(isCaretPos(gPanel, 5),
"The source editor caret position is correct (2).");
let packet = yield clickButtonAndPause();
is(packet.why.type, "breakpoint",
"Execution has advanced to the breakpoint.");
isnot(packet.why.type, "debuggerStatement",
"The breakpoint was hit before the debugger statement.");
yield ensureCaretAt(gPanel, 5, 1, true);
is(gDebugger.gThreadClient.state, "paused",
"The breakpoint was hit (3).");
is(getSelectedSourceURL(gSources), SOURCE_URL,
"The currently shown source is incorrect (3).");
ok(isCaretPos(gPanel, 5),
"The source editor caret position is incorrect (3).");
let paused = waitForPause(gDebugger.gThreadClient);
gDebugger.gThreadClient.resume();
packet = yield paused;
is(packet.why.type, "debuggerStatement",
"Execution has advanced to the next line.");
isnot(packet.why.type, "breakpoint",
"No ghost breakpoint was hit.");
yield ensureCaretAt(gPanel, 6, 1, true);
is(gDebugger.gThreadClient.state, "paused",
"The debugger statement was hit (4).");
is(getSelectedSourceURL(gSources), SOURCE_URL,
"The currently shown source is incorrect (4).");
ok(isCaretPos(gPanel, 6),
"The source editor caret position is incorrect (4).");
yield promise.all([
reload(gPanel),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN)
]);
isnot(gDebugger.gThreadClient.state, "paused",
"The breakpoint wasn't hit yet (5).");
is(getSelectedSourceURL(gSources), SOURCE_URL,
"The currently shown source is incorrect (5).");
ok(isCaretPos(gPanel, 1),
"The source editor caret position is incorrect (5).");
paused = waitForPause(gDebugger.gThreadClient);
clickButtonAndPause();
packet = yield paused;
is(packet.why.type, "breakpoint",
"Execution has advanced to the breakpoint.");
isnot(packet.why.type, "debuggerStatement",
"The breakpoint was hit before the debugger statement.");
yield ensureCaretAt(gPanel, 5, 1, true);
is(gDebugger.gThreadClient.state, "paused",
"The breakpoint was hit (6).");
is(getSelectedSourceURL(gSources), SOURCE_URL,
"The currently shown source is incorrect (6).");
ok(isCaretPos(gPanel, 5),
"The source editor caret position is incorrect (6).");
paused = waitForPause(gDebugger.gThreadClient);
gDebugger.gThreadClient.resume();
packet = yield paused;
is(packet.why.type, "debuggerStatement",
"Execution has advanced to the next line.");
isnot(packet.why.type, "breakpoint",
"No ghost breakpoint was hit.");
yield ensureCaretAt(gPanel, 6, 1, true)
is(gDebugger.gThreadClient.state, "paused",
"The debugger statement was hit (7).");
is(getSelectedSourceURL(gSources), SOURCE_URL,
"The currently shown source is incorrect (7).");
ok(isCaretPos(gPanel, 6),
"The source editor caret position is incorrect (7).");
let sourceShown = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN)
// Click the second source in the list.
yield actions.selectSource(getSourceForm(gSources, TAB_URL));
yield sourceShown;
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.");
yield ensureCaretAt(gPanel, 1, 1, true);
sourceShown = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
yield actions.selectSource(getSourceForm(gSources, SOURCE_URL));
yield sourceShown;
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.");
//yield waitForTime(2000);
yield ensureCaretAt(gPanel, 1, 1, true);
//yield waitForTime(50000);
resumeDebuggerThenCloseAndFinish(gPanel);
});
callInTab(gTab, "runDebuggerStatement");
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({ actor: getSourceActor(gSources, SOURCE_URL), line: 5 });
}
function testResume() {
is(gDebugger.gThreadClient.state, "paused",
"The breakpoint wasn't hit yet (1).");
is(getSelectedSourceURL(gSources), 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(getSelectedSourceURL(gSources), 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.");
ensureCaretAt(gPanel, 5, 1, true).then(afterBreakpointHit);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
}
function afterBreakpointHit() {
is(gDebugger.gThreadClient.state, "paused",
"The breakpoint was hit (3).");
is(getSelectedSourceURL(gSources), 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(getSelectedSourceURL(gSources), SOURCE_URL,
"The currently shown source is incorrect (4).");
ok(isCaretPos(gPanel, 6),
"The source editor caret position is incorrect (4).");
promise.all([
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.NEW_SOURCE),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCES_ADDED),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN),
reloadActiveTab(gPanel, gDebugger.EVENTS.BREAKPOINT_SHOWN_IN_EDITOR),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_SHOWN_IN_PANE)
]).then(testClickAgain);
}
function testClickAgain() {
isnot(gDebugger.gThreadClient.state, "paused",
"The breakpoint wasn't hit yet (5).");
is(getSelectedSourceURL(gSources), 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(getSelectedSourceURL(gSources), 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(getSelectedSourceURL(gSources), 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;
});

Просмотреть файл

@ -18,10 +18,8 @@ function test() {
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
const constants = gDebugger.require('./content/constants');
reloadActiveTab(gPanel);
waitForDispatch(gPanel, constants.LOAD_SOURCES)
reloadActiveTab(gPanel, gDebugger.EVENTS.SOURCES_ADDED)
.then(testSourcesEmptyText)
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {

Просмотреть файл

@ -25,13 +25,9 @@ function test() {
isnot(gOptions._pauseOnExceptionsItem.getAttribute("checked"), "true",
"The pause-on-exceptions menu item should not be checked.");
waitForSourceShown(aPanel, ".html")
.then(enablePauseOnExceptions)
enablePauseOnExceptions()
.then(disableIgnoreCaughtExceptions)
.then(() => reloadActiveTab(gPanel, gDebugger.EVENTS.SOURCE_SHOWN))
.then(() => {
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
})
.then(testPauseOnExceptionsAfterReload)
.then(disablePauseOnExceptions)
.then(enableIgnoreCaughtExceptions)
@ -128,6 +124,7 @@ function enablePauseOnExceptions() {
gOptions._pauseOnExceptionsItem.setAttribute("checked", "true");
gOptions._togglePauseOnExceptions();
return deferred.promise;
}

Просмотреть файл

@ -7,41 +7,76 @@
const TAB_URL = EXAMPLE_URL + "doc_pretty-print.html";
var gTab, gPanel, gDebugger;
var gEditor, gSources;
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
Task.spawn(function*() {
yield waitForSourceShown(gPanel, "code_ugly.js");
ok(!gEditor.getText().includes("\n "),
"The source shouldn't be pretty printed yet.");
const finished = waitForSourceShown(gPanel, "code_ugly.js");
gDebugger.document.getElementById("pretty-print").click();
const deck = gDebugger.document.getElementById("editor-deck");
is(deck.selectedIndex, 2, "The progress bar should be shown");
yield finished;
ok(gEditor.getText().includes("\n "),
"The source should be pretty printed.")
is(deck.selectedIndex, 0, "The editor should be shown");
const source = queries.getSelectedSource(getState());
const { loading, text } = queries.getSourceText(getState(), source.actor);
ok(!loading, "Source text is not loading");
ok(text.includes("\n "),
"Subsequent calls to getText return the pretty printed source.");
closeDebuggerAndFinish(gPanel);
});
waitForSourceShown(gPanel, "code_ugly.js")
.then(testSourceIsUgly)
.then(() => {
const finished = waitForSourceShown(gPanel, "code_ugly.js");
clickPrettyPrintButton();
testProgressBarShown();
return finished;
})
.then(testSourceIsPretty)
.then(testEditorShown)
.then(testSourceIsStillPretty)
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
});
});
}
function testSourceIsUgly() {
ok(!gEditor.getText().includes("\n "),
"The source shouldn't be pretty printed yet.");
}
function clickPrettyPrintButton() {
gDebugger.document.getElementById("pretty-print").click();
}
function testProgressBarShown() {
const deck = gDebugger.document.getElementById("editor-deck");
is(deck.selectedIndex, 2, "The progress bar should be shown");
}
function testSourceIsPretty() {
ok(gEditor.getText().includes("\n "),
"The source should be pretty printed.")
}
function testEditorShown() {
const deck = gDebugger.document.getElementById("editor-deck");
is(deck.selectedIndex, 0, "The editor should be shown");
}
function testSourceIsStillPretty() {
const deferred = promise.defer();
const { source } = gSources.selectedItem.attachment;
gDebugger.DebuggerController.SourceScripts.getText(source).then(([, text]) => {
ok(text.includes("\n "),
"Subsequent calls to getText return the pretty printed source.");
deferred.resolve();
});
return deferred.promise;
}
registerCleanupFunction(function() {
gTab = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gSources = null;
});

Просмотреть файл

@ -8,29 +8,48 @@
const TAB_URL = EXAMPLE_URL + "doc_pretty-print.html";
var gTab, gPanel, gDebugger;
var gEditor, gContextMenu;
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gContextMenu = gDebugger.document.getElementById("sourceEditorContextMenu");
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gContextMenu = gDebugger.document.getElementById("sourceEditorContextMenu");
Task.spawn(function*() {
yield waitForSourceShown(gPanel, "code_ugly.js");
const finished = waitForSourceShown(gPanel, "code_ugly.js");
once(gContextMenu, "popupshown").then(() => {
const menuItem = gDebugger.document.getElementById("se-dbg-cMenu-prettyPrint");
menuItem.click();
waitForSourceShown(gPanel, "code_ugly.js")
.then(() => {
const finished = waitForSourceShown(gPanel, "code_ugly.js");
selectContextMenuItem();
return finished;
})
.then(testSourceIsPretty)
.then(closeDebuggerAndFinish.bind(null, gPanel))
.then(null, aError => {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
});
gContextMenu.openPopup(gEditor.container, "overlap", 0, 0, true, false);
yield finished;
ok(gEditor.getText().includes("\n "),
"The source should be pretty printed.")
closeDebuggerAndFinish(gPanel);
});
});
}
function selectContextMenuItem() {
once(gContextMenu, "popupshown").then(() => {
const menuItem = gDebugger.document.getElementById("se-dbg-cMenu-prettyPrint");
menuItem.click();
});
gContextMenu.openPopup(gEditor.container, "overlap", 0, 0, true, false);
}
function testSourceIsPretty() {
ok(gEditor.getText().includes("\n "),
"The source should be pretty printed.")
}
registerCleanupFunction(function() {
gTab = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gContextMenu = null;
});

Просмотреть файл

@ -7,27 +7,43 @@
const TAB_URL = EXAMPLE_URL + "doc_pretty-print.html";
var gTab, gPanel, gDebugger;
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
Task.spawn(function*() {
yield waitForSourceShown(gPanel, "code_ugly.js");
const paused = waitForPause(gDebugger.gThreadClient);
callInTab(gTab, "foo");
yield paused;
const finished = promise.all([
waitForSourceShown(gPanel, "code_ugly.js"),
waitForCaretUpdated(gPanel, 7)
]);
gDebugger.document.getElementById("pretty-print").click();
yield finished;
resumeDebuggerThenCloseAndFinish(gPanel);
});
waitForSourceShown(gPanel, "code_ugly.js")
.then(runCodeAndPause)
.then(() => {
const sourceShown = waitForSourceShown(gPanel, "code_ugly.js");
const caretUpdated = waitForCaretUpdated(gPanel, 7);
const finished = promise.all([sourceShown, caretUpdated]);
clickPrettyPrintButton();
return finished;
})
.then(resumeDebuggerThenCloseAndFinish.bind(null, gPanel))
.then(null, aError => {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
});
});
}
function runCodeAndPause() {
const deferred = promise.defer();
once(gDebugger.gThreadClient, "paused").then(deferred.resolve);
callInTab(gTab, "foo");
return deferred.promise;
}
function clickPrettyPrintButton() {
gDebugger.document.getElementById("pretty-print").click();
}
registerCleanupFunction(function() {
gTab = null;
gPanel = null;
gDebugger = null;
});

Просмотреть файл

@ -7,39 +7,64 @@
const TAB_URL = EXAMPLE_URL + "doc_pretty-print.html";
var gTab, gPanel, gDebugger;
var gSearchBox;
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
Task.spawn(function*() {
yield waitForSourceShown(gPanel, "code_ugly.js");
let popupShown = promise.defer();
once(gDebugger, "popupshown").then(() => {
ok(isCaretPos(gPanel, 2, 10),
"The bar function's non-pretty-printed location should be shown.");
popupShown.resolve();
waitForSourceShown(gPanel, "code_ugly.js")
.then(testUglySearch)
.then(() => {
const finished = waitForSourceShown(gPanel, "code_ugly.js");
clickPrettyPrintButton();
return finished;
})
.then(testPrettyPrintedSearch)
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
setText(gSearchBox, "@bar");
yield popupShown.promise;
const finished = waitForSourceShown(gPanel, "code_ugly.js");
gDebugger.document.getElementById("pretty-print").click();
yield finished;
popupShown = promise.defer();
once(gDebugger, "popupshown").then(() => {
ok(isCaretPos(gPanel, 6, 10),
"The bar function's pretty printed location should be shown.");
popupShown.resolve();
});
setText(gSearchBox, "@bar");
yield popupShown.promise;
closeDebuggerAndFinish(gPanel);
});
});
}
function testUglySearch() {
const deferred = promise.defer();
once(gDebugger, "popupshown").then(() => {
ok(isCaretPos(gPanel, 2, 10),
"The bar function's non-pretty-printed location should be shown.");
deferred.resolve();
});
setText(gSearchBox, "@bar");
return deferred.promise;
}
function clickPrettyPrintButton() {
gDebugger.document.getElementById("pretty-print").click();
}
function testPrettyPrintedSearch() {
const deferred = promise.defer();
once(gDebugger, "popupshown").then(() => {
ok(isCaretPos(gPanel, 6, 10),
"The bar function's pretty printed location should be shown.");
deferred.resolve();
});
setText(gSearchBox, "@bar");
return deferred.promise;
}
registerCleanupFunction(function() {
gTab = null;
gPanel = null;
gDebugger = null;
gSearchBox = null;
});

Просмотреть файл

@ -7,17 +7,17 @@
const TAB_URL = EXAMPLE_URL + "doc_included-script.html";
var gTab, gPanel, gDebugger;
var gEditor, gSources, gControllerSources;
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gControllerSources = gDebugger.DebuggerController.SourceScripts;
Task.spawn(function*() {
yield waitForSourceShown(gPanel, TAB_URL);
@ -32,17 +32,19 @@ function test() {
ok(gEditor.getText().includes("myFunction"),
"The source shouldn't be pretty printed yet.");
const source = queries.getSelectedSource(getState());
clickPrettyPrintButton();
let { source } = gSources.selectedItem.attachment;
try {
yield actions.togglePrettyPrint(source);
ok(false, "An error occurred while pretty-printing");
}
catch(err) {
is(err.message, "Can't prettify non-javascript files.",
"The promise was correctly rejected with a meaningful message.");
yield gControllerSources.togglePrettyPrint(source);
ok(false, "The promise for a prettified source should be rejected!");
} catch ([source, error]) {
is(error, "Can't prettify non-javascript files.",
"The promise was correctly rejected with a meaningful message.");
}
const { text } = yield queries.getSourceText(getState(), source.actor);
let text;
[source, text] = yield gControllerSources.getText(source);
is(getSelectedSourceURL(gSources), TAB_URL,
"The correct source is still selected.");
ok(gEditor.getText().includes("myFunction"),
@ -55,6 +57,10 @@ function test() {
});
}
function clickPrettyPrintButton() {
gDebugger.document.getElementById("pretty-print").click();
}
function prepareDebugger(aPanel) {
aPanel._view.Sources.preferredSource = getSourceActor(
aPanel.panelWin.DebuggerView.Sources,
@ -62,3 +68,11 @@ function prepareDebugger(aPanel) {
);
}
registerCleanupFunction(function() {
gTab = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gSources = null;
gControllerSources = null;
});

Просмотреть файл

@ -8,19 +8,18 @@
const TAB_URL = EXAMPLE_URL + "doc_included-script.html";
const JS_URL = EXAMPLE_URL + "code_location-changes.js";
var gTab, gPanel, gDebugger, gClient;
var gEditor, gSources, gControllerSources, gPrettyPrinted;
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gClient = gDebugger.gClient;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
let gPrettyPrinted = false;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gClient = gDebugger.gClient;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gControllerSources = gDebugger.DebuggerController.SourceScripts;
// We can't feed javascript files with syntax errors to the debugger,
// because they will never run, thus sometimes getting gc'd before the
@ -49,18 +48,19 @@ function test() {
ok(gEditor.getText().includes("myFunction"),
"The source shouldn't be pretty printed yet.");
const source = queries.getSelectedSource(getState());
clickPrettyPrintButton();
let { source } = gSources.selectedItem.attachment;
try {
yield actions.togglePrettyPrint(source);
yield gControllerSources.togglePrettyPrint(source);
ok(false, "The promise for a prettified source should be rejected!");
} catch(error) {
ok(error.rdpError, "Error came from a RDP request");
ok(error.rdpError.includes("prettyPrintError"),
} catch ([source, error]) {
ok(error.includes("prettyPrintError"),
"The promise was correctly rejected with a meaningful message.");
}
console.log(getState().sources.sourcesText);
const { text } = yield queries.getSourceText(getState(), source.actor);
let text;
[source, text] = yield gControllerSources.getText(source);
is(getSelectedSourceURL(gSources), JS_URL,
"The correct source is still selected.");
ok(gEditor.getText().includes("myFunction"),
@ -75,3 +75,18 @@ function test() {
});
});
}
function clickPrettyPrintButton() {
gDebugger.document.getElementById("pretty-print").click();
}
registerCleanupFunction(function() {
gTab = null;
gPanel = null;
gDebugger = null;
gClient = null;
gEditor = null;
gSources = null;
gControllerSources = null;
gPrettyPrinted = null;
});

Просмотреть файл

@ -8,35 +8,54 @@
const TAB_URL = EXAMPLE_URL + "doc_pretty-print.html";
var gTab, gPanel, gDebugger;
var gEditor, gSources;
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
Task.spawn(function*() {
yield waitForSourceShown(gPanel, "code_ugly.js");
ok(!gEditor.getText().includes("\n "),
"The source shouldn't be pretty printed yet.");
yield toggleBlackBoxing(gPanel);
// Wait a tick before clicking to make sure the frontend's blackboxchange
// handlers have finished.
yield waitForTick();
gDebugger.document.getElementById("pretty-print").click();
// Make sure the text updates
yield waitForTick();
const source = queries.getSelectedSource(getState());
const { text } = queries.getSourceText(getState(), source.actor);
ok(!text.includes("\n "));
closeDebuggerAndFinish(gPanel);
});
waitForSourceShown(gPanel, "code_ugly.js")
.then(testSourceIsUgly)
.then(toggleBlackBoxing.bind(null, gPanel))
.then(clickPrettyPrintButton)
.then(testSourceIsStillUgly)
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
});
});
}
function testSourceIsUgly() {
ok(!gEditor.getText().includes("\n "),
"The source shouldn't be pretty printed yet.");
}
function clickPrettyPrintButton() {
// Wait a tick before clicking to make sure the frontend's blackboxchange
// handlers have finished.
return new Promise(resolve => {
gDebugger.document.getElementById("pretty-print").click();
resolve();
});
}
function testSourceIsStillUgly() {
const { source } = gSources.selectedItem.attachment;
return gDebugger.DebuggerController.SourceScripts.getText(source).then(([, text]) => {
ok(!text.includes("\n "));
});
}
registerCleanupFunction(function() {
gTab = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gSources = null;
});

Просмотреть файл

@ -8,38 +8,45 @@
const TAB_URL = EXAMPLE_URL + "doc_blackboxing.html";
var gTab, gPanel, gDebugger;
var gEditor, gSources;
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
Task.spawn(function*() {
yield waitForSourceShown(gPanel, "");
const source = getSourceForm(gSources, TAB_URL);
let shown = ensureSourceIs(gPanel, TAB_URL, true);
actions.selectSource(source);
yield shown;
try {
yield actions.togglePrettyPrint(source);
ok(false, "An error occurred while pretty-printing");
}
catch(err) {
is(err.message, "Can't prettify non-javascript files.",
"The promise was correctly rejected with a meaningful message.");
}
is(gDebugger.document.getElementById("pretty-print").checked, false,
"The button shouldn't be checked after trying to pretty print a non-js file.");
closeDebuggerAndFinish(gPanel);
})
waitForSourceShown(gPanel, "")
.then(() => {
let shown = ensureSourceIs(gPanel, TAB_URL, true);
gSources.selectedValue = getSourceActor(gSources, TAB_URL);
return shown;
})
.then(clickPrettyPrintButton)
.then(testButtonIsntChecked)
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
});
});
}
function clickPrettyPrintButton() {
gDebugger.document.getElementById("pretty-print").click();
}
function testButtonIsntChecked() {
is(gDebugger.document.getElementById("pretty-print").checked, false,
"The button shouldn't be checked after trying to pretty print a non-js file.");
}
registerCleanupFunction(function() {
gTab = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gSources = null;
});

Просмотреть файл

@ -9,39 +9,77 @@
const TAB_URL = EXAMPLE_URL + "doc_pretty-print-3.html";
var gTab, gPanel, gDebugger;
var gEditor, gSources;
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
Task.spawn(function*() {
yield waitForSourceShown(gPanel, "code_ugly-8");
ok(!gEditor.getText().includes("\n "),
"The source shouldn't be pretty printed yet.");
const finished = waitForSourceShown(gPanel, "code_ugly-8");
gDebugger.document.getElementById("pretty-print").click();
const deck = gDebugger.document.getElementById("editor-deck");
is(deck.selectedIndex, 2, "The progress bar should be shown");
yield finished;
ok(gEditor.getText().includes("\n "),
"The source should be pretty printed.")
is(deck.selectedIndex, 0, "The editor should be shown");
const source = queries.getSelectedSource(getState());
const { text } = queries.getSourceText(getState(), source.actor);
ok(text.includes("\n "),
"Subsequent calls to getText return the pretty printed source.");
closeDebuggerAndFinish(gPanel);
})
promise.all([waitForSourceShown(gPanel, "code_ugly-8"),
waitForEditorLocationSet(gPanel)])
.then(testSourceIsUgly)
.then(() => {
const finished = waitForSourceShown(gPanel, "code_ugly-8");
clickPrettyPrintButton();
testProgressBarShown();
return finished;
})
.then(testSourceIsPretty)
.then(testEditorShown)
.then(testSourceIsStillPretty)
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
});
});
}
function testSourceIsUgly() {
ok(!gEditor.getText().includes("\n "),
"The source shouldn't be pretty printed yet.");
}
function clickPrettyPrintButton() {
gDebugger.document.getElementById("pretty-print").click();
}
function testProgressBarShown() {
const deck = gDebugger.document.getElementById("editor-deck");
is(deck.selectedIndex, 2, "The progress bar should be shown");
}
function testSourceIsPretty() {
ok(gEditor.getText().includes("\n "),
"The source should be pretty printed.")
}
function testEditorShown() {
const deck = gDebugger.document.getElementById("editor-deck");
is(deck.selectedIndex, 0, "The editor should be shown");
}
function testSourceIsStillPretty() {
const deferred = promise.defer();
const { source } = gSources.selectedItem.attachment;
gDebugger.DebuggerController.SourceScripts.getText(source).then(([, text]) => {
ok(text.includes("\n "),
"Subsequent calls to getText return the pretty printed source.");
deferred.resolve();
});
return deferred.promise;
}
registerCleanupFunction(function() {
gTab = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gSources = null;
});

Просмотреть файл

@ -21,6 +21,8 @@ function test() {
is(!!gDebugger.DebuggerController._startup, true,
"Controller should be initialized after starting the test.");
is(!!gDebugger.DebuggerView._startup, true,
"View should be initialized after starting the test.");
testPause();
});

Просмотреть файл

@ -13,49 +13,28 @@ function test() {
// Debug test slaves are a bit slow at this test.
requestLongerTimeout(2);
let gTab, gPanel, gDebugger;
let gSources, gStep;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = aPanel.panelWin;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
let gStep = 0;
gTab = aTab;
gPanel = aPanel;
gDebugger = aPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
gStep = 0;
function reloadPage() {
const loaded = waitForDispatch(gPanel, gDebugger.constants.LOAD_SOURCES);
reload(gPanel);
return loaded;
}
waitForSourceShown(gPanel, FIRST_URL).then(performTest);
});
function switchAndReload(aUrl) {
actions.selectSource(getSourceForm(gSources, aUrl));
return reloadPage();
}
function testCurrentSource(aUrl, aExpectedUrl = aUrl) {
const prefSource = getSourceURL(gSources, gSources.preferredValue);
const selSource = getSourceURL(gSources, gSources.selectedValue);
info("Currently preferred source: '" + prefSource + "'.");
info("Currently selected source: '" + selSource + "'.");
is(prefSource, aExpectedUrl,
"The preferred source url wasn't set correctly (" + gStep + ").");
is(selSource, aUrl,
"The selected source isn't the correct one (" + gStep + ").");
}
function performTest() {
switch (gStep++) {
function performTest() {
switch (gStep++) {
case 0:
testCurrentSource(FIRST_URL, null);
reloadPage().then(performTest);
reload().then(performTest);
break;
case 1:
testCurrentSource(FIRST_URL);
reloadPage().then(performTest);
reload().then(performTest);
break;
case 2:
testCurrentSource(FIRST_URL);
@ -63,19 +42,36 @@ function test() {
break;
case 3:
testCurrentSource(SECOND_URL);
reloadPage().then(performTest);
reload().then(performTest);
break;
case 4:
testCurrentSource(SECOND_URL);
reloadPage().then(performTest);
reload().then(performTest);
break;
case 5:
testCurrentSource(SECOND_URL);
closeDebuggerAndFinish(gPanel);
break;
}
}
}
waitForSourceShown(gPanel, FIRST_URL).then(performTest);
});
function reload() {
return reloadActiveTab(gPanel, gDebugger.EVENTS.SOURCES_ADDED);
}
function switchAndReload(aUrl) {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(reload);
gSources.selectedValue = getSourceActor(gSources, aUrl);
return finished;
}
function testCurrentSource(aUrl, aExpectedUrl = aUrl) {
info("Currently preferred source: '" + gSources.preferredValue + "'.");
info("Currently selected source: '" + gSources.selectedValue + "'.");
is(getSourceURL(gSources, gSources.preferredValue), aExpectedUrl,
"The preferred source url wasn't set correctly (" + gStep + ").");
is(getSourceURL(gSources, gSources.selectedValue), aUrl,
"The selected source isn't the correct one (" + gStep + ").");
}
}

Просмотреть файл

@ -7,157 +7,186 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
var gTab, gPanel, gDebugger;
var gEditor, gSources;
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
const gLabel1 = "code_script-switching-01.js";
const gLabel2 = "code_script-switching-02.js";
ok(gDebugger.document.title.endsWith(EXAMPLE_URL + gLabel1),
"Title with first source is correct.");
function testSourcesDisplay() {
let deferred = promise.defer();
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1)
.then(testSourcesDisplay)
.then(testSwitchPaused1)
.then(testSwitchPaused2)
.then(testSwitchRunning)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
is(gSources.itemCount, 2,
"Found the expected number of sources.");
is(gSources.items[0].target.querySelector(".dbg-source-item").getAttribute("tooltiptext"),
EXAMPLE_URL + "code_script-switching-01.js",
"The correct tooltip text is displayed for the first source.");
is(gSources.items[1].target.querySelector(".dbg-source-item").getAttribute("tooltiptext"),
EXAMPLE_URL + "code_script-switching-02.js",
"The correct tooltip text is displayed for the second source.");
ok(getSourceActor(gSources, EXAMPLE_URL + gLabel1),
"First source url is incorrect.");
ok(getSourceActor(gSources, EXAMPLE_URL + gLabel2),
"Second source url is incorrect.");
ok(gSources.getItemForAttachment(e => e.label == gLabel1),
"First source label is incorrect.");
ok(gSources.getItemForAttachment(e => e.label == gLabel2),
"Second source label is incorrect.");
ok(gSources.selectedItem,
"There should be a selected item in the sources pane.");
is(getSelectedSourceURL(gSources), EXAMPLE_URL + gLabel2,
"The selected value is the sources pane is incorrect.");
is(gEditor.getText().search(/firstCall/), -1,
"The first source is not displayed.");
is(gEditor.getText().search(/debugger/), 166,
"The second source is displayed.");
ok(gDebugger.document.title.endsWith(EXAMPLE_URL + gLabel2),
"Title with second source is correct.");
ok(isCaretPos(gPanel, 6),
"Editor caret location is correct.");
// The editor's debug location takes a tick to update.
is(gEditor.getDebugLocation(), 5,
"Editor debugger location is correct.");
ok(gEditor.hasLineClass(5, "debug-line"),
"The debugged line is highlighted appropriately (1).");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
gSources.selectedIndex = 0;
return deferred.promise;
}
function testSwitchPaused1() {
let deferred = promise.defer();
ok(gSources.selectedItem,
"There should be a selected item in the sources pane.");
is(getSelectedSourceURL(gSources), EXAMPLE_URL + gLabel1,
"The selected value is the sources pane is incorrect.");
is(gEditor.getText().search(/firstCall/), 118,
"The first source is displayed.");
is(gEditor.getText().search(/debugger/), -1,
"The second source is not displayed.");
// The editor's debug location takes a tick to update.
ok(isCaretPos(gPanel, 1),
"Editor caret location is correct.");
is(gEditor.getDebugLocation(), null,
"Editor debugger location is correct.");
ok(!gEditor.hasLineClass(5, "debug-line"),
"The debugged line highlight was removed.");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
gSources.selectedIndex = 1;
return deferred.promise;
}
function testSwitchPaused2() {
let deferred = promise.defer();
ok(gSources.selectedItem,
"There should be a selected item in the sources pane.");
is(getSelectedSourceURL(gSources), EXAMPLE_URL + gLabel2,
"The selected value is the sources pane is incorrect.");
is(gEditor.getText().search(/firstCall/), -1,
"The first source is not displayed.");
is(gEditor.getText().search(/debugger/), 166,
"The second source is displayed.");
ok(isCaretPos(gPanel, 1),
"Editor caret location is correct.");
is(gEditor.getDebugLocation(), 5,
"Editor debugger location is correct.");
ok(gEditor.hasLineClass(5, "debug-line"),
"The debugged line is highlighted appropriately (2).");
// Step out twice.
waitForThreadEvents(gPanel, "paused").then(() => {
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
gDebugger.gThreadClient.stepOut();
})
gDebugger.gThreadClient.stepOut();
return deferred.promise;
}
function testSwitchRunning() {
ok(gSources.selectedItem,
"There should be a selected item in the sources pane.");
is(getSelectedSourceURL(gSources), EXAMPLE_URL + gLabel1,
"The selected value is the sources pane is incorrect.");
is(gEditor.getText().search(/firstCall/), 118,
"The first source is displayed.");
is(gEditor.getText().search(/debugger/), -1,
"The second source is not displayed.");
ok(isCaretPos(gPanel, 5),
"Editor caret location is correct.");
is(gEditor.getDebugLocation(), 4,
"Editor debugger location is correct.");
ok(gEditor.hasLineClass(4, "debug-line"),
"The debugged line is highlighted appropriately (3).");
}
Task.spawn(function*() {
yield waitForSourceShown(gPanel, "-01.js", 1);
ok(gDebugger.document.title.endsWith(EXAMPLE_URL + gLabel1),
"Title with first source is correct.");
const shown = waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1);
callInTab(gTab, "firstCall");
yield shown;
yield testSourcesDisplay();
yield testSwitchPaused1();
yield testSwitchPaused2();
yield testSwitchRunning();
resumeDebuggerThenCloseAndFinish(gPanel);
});
callInTab(gTab, "firstCall");
});
}
var gLabel1 = "code_script-switching-01.js";
var gLabel2 = "code_script-switching-02.js";
function testSourcesDisplay() {
let deferred = promise.defer();
is(gSources.itemCount, 2,
"Found the expected number of sources.");
is(gSources.items[0].target.querySelector(".dbg-source-item").getAttribute("tooltiptext"),
EXAMPLE_URL + "code_script-switching-01.js",
"The correct tooltip text is displayed for the first source.");
is(gSources.items[1].target.querySelector(".dbg-source-item").getAttribute("tooltiptext"),
EXAMPLE_URL + "code_script-switching-02.js",
"The correct tooltip text is displayed for the second source.");
ok(getSourceActor(gSources, EXAMPLE_URL + gLabel1),
"First source url is incorrect.");
ok(getSourceActor(gSources, EXAMPLE_URL + gLabel2),
"Second source url is incorrect.");
ok(gSources.getItemForAttachment(e => e.label == gLabel1),
"First source label is incorrect.");
ok(gSources.getItemForAttachment(e => e.label == gLabel2),
"Second source label is incorrect.");
ok(gSources.selectedItem,
"There should be a selected item in the sources pane.");
is(getSelectedSourceURL(gSources), EXAMPLE_URL + gLabel2,
"The selected value is the sources pane is incorrect.");
is(gEditor.getText().search(/firstCall/), -1,
"The first source is not displayed.");
is(gEditor.getText().search(/debugger/), 166,
"The second source is displayed.");
ok(gDebugger.document.title.endsWith(EXAMPLE_URL + gLabel2),
"Title with second source is correct.");
ok(isCaretPos(gPanel, 1),
"Editor caret location is correct.");
// The editor's debug location takes a tick to update.
executeSoon(() => {
is(gEditor.getDebugLocation(), 5,
"Editor debugger location is correct.");
ok(gEditor.hasLineClass(5, "debug-line"),
"The debugged line is highlighted appropriately (1).");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
gSources.selectedIndex = 0;
});
return deferred.promise;
}
function testSwitchPaused1() {
let deferred = promise.defer();
ok(gSources.selectedItem,
"There should be a selected item in the sources pane.");
is(getSelectedSourceURL(gSources), EXAMPLE_URL + gLabel1,
"The selected value is the sources pane is incorrect.");
is(gEditor.getText().search(/firstCall/), 118,
"The first source is displayed.");
is(gEditor.getText().search(/debugger/), -1,
"The second source is not displayed.");
// The editor's debug location takes a tick to update.
executeSoon(() => {
ok(isCaretPos(gPanel, 1),
"Editor caret location is correct.");
is(gEditor.getDebugLocation(), null,
"Editor debugger location is correct.");
ok(!gEditor.hasLineClass(5, "debug-line"),
"The debugged line highlight was removed.");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
gSources.selectedIndex = 1;
});
return deferred.promise;
}
function testSwitchPaused2() {
let deferred = promise.defer();
ok(gSources.selectedItem,
"There should be a selected item in the sources pane.");
is(getSelectedSourceURL(gSources), EXAMPLE_URL + gLabel2,
"The selected value is the sources pane is incorrect.");
is(gEditor.getText().search(/firstCall/), -1,
"The first source is not displayed.");
is(gEditor.getText().search(/debugger/), 166,
"The second source is displayed.");
// The editor's debug location takes a tick to update.
executeSoon(() => {
ok(isCaretPos(gPanel, 6),
"Editor caret location is correct.");
is(gEditor.getDebugLocation(), 5,
"Editor debugger location is correct.");
ok(gEditor.hasLineClass(5, "debug-line"),
"The debugged line is highlighted appropriately (2).");
// Step out twice.
waitForThreadEvents(gPanel, "paused").then(() => {
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
gDebugger.gThreadClient.stepOut();
})
gDebugger.gThreadClient.stepOut();
});
return deferred.promise;
}
function testSwitchRunning() {
let deferred = promise.defer();
ok(gSources.selectedItem,
"There should be a selected item in the sources pane.");
is(getSelectedSourceURL(gSources), EXAMPLE_URL + gLabel1,
"The selected value is the sources pane is incorrect.");
is(gEditor.getText().search(/firstCall/), 118,
"The first source is displayed.");
is(gEditor.getText().search(/debugger/), -1,
"The second source is not displayed.");
// The editor's debug location takes a tick to update.
executeSoon(() => {
ok(isCaretPos(gPanel, 5),
"Editor caret location is correct.");
is(gEditor.getDebugLocation(), 4,
"Editor debugger location is correct.");
ok(gEditor.hasLineClass(4, "debug-line"),
"The debugged line is highlighted appropriately (3).");
deferred.resolve();
});
return deferred.promise;
}
registerCleanupFunction(function() {
gTab = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gSources = null;
gLabel1 = null;
gLabel2 = null;
});

Просмотреть файл

@ -7,151 +7,176 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-02.html";
var gLabel1 = "code_script-switching-01.js";
var gLabel2 = "code_script-switching-02.js";
var gParams = "?foo=bar,baz|lol";
var gTab, gPanel, gDebugger;
var gEditor, gSources;
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
function testSourcesDisplay() {
let deferred = promise.defer();
is(gSources.itemCount, 2,
"Found the expected number of sources.");
ok(getSourceActor(gSources, EXAMPLE_URL + gLabel1),
"First source url is incorrect.");
ok(getSourceActor(gSources, EXAMPLE_URL + gLabel2 + gParams),
"Second source url is incorrect.");
ok(gSources.getItemForAttachment(e => e.label == gLabel1),
"First source label is incorrect.");
ok(gSources.getItemForAttachment(e => e.label == gLabel2),
"Second source label is incorrect.");
ok(gSources.selectedItem,
"There should be a selected item in the sources pane.");
is(getSelectedSourceURL(gSources), EXAMPLE_URL + gLabel2 + gParams,
"The selected value is the sources pane is incorrect.");
is(gEditor.getText().search(/firstCall/), -1,
"The first source is not displayed.");
is(gEditor.getText().search(/debugger/), 166,
"The second source is displayed.");
ok(isCaretPos(gPanel, 6),
"Editor caret location is correct.");
is(gEditor.getDebugLocation(), 5,
"Editor debugger location is correct.");
ok(gEditor.hasLineClass(5, "debug-line"),
"The debugged line is highlighted appropriately.");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
gSources.selectedItem = e => e.attachment.label == gLabel1;
return deferred.promise;
}
function testSwitchPaused1() {
let deferred = promise.defer();
ok(gSources.selectedItem,
"There should be a selected item in the sources pane.");
is(getSelectedSourceURL(gSources), EXAMPLE_URL + gLabel1,
"The selected value is the sources pane is incorrect.");
is(gEditor.getText().search(/firstCall/), 118,
"The first source is displayed.");
is(gEditor.getText().search(/debugger/), -1,
"The second source is not displayed.");
// The editor's debug location takes a tick to update.
ok(isCaretPos(gPanel, 1),
"Editor caret location is correct.");
is(gEditor.getDebugLocation(), null,
"Editor debugger location is correct.");
ok(!gEditor.hasLineClass(5, "debug-line"),
"The debugged line highlight was removed.");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
gSources.selectedItem = e => e.attachment.label == gLabel2;
return deferred.promise;
}
function testSwitchPaused2() {
let deferred = promise.defer();
ok(gSources.selectedItem,
"There should be a selected item in the sources pane.");
is(getSelectedSourceURL(gSources), EXAMPLE_URL + gLabel2 + gParams,
"The selected value is the sources pane is incorrect.");
is(gEditor.getText().search(/firstCall/), -1,
"The first source is not displayed.");
is(gEditor.getText().search(/debugger/), 166,
"The second source is displayed.");
// The editor's debug location takes a tick to update.
ok(isCaretPos(gPanel, 1),
"Editor caret location is correct.");
is(gEditor.getDebugLocation(), 5,
"Editor debugger location is correct.");
ok(gEditor.hasLineClass(5, "debug-line"),
"The debugged line is highlighted appropriately.");
// Step out three times.
waitForThreadEvents(gPanel, "paused").then(() => {
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
gDebugger.gThreadClient.stepOut();
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1)
.then(testSourcesDisplay)
.then(testSwitchPaused1)
.then(testSwitchPaused2)
.then(testSwitchRunning)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
gDebugger.gThreadClient.stepOut();
return deferred.promise;
}
function testSwitchRunning() {
let deferred = promise.defer();
ok(gSources.selectedItem,
"There should be a selected item in the sources pane.");
is(getSelectedSourceURL(gSources), EXAMPLE_URL + gLabel1,
"The selected value is the sources pane is incorrect.");
is(gEditor.getText().search(/firstCall/), 118,
"The first source is displayed.");
is(gEditor.getText().search(/debugger/), -1,
"The second source is not displayed.");
// The editor's debug location takes a tick to update.
ok(isCaretPos(gPanel, 5),
"Editor caret location is correct.");
is(gEditor.getDebugLocation(), 4,
"Editor debugger location is correct.");
ok(gEditor.hasLineClass(4, "debug-line"),
"The debugged line is highlighted appropriately.");
deferred.resolve();
return deferred.promise;
}
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1);
yield testSourcesDisplay();
yield testSwitchPaused1();
yield testSwitchPaused2();
yield testSwitchRunning();
resumeDebuggerThenCloseAndFinish(gPanel)
});
callInTab(gTab, "firstCall");
});
}
var gLabel1 = "code_script-switching-01.js";
var gLabel2 = "code_script-switching-02.js";
var gParams = "?foo=bar,baz|lol";
function testSourcesDisplay() {
let deferred = promise.defer();
is(gSources.itemCount, 2,
"Found the expected number of sources.");
ok(getSourceActor(gSources, EXAMPLE_URL + gLabel1),
"First source url is incorrect.");
ok(getSourceActor(gSources, EXAMPLE_URL + gLabel2 + gParams),
"Second source url is incorrect.");
ok(gSources.getItemForAttachment(e => e.label == gLabel1),
"First source label is incorrect.");
ok(gSources.getItemForAttachment(e => e.label == gLabel2),
"Second source label is incorrect.");
ok(gSources.selectedItem,
"There should be a selected item in the sources pane.");
is(getSelectedSourceURL(gSources), EXAMPLE_URL + gLabel2 + gParams,
"The selected value is the sources pane is incorrect.");
is(gEditor.getText().search(/firstCall/), -1,
"The first source is not displayed.");
is(gEditor.getText().search(/debugger/), 166,
"The second source is displayed.");
ok(isCaretPos(gPanel, 1),
"Editor caret location is correct.");
// The editor's debug location takes a tick to update.
executeSoon(() => {
is(gEditor.getDebugLocation(), 5,
"Editor debugger location is correct.");
ok(gEditor.hasLineClass(5, "debug-line"),
"The debugged line is highlighted appropriately.");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
gSources.selectedItem = e => e.attachment.label == gLabel1;
});
return deferred.promise;
}
function testSwitchPaused1() {
let deferred = promise.defer();
ok(gSources.selectedItem,
"There should be a selected item in the sources pane.");
is(getSelectedSourceURL(gSources), EXAMPLE_URL + gLabel1,
"The selected value is the sources pane is incorrect.");
is(gEditor.getText().search(/firstCall/), 118,
"The first source is displayed.");
is(gEditor.getText().search(/debugger/), -1,
"The second source is not displayed.");
// The editor's debug location takes a tick to update.
executeSoon(() => {
ok(isCaretPos(gPanel, 1),
"Editor caret location is correct.");
is(gEditor.getDebugLocation(), null,
"Editor debugger location is correct.");
ok(!gEditor.hasLineClass(5, "debug-line"),
"The debugged line highlight was removed.");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
gSources.selectedItem = e => e.attachment.label == gLabel2;
});
return deferred.promise;
}
function testSwitchPaused2() {
let deferred = promise.defer();
ok(gSources.selectedItem,
"There should be a selected item in the sources pane.");
is(getSelectedSourceURL(gSources), EXAMPLE_URL + gLabel2 + gParams,
"The selected value is the sources pane is incorrect.");
is(gEditor.getText().search(/firstCall/), -1,
"The first source is not displayed.");
is(gEditor.getText().search(/debugger/), 166,
"The second source is displayed.");
// The editor's debug location takes a tick to update.
executeSoon(() => {
ok(isCaretPos(gPanel, 6),
"Editor caret location is correct.");
is(gEditor.getDebugLocation(), 5,
"Editor debugger location is correct.");
ok(gEditor.hasLineClass(5, "debug-line"),
"The debugged line is highlighted appropriately.");
// Step out three times.
waitForThreadEvents(gPanel, "paused").then(() => {
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);
gDebugger.gThreadClient.stepOut();
});
gDebugger.gThreadClient.stepOut();
});
return deferred.promise;
}
function testSwitchRunning() {
let deferred = promise.defer();
ok(gSources.selectedItem,
"There should be a selected item in the sources pane.");
is(getSelectedSourceURL(gSources), EXAMPLE_URL + gLabel1,
"The selected value is the sources pane is incorrect.");
is(gEditor.getText().search(/firstCall/), 118,
"The first source is displayed.");
is(gEditor.getText().search(/debugger/), -1,
"The second source is not displayed.");
// The editor's debug location takes a tick to update.
executeSoon(() => {
ok(isCaretPos(gPanel, 5),
"Editor caret location is correct.");
is(gEditor.getDebugLocation(), 4,
"Editor debugger location is correct.");
ok(gEditor.hasLineClass(4, "debug-line"),
"The debugged line is highlighted appropriately.");
deferred.resolve();
});
return deferred.promise;
}
registerCleanupFunction(function() {
gTab = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gSources = null;
gLabel1 = null;
gLabel2 = null;
gParams = null;
});

Просмотреть файл

@ -7,33 +7,44 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
var gTab, gPanel, gDebugger;
var gView, gEditor, gL10N;
function test() {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gView = gDebugger.DebuggerView;
const gEditor = gDebugger.DebuggerView.editor;
const gL10N = gDebugger.L10N;
const actions = bindActionCreators(gPanel);
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gView = gDebugger.DebuggerView;
gEditor = gDebugger.DebuggerView.editor;
gL10N = gDebugger.L10N;
function showBogusSource() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_ERROR_SHOWN);
actions.newSource({ url: "http://example.com/fake.js", actor: "fake.actor" });
actions.selectSource({ actor: "fake.actor" });
return finished;
}
function testDebuggerLoadingError() {
ok(gEditor.getText().includes(gL10N.getFormatStr("errorLoadingText2", "noSuchActor")),
"The valid error loading message is displayed.");
}
Task.spawn(function*() {
yield waitForSourceShown(gPanel, "-01.js");
yield showBogusSource();
yield testDebuggerLoadingError();
closeDebuggerAndFinish(gPanel);
});
waitForSourceShown(gPanel, "-01.js")
.then(showBogusSource)
.then(testDebuggerLoadingError)
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
});
}
function showBogusSource() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_ERROR_SHOWN);
gView._setEditorSource({ url: "http://example.com/fake.js", actor: "fake.actor" });
return finished;
}
function testDebuggerLoadingError() {
ok(gEditor.getText().includes(gL10N.getFormatStr("errorLoadingText2", "noSuchActor")),
"The valid error loading message is displayed.");
}
registerCleanupFunction(function() {
gTab = null;
gPanel = null;
gDebugger = null;
gView = null;
gEditor = null;
gL10N = null;
});

Просмотреть файл

@ -39,7 +39,7 @@ function test() {
function performSimpleSearch() {
let finished = promise.all([
ensureSourceIs(gPanel, "-02.js"),
ensureCaretAt(gPanel, 6),
ensureCaretAt(gPanel, 1),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FILE_SEARCH_MATCH_FOUND),
waitForSourceShown(gPanel, "-01.js")
]);

Просмотреть файл

@ -43,7 +43,7 @@ function test() {
function performFileSearch() {
let finished = promise.all([
ensureSourceIs(gPanel, "-02.js"),
ensureCaretAt(gPanel, 6),
ensureCaretAt(gPanel, 1),
once(gDebugger, "popupshown"),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FILE_SEARCH_MATCH_FOUND),
waitForSourceShown(gPanel, "-01.js")

Просмотреть файл

@ -21,177 +21,197 @@ function test() {
gSearchView = gDebugger.DebuggerView.GlobalSearch;
gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
function firstSearch() {
let deferred = promise.defer();
is(gSearchView.itemCount, 0,
"The global search pane shouldn't have any entries yet.");
is(gSearchView.widget._parent.hidden, true,
"The global search pane shouldn't be visible yet.");
is(gSearchView._splitter.hidden, true,
"The global search pane splitter shouldn't be visible yet.");
gDebugger.once(gDebugger.EVENTS.GLOBAL_SEARCH_MATCH_FOUND, () => {
// Some operations are synchronously dispatched on the main thread,
// to avoid blocking UI, thus giving the impression of faster searching.
executeSoon(() => {
info("Current source url:\n" + getSelectedSourceURL(gSources));
info("Debugger editor text:\n" + gEditor.getText());
ok(isCaretPos(gPanel, 6),
"The editor shouldn't have jumped to a matching line yet.");
ok(getSelectedSourceURL(gSources).includes("-02.js"),
"The current source shouldn't have changed after a global search.");
is(gSources.visibleItems.length, 2,
"Not all the sources are shown after the global search.");
deferred.resolve();
});
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1)
.then(firstSearch)
.then(doFirstJump)
.then(doSecondJump)
.then(doWrapAroundJump)
.then(doBackwardsWrapAroundJump)
.then(testSearchTokenEmpty)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
setText(gSearchBox, "!function");
return deferred.promise;
}
function doFirstJump() {
let deferred = promise.defer();
waitForSourceAndCaret(gPanel, "-01.js", 4).then(() => {
info("Current source url:\n" + getSelectedSourceURL(gSources));
info("Debugger editor text:\n" + gEditor.getText());
ok(getSelectedSourceURL(gSources).includes("-01.js"),
"The currently shown source is incorrect (1).");
is(gSources.visibleItems.length, 2,
"Not all the sources are shown after the global search (1).");
// The editor's selected text takes a tick to update.
ok(isCaretPos(gPanel, 4, 9),
"The editor didn't jump to the correct line (1).");
is(gEditor.getSelection(), "function",
"The editor didn't select the correct text (1).");
deferred.resolve();
});
EventUtils.sendKey("DOWN", gDebugger);
return deferred.promise;
}
function doSecondJump() {
let deferred = promise.defer();
waitForSourceAndCaret(gPanel, "-02.js", 4).then(() => {
info("Current source url:\n" + getSelectedSourceURL(gSources));
info("Debugger editor text:\n" + gEditor.getText());
ok(getSelectedSourceURL(gSources).includes("-02.js"),
"The currently shown source is incorrect (2).");
is(gSources.visibleItems.length, 2,
"Not all the sources are shown after the global search (2).");
ok(isCaretPos(gPanel, 4, 9),
"The editor didn't jump to the correct line (2).");
is(gEditor.getSelection(), "function",
"The editor didn't select the correct text (2).");
deferred.resolve();
});
EventUtils.sendKey("DOWN", gDebugger);
return deferred.promise;
}
function doWrapAroundJump() {
let deferred = promise.defer();
waitForSourceAndCaret(gPanel, "-01.js", 4).then(() => {
info("Current source url:\n" + getSelectedSourceURL(gSources));
info("Debugger editor text:\n" + gEditor.getText());
ok(getSelectedSourceURL(gSources).includes("-01.js"),
"The currently shown source is incorrect (3).");
is(gSources.visibleItems.length, 2,
"Not all the sources are shown after the global search (3).");
// The editor's selected text takes a tick to update.
ok(isCaretPos(gPanel, 4, 9),
"The editor didn't jump to the correct line (3).");
is(gEditor.getSelection(), "function",
"The editor didn't select the correct text (3).");
deferred.resolve();
});
EventUtils.sendKey("DOWN", gDebugger);
EventUtils.sendKey("DOWN", gDebugger);
return deferred.promise;
}
function doBackwardsWrapAroundJump() {
let deferred = promise.defer();
waitForSourceAndCaret(gPanel, "-02.js", 7).then(() => {
info("Current source url:\n" + getSelectedSourceURL(gSources));
info("Debugger editor text:\n" + gEditor.getText());
ok(getSelectedSourceURL(gSources).includes("-02.js"),
"The currently shown source is incorrect (4).");
is(gSources.visibleItems.length, 2,
"Not all the sources are shown after the global search (4).");
// The editor's selected text takes a tick to update.
ok(isCaretPos(gPanel, 7, 11),
"The editor didn't jump to the correct line (4).");
is(gEditor.getSelection(), "function",
"The editor didn't select the correct text (4).");
deferred.resolve();
});
EventUtils.sendKey("UP", gDebugger);
return deferred.promise;
}
function testSearchTokenEmpty() {
backspaceText(gSearchBox, 4);
info("Current source url:\n" + getSelectedSourceURL(gSources));
info("Debugger editor text:\n" + gEditor.getText());
ok(getSelectedSourceURL(gSources).includes("-02.js"),
"The currently shown source is incorrect (4).");
is(gSources.visibleItems.length, 2,
"Not all the sources are shown after the global search (4).");
ok(isCaretPos(gPanel, 7, 11),
"The editor didn't remain at the correct line (4).");
is(gEditor.getSelection(), "",
"The editor shouldn't keep the previous text selected (4).");
is(gSearchView.itemCount, 0,
"The global search pane shouldn't have any child nodes after clearing.");
is(gSearchView.widget._parent.hidden, true,
"The global search pane shouldn't be visible after clearing.");
is(gSearchView._splitter.hidden, true,
"The global search pane splitter shouldn't be visible after clearing.");
}
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1);
yield firstSearch();
yield doFirstJump();
yield doSecondJump();
yield doWrapAroundJump();
yield doBackwardsWrapAroundJump();
yield testSearchTokenEmpty();
resumeDebuggerThenCloseAndFinish(gPanel);
});
callInTab(gTab, "firstCall");
});
}
function firstSearch() {
let deferred = promise.defer();
is(gSearchView.itemCount, 0,
"The global search pane shouldn't have any entries yet.");
is(gSearchView.widget._parent.hidden, true,
"The global search pane shouldn't be visible yet.");
is(gSearchView._splitter.hidden, true,
"The global search pane splitter shouldn't be visible yet.");
gDebugger.once(gDebugger.EVENTS.GLOBAL_SEARCH_MATCH_FOUND, () => {
// Some operations are synchronously dispatched on the main thread,
// to avoid blocking UI, thus giving the impression of faster searching.
executeSoon(() => {
info("Current source url:\n" + getSelectedSourceURL(gSources));
info("Debugger editor text:\n" + gEditor.getText());
ok(isCaretPos(gPanel, 6),
"The editor shouldn't have jumped to a matching line yet.");
ok(getSelectedSourceURL(gSources).includes("-02.js"),
"The current source shouldn't have changed after a global search.");
is(gSources.visibleItems.length, 2,
"Not all the sources are shown after the global search.");
deferred.resolve();
});
});
setText(gSearchBox, "!function");
return deferred.promise;
}
function doFirstJump() {
let deferred = promise.defer();
waitForSourceAndCaret(gPanel, "-01.js", 4).then(() => {
info("Current source url:\n" + getSelectedSourceURL(gSources));
info("Debugger editor text:\n" + gEditor.getText());
ok(getSelectedSourceURL(gSources).includes("-01.js"),
"The currently shown source is incorrect (1).");
is(gSources.visibleItems.length, 2,
"Not all the sources are shown after the global search (1).");
// The editor's selected text takes a tick to update.
executeSoon(() => {
ok(isCaretPos(gPanel, 4, 9),
"The editor didn't jump to the correct line (1).");
is(gEditor.getSelection(), "function",
"The editor didn't select the correct text (1).");
deferred.resolve();
});
});
EventUtils.sendKey("DOWN", gDebugger);
return deferred.promise;
}
function doSecondJump() {
let deferred = promise.defer();
waitForSourceAndCaret(gPanel, "-02.js", 4).then(() => {
info("Current source url:\n" + getSelectedSourceURL(gSources));
info("Debugger editor text:\n" + gEditor.getText());
ok(getSelectedSourceURL(gSources).includes("-02.js"),
"The currently shown source is incorrect (2).");
is(gSources.visibleItems.length, 2,
"Not all the sources are shown after the global search (2).");
// The editor's selected text takes a tick to update.
executeSoon(() => {
ok(isCaretPos(gPanel, 4, 9),
"The editor didn't jump to the correct line (2).");
is(gEditor.getSelection(), "function",
"The editor didn't select the correct text (2).");
deferred.resolve();
});
});
EventUtils.sendKey("DOWN", gDebugger);
return deferred.promise;
}
function doWrapAroundJump() {
let deferred = promise.defer();
waitForSourceAndCaret(gPanel, "-01.js", 4).then(() => {
info("Current source url:\n" + getSelectedSourceURL(gSources));
info("Debugger editor text:\n" + gEditor.getText());
ok(getSelectedSourceURL(gSources).includes("-01.js"),
"The currently shown source is incorrect (3).");
is(gSources.visibleItems.length, 2,
"Not all the sources are shown after the global search (3).");
// The editor's selected text takes a tick to update.
executeSoon(() => {
ok(isCaretPos(gPanel, 4, 9),
"The editor didn't jump to the correct line (3).");
is(gEditor.getSelection(), "function",
"The editor didn't select the correct text (3).");
deferred.resolve();
});
});
EventUtils.sendKey("DOWN", gDebugger);
EventUtils.sendKey("DOWN", gDebugger);
return deferred.promise;
}
function doBackwardsWrapAroundJump() {
let deferred = promise.defer();
waitForSourceAndCaret(gPanel, "-02.js", 7).then(() => {
info("Current source url:\n" + getSelectedSourceURL(gSources));
info("Debugger editor text:\n" + gEditor.getText());
ok(getSelectedSourceURL(gSources).includes("-02.js"),
"The currently shown source is incorrect (4).");
is(gSources.visibleItems.length, 2,
"Not all the sources are shown after the global search (4).");
// The editor's selected text takes a tick to update.
executeSoon(() => {
ok(isCaretPos(gPanel, 7, 11),
"The editor didn't jump to the correct line (4).");
is(gEditor.getSelection(), "function",
"The editor didn't select the correct text (4).");
deferred.resolve();
});
});
EventUtils.sendKey("UP", gDebugger);
return deferred.promise;
}
function testSearchTokenEmpty() {
backspaceText(gSearchBox, 4);
info("Current source url:\n" + getSelectedSourceURL(gSources));
info("Debugger editor text:\n" + gEditor.getText());
ok(getSelectedSourceURL(gSources).includes("-02.js"),
"The currently shown source is incorrect (4).");
is(gSources.visibleItems.length, 2,
"Not all the sources are shown after the global search (4).");
ok(isCaretPos(gPanel, 7, 11),
"The editor didn't remain at the correct line (4).");
is(gEditor.getSelection(), "",
"The editor shouldn't keep the previous text selected (4).");
is(gSearchView.itemCount, 0,
"The global search pane shouldn't have any child nodes after clearing.");
is(gSearchView.widget._parent.hidden, true,
"The global search pane shouldn't be visible after clearing.");
is(gSearchView._splitter.hidden, true,
"The global search pane splitter shouldn't be visible after clearing.");
}
registerCleanupFunction(function() {
gTab = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gSources = null;
gSearchView = null;
gSearchBox = null;
});

Просмотреть файл

@ -97,9 +97,9 @@ function testClickLineToJump() {
info("Current source url:\n" + getSelectedSourceURL(gSources));
info("Debugger editor text:\n" + gEditor.getText());
ok(isCaretPos(gPanel, 1, 5),
ok(isCaretPos(gPanel, 1, 1),
"The editor didn't jump to the correct line (1).");
is(gEditor.getSelection(), "A",
is(gEditor.getSelection(), "",
"The editor didn't select the correct text (1).");
ok(getSelectedSourceURL(gSources).includes("-01.js"),
"The currently shown source is incorrect (1).");
@ -126,9 +126,9 @@ function testClickMatchToJump() {
info("Current source url:\n" + getSelectedSourceURL(gSources));
info("Debugger editor text:\n" + gEditor.getText());
ok(isCaretPos(gPanel, 13, 3),
ok(isCaretPos(gPanel, 1, 1),
"The editor didn't jump to the correct line (2).");
is(gEditor.getSelection(), "a",
is(gEditor.getSelection(), "",
"The editor didn't select the correct text (2).");
ok(getSelectedSourceURL(gSources).includes("-02.js"),
"The currently shown source is incorrect (2).");

Просмотреть файл

@ -63,11 +63,11 @@ function focusEditor() {
}
function testFocusLost() {
ok(isCaretPos(gPanel, 4, 22),
ok(isCaretPos(gPanel, 6, 1),
"The editor caret position appears to be correct after gaining focus.");
ok(isEditorSel(gPanel, [125, 131]),
ok(isEditorSel(gPanel, [165, 165]),
"The editor selection appears to be correct after gaining focus.");
is(gEditor.getSelection(), "Call()",
is(gEditor.getSelection(), "",
"The editor selected text appears to be correct after gaining focus.");
is(gSearchBoxPanel.state, "closed",

Просмотреть файл

@ -2,7 +2,7 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Test adding conditional breakpoints (with server-side support)
* Bug 740825: Test adding conditional breakpoints (with server-side support)
*/
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
@ -11,201 +11,241 @@ function test() {
// Linux debug test slaves are a bit slow at this test sometimes.
requestLongerTimeout(2);
let gTab, gPanel, gDebugger;
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
gBreakpointsAdded = gBreakpoints._added;
gBreakpointsRemoving = gBreakpoints._removing;
const addBreakpoints = Task.async(function*() {
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 18 },
"undefined");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 19 },
"null");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 20 },
"42");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 21 },
"true");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 22 },
"'nasu'");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 23 },
"/regexp/");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 24 },
"({})");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 25 },
"(function() {})");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 26 },
"(function() { return false; })()");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 27 },
"a");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 28 },
"a !== undefined");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 29 },
"b");
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 30 },
"a !== null");
});
function resumeAndTestBreakpoint(line) {
let finished = waitForCaretUpdated(gPanel, line).then(() => testBreakpoint(line));
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._selectedBreakpoint,
"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.");
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(() => resumeAndTestBreakpoint(30))
.then(() => resumeAndTestNoBreakpoint())
.then(() => {
return promise.all([
reloadActiveTab(gPanel, gDebugger.EVENTS.BREAKPOINT_SHOWN_IN_EDITOR, 13),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_SHOWN_IN_PANE, 13)
]);
})
.then(() => testAfterReload())
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
gDebugger.gThreadClient.resume();
return finished;
}
function testBreakpoint(line, highlightBreakpoint) {
// Highlight the breakpoint only if required.
if (highlightBreakpoint) {
let finished = waitForCaretUpdated(gPanel, line).then(() => testBreakpoint(line));
gSources.highlightBreakpoint({ actor: gSources.selectedValue, line: line });
return finished;
}
let selectedActor = gSources.selectedValue;
let selectedBreakpoint = gSources._selectedBreakpoint;
let selectedBreakpointItem = gSources._getBreakpoint(selectedBreakpoint);
ok(selectedActor,
"There should be a selected item in the sources pane.");
ok(selectedBreakpoint,
"There should be a selected breakpoint in the sources pane.");
let source = gSources.selectedItem.attachment.source;
let bp = queries.getBreakpoint(getState(), selectedBreakpoint.location);
ok(bp, "The selected breakpoint exists");
is(bp.location.actor, source.actor,
"The breakpoint on line " + line + " wasn't added on the correct source.");
is(bp.location.line, line,
"The breakpoint on line " + line + " wasn't found.");
is(!!bp.disabled, false,
"The breakpoint on line " + line + " should be enabled.");
is(!!selectedBreakpointItem.attachment.openPopup, false,
"The breakpoint on line " + line + " should not have opened a popup.");
is(gSources._conditionalPopupVisible, false,
"The breakpoint conditional expression popup should not have been shown.");
isnot(bp.condition, undefined,
"The breakpoint on line " + line + " should have a conditional expression.");
ok(isCaretPos(gPanel, line),
"The editor caret position is not properly set.");
}
const testAfterReload = Task.async(function*() {
let selectedActor = gSources.selectedValue;
let selectedBreakpoint = gSources._selectedBreakpoint;
ok(selectedActor,
"There should be a selected item in the sources pane after reload.");
ok(!selectedBreakpoint,
"There should be no selected breakpoint in the sources pane after reload.");
yield testBreakpoint(18, true);
yield testBreakpoint(19, true);
yield testBreakpoint(20, true);
yield testBreakpoint(21, true);
yield testBreakpoint(22, true);
yield testBreakpoint(23, true);
yield testBreakpoint(24, true);
yield testBreakpoint(25, true);
yield testBreakpoint(26, true);
yield testBreakpoint(27, true);
yield testBreakpoint(28, true);
yield testBreakpoint(29, true);
yield testBreakpoint(30, true);
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._selectedBreakpoint,
"There should be a selected breakpoint in the sources pane.")
is(gSources._conditionalPopupVisible, false,
"The breakpoint conditional expression popup should not be shown.");
});
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 17);
yield addBreakpoints();
is(gDebugger.gThreadClient.state, "paused",
"Should only be getting stack frames while paused.");
is(queries.getSourceCount(getState()), 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(queries.getBreakpoints(getState()).length, 13,
"13 breakpoints currently added.");
yield resumeAndTestBreakpoint(20);
yield resumeAndTestBreakpoint(21);
yield resumeAndTestBreakpoint(22);
yield resumeAndTestBreakpoint(23);
yield resumeAndTestBreakpoint(24);
yield resumeAndTestBreakpoint(25);
yield resumeAndTestBreakpoint(27);
yield resumeAndTestBreakpoint(28);
yield resumeAndTestBreakpoint(29);
yield resumeAndTestBreakpoint(30);
yield resumeAndTestNoBreakpoint();
let sourceShown = waitForSourceShown(gPanel, ".html");
reload(gPanel),
yield sourceShown;
testAfterReload();
// When a breakpoint is highlighted, the conditional expression
// popup opens, and then closes, and when it closes it sends the
// expression to the server which pauses the server. Make sure
// we wait if there is a pending request.
if (gDebugger.gThreadClient.state === "paused") {
yield waitForThreadEvents(gPanel, "resumed");
}
closeDebuggerAndFinish(gPanel);
});
callInTab(gTab, "ermahgerd");
});
function addBreakpoints() {
return promise.resolve(null)
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 18,
condition: "undefined"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 19,
condition: "null"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 20,
condition: "42"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 21,
condition: "true"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 22,
condition: "'nasu'"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 23,
condition: "/regexp/"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 24,
condition: "({})"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 25,
condition: "(function() {})"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 26,
condition: "(function() { return false; })()"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 27,
condition: "a"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 28,
condition: "a !== undefined"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 29,
condition: "a !== null"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 30,
condition: "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({ actor: gSources.selectedValue, line: aLine });
return finished;
}
let selectedActor = gSources.selectedValue;
let selectedBreakpoint = gSources._selectedBreakpointItem;
ok(selectedActor,
"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.actor, selectedActor,
"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.actor, selectedActor,
"The breakpoint's client url is correct");
is(aBreakpointClient.location.line, aLine,
"The breakpoint's client line is correct");
isnot(aBreakpointClient.condition, 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 selectedActor = getSelectedSourceURL(gSources);
let selectedBreakpoint = gSources._selectedBreakpointItem;
ok(selectedActor,
"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.");
});
}
}

Просмотреть файл

@ -2,186 +2,192 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Test adding and modifying conditional breakpoints (with server-side support)
* Bug 812172: Test adding and modifying conditional breakpoints (with server-side support)
*/
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
function test() {
let gTab, gPanel, gDebugger;
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
gBreakpointsAdded = gBreakpoints._added;
gBreakpointsRemoving = gBreakpoints._removing;
function addBreakpoint1() {
return actions.addBreakpoint({ actor: gSources.selectedValue, line: 18 });
}
function addBreakpoint2() {
let finished = waitForDispatch(gPanel, constants.ADD_BREAKPOINT);
setCaretPosition(19);
gSources._onCmdAddBreakpoint();
return finished;
}
function modBreakpoint2() {
setCaretPosition(19);
gSources._onCmdAddConditionalBreakpoint();
}
function addBreakpoint3() {
let finished = waitForDispatch(gPanel, constants.ADD_BREAKPOINT);
setCaretPosition(20);
gSources._onCmdAddConditionalBreakpoint();
return finished;
}
function modBreakpoint3() {
let finished = waitForDispatch(gPanel, constants.SET_BREAKPOINT_CONDITION);
setCaretPosition(20);
gSources._onCmdAddConditionalBreakpoint();
typeText(gSources._cbTextbox, "bamboocha");
EventUtils.sendKey("RETURN", gDebugger);
return finished;
}
function addBreakpoint4() {
let finished = waitForDispatch(gPanel, constants.ADD_BREAKPOINT);
setCaretPosition(21);
gSources._onCmdAddBreakpoint();
return finished;
}
function delBreakpoint4() {
let finished = waitForDispatch(gPanel, constants.REMOVE_BREAKPOINT);
setCaretPosition(21);
gSources._onCmdAddBreakpoint();
return finished;
}
function testBreakpoint(aLine, aPopupVisible, aConditionalExpression) {
const source = queries.getSelectedSource(getState());
ok(source,
"There should be a selected item in the sources pane.");
const bp = queries.getBreakpoint(getState(), {
actor: source.actor,
line: aLine
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);
});
const bpItem = gSources._getBreakpoint(bp);
ok(bp, "There should be a breakpoint.");
ok(bpItem, "There should be a breakpoint in the sources pane.");
is(bp.location.actor, source.actor,
"The breakpoint on line " + aLine + " wasn't added on the correct source.");
is(bp.location.line, aLine,
"The breakpoint on line " + aLine + " wasn't found.");
is(!!bp.disabled, false,
"The breakpoint on line " + aLine + " should be enabled.");
is(gSources._conditionalPopupVisible, aPopupVisible,
"The breakpoint on line " + aLine + " should have a correct popup state (2).");
is(bp.condition, aConditionalExpression,
"The breakpoint on line " + aLine + " should have a correct conditional expression.");
}
function testNoBreakpoint(aLine) {
let selectedActor = gSources.selectedValue;
let selectedBreakpoint = gSources._selectedBreakpoint;
ok(selectedActor,
"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.setCursor({ line: aLine - 1, ch: 0 });
}
function clickOnBreakpoint(aIndex) {
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelectorAll(".dbg-breakpoint")[aIndex],
gDebugger);
}
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 17);
is(gDebugger.gThreadClient.state, "paused",
"Should only be getting stack frames while paused.");
is(queries.getSourceCount(getState()), 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(queries.getBreakpoints(getState()).length, 0,
"No breakpoints currently added.");
yield addBreakpoint1();
testBreakpoint(18, false, undefined)
yield addBreakpoint2();
testBreakpoint(19, false, undefined);
yield modBreakpoint2();
testBreakpoint(19, true, undefined);
yield addBreakpoint3();
testBreakpoint(20, false, undefined);
yield modBreakpoint3();
testBreakpoint(20, false, "bamboocha");
yield addBreakpoint4();
testBreakpoint(21, false, undefined);
yield delBreakpoint4();
setCaretPosition(18);
is(gSources._selectedBreakpoint.location.line, 18,
"The selected breakpoint is line 18");
yield testBreakpoint(18, false, undefined);
setCaretPosition(19);
is(gSources._selectedBreakpoint.location.line, 19,
"The selected breakpoint is line 19");
yield testBreakpoint(19, false, "");
setCaretPosition(20);
is(gSources._selectedBreakpoint.location.line, 20,
"The selected breakpoint is line 20");
yield testBreakpoint(20, false, "bamboocha");
setCaretPosition(17);
yield testNoBreakpoint(17);
setCaretPosition(21);
yield testNoBreakpoint(21);
clickOnBreakpoint(0);
is(gSources._selectedBreakpoint.location.line, 18,
"The selected breakpoint is line 18");
yield testBreakpoint(18, false, undefined);
clickOnBreakpoint(1);
is(gSources._selectedBreakpoint.location.line, 19,
"The selected breakpoint is line 19");
yield testBreakpoint(19, false, "");
clickOnBreakpoint(2);
is(gSources._selectedBreakpoint.location.line, 20,
"The selected breakpoint is line 20");
testBreakpoint(20, true, "bamboocha");
resumeDebuggerThenCloseAndFinish(gPanel);
});
callInTab(gTab, "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({ actor: "foo", line: 3 }),
"_getAdded('foo', 3) returns falsey.");
ok(!gBreakpoints._getRemoving({ actor: "bar", line: 3 }),
"_getRemoving('bar', 3) returns falsey.");
}
function addBreakpoint1() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
gPanel.addBreakpoint({ actor: gSources.selectedValue, line: 18 });
return finished;
}
function addBreakpoint2() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
setCaretPosition(19);
gSources._onCmdAddBreakpoint();
return finished;
}
function modBreakpoint2() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
setCaretPosition(19);
gSources._onCmdAddConditionalBreakpoint();
return finished;
}
function addBreakpoint3() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
setCaretPosition(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);
setCaretPosition(21);
gSources._onCmdAddBreakpoint();
return finished;
}
function delBreakpoint4() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED);
setCaretPosition(21);
gSources._onCmdAddBreakpoint();
return finished;
}
function testBreakpoint(aLine, aOpenPopupFlag, aPopupVisible, aConditionalExpression) {
let selectedActor = gSources.selectedValue;
let selectedBreakpoint = gSources._selectedBreakpointItem;
ok(selectedActor,
"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.actor, selectedActor,
"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.actor, selectedActor,
"The breakpoint's client url is correct");
is(aBreakpointClient.location.line, aLine,
"The breakpoint's client line is correct");
is(aBreakpointClient.condition, aConditionalExpression,
"The breakpoint on line " + aLine + " should have a correct conditional expression.");
is("condition" 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 = getSelectedSourceURL(gSources);
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.setCursor({ line: aLine - 1, ch: 0 });
}
function clickOnBreakpoint(aIndex) {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_CLICKED);
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelectorAll(".dbg-breakpoint")[aIndex],
gDebugger);
return finished;
}
}

Просмотреть файл

@ -9,39 +9,74 @@
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
function test() {
let gTab, gPanel, gDebugger;
let gSources, gBreakpoints, gLocation;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 17);
const location = { actor: gSources.selectedValue, line: 18 };
gLocation = { actor: gSources.selectedValue, line: 18 };
yield actions.addBreakpoint(location, "hello");
yield actions.disableBreakpoint(location);
yield actions.addBreakpoint(location);
const bp = queries.getBreakpoint(getState(), location);
is(bp.condition, "hello", "The conditional expression is correct.");
const finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelector(".dbg-breakpoint"),
gDebugger);
yield finished;
const textbox = gDebugger.document.getElementById("conditional-breakpoint-panel-textbox");
is(textbox.value, "hello", "The expression is correct (2).")
resumeDebuggerThenCloseAndFinish(gPanel);
});
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
.then(addBreakpoint)
.then(setConditional)
.then(() => {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED);
toggleBreakpoint();
return finished;
})
.then(() => {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
toggleBreakpoint();
return finished;
})
.then(testConditionalExpressionOnClient)
.then(() => {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
openConditionalPopup();
return finished;
})
.then(testConditionalExpressionInPopup)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
callInTab(gTab, "ermahgerd");
});
function addBreakpoint() {
return gPanel.addBreakpoint(gLocation);
}
function setConditional(aClient) {
return gBreakpoints.updateCondition(aClient.location, "hello");
}
function toggleBreakpoint() {
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelector(".dbg-breakpoint-checkbox"),
gDebugger);
}
function openConditionalPopup() {
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelector(".dbg-breakpoint"),
gDebugger);
}
function testConditionalExpressionOnClient() {
return gBreakpoints._getAdded(gLocation).then(aClient => {
is(aClient.condition, "hello", "The expression is correct (1).");
});
}
function testConditionalExpressionInPopup() {
let textbox = gDebugger.document.getElementById("conditional-breakpoint-panel-textbox");
is(textbox.value, "hello", "The expression is correct (2).")
}
}

Просмотреть файл

@ -10,30 +10,75 @@
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
function test() {
let gTab, gPanel, gDebugger;
let gSources, gBreakpoints, gLocation;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 17);
const location = { actor: gSources.selectedValue, line: 18 };
gLocation = { actor: gSources.selectedValue, line: 18 };
yield actions.addBreakpoint(location, "");
yield actions.disableBreakpoint(location);
yield actions.addBreakpoint(location);
const bp = queries.getBreakpoint(getState(), location);
is(bp.condition, undefined, "The conditional expression is correct.");
resumeDebuggerThenCloseAndFinish(gPanel);
});
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
.then(addBreakpoint)
.then(setDummyConditional)
.then(() => {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED);
toggleBreakpoint();
return finished;
})
.then(() => {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED);
toggleBreakpoint();
return finished;
})
.then(testConditionalExpressionOnClient)
.then(() => {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWING);
openConditionalPopup();
finished.then(() => ok(false, "The popup shouldn't have opened."));
return waitForTime(1000);
})
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
callInTab(gTab, "ermahgerd");
});
function addBreakpoint() {
return gPanel.addBreakpoint(gLocation);
}
function setDummyConditional(aClient) {
// This happens when a conditional expression input popup is shown
// but the user doesn't type anything into it.
return gBreakpoints.updateCondition(aClient.location, '');
}
function toggleBreakpoint() {
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelector(".dbg-breakpoint-checkbox"),
gDebugger);
}
function openConditionalPopup() {
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelector(".dbg-breakpoint"),
gDebugger);
}
function testConditionalExpressionOnClient() {
return gBreakpoints._getAdded(gLocation).then(aClient => {
if ("condition" in aClient) {
ok(false, "A conditional expression shouldn't have been set.");
} else {
ok(true, "The conditional expression wasn't set, as expected.");
}
});
}
}

Просмотреть файл

@ -9,120 +9,163 @@
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
function test() {
// Linux debug test slaves are a bit slow at this test sometimes.
requestLongerTimeout(2);
let gTab, gPanel, gDebugger;
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const queries = gDebugger.require('./content/queries');
const constants = gDebugger.require('./content/constants');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
gBreakpointsAdded = gBreakpoints._added;
gBreakpointsRemoving = gBreakpoints._removing;
function resumeAndTestBreakpoint(line) {
let finished = waitForCaretUpdated(gPanel, line).then(() => testBreakpoint(line));
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._selectedBreakpoint,
"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, 6,
"There should be thirteen visible breakpoints.");
waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
.then(() => addBreakpoints())
.then(() => initialChecks())
.then(() => resumeAndTestBreakpoint(18))
.then(() => resumeAndTestBreakpoint(19))
.then(() => resumeAndTestBreakpoint(20))
.then(() => resumeAndTestBreakpoint(23))
.then(() => resumeAndTestNoBreakpoint())
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
gDebugger.gThreadClient.resume();
return finished;
}
function testBreakpoint(line, highlightBreakpoint) {
// Highlight the breakpoint only if required.
if (highlightBreakpoint) {
let finished = waitForCaretUpdated(gPanel, line).then(() => testBreakpoint(line));
gSources.highlightBreakpoint({ actor: gSources.selectedValue, line: line });
return finished;
}
let selectedActor = gSources.selectedValue;
let selectedBreakpoint = gSources._selectedBreakpoint;
let selectedBreakpointItem = gSources._getBreakpoint(selectedBreakpoint);
let source = queries.getSource(getState(), selectedActor);
ok(selectedActor,
"There should be a selected item in the sources pane.");
ok(selectedBreakpoint,
"There should be a selected breakpoint.");
ok(selectedBreakpointItem,
"There should be a selected breakpoint item in the sources pane.");
is(selectedBreakpoint.location.actor, source.actor,
"The breakpoint on line " + line + " wasn't added on the correct source.");
is(selectedBreakpoint.location.line, line,
"The breakpoint on line " + line + " wasn't found.");
is(!!selectedBreakpoint.location.disabled, false,
"The breakpoint on line " + line + " should be enabled.");
is(gSources._conditionalPopupVisible, false,
"The breakpoint conditional expression popup should not have been shown.");
isnot(selectedBreakpoint.condition, undefined,
"The breakpoint on line " + line + " should have a conditional expression.");
ok(isCaretPos(gPanel, line),
"The editor caret position is not properly set.");
}
Task.spawn(function*() {
yield waitForSourceAndCaretAndScopes(gPanel, ".html", 17)
yield actions.addBreakpoint(
{ actor: gSources.selectedValue, line: 18 }, " 1a"
);
yield actions.addBreakpoint(
{ actor: gSources.selectedValue, line: 19 }, "new Error()"
);
yield actions.addBreakpoint(
{ actor: gSources.selectedValue, line: 20 }, "true"
);
yield actions.addBreakpoint(
{ actor: gSources.selectedValue, line: 21 }, "false"
);
yield actions.addBreakpoint(
{ actor: gSources.selectedValue, line: 22 }, "0"
);
yield actions.addBreakpoint(
{ actor: gSources.selectedValue, line: 23 }, "randomVar"
);
yield resumeAndTestBreakpoint(18);
yield resumeAndTestBreakpoint(19);
yield resumeAndTestBreakpoint(20);
yield resumeAndTestBreakpoint(23);
yield resumeAndTestNoBreakpoint();
closeDebuggerAndFinish(gPanel);
});
callInTab(gTab, "ermahgerd");
});
function addBreakpoints() {
return promise.resolve(null)
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 18,
condition: "1a"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 19,
condition: "new Error()"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 20,
condition: "true"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 21,
condition: "false"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 22,
condition: "undefined"
}))
.then(() => gPanel.addBreakpoint({ actor: gSources.selectedValue,
line: 23,
condition: "randomVar"
}));
}
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, 6,
"6 breakpoints currently added.");
is(gBreakpointsRemoving.size, 0,
"No breakpoints currently being removed.");
is(gEditor.getBreakpoints().length, 6,
"6 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, 6,
"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({ actor: gSources.selectedValue, line: aLine });
return finished;
}
let selectedActor = gSources.selectedValue;
let selectedBreakpoint = gSources._selectedBreakpointItem;
ok(selectedActor,
"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.actor, selectedActor,
"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.actor, selectedActor,
"The breakpoint's client url is correct");
is(aBreakpointClient.location.line, aLine,
"The breakpoint's client line is correct");
isnot(aBreakpointClient.condition, undefined,
"The breakpoint on line " + aLine + " should have a conditional expression.");
ok(isCaretPos(gPanel, aLine),
"The editor caret position is not properly set.");
});
}
}

Просмотреть файл

@ -10,37 +10,38 @@ const TAB_URL = EXAMPLE_URL + "doc_script-bookmarklet.html";
const BOOKMARKLET_SCRIPT_CODE = "console.log('bookmarklet executed');";
function test() {
let gTab, gPanel, gDebugger;
let gSources, gBreakpoints;
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
const gTab = aTab;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gSources = gDebugger.DebuggerView.Sources;
const gBreakpoints = gDebugger.DebuggerController.Breakpoints;
const getState = gDebugger.DebuggerController.getState;
const constants = gDebugger.require('./content/constants');
const queries = gDebugger.require('./content/queries');
const actions = bindActionCreators(gPanel);
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
return Task.spawn(function*() {
yield waitForSourceShown(gPanel, '.html');
let waitForSource = waitForDebuggerEvents(gPanel, gPanel.panelWin.EVENTS.NEW_SOURCE, 1);
const added = waitForNextDispatch(gDebugger.DebuggerController, constants.ADD_SOURCE);
// NOTE: devtools debugger panel needs to be already open,
// or the bookmarklet script will not be shown in the sources panel
callInTab(gTab, "injectBookmarklet", BOOKMARKLET_SCRIPT_CODE);
yield added;
is(queries.getSourceCount(getState()), 2, "Should have 2 sources");
yield waitForSource;
const sources = queries.getSources(getState());
const sourceActor = Object.keys(sources).filter(k => {
return sources[k].url.indexOf("javascript:") === 0;
})[0];
const source = sources[sourceActor];
ok(source, "Source exists.");
is(gSources.values.length, 2, "Should have 2 source");
let res = yield actions.loadSourceText(source);
is(res.text, BOOKMARKLET_SCRIPT_CODE, "source is correct");
let item = gSources.getItemForAttachment(e => {
return e.label.indexOf("javascript:") === 0;
});
ok(item, "Source label is incorrect.");
let res = yield promiseInvoke(gDebugger.DebuggerController.client,
gDebugger.DebuggerController.client.request,
{ to: item.value, type: "source"});
ok(res && res.source == BOOKMARKLET_SCRIPT_CODE, "SourceActor reply received");
is(res.source, BOOKMARKLET_SCRIPT_CODE, "source is correct");
is(res.contentType, "text/javascript", "contentType is correct");
yield closeDebuggerAndFinish(gPanel);

Просмотреть файл

@ -8,135 +8,135 @@
const TAB_URL = EXAMPLE_URL + "doc_function-search.html";
const TOTAL_SOURCES = 4;
var gTab, gDebuggee, gPanel, gDebugger;
var gEditor, gSources, gControllerSources;
var gPrevLabelsCache, gPrevGroupsCache;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
const gTab = aTab;
const gDebuggee = aDebuggee;
const gPanel = aPanel;
const gDebugger = gPanel.panelWin;
const gEditor = gDebugger.DebuggerView.editor;
const gSources = gDebugger.DebuggerView.Sources;
const gPrevLabelsCache = gDebugger.SourceUtils._labelsCache;
const gPrevGroupsCache = gDebugger.SourceUtils._groupsCache;
const getState = gDebugger.DebuggerController.getState;
const queries = gDebugger.require('./content/queries');
const actions = bindActionCreators(gPanel);
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gControllerSources = gDebugger.DebuggerController.SourceScripts;
gPrevLabelsCache = gDebugger.SourceUtils._labelsCache;
gPrevGroupsCache = gDebugger.SourceUtils._groupsCache;
function initialChecks() {
ok(gEditor.getText().includes("First source!"),
"Editor text contents appears to be correct.");
is(gSources.selectedItem.attachment.label, "code_function-search-01.js",
"The currently selected label in the sources container is correct.");
ok(getSelectedSourceURL(gSources).includes("code_function-search-01.js"),
"The currently selected value in the sources container appears to be correct.");
is(gSources.itemCount, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " sources present in the sources list.");
is(gSources.visibleItems.length, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " sources visible in the sources list.");
is(gSources.attachments.length, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " attachments stored in the sources container model.")
is(gSources.values.length, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " values stored in the sources container model.")
info("Source labels: " + gSources.attachments.toSource());
info("Source values: " + gSources.values.toSource());
is(gSources.attachments[0].label, "code_function-search-01.js",
"The first source label is correct.");
ok(gSources.attachments[0].source.url.includes("code_function-search-01.js"),
"The first source value appears to be correct.");
is(gSources.attachments[1].label, "code_function-search-02.js",
"The second source label is correct.");
ok(gSources.attachments[1].source.url.includes("code_function-search-02.js"),
"The second source value appears to be correct.");
is(gSources.attachments[2].label, "code_function-search-03.js",
"The third source label is correct.");
ok(gSources.attachments[2].source.url.includes("code_function-search-03.js"),
"The third source value appears to be correct.");
is(gSources.attachments[3].label, "doc_function-search.html",
"The third source label is correct.");
ok(gSources.attachments[3].source.url.includes("doc_function-search.html"),
"The third source value appears to be correct.");
is(gDebugger.SourceUtils._labelsCache.size, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " labels cached.");
is(gDebugger.SourceUtils._groupsCache.size, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " groups cached.");
}
function performReloadAndTestState() {
gDebugger.gTarget.once("will-navigate", testStateBeforeReload);
gDebugger.gTarget.once("navigate", testStateAfterReload);
return reloadActiveTab(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
}
function testCacheIntegrity(cachedSources) {
const contents = {
[EXAMPLE_URL + "code_function-search-01.js"]: "First source!",
[EXAMPLE_URL + "code_function-search-02.js"]: "Second source!",
[EXAMPLE_URL + "code_function-search-03.js"]: "Third source!",
[EXAMPLE_URL + "doc_function-search.html"]: "Peanut butter jelly time!"
};
const sourcesText = getState().sources.sourcesText;
is(Object.keys(sourcesText).length, cachedSources.length,
"The right number of sources is cached");
cachedSources.forEach(sourceUrl => {
const source = queries.getSourceByURL(getState(), EXAMPLE_URL + sourceUrl);
const content = queries.getSourceText(getState(), source.actor);
ok(content, "Source text is cached");
ok(content.text.includes(contents[source.url]), "Source text is correct");
waitForSourceShown(gPanel, "-01.js")
.then(initialChecks)
.then(getTextForSourcesAndCheckIntegrity)
.then(performReloadAndTestState)
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
}
function fetchAllSources() {
const sources = queries.getSources(getState());
return Promise.all(Object.keys(sources).map(k => {
const source = sources[k];
return actions.loadSourceText(source);
}));
}
function testStateBeforeReload() {
is(gSources.itemCount, 0,
"There should be no sources present in the sources list during reload.");
is(gDebugger.SourceUtils._labelsCache, gPrevLabelsCache,
"The labels cache has been refreshed during reload and no new objects were created.");
is(gDebugger.SourceUtils._groupsCache, gPrevGroupsCache,
"The groups cache has been refreshed during reload and no new objects were created.");
is(gDebugger.SourceUtils._labelsCache.size, 0,
"There should be no labels cached during reload");
is(gDebugger.SourceUtils._groupsCache.size, 0,
"There should be no groups cached during reload");
}
function testStateAfterReload() {
is(gSources.itemCount, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " sources present in the sources list.");
is(gDebugger.SourceUtils._labelsCache.size, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " labels cached after reload.");
is(gDebugger.SourceUtils._groupsCache.size, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " groups cached after reload.");
}
Task.spawn(function*() {
yield waitForSourceShown(gPanel, "-01.js");
yield initialChecks();
yield testCacheIntegrity(["code_function-search-01.js"]);
yield fetchAllSources();
yield testCacheIntegrity([
"code_function-search-01.js",
"code_function-search-02.js",
"code_function-search-03.js",
"doc_function-search.html"
]);
yield performReloadAndTestState();
closeDebuggerAndFinish(gPanel);
});
});
}
function initialChecks() {
ok(gEditor.getText().includes("First source!"),
"Editor text contents appears to be correct.");
is(gSources.selectedItem.attachment.label, "code_function-search-01.js",
"The currently selected label in the sources container is correct.");
ok(getSelectedSourceURL(gSources).includes("code_function-search-01.js"),
"The currently selected value in the sources container appears to be correct.");
is(gSources.itemCount, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " sources present in the sources list.");
is(gSources.visibleItems.length, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " sources visible in the sources list.");
is(gSources.attachments.length, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " attachments stored in the sources container model.")
is(gSources.values.length, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " values stored in the sources container model.")
info("Source labels: " + gSources.attachments.toSource());
info("Source values: " + gSources.values.toSource());
is(gSources.attachments[0].label, "code_function-search-01.js",
"The first source label is correct.");
ok(gSources.attachments[0].source.url.includes("code_function-search-01.js"),
"The first source value appears to be correct.");
is(gSources.attachments[1].label, "code_function-search-02.js",
"The second source label is correct.");
ok(gSources.attachments[1].source.url.includes("code_function-search-02.js"),
"The second source value appears to be correct.");
is(gSources.attachments[2].label, "code_function-search-03.js",
"The third source label is correct.");
ok(gSources.attachments[2].source.url.includes("code_function-search-03.js"),
"The third source value appears to be correct.");
is(gSources.attachments[3].label, "doc_function-search.html",
"The third source label is correct.");
ok(gSources.attachments[3].source.url.includes("doc_function-search.html"),
"The third source value appears to be correct.");
is(gDebugger.SourceUtils._labelsCache.size, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " labels cached.");
is(gDebugger.SourceUtils._groupsCache.size, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " groups cached.");
}
function getTextForSourcesAndCheckIntegrity() {
return gControllerSources.getTextForSources(gSources.values).then(testCacheIntegrity);
}
function performReloadAndTestState() {
gDebugger.gTarget.once("will-navigate", testStateBeforeReload);
gDebugger.gTarget.once("navigate", testStateAfterReload);
return reloadActiveTab(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
}
function testCacheIntegrity(aSources) {
for (let [actor, contents] of aSources) {
// Sources of a debugee don't always finish fetching consecutively. D'uh.
let index = gSources.values.indexOf(actor);
ok(index >= 0 && index <= TOTAL_SOURCES,
"Found a source actor cached correctly (" + index + ").");
ok(contents.includes(
["First source!", "Second source!", "Third source!", "Peanut butter jelly time!"][index]),
"Found a source's text contents cached correctly (" + index + ").");
info("Cached source actor at " + index + ": " + actor);
info("Cached source text at " + index + ": " + contents);
}
}
function testStateBeforeReload() {
is(gSources.itemCount, 0,
"There should be no sources present in the sources list during reload.");
is(gDebugger.SourceUtils._labelsCache, gPrevLabelsCache,
"The labels cache has been refreshed during reload and no new objects were created.");
is(gDebugger.SourceUtils._groupsCache, gPrevGroupsCache,
"The groups cache has been refreshed during reload and no new objects were created.");
is(gDebugger.SourceUtils._labelsCache.size, 0,
"There should be no labels cached during reload");
is(gDebugger.SourceUtils._groupsCache.size, 0,
"There should be no groups cached during reload");
}
function testStateAfterReload() {
is(gSources.itemCount, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " sources present in the sources list.");
is(gDebugger.SourceUtils._labelsCache.size, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " labels cached after reload.");
is(gDebugger.SourceUtils._groupsCache.size, TOTAL_SOURCES,
"There should be " + TOTAL_SOURCES + " groups cached after reload.");
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gSources = null;
gControllerSources = null;
gPrevLabelsCache = null;
gPrevGroupsCache = null;
});

Просмотреть файл

@ -19,26 +19,24 @@ function test() {
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
gEditor = gDebugger.DebuggerView.editor;
const constants = gDebugger.require('./content/constants');
const queries = gDebugger.require('./content/queries');
const actions = bindActionCreators(gPanel);
const getState = gDebugger.DebuggerController.getState;
return Task.spawn(function*() {
yield waitForSourceShown(gPanel, "-eval.js");
is(queries.getSourceCount(getState()), 1, "Should have 1 source");
is(gSources.values.length, 1, "Should have 1 source");
const newSource = waitForDispatch(gPanel, constants.ADD_SOURCE);
let newSource = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.NEW_SOURCE);
callInTab(gTab, "evalSourceWithSourceURL");
yield newSource;
is(queries.getSourceCount(getState()), 2, "Should have 2 sources");
is(gSources.values.length, 2, "Should have 2 sources");
const source = queries.getSourceByURL(getState(), EXAMPLE_URL + "bar.js");
ok(source, "Source exists.");
let item = gSources.getItemForAttachment(e => e.label == "bar.js");
ok(item, "Source label is incorrect.");
is(item.attachment.group, 'http://example.com',
'Source group is incorrect');
let shown = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
actions.selectSource(source);
gSources.selectedItem = item;
yield shown;
ok(gEditor.getText().indexOf('bar = function() {') === 0,

Просмотреть файл

@ -11,7 +11,7 @@ function test() {
let gTab, gPanel, gDebugger;
let gSources, gUtils;
initDebugger(TAB_URL).then(Task.async(function*([aTab,, aPanel]) {
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
gTab = aTab;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
@ -21,8 +21,6 @@ function test() {
let ellipsis = gPanel.panelWin.L10N.ellipsis;
let nananana = new Array(20).join(NaN);
yield waitForSourceShown(gPanel, '.html');
// Test trimming url queries.
let someUrl = "a/b/c.d?test=1&random=4#reference";
@ -164,5 +162,5 @@ function test() {
"gSources.getItemForAttachment isn't functioning properly (1).");
closeDebuggerAndFinish(gPanel);
}));
});
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше