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:
David Walsh 2018-10-24 15:13:17 -05:00
Родитель d843fa0143
Коммит 4a01b79d33
9 изменённых файлов: 234 добавлений и 258 удалений

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

@ -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");