Files
UXP-Fixed/devtools/client/aboutdebugging/test/browser_addons_debug_webextension_popup.js
2018-02-02 04:16:08 -05:00

190 lines
6.5 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Avoid test timeouts that can occur while waiting for the "addon-console-works" message.
requestLongerTimeout(2);
const ADDON_ID = "test-devtools-webextension@mozilla.org";
const ADDON_NAME = "test-devtools-webextension";
const ADDON_MANIFEST_PATH = "addons/test-devtools-webextension/manifest.json";
const {
BrowserToolboxProcess
} = Cu.import("resource://devtools/client/framework/ToolboxProcess.jsm", {});
/**
* This test file ensures that the webextension addon developer toolbox:
* - when the debug button is clicked on a webextension, the opened toolbox
* has a working webconsole with the background page as default target;
* - the webextension developer toolbox has a working Inspector panel, with the
* background page as default target;
* - the webextension developer toolbox is connected to a fallback page when the
* background page is not available (and in the fallback page document body contains
* the expected message, which warns the user that the current page is not a real
* webextension context);
* - the webextension developer toolbox has a frame list menu and the noautohide toolbar
* toggle button, and they can be used to switch the current target to the extension
* popup page.
*/
/**
* Returns the widget id for an extension with the passed id.
*/
function makeWidgetId(id) {
id = id.toLowerCase();
return id.replace(/[^a-z0-9_-]/g, "_");
}
add_task(function* testWebExtensionsToolboxSwitchToPopup() {
let {
tab, document, debugBtn,
} = yield setupTestAboutDebuggingWebExtension(ADDON_NAME, ADDON_MANIFEST_PATH);
let onReadyForOpenPopup = new Promise(done => {
Services.obs.addObserver(function listener(message, topic) {
let apiMessage = message.wrappedJSObject;
if (!apiMessage.originAttributes ||
apiMessage.originAttributes.addonId != ADDON_ID) {
return;
}
if (apiMessage.arguments[0] == "readyForOpenPopup") {
Services.obs.removeObserver(listener, "console-api-log-event");
done();
}
}, "console-api-log-event", false);
});
// Be careful, this JS function is going to be executed in the addon toolbox,
// which lives in another process. So do not try to use any scope variable!
let env = Cc["@mozilla.org/process/environment;1"]
.getService(Ci.nsIEnvironment);
let testScript = function () {
/* eslint-disable no-undef */
let jsterm;
let popupFramePromise;
toolbox.selectTool("webconsole")
.then(console => {
dump(`Clicking the noautohide button\n`);
toolbox.doc.getElementById("command-button-noautohide").click();
dump(`Clicked the noautohide button\n`);
popupFramePromise = new Promise(resolve => {
let listener = (event, data) => {
if (data.frames.some(({url}) => url && url.endsWith("popup.html"))) {
toolbox.target.off("frame-update", listener);
resolve();
}
};
toolbox.target.on("frame-update", listener);
});
let waitForFrameListUpdate = new Promise((done) => {
toolbox.target.once("frame-update", () => {
done(console);
});
});
jsterm = console.hud.jsterm;
jsterm.execute("myWebExtensionShowPopup()");
// Wait the initial frame update (which list the background page).
return waitForFrameListUpdate;
})
.then((console) => {
// Wait the new frame update (once the extension popup has been opened).
return popupFramePromise;
})
.then(() => {
dump(`Clicking the frame list button\n`);
let btn = toolbox.doc.getElementById("command-button-frames");
let menu = toolbox.showFramesMenu({target: btn});
dump(`Clicked the frame list button\n`);
return menu.once("open").then(() => {
return menu;
});
})
.then(frameMenu => {
let frames = frameMenu.items;
if (frames.length != 2) {
throw Error(`Number of frames found is wrong: ${frames.length} != 2`);
}
let popupFrameBtn = frames.filter((frame) => {
return frame.label.endsWith("popup.html");
}).pop();
if (!popupFrameBtn) {
throw Error("Extension Popup frame not found in the listed frames");
}
let waitForNavigated = toolbox.target.once("navigate");
popupFrameBtn.click();
return waitForNavigated;
})
.then(() => {
return jsterm.execute("myWebExtensionPopupAddonFunction()");
})
.then(() => toolbox.destroy())
.catch((error) => {
dump("Error while running code in the browser toolbox process:\n");
dump(error + "\n");
dump("stack:\n" + error.stack + "\n");
});
/* eslint-enable no-undef */
};
env.set("MOZ_TOOLBOX_TEST_SCRIPT", "new " + testScript);
registerCleanupFunction(() => {
env.set("MOZ_TOOLBOX_TEST_SCRIPT", "");
});
// Wait for a notification sent by a script evaluated the test addon via
// the web console.
let onPopupCustomMessage = new Promise(done => {
Services.obs.addObserver(function listener(message, topic) {
let apiMessage = message.wrappedJSObject;
if (!apiMessage.originAttributes ||
apiMessage.originAttributes.addonId != ADDON_ID) {
return;
}
if (apiMessage.arguments[0] == "Popup page function called") {
Services.obs.removeObserver(listener, "console-api-log-event");
done(apiMessage.arguments);
}
}, "console-api-log-event", false);
});
let onToolboxClose = BrowserToolboxProcess.once("close");
debugBtn.click();
yield onReadyForOpenPopup;
let browserActionId = makeWidgetId(ADDON_ID) + "-browser-action";
let browserActionEl = window.document.getElementById(browserActionId);
ok(browserActionEl, "Got the browserAction button from the browser UI");
browserActionEl.click();
info("Clicked on the browserAction button");
let args = yield onPopupCustomMessage;
ok(true, "Received console message from the popup page function as expected");
is(args[0], "Popup page function called", "Got the expected console message");
is(args[1] && args[1].name, ADDON_NAME,
"Got the expected manifest from WebExtension API");
yield onToolboxClose;
ok(true, "Addon toolbox closed");
yield uninstallAddon({document, id: ADDON_ID, name: ADDON_NAME});
yield closeAboutDebugging(tab);
});