--- a/browser/components/extensions/ext-browserAction.js
+++ b/browser/components/extensions/ext-browserAction.js
@@ -32,17 +32,17 @@ function BrowserAction(options, extensio
let title = extension.localize(options.default_title || "");
let popup = extension.localize(options.default_popup || "");
if (popup) {
popup = extension.baseURI.resolve(popup);
}
this.defaults = {
enabled: true,
- title: title,
+ title: title || extension.name,
badgeText: "",
badgeBackgroundColor: null,
icon: IconDetails.normalize({ path: options.default_icon }, extension,
null, true),
popup: popup,
};
this.tabContext = new TabContext(tab => Object.create(this.defaults),
@@ -91,25 +91,19 @@ BrowserAction.prototype = {
togglePopup(node, popupResource) {
openPanel(node, popupResource, this.extension);
},
// Update the toolbar button |node| with the tab context data
// in |tabData|.
updateButton(node, tabData) {
- if (tabData.title) {
- node.setAttribute("tooltiptext", tabData.title);
- node.setAttribute("label", tabData.title);
- node.setAttribute("aria-label", tabData.title);
- } else {
- node.removeAttribute("tooltiptext");
- node.removeAttribute("label");
- node.removeAttribute("aria-label");
- }
+ let title = tabData.title || this.extension.name;
+ node.setAttribute("tooltiptext", title);
+ node.setAttribute("label", title);
if (tabData.badgeText) {
node.setAttribute("badge", tabData.badgeText);
} else {
node.removeAttribute("badge");
}
if (tabData.enabled) {
@@ -157,18 +151,20 @@ BrowserAction.prototype = {
}
},
// tab is allowed to be null.
// prop should be one of "icon", "title", "badgeText", "popup", or "badgeBackgroundColor".
setProperty(tab, prop, value) {
if (tab == null) {
this.defaults[prop] = value;
+ } else if (value != null) {
+ this.tabContext.get(tab)[prop] = value;
} else {
- this.tabContext.get(tab)[prop] = value;
+ delete this.tabContext.get(tab)[prop];
}
this.updateOnChange(tab);
},
// tab is allowed to be null.
// prop should be one of "title", "badgeText", "popup", or "badgeBackgroundColor".
getProperty(tab, prop) {
@@ -221,17 +217,23 @@ extensions.registerSchemaAPI("browserAct
disable: function(tabId) {
let tab = tabId !== null ? TabManager.getTab(tabId) : null;
browserActionOf(extension).setProperty(tab, "enabled", false);
},
setTitle: function(details) {
let tab = details.tabId !== null ? TabManager.getTab(details.tabId) : null;
- browserActionOf(extension).setProperty(tab, "title", details.title);
+
+ let title = details.title;
+ // Clear the tab-specific title when given a null string.
+ if (tab && title == "") {
+ title = null;
+ }
+ browserActionOf(extension).setProperty(tab, "title", title);
},
getTitle: function(details, callback) {
let tab = details.tabId !== null ? TabManager.getTab(details.tabId) : null;
let title = browserActionOf(extension).getProperty(tab, "title");
runSafe(context, callback, title);
},
--- a/browser/components/extensions/ext-pageAction.js
+++ b/browser/components/extensions/ext-pageAction.js
@@ -23,17 +23,17 @@ function PageAction(options, extension)
let title = extension.localize(options.default_title || "");
let popup = extension.localize(options.default_popup || "");
if (popup) {
popup = extension.baseURI.resolve(popup);
}
this.defaults = {
show: false,
- title: title,
+ title: title || extension.name,
icon: IconDetails.normalize({ path: options.default_icon }, extension,
null, true),
popup: popup && extension.baseURI.resolve(popup),
};
this.tabContext = new TabContext(tab => Object.create(this.defaults),
extension);
@@ -53,17 +53,22 @@ PageAction.prototype = {
},
// Sets the value of the property |prop| for the given tab to the
// given value, symmetrically to |getProperty|.
//
// If |tab| is currently selected, updates the page action button to
// reflect the new value.
setProperty(tab, prop, value) {
- this.tabContext.get(tab)[prop] = value;
+ if (value != null) {
+ this.tabContext.get(tab)[prop] = value;
+ } else {
+ delete this.tabContext.get(tab)[prop];
+ }
+
if (tab.selected) {
this.updateButton(tab.ownerDocument.defaultView);
}
},
// Updates the page action button in the given window to reflect the
// properties of the currently selected tab:
//
@@ -79,23 +84,19 @@ PageAction.prototype = {
return;
}
let button = this.getButton(window);
if (tabData.show) {
// Update the title and icon only if the button is visible.
- if (tabData.title) {
- button.setAttribute("tooltiptext", tabData.title);
- button.setAttribute("aria-label", tabData.title);
- } else {
- button.removeAttribute("tooltiptext");
- button.removeAttribute("aria-label");
- }
+ let title = tabData.title || this.extension.name;
+ button.setAttribute("tooltiptext", title);
+ button.setAttribute("aria-label", title);
let icon = IconDetails.getURL(tabData.icon, window, this.extension);
button.setAttribute("src", icon);
}
button.hidden = !tabData.show;
},
@@ -208,17 +209,19 @@ extensions.registerSchemaAPI("pageAction
hide(tabId) {
let tab = TabManager.getTab(tabId);
PageAction.for(extension).setProperty(tab, "show", false);
},
setTitle(details) {
let tab = TabManager.getTab(details.tabId);
- PageAction.for(extension).setProperty(tab, "title", details.title);
+
+ // Clear the tab-specific title when given a null string.
+ PageAction.for(extension).setProperty(tab, "title", details.title || null);
},
getTitle(details, callback) {
let tab = TabManager.getTab(details.tabId);
let title = PageAction.for(extension).getProperty(tab, "title");
runSafe(context, callback, title);
},
--- a/browser/components/extensions/test/browser/browser_ext_browserAction_context.js
+++ b/browser/components/extensions/test/browser/browser_ext_browserAction_context.js
@@ -1,24 +1,157 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
+function* runTests(options) {
+ function background(getTests) {
+ // Gets the current details of the browser action, and returns a
+ // promise that resolves to an object containing them.
+ function getDetails(tabId) {
+ return Promise.all([
+ new Promise(resolve => browser.browserAction.getTitle({tabId}, resolve)),
+ new Promise(resolve => browser.browserAction.getPopup({tabId}, resolve)),
+ new Promise(resolve => browser.browserAction.getBadgeText({tabId}, resolve)),
+ new Promise(resolve => browser.browserAction.getBadgeBackgroundColor({tabId}, resolve))]
+ ).then(details => {
+ return Promise.resolve({ title: details[0],
+ popup: details[1],
+ badge: details[2],
+ badgeBackgroundColor: details[3] });
+ });
+ }
+
+ function checkDetails(expecting, tabId) {
+ return getDetails(tabId).then(details => {
+ browser.test.assertEq(expecting.title, details.title,
+ "expected value from getTitle");
+
+ browser.test.assertEq(expecting.popup, details.popup,
+ "expected value from getPopup");
+
+ browser.test.assertEq(expecting.badge, details.badge,
+ "expected value from getBadge");
+
+ browser.test.assertEq(String(expecting.badgeBackgroundColor),
+ String(details.badgeBackgroundColor),
+ "expected value from getBadgeBackgroundColor");
+ });
+ }
+
+ let expectDefaults = expecting => {
+ return checkDetails(expecting);
+ };
+
+ let tabs = [];
+ let tests = getTests(tabs, expectDefaults);
+
+ // 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(expecting => {
+ // Check that the API returns the expected values, and then
+ // run the next test.
+ new Promise(resolve => {
+ return browser.tabs.query({ active: true, currentWindow: true }, resolve);
+ }).then(tabs => {
+ return checkDetails(expecting, tabs[0].id);
+ }).then(() => {
+ // Check that the actual icon has the expected values, then
+ // run the next test.
+ browser.test.sendMessage("nextTest", expecting, tests.length);
+ });
+ });
+ }
+
+ browser.test.onMessage.addListener((msg) => {
+ if (msg != "runNextTest") {
+ browser.test.fail("Expecting 'runNextTest' message");
+ }
+
+ nextTest();
+ });
+
+ browser.tabs.query({ active: true, currentWindow: true }, resultTabs => {
+ tabs[0] = resultTabs[0].id;
+
+ nextTest();
+ });
+ }
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: options.manifest,
+
+ background: `(${background})(${options.getTests})`,
+ });
+
+
+ let browserActionId = makeWidgetId(extension.id) + "-browser-action";
+
+ function checkDetails(details) {
+ let button = document.getElementById(browserActionId);
+
+ ok(button, "button exists");
+
+ let title = details.title || options.manifest.name;
+
+ is(button.getAttribute("image"), details.icon, "icon URL is correct");
+ is(button.getAttribute("tooltiptext"), title, "image title is correct");
+ is(button.getAttribute("label"), title, "image label is correct");
+ is(button.getAttribute("badge"), details.badge, "badge text is correct");
+ is(button.getAttribute("disabled") == "true", Boolean(details.disabled), "disabled state is correct");
+
+ if (details.badge && details.badgeBackgroundColor) {
+ let badge = button.ownerDocument.getAnonymousElementByAttribute(
+ button, "class", "toolbarbutton-badge");
+
+ let badgeColor = window.getComputedStyle(badge).backgroundColor;
+ let color = details.badgeBackgroundColor;
+ let expectedColor = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+
+ is(badgeColor, expectedColor, "badge color is correct");
+ }
+
+
+ // TODO: Popup URL.
+ }
+
+ let awaitFinish = new Promise(resolve => {
+ extension.onMessage("nextTest", (expecting, testsRemaining) => {
+ checkDetails(expecting);
+
+ if (testsRemaining) {
+ extension.sendMessage("runNextTest");
+ } else {
+ resolve();
+ }
+ });
+ });
+
+ yield extension.startup();
+
+ yield awaitFinish;
+
+ yield extension.unload();
+}
+
add_task(function* testTabSwitchContext() {
- let extension = ExtensionTestUtils.loadExtension({
+ yield runTests({
manifest: {
"browser_action": {
"default_icon": "default.png",
"default_popup": "default.html",
"default_title": "Default Title",
},
"permissions": ["tabs"],
},
- background: function() {
+ getTests(tabs, expectDefaults) {
let details = [
{ "icon": browser.runtime.getURL("default.png"),
"popup": browser.runtime.getURL("default.html"),
"title": "Default Title",
"badge": "",
"badgeBackgroundColor": null },
{ "icon": browser.runtime.getURL("1.png"),
"popup": browser.runtime.getURL("default.html"),
@@ -45,20 +178,17 @@ add_task(function* testTabSwitchContext(
"disabled": false },
{ "icon": browser.runtime.getURL("default-2.png"),
"popup": browser.runtime.getURL("default-2.html"),
"title": "Default Title 2",
"badge": "d2",
"badgeBackgroundColor": [0, 0xff, 0, 0xff] },
];
- let tabs = [];
-
- let expectDefaults;
- let tests = [
+ return [
expect => {
browser.test.log("Initial state, expect default properties.");
expectDefaults(details[0]).then(() => {
expect(details[0]);
});
},
expect => {
browser.test.log("Change the icon in the current tab. Expect default properties excluding the icon.");
@@ -152,129 +282,87 @@ add_task(function* testTabSwitchContext(
},
expect => {
browser.test.log("Delete tab.");
browser.tabs.remove(tabs[2], () => {
expect(details[4]);
});
},
];
-
- // Gets the current details of the browser action, and returns a
- // promise that resolves to an object containing them.
- function getDetails(tabId) {
- return Promise.all([
- new Promise(resolve => browser.browserAction.getTitle({tabId}, resolve)),
- new Promise(resolve => browser.browserAction.getPopup({tabId}, resolve)),
- new Promise(resolve => browser.browserAction.getBadgeText({tabId}, resolve)),
- new Promise(resolve => browser.browserAction.getBadgeBackgroundColor({tabId}, resolve))]
- ).then(details => {
- return Promise.resolve({ title: details[0],
- popup: details[1],
- badge: details[2],
- badgeBackgroundColor: details[3] });
- });
- }
-
- function checkDetails(expecting, tabId) {
- return getDetails(tabId).then(details => {
- browser.test.assertEq(expecting.title, details.title,
- "expected value from getTitle");
-
- browser.test.assertEq(expecting.popup, details.popup,
- "expected value from getPopup");
-
- browser.test.assertEq(expecting.badge, details.badge,
- "expected value from getBadge");
-
- browser.test.assertEq(String(expecting.badgeBackgroundColor),
- String(details.badgeBackgroundColor),
- "expected value from getBadgeBackgroundColor");
- });
- }
-
- expectDefaults = expecting => {
- return checkDetails(expecting);
- };
-
- // 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(expecting => {
- // Check that the API returns the expected values, and then
- // run the next test.
- new Promise(resolve => {
- return browser.tabs.query({ active: true, currentWindow: true }, resolve);
- }).then(tabs => {
- return checkDetails(expecting, tabs[0].id);
- }).then(() => {
- // Check that the actual icon has the expected values, then
- // run the next test.
- browser.test.sendMessage("nextTest", expecting, tests.length);
- });
- });
- }
-
- browser.test.onMessage.addListener((msg) => {
- if (msg != "runNextTest") {
- browser.test.fail("Expecting 'runNextTest' message");
- }
-
- nextTest();
- });
-
- browser.tabs.query({ active: true, currentWindow: true }, resultTabs => {
- tabs[0] = resultTabs[0].id;
-
- nextTest();
- });
},
});
+});
- let browserActionId = makeWidgetId(extension.id) + "-browser-action";
+add_task(function* testDefaultTitle() {
+ yield runTests({
+ manifest: {
+ "name": "Foo Extension",
- function checkDetails(details) {
- let button = document.getElementById(browserActionId);
+ "browser_action": {
+ "default_icon": "icon.png",
+ },
- ok(button, "button exists");
+ "permissions": ["tabs"],
+ },
- is(button.getAttribute("image"), details.icon, "icon URL is correct");
- is(button.getAttribute("tooltiptext"), details.title, "image title is correct");
- is(button.getAttribute("label"), details.title, "image label is correct");
- is(button.getAttribute("aria-label"), details.title, "image aria-label is correct");
- is(button.getAttribute("badge"), details.badge, "badge text is correct");
- is(button.getAttribute("disabled") == "true", Boolean(details.disabled), "disabled state is correct");
-
- if (details.badge && details.badgeBackgroundColor) {
- let badge = button.ownerDocument.getAnonymousElementByAttribute(
- button, "class", "toolbarbutton-badge");
-
- let badgeColor = window.getComputedStyle(badge).backgroundColor;
- let color = details.badgeBackgroundColor;
- let expectedColor = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
+ getTests(tabs, expectDefaults) {
+ let details = [
+ { "title": "Foo Extension",
+ "popup": "",
+ "badge": "",
+ "badgeBackgroundColor": null,
+ "icon": browser.runtime.getURL("icon.png") },
+ { "title": "Foo Title",
+ "popup": "",
+ "badge": "",
+ "badgeBackgroundColor": null,
+ "icon": browser.runtime.getURL("icon.png") },
+ { "title": "Bar Title",
+ "popup": "",
+ "badge": "",
+ "badgeBackgroundColor": null,
+ "icon": browser.runtime.getURL("icon.png") },
+ { "title": "",
+ "popup": "",
+ "badge": "",
+ "badgeBackgroundColor": null,
+ "icon": browser.runtime.getURL("icon.png") },
+ ];
- is(badgeColor, expectedColor, "badge color is correct");
- }
-
-
- // TODO: Popup URL.
- }
-
- let awaitFinish = new Promise(resolve => {
- extension.onMessage("nextTest", (expecting, testsRemaining) => {
- checkDetails(expecting);
-
- if (testsRemaining) {
- extension.sendMessage("runNextTest");
- } else {
- resolve();
- }
- });
+ return [
+ expect => {
+ browser.test.log("Initial state. Expect extension title as default title.");
+ expectDefaults(details[0]).then(() => {
+ expect(details[0]);
+ });
+ },
+ expect => {
+ browser.test.log("Change the title. Expect new title.");
+ browser.browserAction.setTitle({ tabId: tabs[0], title: "Foo Title" });
+ expectDefaults(details[0]).then(() => {
+ expect(details[1]);
+ });
+ },
+ expect => {
+ browser.test.log("Change the default. Expect same properties.");
+ browser.browserAction.setTitle({ title: "Bar Title" });
+ expectDefaults(details[2]).then(() => {
+ expect(details[1]);
+ });
+ },
+ expect => {
+ browser.test.log("Clear the title. Expect new default title.");
+ browser.browserAction.setTitle({ tabId: tabs[0], title: "" });
+ expectDefaults(details[2]).then(() => {
+ expect(details[2]);
+ });
+ },
+ expect => {
+ browser.test.log("Set default title to null string. Expect null string from API, extension title in UI.");
+ browser.browserAction.setTitle({ title: "" });
+ expectDefaults(details[3]).then(() => {
+ expect(details[3]);
+ });
+ },
+ ];
+ },
});
-
- yield extension.startup();
-
- yield awaitFinish;
-
- yield extension.unload();
});
--- a/browser/components/extensions/test/browser/browser_ext_pageAction_context.js
+++ b/browser/components/extensions/test/browser/browser_ext_pageAction_context.js
@@ -1,39 +1,187 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
-add_task(function* testTabSwitchContext() {
+function* runTests(options) {
+ function background(getTests) {
+ let tabs;
+ let tests;
+
+ // Gets the current details of the page action, and returns a
+ // promise that resolves to an object containing them.
+ function getDetails() {
+ return new Promise(resolve => {
+ return browser.tabs.query({ active: true, currentWindow: true }, resolve);
+ }).then(tabs => {
+ let tabId = tabs[0].id;
+ return Promise.all([
+ new Promise(resolve => browser.pageAction.getTitle({tabId}, resolve)),
+ new Promise(resolve => browser.pageAction.getPopup({tabId}, resolve))]);
+ }).then(details => {
+ return Promise.resolve({ title: details[0],
+ popup: details[1] });
+ });
+ }
+
+
+ // 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(expecting => {
+ function finish() {
+ // Check that the actual icon has the expected values, then
+ // run the next test.
+ browser.test.sendMessage("nextTest", expecting, tests.length);
+ }
+
+ if (expecting) {
+ // Check that the API returns the expected values, and then
+ // run the next test.
+ getDetails().then(details => {
+ browser.test.assertEq(expecting.title, details.title,
+ "expected value from getTitle");
+
+ browser.test.assertEq(expecting.popup, details.popup,
+ "expected value from getPopup");
+
+ finish();
+ });
+ } else {
+ finish();
+ }
+ });
+ }
+
+ function runTests() {
+ tabs = [];
+ tests = getTests(tabs);
+
+ browser.tabs.query({ active: true, currentWindow: true }, resultTabs => {
+ tabs[0] = resultTabs[0].id;
+
+ nextTest();
+ });
+ }
+
+ browser.test.onMessage.addListener((msg) => {
+ if (msg == "runTests") {
+ runTests();
+ } else if (msg == "runNextTest") {
+ nextTest();
+ } else {
+ browser.test.fail(`Unexpected message: ${msg}`);
+ }
+ });
+
+ runTests();
+ }
+
let extension = ExtensionTestUtils.loadExtension({
+ manifest: options.manifest,
+
+ background: `(${background})(${options.getTests})`,
+ });
+
+ let pageActionId = makeWidgetId(extension.id) + "-page-action";
+ let currentWindow = window;
+ let windows = [];
+
+ function checkDetails(details) {
+ let image = currentWindow.document.getElementById(pageActionId);
+ if (details == null) {
+ ok(image == null || image.hidden, "image is hidden");
+ } else {
+ ok(image, "image exists");
+
+ is(image.src, details.icon, "icon URL is correct");
+
+ let title = details.title || options.manifest.name;
+ is(image.getAttribute("tooltiptext"), title, "image title is correct");
+ is(image.getAttribute("aria-label"), title, "image aria-label is correct");
+ // TODO: Popup URL.
+ }
+ }
+
+ let testNewWindows = 1;
+
+ let awaitFinish = new Promise(resolve => {
+ extension.onMessage("nextTest", (expecting, testsRemaining) => {
+ checkDetails(expecting);
+
+ if (testsRemaining) {
+ extension.sendMessage("runNextTest");
+ } else if (testNewWindows) {
+ testNewWindows--;
+
+ BrowserTestUtils.openNewBrowserWindow().then(window => {
+ windows.push(window);
+ currentWindow = window;
+ return focusWindow(window);
+ }).then(() => {
+ extension.sendMessage("runTests");
+ });
+ } else {
+ resolve();
+ }
+ });
+ });
+
+ yield extension.startup();
+
+ yield awaitFinish;
+
+ yield extension.unload();
+
+ let node = document.getElementById(pageActionId);
+ is(node, null, "pageAction image removed from document");
+
+ currentWindow = null;
+ for (let win of windows.splice(0)) {
+ node = win.document.getElementById(pageActionId);
+ is(node, null, "pageAction image removed from second document");
+
+ yield BrowserTestUtils.closeWindow(win);
+ }
+}
+
+add_task(function* testTabSwitchContext() {
+ yield runTests({
manifest: {
+ "name": "Foo Extension",
+
"page_action": {
"default_icon": "default.png",
"default_popup": "default.html",
"default_title": "Default Title",
},
+
"permissions": ["tabs"],
},
- background: function() {
+ getTests(tabs) {
let details = [
{ "icon": browser.runtime.getURL("default.png"),
"popup": browser.runtime.getURL("default.html"),
"title": "Default Title" },
{ "icon": browser.runtime.getURL("1.png"),
"popup": browser.runtime.getURL("default.html"),
"title": "Default Title" },
{ "icon": browser.runtime.getURL("2.png"),
"popup": browser.runtime.getURL("2.html"),
"title": "Title 2" },
+ { "icon": browser.runtime.getURL("2.png"),
+ "popup": browser.runtime.getURL("2.html"),
+ "title": "Default Title" },
];
- let tabs;
- let tests;
- let allTests = [
+ return [
expect => {
browser.test.log("Initial state. No icon visible.");
expect(null);
},
expect => {
browser.test.log("Show the icon on the first tab, expect default properties.");
browser.pageAction.show(tabs[0]);
expect(details[0]);
@@ -56,16 +204,22 @@ add_task(function* testTabSwitchContext(
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]);
},
expect => {
+ browser.test.log("Clear the title. Expect default title.");
+ browser.pageAction.setTitle({ tabId: tabs[1], title: "" });
+
+ expect(details[3]);
+ },
+ 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.
browser.tabs.onUpdated.addListener(function listener(tabId, changed) {
if (tabId == tabs[1] && changed.url) {
browser.tabs.onUpdated.removeListener(listener);
expect(null);
@@ -99,140 +253,58 @@ add_task(function* testTabSwitchContext(
});
},
expect => {
browser.test.log("Hide the icon. Expect hidden.");
browser.pageAction.hide(tabs[0]);
expect(null);
},
];
-
- // Gets the current details of the page action, and returns a
- // promise that resolves to an object containing them.
- function getDetails() {
- return new Promise(resolve => {
- return browser.tabs.query({ active: true, currentWindow: true }, resolve);
- }).then(tabs => {
- let tabId = tabs[0].id;
- return Promise.all([
- new Promise(resolve => browser.pageAction.getTitle({tabId}, resolve)),
- new Promise(resolve => browser.pageAction.getPopup({tabId}, resolve))]);
- }).then(details => {
- return Promise.resolve({ title: details[0],
- popup: details[1] });
- });
- }
-
-
- // 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(expecting => {
- function finish() {
- // Check that the actual icon has the expected values, then
- // run the next test.
- browser.test.sendMessage("nextTest", expecting, tests.length);
- }
-
- if (expecting) {
- // Check that the API returns the expected values, and then
- // run the next test.
- getDetails().then(details => {
- browser.test.assertEq(expecting.title, details.title,
- "expected value from getTitle");
-
- browser.test.assertEq(expecting.popup, details.popup,
- "expected value from getPopup");
-
- finish();
- });
- } else {
- finish();
- }
- });
- }
-
- function runTests() {
- tabs = [];
- tests = allTests.slice();
-
- browser.tabs.query({ active: true, currentWindow: true }, resultTabs => {
- tabs[0] = resultTabs[0].id;
-
- nextTest();
- });
- }
-
- browser.test.onMessage.addListener((msg) => {
- if (msg == "runTests") {
- runTests();
- } else if (msg == "runNextTest") {
- nextTest();
- } else {
- browser.test.fail(`Unexpected message: ${msg}`);
- }
- });
-
- runTests();
},
});
-
- let pageActionId = makeWidgetId(extension.id) + "-page-action";
- let currentWindow = window;
- let windows = [];
+});
- function checkDetails(details) {
- let image = currentWindow.document.getElementById(pageActionId);
- if (details == null) {
- ok(image == null || image.hidden, "image is hidden");
- } else {
- ok(image, "image exists");
+add_task(function* testDefaultTitle() {
+ yield runTests({
+ manifest: {
+ "name": "Foo Extension",
+
+ "page_action": {
+ "default_icon": "icon.png",
+ },
- is(image.src, details.icon, "icon URL is correct");
- is(image.getAttribute("tooltiptext"), details.title, "image title is correct");
- is(image.getAttribute("aria-label"), details.title, "image aria-label is correct");
- // TODO: Popup URL.
- }
- }
-
- let testNewWindows = 1;
+ "permissions": ["tabs"],
+ },
- let awaitFinish = new Promise(resolve => {
- extension.onMessage("nextTest", (expecting, testsRemaining) => {
- checkDetails(expecting);
-
- if (testsRemaining) {
- extension.sendMessage("runNextTest");
- } else if (testNewWindows) {
- testNewWindows--;
+ getTests(tabs) {
+ let details = [
+ { "title": "Foo Extension",
+ "popup": "",
+ "icon": browser.runtime.getURL("icon.png") },
+ { "title": "Foo Title",
+ "popup": "",
+ "icon": browser.runtime.getURL("icon.png") },
+ ];
- BrowserTestUtils.openNewBrowserWindow().then(window => {
- windows.push(window);
- currentWindow = window;
- return focusWindow(window);
- }).then(() => {
- extension.sendMessage("runTests");
- });
- } else {
- resolve();
- }
- });
+ return [
+ expect => {
+ browser.test.log("Initial state. No icon visible.");
+ expect(null);
+ },
+ expect => {
+ browser.test.log("Show the icon on the first tab, expect extension title as default title.");
+ browser.pageAction.show(tabs[0]);
+ expect(details[0]);
+ },
+ expect => {
+ browser.test.log("Change the title. Expect new title.");
+ browser.pageAction.setTitle({ tabId: tabs[0], title: "Foo Title" });
+ expect(details[1]);
+ },
+ expect => {
+ browser.test.log("Clear the title. Expect extension title.");
+ browser.pageAction.setTitle({ tabId: tabs[0], title: "" });
+ expect(details[0]);
+ },
+ ];
+ },
});
-
- yield extension.startup();
-
- yield awaitFinish;
-
- yield extension.unload();
-
- let node = document.getElementById(pageActionId);
- is(node, null, "pageAction image removed from document");
-
- currentWindow = null;
- for (let win of windows.splice(0)) {
- node = win.document.getElementById(pageActionId);
- is(node, null, "pageAction image removed from second document");
-
- yield BrowserTestUtils.closeWindow(win);
- }
});
--- a/browser/components/extensions/test/browser/browser_ext_pageAction_popup.js
+++ b/browser/components/extensions/test/browser/browser_ext_pageAction_popup.js
@@ -12,38 +12,40 @@ function promisePopupShown(popup) {
resolve();
};
popup.addEventListener("popupshown", onPopupShown);
}
});
}
add_task(function* testPageActionPopup() {
+ let scriptPage = url => `<html><head><meta charset="utf-8"><script src="${url}"></script></head></html>`;
+
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"background": {
"page": "data/background.html",
},
"page_action": {
"default_popup": "popup-a.html",
},
},
files: {
- "popup-a.html": `<script src="popup-a.js"></script>`,
+ "popup-a.html": scriptPage("popup-a.js"),
"popup-a.js": function() {
browser.runtime.sendMessage("from-popup-a");
},
- "data/popup-b.html": `<script src="popup-b.js"></script>`,
+ "data/popup-b.html": scriptPage("popup-b.js"),
"data/popup-b.js": function() {
browser.runtime.sendMessage("from-popup-b");
},
- "data/background.html": `<script src="background.js"></script>`,
+ "data/background.html": scriptPage("background.js"),
"data/background.js": function() {
let tabId;
let sendClick;
let tests = [
() => {
sendClick({ expectEvent: false, expectPopup: "a" });