summaryrefslogtreecommitdiffstats
path: root/browser/components/extensions/test/browser/browser_ext_sidebarAction_context.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/extensions/test/browser/browser_ext_sidebarAction_context.js')
-rw-r--r--browser/components/extensions/test/browser/browser_ext_sidebarAction_context.js683
1 files changed, 683 insertions, 0 deletions
diff --git a/browser/components/extensions/test/browser/browser_ext_sidebarAction_context.js b/browser/components/extensions/test/browser/browser_ext_sidebarAction_context.js
new file mode 100644
index 0000000000..6e5b4d6cd0
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_sidebarAction_context.js
@@ -0,0 +1,683 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+async function runTests(options) {
+ async function background(getTests) {
+ async function checkDetails(expecting, details) {
+ let title = await browser.sidebarAction.getTitle(details);
+ browser.test.assertEq(
+ expecting.title,
+ title,
+ "expected value from getTitle in " + JSON.stringify(details)
+ );
+
+ let panel = await browser.sidebarAction.getPanel(details);
+ browser.test.assertEq(
+ expecting.panel,
+ panel,
+ "expected value from getPanel in " + JSON.stringify(details)
+ );
+ }
+
+ let tabs = [];
+ let windows = [];
+ let tests = getTests(tabs, windows);
+
+ {
+ let tabId = 0xdeadbeef;
+ let calls = [
+ () => browser.sidebarAction.setTitle({ tabId, title: "foo" }),
+ () => browser.sidebarAction.setIcon({ tabId, path: "foo.png" }),
+ () => browser.sidebarAction.setPanel({ tabId, panel: "foo.html" }),
+ ];
+
+ for (let call of calls) {
+ await browser.test.assertRejects(
+ new Promise(resolve => resolve(call())),
+ RegExp(`Invalid tab ID: ${tabId}`),
+ "Expected invalid tab ID error"
+ );
+ }
+ }
+
+ // Runs the next test in the `tests` array, checks the results,
+ // and passes control back to the outer test scope.
+ function nextTest() {
+ let test = tests.shift();
+
+ test(async (expectTab, expectWindow, expectGlobal, expectDefault) => {
+ expectGlobal = { ...expectDefault, ...expectGlobal };
+ expectWindow = { ...expectGlobal, ...expectWindow };
+ expectTab = { ...expectWindow, ...expectTab };
+
+ // Check that the API returns the expected values, and then
+ // run the next test.
+ let [{ windowId, id: tabId }] = await browser.tabs.query({
+ active: true,
+ currentWindow: true,
+ });
+ await checkDetails(expectTab, { tabId });
+ await checkDetails(expectWindow, { windowId });
+ await checkDetails(expectGlobal, {});
+
+ // Check that the actual icon has the expected values, then
+ // run the next test.
+ browser.test.sendMessage("nextTest", expectTab, windowId, tests.length);
+ });
+ }
+
+ browser.test.onMessage.addListener(msg => {
+ if (msg != "runNextTest") {
+ browser.test.fail("Expecting 'runNextTest' message");
+ }
+
+ nextTest();
+ });
+
+ let [{ id, windowId }] = await browser.tabs.query({
+ active: true,
+ currentWindow: true,
+ });
+ tabs.push(id);
+ windows.push(windowId);
+
+ browser.test.sendMessage("background-page-ready");
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: options.manifest,
+ useAddonManager: "temporary",
+
+ files: options.files || {},
+
+ background: `(${background})(${options.getTests})`,
+ });
+
+ let sidebarActionId;
+ function checkDetails(details, windowId) {
+ let { document } = Services.wm.getOuterWindowWithId(windowId);
+ if (!sidebarActionId) {
+ sidebarActionId = `${makeWidgetId(extension.id)}-sidebar-action`;
+ }
+
+ let menuId = `menu_${sidebarActionId}`;
+ let menu = document.getElementById(menuId);
+ ok(menu, "menu exists");
+
+ let title = details.title || options.manifest.name;
+
+ is(getListStyleImage(menu), details.icon, "icon URL is correct");
+ is(menu.getAttribute("label"), title, "image label is correct");
+ }
+
+ let awaitFinish = new Promise(resolve => {
+ extension.onMessage("nextTest", (expecting, windowId, testsRemaining) => {
+ checkDetails(expecting, windowId);
+
+ if (testsRemaining) {
+ extension.sendMessage("runNextTest");
+ } else {
+ resolve();
+ }
+ });
+ });
+
+ // Wait for initial sidebar load.
+ SidebarUI.browser.addEventListener(
+ "load",
+ async () => {
+ // Wait for the background page listeners to be ready and
+ // then start the tests.
+ await extension.awaitMessage("background-page-ready");
+ extension.sendMessage("runNextTest");
+ },
+ { capture: true, once: true }
+ );
+
+ await extension.startup();
+
+ await awaitFinish;
+ await extension.unload();
+}
+
+let sidebar = `
+ <!DOCTYPE html>
+ <html>
+ <head><meta charset="utf-8"/></head>
+ <body>
+ A Test Sidebar
+ </body></html>
+`;
+
+add_task(async function testTabSwitchContext() {
+ await runTests({
+ manifest: {
+ sidebar_action: {
+ default_icon: "default.png",
+ default_panel: "__MSG_panel__",
+ default_title: "Default __MSG_title__",
+ },
+
+ default_locale: "en",
+
+ permissions: ["tabs"],
+ },
+
+ files: {
+ "default.html": sidebar,
+ "global.html": sidebar,
+ "2.html": sidebar,
+
+ "_locales/en/messages.json": {
+ panel: {
+ message: "default.html",
+ description: "Panel",
+ },
+
+ title: {
+ message: "Title",
+ description: "Title",
+ },
+ },
+
+ "default.png": imageBuffer,
+ "global.png": imageBuffer,
+ "1.png": imageBuffer,
+ "2.png": imageBuffer,
+ },
+
+ getTests: function (tabs) {
+ let details = [
+ {
+ icon: browser.runtime.getURL("default.png"),
+ panel: browser.runtime.getURL("default.html"),
+ title: "Default Title",
+ },
+ { icon: browser.runtime.getURL("1.png") },
+ {
+ icon: browser.runtime.getURL("2.png"),
+ panel: browser.runtime.getURL("2.html"),
+ title: "Title 2",
+ },
+ {
+ icon: browser.runtime.getURL("global.png"),
+ panel: browser.runtime.getURL("global.html"),
+ title: "Global Title",
+ },
+ {
+ icon: browser.runtime.getURL("1.png"),
+ panel: browser.runtime.getURL("2.html"),
+ },
+ ];
+
+ return [
+ async expect => {
+ browser.test.log("Initial state, expect default properties.");
+
+ expect(null, null, null, details[0]);
+ },
+ async expect => {
+ browser.test.log(
+ "Change the icon in the current tab. Expect default properties excluding the icon."
+ );
+ await browser.sidebarAction.setIcon({
+ tabId: tabs[0],
+ path: "1.png",
+ });
+
+ expect(details[1], null, null, details[0]);
+ },
+ async expect => {
+ browser.test.log("Create a new tab. Expect default properties.");
+ let tab = await browser.tabs.create({
+ active: true,
+ url: "about:blank?0",
+ });
+ tabs.push(tab.id);
+
+ expect(null, null, null, details[0]);
+ },
+ async expect => {
+ browser.test.log("Change properties. Expect new properties.");
+ let tabId = tabs[1];
+ await Promise.all([
+ browser.sidebarAction.setIcon({ tabId, path: "2.png" }),
+ browser.sidebarAction.setPanel({ tabId, panel: "2.html" }),
+ browser.sidebarAction.setTitle({ tabId, title: "Title 2" }),
+ ]);
+ expect(details[2], null, null, details[0]);
+ },
+ expect => {
+ browser.test.log("Navigate to a new page. Expect no changes.");
+
+ // TODO: This listener should not be necessary, but the |tabs.update|
+ // callback currently fires too early in e10s windows.
+ browser.tabs.onUpdated.addListener(function listener(tabId, changed) {
+ if (tabId == tabs[1] && changed.url) {
+ browser.tabs.onUpdated.removeListener(listener);
+ expect(details[2], null, null, details[0]);
+ }
+ });
+
+ browser.tabs.update(tabs[1], { url: "about:blank?1" });
+ },
+ async expect => {
+ browser.test.log(
+ "Switch back to the first tab. Expect previously set properties."
+ );
+ await browser.tabs.update(tabs[0], { active: true });
+ expect(details[1], null, null, details[0]);
+ },
+ async expect => {
+ browser.test.log(
+ "Change global values, expect those changes reflected."
+ );
+ await Promise.all([
+ browser.sidebarAction.setIcon({ path: "global.png" }),
+ browser.sidebarAction.setPanel({ panel: "global.html" }),
+ browser.sidebarAction.setTitle({ title: "Global Title" }),
+ ]);
+
+ expect(details[1], null, details[3], details[0]);
+ },
+ async expect => {
+ browser.test.log(
+ "Switch back to tab 2. Expect former tab values, and new global values from previous step."
+ );
+ await browser.tabs.update(tabs[1], { active: true });
+
+ expect(details[2], null, details[3], details[0]);
+ },
+ async expect => {
+ browser.test.log(
+ "Delete tab, switch back to tab 1. Expect previous results again."
+ );
+ await browser.tabs.remove(tabs[1]);
+ expect(details[1], null, details[3], details[0]);
+ },
+ async expect => {
+ browser.test.log("Create a new tab. Expect new global properties.");
+ let tab = await browser.tabs.create({
+ active: true,
+ url: "about:blank?2",
+ });
+ tabs.push(tab.id);
+ expect(null, null, details[3], details[0]);
+ },
+ async expect => {
+ browser.test.log("Delete tab.");
+ await browser.tabs.remove(tabs[2]);
+ expect(details[1], null, details[3], details[0]);
+ },
+ async expect => {
+ browser.test.log("Change tab panel.");
+ let tabId = tabs[0];
+ await browser.sidebarAction.setPanel({ tabId, panel: "2.html" });
+ expect(details[4], null, details[3], details[0]);
+ },
+ async expect => {
+ browser.test.log("Revert tab panel.");
+ let tabId = tabs[0];
+ await browser.sidebarAction.setPanel({ tabId, panel: null });
+ expect(details[1], null, details[3], details[0]);
+ },
+ ];
+ },
+ });
+});
+
+add_task(async function testDefaultTitle() {
+ await runTests({
+ manifest: {
+ name: "Foo Extension",
+
+ sidebar_action: {
+ default_icon: "icon.png",
+ default_panel: "sidebar.html",
+ },
+
+ permissions: ["tabs"],
+ },
+
+ files: {
+ "sidebar.html": sidebar,
+ "icon.png": imageBuffer,
+ },
+
+ getTests: function (tabs) {
+ let details = [
+ {
+ title: "Foo Extension",
+ panel: browser.runtime.getURL("sidebar.html"),
+ icon: browser.runtime.getURL("icon.png"),
+ },
+ { title: "Foo Title" },
+ { title: "Bar Title" },
+ ];
+
+ return [
+ async expect => {
+ browser.test.log("Initial state. Expect default extension title.");
+
+ expect(null, null, null, details[0]);
+ },
+ async expect => {
+ browser.test.log("Change the tab title. Expect new title.");
+ browser.sidebarAction.setTitle({
+ tabId: tabs[0],
+ title: "Foo Title",
+ });
+
+ expect(details[1], null, null, details[0]);
+ },
+ async expect => {
+ browser.test.log("Change the global title. Expect same properties.");
+ browser.sidebarAction.setTitle({ title: "Bar Title" });
+
+ expect(details[1], null, details[2], details[0]);
+ },
+ async expect => {
+ browser.test.log("Clear the tab title. Expect new global title.");
+ browser.sidebarAction.setTitle({ tabId: tabs[0], title: null });
+
+ expect(null, null, details[2], details[0]);
+ },
+ async expect => {
+ browser.test.log("Clear the global title. Expect default title.");
+ browser.sidebarAction.setTitle({ title: null });
+
+ expect(null, null, null, details[0]);
+ },
+ async expect => {
+ browser.test.assertRejects(
+ browser.sidebarAction.setPanel({ panel: "about:addons" }),
+ /Access denied for URL about:addons/,
+ "unable to set panel to about:addons"
+ );
+
+ expect(null, null, null, details[0]);
+ },
+ ];
+ },
+ });
+});
+
+add_task(async function testPropertyRemoval() {
+ await runTests({
+ manifest: {
+ name: "Foo Extension",
+
+ sidebar_action: {
+ default_icon: "default.png",
+ default_panel: "default.html",
+ default_title: "Default Title",
+ },
+
+ permissions: ["tabs"],
+ },
+
+ files: {
+ "default.html": sidebar,
+ "global.html": sidebar,
+ "global2.html": sidebar,
+ "window.html": sidebar,
+ "tab.html": sidebar,
+ "default.png": imageBuffer,
+ "global.png": imageBuffer,
+ "global2.png": imageBuffer,
+ "window.png": imageBuffer,
+ "tab.png": imageBuffer,
+ },
+
+ getTests: function (tabs, windows) {
+ let defaultIcon = "chrome://mozapps/skin/extensions/extensionGeneric.svg";
+ let details = [
+ {
+ icon: browser.runtime.getURL("default.png"),
+ panel: browser.runtime.getURL("default.html"),
+ title: "Default Title",
+ },
+ {
+ icon: browser.runtime.getURL("global.png"),
+ panel: browser.runtime.getURL("global.html"),
+ title: "global",
+ },
+ {
+ icon: browser.runtime.getURL("window.png"),
+ panel: browser.runtime.getURL("window.html"),
+ title: "window",
+ },
+ {
+ icon: browser.runtime.getURL("tab.png"),
+ panel: browser.runtime.getURL("tab.html"),
+ title: "tab",
+ },
+ { icon: defaultIcon, title: "" },
+ {
+ icon: browser.runtime.getURL("global2.png"),
+ panel: browser.runtime.getURL("global2.html"),
+ title: "global2",
+ },
+ ];
+
+ return [
+ async expect => {
+ browser.test.log("Initial state, expect default properties.");
+ expect(null, null, null, details[0]);
+ },
+ async expect => {
+ browser.test.log("Set global values, expect the new values.");
+ browser.sidebarAction.setIcon({ path: "global.png" });
+ browser.sidebarAction.setPanel({ panel: "global.html" });
+ browser.sidebarAction.setTitle({ title: "global" });
+ expect(null, null, details[1], details[0]);
+ },
+ async expect => {
+ browser.test.log("Set window values, expect the new values.");
+ let windowId = windows[0];
+ browser.sidebarAction.setIcon({ windowId, path: "window.png" });
+ browser.sidebarAction.setPanel({ windowId, panel: "window.html" });
+ browser.sidebarAction.setTitle({ windowId, title: "window" });
+ expect(null, details[2], details[1], details[0]);
+ },
+ async expect => {
+ browser.test.log("Set tab values, expect the new values.");
+ let tabId = tabs[0];
+ browser.sidebarAction.setIcon({ tabId, path: "tab.png" });
+ browser.sidebarAction.setPanel({ tabId, panel: "tab.html" });
+ browser.sidebarAction.setTitle({ tabId, title: "tab" });
+ expect(details[3], details[2], details[1], details[0]);
+ },
+ async expect => {
+ browser.test.log("Set empty tab values.");
+ let tabId = tabs[0];
+ browser.sidebarAction.setIcon({ tabId, path: "" });
+ browser.sidebarAction.setPanel({ tabId, panel: "" });
+ browser.sidebarAction.setTitle({ tabId, title: "" });
+ expect(details[4], details[2], details[1], details[0]);
+ },
+ async expect => {
+ browser.test.log("Remove tab values, expect window values.");
+ let tabId = tabs[0];
+ browser.sidebarAction.setIcon({ tabId, path: null });
+ browser.sidebarAction.setPanel({ tabId, panel: null });
+ browser.sidebarAction.setTitle({ tabId, title: null });
+ expect(null, details[2], details[1], details[0]);
+ },
+ async expect => {
+ browser.test.log("Remove window values, expect global values.");
+ let windowId = windows[0];
+ browser.sidebarAction.setIcon({ windowId, path: null });
+ browser.sidebarAction.setPanel({ windowId, panel: null });
+ browser.sidebarAction.setTitle({ windowId, title: null });
+ expect(null, null, details[1], details[0]);
+ },
+ async expect => {
+ browser.test.log("Change global values, expect the new values.");
+ browser.sidebarAction.setIcon({ path: "global2.png" });
+ browser.sidebarAction.setPanel({ panel: "global2.html" });
+ browser.sidebarAction.setTitle({ title: "global2" });
+ expect(null, null, details[5], details[0]);
+ },
+ async expect => {
+ browser.test.log("Remove global values, expect defaults.");
+ browser.sidebarAction.setIcon({ path: null });
+ browser.sidebarAction.setPanel({ panel: null });
+ browser.sidebarAction.setTitle({ title: null });
+ expect(null, null, null, details[0]);
+ },
+ ];
+ },
+ });
+});
+
+add_task(async function testMultipleWindows() {
+ await runTests({
+ manifest: {
+ name: "Foo Extension",
+
+ sidebar_action: {
+ default_icon: "default.png",
+ default_panel: "default.html",
+ default_title: "Default Title",
+ },
+
+ permissions: ["tabs"],
+ },
+
+ files: {
+ "default.html": sidebar,
+ "window1.html": sidebar,
+ "window2.html": sidebar,
+ "default.png": imageBuffer,
+ "window1.png": imageBuffer,
+ "window2.png": imageBuffer,
+ },
+
+ getTests: function (tabs, windows) {
+ let details = [
+ {
+ icon: browser.runtime.getURL("default.png"),
+ panel: browser.runtime.getURL("default.html"),
+ title: "Default Title",
+ },
+ {
+ icon: browser.runtime.getURL("window1.png"),
+ panel: browser.runtime.getURL("window1.html"),
+ title: "window1",
+ },
+ {
+ icon: browser.runtime.getURL("window2.png"),
+ panel: browser.runtime.getURL("window2.html"),
+ title: "window2",
+ },
+ { title: "tab" },
+ ];
+
+ return [
+ async expect => {
+ browser.test.log("Initial state, expect default properties.");
+ expect(null, null, null, details[0]);
+ },
+ async expect => {
+ browser.test.log("Set window values, expect the new values.");
+ let windowId = windows[0];
+ browser.sidebarAction.setIcon({ windowId, path: "window1.png" });
+ browser.sidebarAction.setPanel({ windowId, panel: "window1.html" });
+ browser.sidebarAction.setTitle({ windowId, title: "window1" });
+ expect(null, details[1], null, details[0]);
+ },
+ async expect => {
+ browser.test.log("Create a new tab, expect window values.");
+ let tab = await browser.tabs.create({ active: true });
+ tabs.push(tab.id);
+ expect(null, details[1], null, details[0]);
+ },
+ async expect => {
+ browser.test.log("Set a tab title, expect it.");
+ await browser.sidebarAction.setTitle({
+ tabId: tabs[1],
+ title: "tab",
+ });
+ expect(details[3], details[1], null, details[0]);
+ },
+ async expect => {
+ browser.test.log("Open a new window, expect default values.");
+ let { id } = await browser.windows.create();
+ windows.push(id);
+ expect(null, null, null, details[0]);
+ },
+ async expect => {
+ browser.test.log("Set window values, expect the new values.");
+ let windowId = windows[1];
+ browser.sidebarAction.setIcon({ windowId, path: "window2.png" });
+ browser.sidebarAction.setPanel({ windowId, panel: "window2.html" });
+ browser.sidebarAction.setTitle({ windowId, title: "window2" });
+ expect(null, details[2], null, details[0]);
+ },
+ async expect => {
+ browser.test.log(
+ "Move tab from old window to the new one. Tab-specific data" +
+ " is preserved but inheritance is from the new window"
+ );
+ await browser.tabs.move(tabs[1], { windowId: windows[1], index: -1 });
+ await browser.tabs.update(tabs[1], { active: true });
+ expect(details[3], details[2], null, details[0]);
+ },
+ async expect => {
+ browser.test.log("Close the initial tab of the new window.");
+ let [{ id }] = await browser.tabs.query({
+ windowId: windows[1],
+ index: 0,
+ });
+ await browser.tabs.remove(id);
+ expect(details[3], details[2], null, details[0]);
+ },
+ async expect => {
+ browser.test.log(
+ "Move the previous tab to a 3rd window, the 2nd one will close."
+ );
+ await browser.windows.create({ tabId: tabs[1] });
+ expect(details[3], null, null, details[0]);
+ },
+ async expect => {
+ browser.test.log("Close the tab, go back to the 1st window.");
+ await browser.tabs.remove(tabs[1]);
+ expect(null, details[1], null, details[0]);
+ },
+ async expect => {
+ browser.test.log(
+ "Assert failures for bad parameters. Expect no change"
+ );
+
+ let calls = {
+ setIcon: { path: "default.png" },
+ setPanel: { panel: "default.html" },
+ setTitle: { title: "Default Title" },
+ getPanel: {},
+ getTitle: {},
+ };
+ for (let [method, arg] of Object.entries(calls)) {
+ browser.test.assertThrows(
+ () => browser.sidebarAction[method]({ ...arg, windowId: -3 }),
+ /-3 is too small \(must be at least -2\)/,
+ method + " with invalid windowId"
+ );
+ await browser.test.assertRejects(
+ browser.sidebarAction[method]({
+ ...arg,
+ tabId: tabs[0],
+ windowId: windows[0],
+ }),
+ /Only one of tabId and windowId can be specified/,
+ method + " with both tabId and windowId"
+ );
+ }
+
+ expect(null, details[1], null, details[0]);
+ },
+ ];
+ },
+ });
+});