зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1500986 - Migrate addon test from old debugger to shared r=jdescottes
--HG-- rename : devtools/client/debugger/test/mochitest/addon4.xpi => devtools/client/shared/test/addon4.xpi rename : devtools/client/debugger/test/mochitest/browser_dbg_addon-console.js => devtools/client/shared/test/browser_dbg_addon-console.js
This commit is contained in:
Родитель
d843fa0143
Коммит
4a01b79d33
|
@ -1,12 +1,8 @@
|
|||
# Tests in this directory are split into two manifests (this and browser2.ini)
|
||||
# to facilitate better chunking; see bug 1294489.
|
||||
|
||||
[DEFAULT]
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
skip-if = (os == 'linux' && debug && bits == 32)
|
||||
support-files =
|
||||
addon4.xpi
|
||||
doc_promise-get-allocation-stack.html
|
||||
doc_promise-get-fulfillment-stack.html
|
||||
doc_promise-get-rejection-stack.html
|
||||
|
@ -14,9 +10,6 @@ support-files =
|
|||
head.js
|
||||
!/devtools/client/shared/test/shared-head.js
|
||||
!/devtools/client/shared/test/telemetry-test-helpers.js
|
||||
[browser_dbg_addon-console.js]
|
||||
skip-if = (e10s && debug || os == 'win' || verify) || true # bug 1005274
|
||||
tags = addons
|
||||
[browser_dbg_promises-allocation-stack.js]
|
||||
uses-unsafe-cpows = true
|
||||
skip-if = true
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that the we can see console messages from the add-on
|
||||
|
||||
const ADDON_ID = "browser_dbg_addon4@tests.mozilla.org";
|
||||
const ADDON_PATH = "addon4.xpi";
|
||||
|
||||
function getCachedMessages(webConsole) {
|
||||
let deferred = promise.defer();
|
||||
webConsole.getCachedMessages(["ConsoleAPI"], (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
deferred.reject(aResponse.error);
|
||||
return;
|
||||
}
|
||||
deferred.resolve(aResponse.messages);
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
let addon = yield addTemporaryAddon(ADDON_PATH);
|
||||
let addonDebugger = yield initAddonDebugger(ADDON_ID);
|
||||
|
||||
let webConsole = addonDebugger.webConsole;
|
||||
let messages = yield getCachedMessages(webConsole);
|
||||
is(messages.length, 1, "Should be one cached message");
|
||||
is(messages[0].arguments[0].type, "object", "Should have logged an object");
|
||||
is(messages[0].arguments[0].preview.ownProperties.msg.value, "Hello from the test add-on", "Should have got the right message");
|
||||
|
||||
let consolePromise = addonDebugger.once("console");
|
||||
|
||||
console.log("Bad message");
|
||||
Services.obs.notifyObservers(null, "addon-test-ping");
|
||||
|
||||
let messageGrip = yield consolePromise;
|
||||
is(messageGrip.arguments[0].type, "object", "Should have logged an object");
|
||||
is(messageGrip.arguments[0].preview.ownProperties.msg.value, "Hello again", "Should have got the right message");
|
||||
|
||||
yield addonDebugger.destroy();
|
||||
yield removeAddon(addon);
|
||||
finish();
|
||||
});
|
||||
}
|
|
@ -591,157 +591,6 @@ let initDebugger = Task.async(function*(urlOrTab, options) {
|
|||
return [tab, debuggerPanel, window];
|
||||
});
|
||||
|
||||
// Creates an add-on debugger for a given add-on. The returned AddonDebugger
|
||||
// object must be destroyed before finishing the test
|
||||
function initAddonDebugger(aAddonId) {
|
||||
let addonDebugger = new AddonDebugger();
|
||||
return addonDebugger.init(aAddonId).then(() => addonDebugger);
|
||||
}
|
||||
|
||||
function AddonDebugger() {
|
||||
this._onMessage = this._onMessage.bind(this);
|
||||
this._onConsoleAPICall = this._onConsoleAPICall.bind(this);
|
||||
EventEmitter.decorate(this);
|
||||
}
|
||||
|
||||
AddonDebugger.prototype = {
|
||||
init: Task.async(function* (aAddonId) {
|
||||
info("Initializing an addon debugger panel.");
|
||||
|
||||
DebuggerServer.init();
|
||||
DebuggerServer.registerAllActors();
|
||||
DebuggerServer.allowChromeProcess = true;
|
||||
|
||||
this.frame = document.createElement("iframe");
|
||||
this.frame.setAttribute("height", 400);
|
||||
document.documentElement.appendChild(this.frame);
|
||||
window.addEventListener("message", this._onMessage);
|
||||
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
this.client = new DebuggerClient(transport);
|
||||
|
||||
yield this.client.connect();
|
||||
|
||||
let addonTargetActor = yield getAddonActorForId(this.client, aAddonId);
|
||||
|
||||
let targetOptions = {
|
||||
form: addonTargetActor,
|
||||
client: this.client,
|
||||
chrome: true,
|
||||
};
|
||||
|
||||
let toolboxOptions = {
|
||||
customIframe: this.frame
|
||||
};
|
||||
|
||||
this.target = yield TargetFactory.forRemoteTab(targetOptions);
|
||||
let toolbox = yield gDevTools.showToolbox(this.target, "jsdebugger", Toolbox.HostType.CUSTOM, toolboxOptions);
|
||||
|
||||
info("Addon debugger panel shown successfully.");
|
||||
|
||||
this.debuggerPanel = toolbox.getCurrentPanel();
|
||||
yield waitForSourceShown(this.debuggerPanel, "");
|
||||
|
||||
prepareDebugger(this.debuggerPanel);
|
||||
yield this._attachConsole();
|
||||
}),
|
||||
|
||||
destroy: Task.async(function* () {
|
||||
yield this.client.close();
|
||||
yield this.debuggerPanel._toolbox.destroy();
|
||||
this.frame.remove();
|
||||
window.removeEventListener("message", this._onMessage);
|
||||
}),
|
||||
|
||||
_attachConsole: function () {
|
||||
let deferred = promise.defer();
|
||||
this.client.attachConsole(this.target.form.consoleActor, ["ConsoleAPI"])
|
||||
.then(([aResponse, aWebConsoleClient]) => {
|
||||
this.webConsole = aWebConsoleClient;
|
||||
this.client.addListener("consoleAPICall", this._onConsoleAPICall);
|
||||
deferred.resolve();
|
||||
}, e => {
|
||||
deferred.reject(e);
|
||||
});
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
_onConsoleAPICall: function (aType, aPacket) {
|
||||
if (aPacket.from != this.webConsole.actor)
|
||||
return;
|
||||
this.emit("console", aPacket.message);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a list of the groups and sources in the UI. The returned array
|
||||
* contains objects for each group with properties name and sources. The
|
||||
* sources property contains an array with objects for each source for that
|
||||
* group with properties label and url.
|
||||
*/
|
||||
getSourceGroups: Task.async(function* () {
|
||||
let debuggerWin = this.debuggerPanel.panelWin;
|
||||
let sources = yield getSources(debuggerWin.gThreadClient);
|
||||
ok(sources.length, "retrieved sources");
|
||||
|
||||
// groups will be the return value, groupmap and the maps we put in it will
|
||||
// be used as quick lookups to add the url information in below
|
||||
let groups = [];
|
||||
let groupmap = new Map();
|
||||
|
||||
let uigroups = this.debuggerPanel.panelWin.document.querySelectorAll(".side-menu-widget-group");
|
||||
for (let g of uigroups) {
|
||||
let name = g.querySelector(".side-menu-widget-group-title .name").value;
|
||||
let group = {
|
||||
name: name,
|
||||
sources: []
|
||||
};
|
||||
groups.push(group);
|
||||
let labelmap = new Map();
|
||||
groupmap.set(name, labelmap);
|
||||
|
||||
for (let l of g.querySelectorAll(".dbg-source-item")) {
|
||||
let source = {
|
||||
label: l.value,
|
||||
url: null
|
||||
};
|
||||
|
||||
labelmap.set(l.value, source);
|
||||
group.sources.push(source);
|
||||
}
|
||||
}
|
||||
|
||||
for (let source of sources) {
|
||||
let { label, group } = debuggerWin.DebuggerView.Sources.getItemByValue(source.actor).attachment;
|
||||
|
||||
if (!groupmap.has(group)) {
|
||||
ok(false, "Saw a source group not in the UI: " + group);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!groupmap.get(group).has(label)) {
|
||||
ok(false, "Saw a source label not in the UI: " + label);
|
||||
continue;
|
||||
}
|
||||
|
||||
groupmap.get(group).get(label).url = source.url.split(" -> ").pop();
|
||||
}
|
||||
|
||||
return groups;
|
||||
}),
|
||||
|
||||
_onMessage: function(event) {
|
||||
if (!event.data) {
|
||||
return;
|
||||
}
|
||||
const msg = event.data;
|
||||
switch (msg.name) {
|
||||
case "toolbox-title":
|
||||
this.title = msg.data.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function initChromeDebugger(aOnClose) {
|
||||
info("Initializing a chrome debugger process.");
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ subsuite = devtools
|
|||
support-files =
|
||||
addon1.xpi
|
||||
addon2.xpi
|
||||
addon4.xpi
|
||||
browser_devices.json
|
||||
code_listworkers-worker1.js
|
||||
code_listworkers-worker2.js
|
||||
|
@ -49,6 +50,7 @@ support-files =
|
|||
dummy.html
|
||||
frame-script-utils.js
|
||||
head.js
|
||||
helper_addons.js
|
||||
helper_color_data.js
|
||||
helper_html_tooltip.js
|
||||
helper_inplace_editor.js
|
||||
|
@ -74,6 +76,9 @@ support-files =
|
|||
[browser_cubic-bezier-05.js]
|
||||
[browser_cubic-bezier-06.js]
|
||||
[browser_cubic-bezier-07.js]
|
||||
[browser_dbg_addon-console.js]
|
||||
skip-if = (e10s && debug || os == 'win' || verify)
|
||||
tags = addons
|
||||
[browser_dbg_debugger-statement.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_event-listeners-01.js]
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/* import-globals-from helper_addons.js */
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/shared/test/helper_addons.js",
|
||||
this);
|
||||
|
||||
var { DebuggerServer } = require("devtools/server/main");
|
||||
var { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
var { Toolbox } = require("devtools/client/framework/toolbox");
|
||||
var { Task } = require("devtools/shared/task");
|
||||
|
||||
// Test that the we can see console messages from the add-on
|
||||
|
||||
const ADDON_ID = "browser_dbg_addon4@tests.mozilla.org";
|
||||
const ADDON_PATH = "addon4.xpi";
|
||||
|
||||
function getCachedMessages(webConsole) {
|
||||
const deferred = getDeferredPromise().defer();
|
||||
webConsole.getCachedMessages(["ConsoleAPI"], response => {
|
||||
if (response.error) {
|
||||
deferred.reject(response.error);
|
||||
return;
|
||||
}
|
||||
deferred.resolve(response.messages);
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
// Creates an add-on debugger for a given add-on. The returned AddonDebugger
|
||||
// object must be destroyed before finishing the test
|
||||
function initAddonDebugger(addonId) {
|
||||
const addonDebugger = new AddonDebugger();
|
||||
return addonDebugger.init(addonId).then(() => addonDebugger);
|
||||
}
|
||||
|
||||
function AddonDebugger() {
|
||||
this._onMessage = this._onMessage.bind(this);
|
||||
this._onConsoleAPICall = this._onConsoleAPICall.bind(this);
|
||||
EventEmitter.decorate(this);
|
||||
}
|
||||
|
||||
AddonDebugger.prototype = {
|
||||
init: Task.async(function* (addonId) {
|
||||
info("Initializing an addon debugger panel.");
|
||||
|
||||
DebuggerServer.init();
|
||||
DebuggerServer.registerAllActors();
|
||||
DebuggerServer.allowChromeProcess = true;
|
||||
|
||||
this.frame = document.createElement("iframe");
|
||||
this.frame.setAttribute("height", 400);
|
||||
document.documentElement.appendChild(this.frame);
|
||||
window.addEventListener("message", this._onMessage);
|
||||
|
||||
const transport = DebuggerServer.connectPipe();
|
||||
this.client = new DebuggerClient(transport);
|
||||
|
||||
yield this.client.connect();
|
||||
|
||||
const addonTargetActor = yield getAddonActorForId(this.client, addonId);
|
||||
|
||||
const targetOptions = {
|
||||
form: addonTargetActor,
|
||||
client: this.client,
|
||||
chrome: true,
|
||||
};
|
||||
|
||||
const toolboxOptions = {
|
||||
customIframe: this.frame,
|
||||
};
|
||||
|
||||
this.target = yield TargetFactory.forRemoteTab(targetOptions);
|
||||
const toolbox = yield gDevTools.showToolbox(
|
||||
this.target, "jsdebugger", Toolbox.HostType.CUSTOM, toolboxOptions);
|
||||
|
||||
info("Addon debugger panel shown successfully.");
|
||||
|
||||
this.debuggerPanel = toolbox.getCurrentPanel();
|
||||
yield this._attachConsole();
|
||||
}),
|
||||
|
||||
destroy: Task.async(function* () {
|
||||
yield this.client.close();
|
||||
this.frame.remove();
|
||||
window.removeEventListener("message", this._onMessage);
|
||||
}),
|
||||
|
||||
_attachConsole: function() {
|
||||
const deferred = getDeferredPromise().defer();
|
||||
this.client.attachConsole(this.target.form.consoleActor, ["ConsoleAPI"])
|
||||
.then(([aResponse, aWebConsoleClient]) => {
|
||||
this.webConsole = aWebConsoleClient;
|
||||
this.client.addListener("consoleAPICall", this._onConsoleAPICall);
|
||||
deferred.resolve();
|
||||
}, e => {
|
||||
deferred.reject(e);
|
||||
});
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
_onConsoleAPICall: function(type, packet) {
|
||||
if (packet.from != this.webConsole.actor) {
|
||||
return;
|
||||
}
|
||||
this.emit("console", packet.message);
|
||||
},
|
||||
|
||||
_onMessage: function(event) {
|
||||
if (!event.data) {
|
||||
return;
|
||||
}
|
||||
const msg = event.data;
|
||||
switch (msg.name) {
|
||||
case "toolbox-title":
|
||||
this.title = msg.data.value;
|
||||
break;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
add_task(async function test() {
|
||||
const addon = await addTemporaryAddon(ADDON_PATH);
|
||||
const addonDebugger = await initAddonDebugger(ADDON_ID);
|
||||
|
||||
const webConsole = addonDebugger.webConsole;
|
||||
const messages = await getCachedMessages(webConsole);
|
||||
is(messages.length, 1, "Should be one cached message");
|
||||
is(messages[0].arguments[0].type, "object", "Should have logged an object");
|
||||
is(messages[0].arguments[0].preview.ownProperties.msg.value,
|
||||
"Hello from the test add-on", "Should have got the right message");
|
||||
|
||||
const consolePromise = addonDebugger.once("console");
|
||||
|
||||
console.log("Bad message");
|
||||
Services.obs.notifyObservers(null, "addon-test-ping");
|
||||
|
||||
const messageGrip = await consolePromise;
|
||||
is(messageGrip.arguments[0].type, "object", "Should have logged an object");
|
||||
is(messageGrip.arguments[0].preview.ownProperties.msg.value,
|
||||
"Hello again", "Should have got the right message");
|
||||
|
||||
await addonDebugger.destroy();
|
||||
await removeAddon(addon);
|
||||
finish();
|
||||
});
|
|
@ -5,16 +5,14 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
/* import-globals-from helper_addons.js */
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/shared/test/helper_addons.js",
|
||||
this);
|
||||
|
||||
var { DebuggerServer } = require("devtools/server/main");
|
||||
var { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
|
||||
const chromeRegistry =
|
||||
Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);
|
||||
const DEBUGGER_CHROME_URL = "chrome://mochitests/content/browser/devtools/client/shared/test/";
|
||||
const DEBUGGER_CHROME_URI = Services.io.newURI(DEBUGGER_CHROME_URL);
|
||||
|
||||
var { AddonManager } = ChromeUtils.import("resource://gre/modules/AddonManager.jsm", {});
|
||||
|
||||
/**
|
||||
* Make sure the listAddons request works as specified.
|
||||
*/
|
||||
|
@ -118,48 +116,3 @@ registerCleanupFunction(function() {
|
|||
gAddon2 = null;
|
||||
gClient = null;
|
||||
});
|
||||
|
||||
function getAddonURIFromPath(path) {
|
||||
const chromeURI = Services.io.newURI(path, null, DEBUGGER_CHROME_URI);
|
||||
return chromeRegistry.convertChromeURL(chromeURI).QueryInterface(Ci.nsIFileURL);
|
||||
}
|
||||
|
||||
function addTemporaryAddon(path) {
|
||||
const addonFile = getAddonURIFromPath(path).file;
|
||||
info("Installing addon: " + addonFile.path);
|
||||
|
||||
return AddonManager.installTemporaryAddon(addonFile);
|
||||
}
|
||||
|
||||
function getAddonActorForId(client, addonId) {
|
||||
info("Get addon actor for ID: " + addonId);
|
||||
const deferred = promise.defer();
|
||||
|
||||
client.listAddons().then(response => {
|
||||
const addonTargetActor = response.addons.filter(grip => grip.id == addonId).pop();
|
||||
info("got addon actor for ID: " + addonId);
|
||||
deferred.resolve(addonTargetActor);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function removeAddon(addon) {
|
||||
info("Removing addon.");
|
||||
|
||||
const deferred = promise.defer();
|
||||
|
||||
const listener = {
|
||||
onUninstalled: function(uninstalledAddon) {
|
||||
if (uninstalledAddon != addon) {
|
||||
return;
|
||||
}
|
||||
AddonManager.removeAddonListener(listener);
|
||||
deferred.resolve();
|
||||
},
|
||||
};
|
||||
AddonManager.addAddonListener(listener);
|
||||
addon.uninstall();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* eslint no-unused-vars: [2, {"vars": "local", "args": "none"}] */
|
||||
|
||||
"use strict";
|
||||
|
||||
const chromeRegistry =
|
||||
Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);
|
||||
const DEBUGGER_CHROME_URL = "chrome://mochitests/content/browser/devtools/client/shared/test/";
|
||||
const DEBUGGER_CHROME_URI = Services.io.newURI(DEBUGGER_CHROME_URL);
|
||||
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
|
||||
var { AddonManager } = ChromeUtils.import("resource://gre/modules/AddonManager.jsm", {});
|
||||
|
||||
/**
|
||||
* Returns a thenable promise
|
||||
* @return {Promise}
|
||||
*/
|
||||
function getDeferredPromise() {
|
||||
// Override promise with deprecated-sync-thenables
|
||||
const promise = require("devtools/shared/deprecated-sync-thenables");
|
||||
return promise;
|
||||
}
|
||||
|
||||
function getAddonURIFromPath(path) {
|
||||
const chromeURI = Services.io.newURI(path, null, DEBUGGER_CHROME_URI);
|
||||
return chromeRegistry.convertChromeURL(chromeURI).QueryInterface(Ci.nsIFileURL);
|
||||
}
|
||||
|
||||
function addTemporaryAddon(path) {
|
||||
const addonFile = getAddonURIFromPath(path).file;
|
||||
info("Installing addon: " + addonFile.path);
|
||||
|
||||
return AddonManager.installTemporaryAddon(addonFile);
|
||||
}
|
||||
|
||||
function getAddonActorForId(client, addonId) {
|
||||
info("Get addon actor for ID: " + addonId);
|
||||
const deferred = getDeferredPromise().defer();
|
||||
|
||||
client.listAddons().then(response => {
|
||||
const addonTargetActor = response.addons.filter(grip => grip.id == addonId).pop();
|
||||
info("got addon actor for ID: " + addonId);
|
||||
deferred.resolve(addonTargetActor);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function removeAddon(addon) {
|
||||
info("Removing addon.");
|
||||
|
||||
const deferred = getDeferredPromise().defer();
|
||||
|
||||
const listener = {
|
||||
onUninstalled: function(uninstalledAddon) {
|
||||
if (uninstalledAddon != addon) {
|
||||
return;
|
||||
}
|
||||
AddonManager.removeAddonListener(listener);
|
||||
deferred.resolve();
|
||||
},
|
||||
};
|
||||
AddonManager.addAddonListener(listener);
|
||||
addon.uninstall();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
|
@ -12,13 +12,16 @@ Services.scriptloader.loadSubScript(
|
|||
|
||||
var { DebuggerServer } = require("devtools/server/main");
|
||||
var { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
|
||||
var { Toolbox } = require("devtools/client/framework/toolbox");
|
||||
|
||||
const FRAME_SCRIPT_URL = getRootDirectory(gTestPath) + "code_frame-script.js";
|
||||
|
||||
var nextId = 0;
|
||||
|
||||
/**
|
||||
* Returns a thenable promise
|
||||
* @return {Promise}
|
||||
*/
|
||||
function getDeferredPromise() {
|
||||
// Override promise with deprecated-sync-thenables
|
||||
const promise = require("devtools/shared/deprecated-sync-thenables");
|
||||
|
|
Загрузка…
Ссылка в новой задаче