Skip to content
This repository has been archived by the owner on Jul 3, 2018. It is now read-only.

Commit

Permalink
Bug 1215117 - Make console input field work inside a worker toolbox;r…
Browse files Browse the repository at this point in the history
…=ejpbruel

--HG--
extra : commitid : 284VqUOwCvf
  • Loading branch information
bgrins committed Oct 26, 2015
1 parent 57708c4 commit 1e63b6e
Show file tree
Hide file tree
Showing 16 changed files with 304 additions and 107 deletions.
2 changes: 2 additions & 0 deletions devtools/client/debugger/test/mochitest/browser.ini
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,8 @@ skip-if = e10s && debug
skip-if = e10s && debug
[browser_dbg_watch-expressions-02.js]
skip-if = e10s && debug
[browser_dbg_worker-console.js]
skip-if = e10s && debug
[browser_dbg_worker-window.js]
skip-if = e10s && debug
[browser_dbg_WorkerActor.attach.js]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function test() {

let oncePaused = gTarget.once("thread-paused");
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
let jsterm = yield getSplitConsole();
let jsterm = yield getSplitConsole(gDevTools.getToolbox(gPanel.target));
let executed = jsterm.execute("1+1");
yield oncePaused;

Expand All @@ -54,20 +54,4 @@ function test() {

yield executed;
});

function getSplitConsole() {
return new Promise(resolve => {
let toolbox = gDevTools.getToolbox(gPanel.target);
toolbox.once("webconsole-ready", () => {
ok(toolbox.splitConsole, "Split console is shown.");
let jsterm = toolbox.getPanel("webconsole").hud.jsterm;
resolve(jsterm);
});
EventUtils.synthesizeKey("VK_ESCAPE", {}, gDebugger);
});
}
}

registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled");
});
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,4 @@ function test() {
closeDebuggerAndFinish(gPanel);
});
});

function getSplitConsole(toolbox, theDebugger) {
return new Promise(resolve => {
toolbox.once("webconsole-ready", () => {
let jsterm = toolbox.getPanel("webconsole").hud.jsterm;
resolve(jsterm);
});
EventUtils.synthesizeKey("VK_ESCAPE", {}, theDebugger);
});
}
}

registerCleanupFunction(() => {
// We don't want the open split console to confuse other tests..
Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled");
});
145 changes: 145 additions & 0 deletions devtools/client/debugger/test/mochitest/browser_dbg_worker-console.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// Check to make sure that a worker can be attached to a toolbox
// and that the console works.

var TAB_URL = EXAMPLE_URL + "doc_WorkerActor.attachThread-tab.html";
var WORKER_URL = "code_WorkerActor.attachThread-worker.js";

function* initWorkerDebugger(TAB_URL, WORKER_URL) {
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
}

let client = new DebuggerClient(DebuggerServer.connectPipe());
yield connect(client);

let tab = yield addTab(TAB_URL);
let { tabs } = yield listTabs(client);
let [, tabClient] = yield attachTab(client, findTab(tabs, TAB_URL));

yield createWorkerInTab(tab, WORKER_URL);

let { workers } = yield listWorkers(tabClient);
let [, workerClient] = yield attachWorker(tabClient,
findWorker(workers, WORKER_URL));

let toolbox = yield gDevTools.showToolbox(TargetFactory.forWorker(workerClient),
"jsdebugger",
Toolbox.HostType.WINDOW);

let debuggerPanel = toolbox.getCurrentPanel();
let gDebugger = debuggerPanel.panelWin;

return {client,tab,tabClient,workerClient,toolbox,gDebugger};
}

add_task(function* testNormalExecution() {
let {client,tab,tabClient,workerClient,toolbox,gDebugger} =
yield initWorkerDebugger(TAB_URL, WORKER_URL);

let jsterm = yield getSplitConsole(toolbox);
let executed = yield jsterm.execute("this.location.toString()");
ok(executed.textContent.includes(WORKER_URL),
"Evaluating the global's location works");

yield gDevTools.closeToolbox(TargetFactory.forWorker(workerClient));
terminateWorkerInTab(tab, WORKER_URL);
yield waitForWorkerClose(workerClient);
yield close(client);
yield removeTab(tab);
});

add_task(function* testWhilePaused() {
let {client,tab,tabClient,workerClient,toolbox,gDebugger} =
yield initWorkerDebugger(TAB_URL, WORKER_URL);

let gTarget = gDebugger.gTarget;
let gResumeButton = gDebugger.document.getElementById("resume");
let gResumeKey = gDebugger.document.getElementById("resumeKey");

// Execute some basic math to make sure evaluations are working.
let jsterm = yield getSplitConsole(toolbox);
let executed = yield jsterm.execute("10000+1");
ok(executed.textContent.includes("10001"), "Text for message appeared correct");

// Pause the worker by waiting for next execution and then sending a message to
// it from the main thread.
let oncePaused = gTarget.once("thread-paused");
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
once(gDebugger.gClient, "willInterrupt").then(() => {
info("Posting message to worker, then waiting for a pause");
postMessageToWorkerInTab(tab, WORKER_URL, "ping");
});
yield oncePaused;

let command1 = jsterm.execute("10000+2");
let command2 = jsterm.execute("10000+3");
let command3 = jsterm.execute("foobar"); // throw an error

info ("Trying to get the result of command1");
executed = yield command1;
ok(executed.textContent.includes("10002"),
"command1 executed successfully");

info ("Trying to get the result of command2");
executed = yield command2;
ok(executed.textContent.includes("10003"),
"command2 executed successfully");

info ("Trying to get the result of command3")
executed = yield command3;
// XXXworkers This is failing until Bug 1215120 is resolved.
todo(executed.textContent.includes("ReferenceError: foobar is not defined"),
"command3 executed successfully");

let onceResumed = gTarget.once("thread-resumed");
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
yield onceResumed;

yield gDevTools.closeToolbox(TargetFactory.forWorker(workerClient));
terminateWorkerInTab(tab, WORKER_URL);
yield waitForWorkerClose(workerClient);
yield close(client);
yield removeTab(tab);
});

// Test to see if creating the pause from the console works.
add_task(function* testPausedByConsole() {
let {client,tab,tabClient,workerClient,toolbox,gDebugger} =
yield initWorkerDebugger(TAB_URL, WORKER_URL);

let gTarget = gDebugger.gTarget;
let gResumeButton = gDebugger.document.getElementById("resume");
let gResumeKey = gDebugger.document.getElementById("resumeKey");

let jsterm = yield getSplitConsole(toolbox);
let executed = yield jsterm.execute("10000+1");
ok(executed.textContent.includes("10001"),
"Text for message appeared correct");

let oncePaused = gTarget.once("thread-paused");
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
let pausedExecution = jsterm.execute("10000+2");

info("Executed a command with 'break on next' active, waiting for pause");
yield oncePaused;

executed = yield jsterm.execute("10000+3");
ok(executed.textContent.includes("10003"),
"Text for message appeared correct");

info("Waiting for a resume");
let onceResumed = gTarget.once("thread-resumed");
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
yield onceResumed;

executed = yield pausedExecution;
ok(executed.textContent.includes("10002"),
"Text for message appeared correct");

yield gDevTools.closeToolbox(TargetFactory.forWorker(workerClient));
terminateWorkerInTab(tab, WORKER_URL);
yield waitForWorkerClose(workerClient);
yield close(client);
yield removeTab(tab);
});
25 changes: 25 additions & 0 deletions devtools/client/debugger/test/mochitest/head.js
Original file line number Diff line number Diff line change
Expand Up @@ -1190,3 +1190,28 @@ function afterDispatch(store, type) {
});
});
}

// Return a promise with a reference to jsterm, opening the split
// console if necessary. This cleans up the split console pref so
// it won't pollute other tests.
function getSplitConsole(toolbox, win) {
registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled");
});

if (!win) {
win = toolbox.doc.defaultView;
}

if (!toolbox.splitConsole) {
EventUtils.synthesizeKey("VK_ESCAPE", {}, win);
}

return new Promise(resolve => {
toolbox.getPanelWhenReady("webconsole").then(() => {
ok(toolbox.splitConsole, "Split console is shown.");
let jsterm = toolbox.getPanel("webconsole").hud.jsterm;
resolve(jsterm);
});
});
}
8 changes: 7 additions & 1 deletion devtools/client/framework/target.js
Original file line number Diff line number Diff line change
Expand Up @@ -732,8 +732,14 @@ WorkerTarget.prototype = {
return this._workerClient.url;
},

get isWorkerTarget() {
return true;
},

get form() {
return {};
return {
consoleActor: this._workerClient.consoleActor
};
},

get activeTab() {
Expand Down
18 changes: 11 additions & 7 deletions devtools/client/webconsole/webconsole.js
Original file line number Diff line number Diff line change
Expand Up @@ -5033,13 +5033,17 @@ WebConsoleConnectionProxy.prototype = {

let client = this.client = this.target.client;

client.addListener("logMessage", this._onLogMessage);
client.addListener("pageError", this._onPageError);
client.addListener("consoleAPICall", this._onConsoleAPICall);
client.addListener("fileActivity", this._onFileActivity);
client.addListener("reflowActivity", this._onReflowActivity);
client.addListener("serverLogCall", this._onServerLogCall);
client.addListener("lastPrivateContextExited", this._onLastPrivateContextExited);
if (this.target.isWorkerTarget) {
// XXXworkers: Not Console API yet inside of workers (Bug 1209353).
} else {
client.addListener("logMessage", this._onLogMessage);
client.addListener("pageError", this._onPageError);
client.addListener("consoleAPICall", this._onConsoleAPICall);
client.addListener("fileActivity", this._onFileActivity);
client.addListener("reflowActivity", this._onReflowActivity);
client.addListener("serverLogCall", this._onServerLogCall);
client.addListener("lastPrivateContextExited", this._onLastPrivateContextExited);
}
this.target.on("will-navigate", this._onTabNavigated);
this.target.on("navigate", this._onTabNavigated);

Expand Down
66 changes: 33 additions & 33 deletions devtools/server/actors/webconsole.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,18 @@

"use strict";

const Services = require("Services");
const { Cc, Ci, Cu } = require("chrome");
const { DebuggerServer, ActorPool } = require("devtools/server/main");
const { EnvironmentActor, ThreadActor } = require("devtools/server/actors/script");
const { ObjectActor, LongStringActor, createValueGrip, stringIsLong } = require("devtools/server/actors/object");
const DevToolsUtils = require("devtools/shared/DevToolsUtils");

Cu.import("resource://gre/modules/XPCOMUtils.jsm");

XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyGetter(this, "NetworkMonitor", () => {
return require("devtools/shared/webconsole/network-monitor")
.NetworkMonitor;
});
XPCOMUtils.defineLazyGetter(this, "NetworkMonitorChild", () => {
return require("devtools/shared/webconsole/network-monitor")
.NetworkMonitorChild;
});
XPCOMUtils.defineLazyGetter(this, "ConsoleProgressListener", () => {
return require("devtools/shared/webconsole/network-monitor")
.ConsoleProgressListener;
});
XPCOMUtils.defineLazyGetter(this, "events", () => {
return require("sdk/event/core");
});
XPCOMUtils.defineLazyGetter(this, "ServerLoggingListener", () => {
return require("devtools/shared/webconsole/server-logger")
.ServerLoggingListener;
});
loader.lazyRequireGetter(this, "NetworkMonitor", "devtools/shared/webconsole/network-monitor", true);
loader.lazyRequireGetter(this, "NetworkMonitorChild", "devtools/shared/webconsole/network-monitor", true);
loader.lazyRequireGetter(this, "ConsoleProgressListener", "devtools/shared/webconsole/network-monitor", true);
loader.lazyRequireGetter(this, "events", "sdk/event/core");
loader.lazyRequireGetter(this, "ServerLoggingListener", "devtools/shared/webconsole/server-logger", true);

for (let name of ["WebConsoleUtils", "ConsoleServiceListener",
"ConsoleAPIListener", "addWebConsoleCommands", "JSPropertyProvider",
Expand All @@ -44,7 +27,11 @@ for (let name of ["WebConsoleUtils", "ConsoleServiceListener",
if (prop == "WebConsoleUtils") {
prop = "Utils";
}
return require("devtools/shared/webconsole/utils")[prop];
if (isWorker) {
return require("devtools/shared/webconsole/worker-utils")[prop];
} else {
return require("devtools/shared/webconsole/utils")[prop];
}
}.bind(null, name),
configurable: true,
enumerable: true
Expand Down Expand Up @@ -556,6 +543,11 @@ WebConsoleActor.prototype =
*/
onStartListeners: function WCA_onStartListeners(aRequest)
{
// XXXworkers: Not handling the Console API yet for workers (Bug 1209353).
if (isWorker) {
aRequest.listeners = [];
}

let startedListeners = [];
let window = !this.parentActor.isRootActor ? this.window : null;
let appId = null;
Expand Down Expand Up @@ -849,8 +841,12 @@ WebConsoleActor.prototype =
} else if ("throw" in evalResult) {
let error = evalResult.throw;
errorGrip = this.createValueGrip(error);
errorMessage = error && (typeof error === "object")
? error.unsafeDereference().toString()
// XXXworkers: Calling unsafeDereference() returns an object with no
// toString method in workers. See Bug 1215120.
let unsafeDereference = error && (typeof error === "object") &&
error.unsafeDereference();
errorMessage = unsafeDereference && unsafeDereference.toString
? unsafeDereference.toString()
: "" + error;
}
}
Expand Down Expand Up @@ -899,8 +895,8 @@ WebConsoleActor.prototype =
environment = frame.environment;
}
else {
Cu.reportError("Web Console Actor: the frame actor was not found: " +
frameActorId);
DevToolsUtils.reportException("onAutocomplete",
Error("The frame actor was not found: " + frameActorId));
}
}
// This is the general case (non-paused debugger)
Expand Down Expand Up @@ -1043,9 +1039,13 @@ WebConsoleActor.prototype =
}
for (let name in helpers.sandbox) {
let desc = Object.getOwnPropertyDescriptor(helpers.sandbox, name);
maybeExport(desc, 'get');
maybeExport(desc, 'set');
maybeExport(desc, 'value');

// Workers don't have access to Cu so won't be able to exportFunction.
if (!isWorker) {
maybeExport(desc, 'get');
maybeExport(desc, 'set');
maybeExport(desc, 'value');
}
if (desc.value) {
// Make sure the helpers can be used during eval.
desc.value = aDebuggerGlobal.makeDebuggeeValue(desc.value);
Expand Down Expand Up @@ -1138,8 +1138,8 @@ WebConsoleActor.prototype =
frame = frameActor.frame;
}
else {
Cu.reportError("Web Console Actor: the frame actor was not found: " +
aOptions.frameActor);
DevToolsUtils.reportException("evalWithDebugger",
Error("The frame actor was not found: " + aOptions.frameActor));
}
}

Expand Down
Loading

0 comments on commit 1e63b6e

Please sign in to comment.