summaryrefslogtreecommitdiffstats
path: root/browser/components/extensions/test/browser/browser_ext_pageAction_context.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/extensions/test/browser/browser_ext_pageAction_context.js')
-rw-r--r--browser/components/extensions/test/browser/browser_ext_pageAction_context.js453
1 files changed, 453 insertions, 0 deletions
diff --git a/browser/components/extensions/test/browser/browser_ext_pageAction_context.js b/browser/components/extensions/test/browser/browser_ext_pageAction_context.js
new file mode 100644
index 0000000000..fde45cf2f5
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_pageAction_context.js
@@ -0,0 +1,453 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+loadTestSubscript("head_pageAction.js");
+
+add_task(async function testTabSwitchContext() {
+ await runTests({
+ manifest: {
+ name: "Foo Extension",
+
+ page_action: {
+ default_icon: "default.png",
+ default_popup: "__MSG_popup__",
+ default_title: "Default __MSG_title__ \u263a",
+ },
+
+ default_locale: "en",
+
+ permissions: ["tabs"],
+ },
+
+ files: {
+ "_locales/en/messages.json": {
+ popup: {
+ message: "default.html",
+ description: "Popup",
+ },
+
+ title: {
+ message: "Title",
+ description: "Title",
+ },
+ },
+
+ "_locales/es_ES/messages.json": {
+ popup: {
+ message: "default.html",
+ description: "Popup",
+ },
+
+ title: {
+ message: "T\u00edtulo",
+ description: "Title",
+ },
+ },
+
+ "default.png": imageBuffer,
+ "1.png": imageBuffer,
+ "2.png": imageBuffer,
+ },
+
+ getTests: function (tabs) {
+ let defaultIcon = "chrome://mozapps/skin/extensions/extensionGeneric.svg";
+ let details = [
+ {
+ icon: browser.runtime.getURL("default.png"),
+ popup: browser.runtime.getURL("default.html"),
+ title: "Default T\u00edtulo \u263a",
+ },
+ {
+ icon: browser.runtime.getURL("1.png"),
+ popup: browser.runtime.getURL("default.html"),
+ title: "Default T\u00edtulo \u263a",
+ },
+ {
+ icon: browser.runtime.getURL("2.png"),
+ popup: browser.runtime.getURL("2.html"),
+ title: "Title 2",
+ },
+ { icon: defaultIcon, popup: "", title: "" },
+ ];
+
+ let promiseTabLoad = details => {
+ return new Promise(resolve => {
+ browser.tabs.onUpdated.addListener(function listener(tabId, changed) {
+ if (tabId == details.id && changed.url == details.url) {
+ browser.tabs.onUpdated.removeListener(listener);
+ resolve();
+ }
+ });
+ });
+ };
+
+ return [
+ expect => {
+ browser.test.log("Initial state. No icon visible.");
+ expect(null);
+ },
+ async expect => {
+ browser.test.log(
+ "Show the icon on the first tab, expect default properties."
+ );
+ await browser.pageAction.show(tabs[0]);
+ expect(details[0]);
+ },
+ expect => {
+ browser.test.log(
+ "Change the icon. Expect default properties excluding the icon."
+ );
+ browser.pageAction.setIcon({ tabId: tabs[0], path: "1.png" });
+ expect(details[1]);
+ },
+ async expect => {
+ browser.test.log("Create a new tab. No icon visible.");
+ let tab = await browser.tabs.create({
+ active: true,
+ url: "about:blank?0",
+ });
+ tabs.push(tab.id);
+ expect(null);
+ },
+ async expect => {
+ browser.test.log("Await tab load. No icon visible.");
+ let promise = promiseTabLoad({ id: tabs[1], url: "about:blank?0" });
+ let { url } = await browser.tabs.get(tabs[1]);
+ if (url === "about:blank") {
+ await promise;
+ }
+ expect(null);
+ },
+ async expect => {
+ browser.test.log("Change properties. Expect new properties.");
+ let tabId = tabs[1];
+ await browser.pageAction.show(tabId);
+
+ browser.pageAction.setIcon({ tabId, path: "2.png" });
+ browser.pageAction.setPopup({ tabId, popup: "2.html" });
+ browser.pageAction.setTitle({ tabId, title: "Title 2" });
+
+ expect(details[2]);
+ },
+ async expect => {
+ browser.test.log("Change the hash. Expect same properties.");
+
+ let promise = promiseTabLoad({
+ id: tabs[1],
+ url: "about:blank?0#ref",
+ });
+ browser.tabs.update(tabs[1], { url: "about:blank?0#ref" });
+ await promise;
+
+ expect(details[2]);
+ },
+ expect => {
+ browser.test.log(
+ "Set empty string values. Expect empty strings but default icon."
+ );
+ browser.pageAction.setIcon({ tabId: tabs[1], path: "" });
+ browser.pageAction.setPopup({ tabId: tabs[1], popup: "" });
+ browser.pageAction.setTitle({ tabId: tabs[1], title: "" });
+
+ expect(details[3]);
+ },
+ expect => {
+ browser.test.log("Clear the values. Expect default ones.");
+ browser.pageAction.setIcon({ tabId: tabs[1], path: null });
+ browser.pageAction.setPopup({ tabId: tabs[1], popup: null });
+ browser.pageAction.setTitle({ tabId: tabs[1], title: null });
+
+ expect(details[0]);
+ },
+ async expect => {
+ browser.test.log("Navigate to a new page. Expect icon hidden.");
+
+ // TODO: This listener should not be necessary, but the |tabs.update|
+ // callback currently fires too early in e10s windows.
+ let promise = promiseTabLoad({ id: tabs[1], url: "about:blank?1" });
+
+ browser.tabs.update(tabs[1], { url: "about:blank?1" });
+
+ await promise;
+ expect(null);
+ },
+ async expect => {
+ browser.test.log("Show the icon. Expect default properties again.");
+
+ await browser.pageAction.show(tabs[1]);
+ expect(details[0]);
+ },
+ 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]);
+ },
+ async expect => {
+ browser.test.log(
+ "Hide the icon on tab 2. Switch back, expect hidden."
+ );
+ await browser.pageAction.hide(tabs[1]);
+
+ await browser.tabs.update(tabs[1], { active: true });
+ expect(null);
+ },
+ async expect => {
+ browser.test.log(
+ "Switch back to tab 1. Expect previous results again."
+ );
+ await browser.tabs.remove(tabs[1]);
+ expect(details[1]);
+ },
+ async expect => {
+ browser.test.log("Hide the icon. Expect hidden.");
+
+ await browser.pageAction.hide(tabs[0]);
+ expect(null);
+ },
+ async expect => {
+ browser.test.assertRejects(
+ browser.pageAction.setPopup({
+ tabId: tabs[0],
+ popup: "about:addons",
+ }),
+ /Access denied for URL about:addons/,
+ "unable to set popup to about:addons"
+ );
+
+ expect(null);
+ },
+ ];
+ },
+ });
+});
+
+add_task(async function testMultipleWindows() {
+ // Disable newtab preloading, so that the tabs.create call below will always
+ // trigger a new load that can be detected by webNavigation.onCompleted.
+ await SpecialPowers.pushPrefEnv({
+ set: [["browser.newtab.preload", false]],
+ });
+ await runTests({
+ manifest: {
+ page_action: {
+ default_icon: "default.png",
+ default_popup: "default.html",
+ default_title: "Default Title",
+ },
+ permissions: ["webNavigation"],
+ },
+
+ files: {
+ "default.png": imageBuffer,
+ "tab.png": imageBuffer,
+ },
+
+ getTests: function (tabs, windows) {
+ let details = [
+ {
+ icon: browser.runtime.getURL("default.png"),
+ popup: browser.runtime.getURL("default.html"),
+ title: "Default Title",
+ },
+ {
+ icon: browser.runtime.getURL("tab.png"),
+ popup: browser.runtime.getURL("tab.html"),
+ title: "tab",
+ },
+ ];
+
+ function promiseWebNavigationCompleted(url) {
+ return new Promise(resolve => {
+ // The pageAction visibility state is reset when the location changes.
+ // The webNavigation.onCompleted event is triggered when that happens.
+ browser.webNavigation.onCompleted.addListener(
+ function listener() {
+ browser.webNavigation.onCompleted.removeListener(listener);
+ resolve();
+ },
+ {
+ url: [{ urlEquals: url }],
+ }
+ );
+ });
+ }
+
+ return [
+ async expect => {
+ browser.test.log("Create a new tab, expect hidden pageAction.");
+ let promise = promiseWebNavigationCompleted("about:newtab");
+ let tab = await browser.tabs.create({ active: true });
+ await promise;
+ tabs.push(tab.id);
+ expect(null);
+ },
+ async expect => {
+ browser.test.log("Show the pageAction, expect default values.");
+ await browser.pageAction.show(tabs[1]);
+ expect(details[0]);
+ },
+ async expect => {
+ browser.test.log("Set tab-specific values, expect them.");
+ await browser.pageAction.setIcon({ tabId: tabs[1], path: "tab.png" });
+ await browser.pageAction.setPopup({
+ tabId: tabs[1],
+ popup: "tab.html",
+ });
+ await browser.pageAction.setTitle({ tabId: tabs[1], title: "tab" });
+ expect(details[1]);
+ },
+ async expect => {
+ browser.test.log("Open a new window, expect hidden pageAction.");
+ let { id } = await browser.windows.create();
+ windows.push(id);
+ expect(null);
+ },
+ async expect => {
+ browser.test.log(
+ "Move tab from old window to the new one, expect old values."
+ );
+ await browser.tabs.move(tabs[1], { windowId: windows[1], index: -1 });
+ await browser.tabs.update(tabs[1], { active: true });
+ expect(details[1]);
+ },
+ 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[1]);
+ },
+ 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[1]);
+ },
+ async expect => {
+ browser.test.log("Close the tab, go back to the 1st window.");
+ await browser.tabs.remove(tabs[1]);
+ expect(null);
+ },
+ ];
+ },
+ });
+ await SpecialPowers.popPrefEnv();
+});
+
+add_task(async function testNavigationClearsData() {
+ let url = "http://example.com/";
+ let default_title = "Default title";
+ let tab_title = "Tab title";
+
+ const {
+ Management: {
+ global: { tabTracker },
+ },
+ } = ChromeUtils.importESModule("resource://gre/modules/Extension.sys.mjs");
+ let extension,
+ tabs = [];
+ async function addTab(...args) {
+ let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, ...args);
+ tabs.push(tab);
+ return tab;
+ }
+ async function sendMessage(method, param, expect, msg) {
+ extension.sendMessage({ method, param, expect, msg });
+ await extension.awaitMessage("done");
+ }
+ async function expectTabSpecificData(tab, msg) {
+ let tabId = tabTracker.getId(tab);
+ await sendMessage("isShown", { tabId }, true, msg);
+ await sendMessage("getTitle", { tabId }, tab_title, msg);
+ }
+ async function expectDefaultData(tab, msg) {
+ let tabId = tabTracker.getId(tab);
+ await sendMessage("isShown", { tabId }, false, msg);
+ await sendMessage("getTitle", { tabId }, default_title, msg);
+ }
+ async function setTabSpecificData(tab) {
+ let tabId = tabTracker.getId(tab);
+ await expectDefaultData(
+ tab,
+ "Expect default data before setting tab-specific data."
+ );
+ await sendMessage("show", tabId);
+ await sendMessage("setTitle", { tabId, title: tab_title });
+ await expectTabSpecificData(
+ tab,
+ "Expect tab-specific data after setting it."
+ );
+ }
+
+ info("Load a tab before installing the extension");
+ let tab1 = await addTab(url, true, true);
+
+ extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ page_action: { default_title },
+ },
+ background: function () {
+ browser.test.onMessage.addListener(
+ async ({ method, param, expect, msg }) => {
+ let result = await browser.pageAction[method](param);
+ if (expect !== undefined) {
+ browser.test.assertEq(expect, result, msg);
+ }
+ browser.test.sendMessage("done");
+ }
+ );
+ },
+ });
+ await extension.startup();
+
+ info("Set tab-specific data to the existing tab.");
+ await setTabSpecificData(tab1);
+
+ info("Add a hash. Does not cause navigation.");
+ await navigateTab(tab1, url + "#hash");
+ await expectTabSpecificData(
+ tab1,
+ "Adding a hash does not clear tab-specific data"
+ );
+
+ info("Remove the hash. Causes navigation.");
+ await navigateTab(tab1, url);
+ await expectDefaultData(tab1, "Removing hash clears tab-specific data");
+
+ info("Open a new tab, set tab-specific data to it.");
+ let tab2 = await addTab("about:newtab", false, false);
+ await setTabSpecificData(tab2);
+
+ info("Load a page in that tab.");
+ await navigateTab(tab2, url);
+ await expectDefaultData(tab2, "Loading a page clears tab-specific data.");
+
+ info("Set tab-specific data.");
+ await setTabSpecificData(tab2);
+
+ info("Push history state. Does not cause navigation.");
+ await historyPushState(tab2, url + "/path");
+ await expectTabSpecificData(
+ tab2,
+ "history.pushState() does not clear tab-specific data"
+ );
+
+ info("Navigate when the tab is not selected");
+ gBrowser.selectedTab = tab1;
+ await navigateTab(tab2, url);
+ await expectDefaultData(
+ tab2,
+ "Navigating clears tab-specific data, even when not selected."
+ );
+
+ for (let tab of tabs) {
+ BrowserTestUtils.removeTab(tab);
+ }
+ await extension.unload();
+});