Bug 1390464 - Add windowId parameter in sidebarAction methods r=mixedpuppy

MozReview-Commit-ID: eSJnVzpNvO

--HG--
extra : rebase_source : 5837207b8375649c5ebc24e27a6dcc6894d6d40b
This commit is contained in:
Oriol Brufau 2018-01-28 20:46:24 +01:00
Родитель 263541211d
Коммит 2b62ae8f00
3 изменённых файлов: 338 добавлений и 178 удалений

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

@ -4,6 +4,10 @@
ChromeUtils.import("resource://gre/modules/ExtensionParent.jsm");
var {
ExtensionError,
} = ExtensionUtils;
var {
IconDetails,
} = ExtensionParent;
@ -50,8 +54,13 @@ this.sidebarAction = class extends ExtensionAPI {
};
this.globals = Object.create(this.defaults);
this.tabContext = new TabContext(tab => Object.create(this.globals),
extension);
this.tabContext = new TabContext(target => {
let window = target.ownerGlobal;
if (target === window) {
return Object.create(this.globals);
}
return Object.create(this.tabContext.get(window));
}, extension);
// We need to ensure our elements are available before session restore.
this.windowOpenListener = (window) => {
@ -248,16 +257,18 @@ this.sidebarAction = class extends ExtensionAPI {
/**
* Update the broadcaster and menuitem when the extension changes the icon,
* title, url, etc. If it only changes a parameter for a single
* tab, `tab` will be that tab. Otherwise it will be null.
* title, url, etc. If it only changes a parameter for a single tab, `target`
* will be that tab. If it only changes a parameter for a single window,
* `target` will be that window. Otherwise `target` will be null.
*
* @param {XULElement|null} nativeTab
* Browser tab, may be null.
* @param {XULElement|ChromeWindow|null} target
* Browser tab or browser chrome window, may be null.
*/
updateOnChange(nativeTab) {
if (nativeTab) {
if (nativeTab.selected) {
this.updateWindow(nativeTab.ownerGlobal);
updateOnChange(target) {
if (target) {
let window = target.ownerGlobal;
if (target === window || target.selected) {
this.updateWindow(window);
}
} else {
for (let window of windowTracker.browserWindows()) {
@ -267,46 +278,71 @@ this.sidebarAction = class extends ExtensionAPI {
}
/**
* Set a default or tab specific property.
* Gets the target object and its associated values corresponding to
* the `details` parameter of the various get* and set* API methods.
*
* @param {XULElement|null} nativeTab
* Webextension tab object, may be null.
* @param {Object} details
* An object with optional `tabId` or `windowId` properties.
* @throws if both `tabId` and `windowId` are specified, or if they are invalid.
* @returns {Object}
* An object with two properties: `target` and `values`.
* - If a `tabId` was specified, `target` will be the corresponding
* XULElement tab. If a `windowId` was specified, `target` will be
* the corresponding ChromeWindow. Otherwise it will be `null`.
* - `values` will contain the icon, title and panel associated with
* the target.
*/
getContextData({tabId, windowId}) {
if (tabId != null && windowId != null) {
throw new ExtensionError("Only one of tabId and windowId can be specified.");
}
let target, values;
if (tabId != null) {
target = tabTracker.getTab(tabId);
values = this.tabContext.get(target);
} else if (windowId != null) {
target = windowTracker.getWindow(windowId);
values = this.tabContext.get(target);
} else {
target = null;
values = this.globals;
}
return {target, values};
}
/**
* Set a global, window specific or tab specific property.
*
* @param {Object} details
* An object with optional `tabId` or `windowId` properties.
* @param {string} prop
* String property to retrieve ["icon", "title", or "panel"].
* String property to set ["icon", "title", or "panel"].
* @param {string} value
* Value for property.
*/
setProperty(nativeTab, prop, value) {
let values;
if (nativeTab === null) {
values = this.globals;
} else {
values = this.tabContext.get(nativeTab);
}
setProperty(details, prop, value) {
let {target, values} = this.getContextData(details);
if (value === null) {
delete values[prop];
} else {
values[prop] = value;
}
this.updateOnChange(nativeTab);
this.updateOnChange(target);
}
/**
* Retrieve a property from the tab or globals if tab is null.
* Retrieve the value of a global, window specific or tab specific property.
*
* @param {XULElement|null} nativeTab
* Browser tab object, may be null.
* @param {Object} details
* An object with optional `tabId` or `windowId` properties.
* @param {string} prop
* String property to retrieve ["icon", "title", or "panel"]
* @returns {string} value
* Value for prop.
* Value of prop.
*/
getProperty(nativeTab, prop) {
if (nativeTab === null) {
return this.globals[prop];
}
return this.tabContext.get(nativeTab)[prop];
getProperty(details, prop) {
return this.getContextData(details).values[prop];
}
/**
@ -360,40 +396,25 @@ this.sidebarAction = class extends ExtensionAPI {
let {extension} = context;
const sidebarAction = this;
function getTab(tabId) {
if (tabId !== null) {
return tabTracker.getTab(tabId);
}
return null;
}
return {
sidebarAction: {
async setTitle(details) {
let nativeTab = getTab(details.tabId);
sidebarAction.setProperty(nativeTab, "title", details.title);
sidebarAction.setProperty(details, "title", details.title);
},
getTitle(details) {
let nativeTab = getTab(details.tabId);
let title = sidebarAction.getProperty(nativeTab, "title");
return Promise.resolve(title);
return sidebarAction.getProperty(details, "title");
},
async setIcon(details) {
let nativeTab = getTab(details.tabId);
let icon = IconDetails.normalize(details, extension, context);
if (!Object.keys(icon).length) {
icon = null;
}
sidebarAction.setProperty(nativeTab, "icon", icon);
sidebarAction.setProperty(details, "icon", icon);
},
async setPanel(details) {
let nativeTab = getTab(details.tabId);
let url;
// Clear the url when given null or empty string.
if (!details.panel) {
@ -405,14 +426,11 @@ this.sidebarAction = class extends ExtensionAPI {
}
}
sidebarAction.setProperty(nativeTab, "panel", url);
sidebarAction.setProperty(details, "panel", url);
},
getPanel(details) {
let nativeTab = getTab(details.tabId);
let panel = sidebarAction.getProperty(nativeTab, "panel");
return Promise.resolve(panel);
return sidebarAction.getProperty(details, "panel");
},
open() {

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

@ -74,6 +74,12 @@
"type": "integer",
"optional": true,
"description": "Sets the sidebar title for the tab specified by tabId. Automatically resets when the tab is closed."
},
"windowId": {
"type": "integer",
"optional": true,
"minimum": -2,
"description": "Sets the sidebar title for the window specified by windowId."
}
}
}
@ -92,7 +98,13 @@
"tabId": {
"type": "integer",
"optional": true,
"description": "Specify the tab to get the title from. If no tab is specified, the non-tab-specific title is returned."
"description": "Specify the tab to get the title from. If no tab nor window is specified, the global title is returned."
},
"windowId": {
"type": "integer",
"optional": true,
"minimum": -2,
"description": "Specify the window to get the title from. If no tab nor window is specified, the global title is returned."
}
}
}
@ -137,6 +149,12 @@
"type": "integer",
"optional": true,
"description": "Sets the sidebar icon for the tab specified by tabId. Automatically resets when the tab is closed."
},
"windowId": {
"type": "integer",
"optional": true,
"minimum": -2,
"description": "Sets the sidebar icon for the window specified by windowId."
}
}
}
@ -158,6 +176,12 @@
"minimum": 0,
"description": "Sets the sidebar url for the tab specified by tabId. Automatically resets when the tab is closed."
},
"windowId": {
"type": "integer",
"optional": true,
"minimum": -2,
"description": "Sets the sidebar url for the window specified by windowId."
},
"panel": {
"choices": [
{"type": "string"},
@ -182,7 +206,13 @@
"tabId": {
"type": "integer",
"optional": true,
"description": "Specify the tab to get the sidebar from. If no tab is specified, the non-tab-specific sidebar is returned."
"description": "Specify the tab to get the panel from. If no tab nor window is specified, the global panel is returned."
},
"windowId": {
"type": "integer",
"optional": true,
"minimum": -2,
"description": "Specify the window to get the panel from. If no tab nor window is specified, the global panel is returned."
}
}
}

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

@ -11,22 +11,19 @@ SpecialPowers.pushPrefEnv({
async function runTests(options) {
async function background(getTests) {
async function checkDetails(expecting, tabId) {
let title = await browser.sidebarAction.getTitle({tabId});
async function checkDetails(expecting, details) {
let title = await browser.sidebarAction.getTitle(details);
browser.test.assertEq(expecting.title, title,
"expected value from getTitle");
"expected value from getTitle in " + JSON.stringify(details));
let panel = await browser.sidebarAction.getPanel({tabId});
let panel = await browser.sidebarAction.getPanel(details);
browser.test.assertEq(expecting.panel, panel,
"expected value from getPanel");
"expected value from getPanel in " + JSON.stringify(details));
}
let expectDefaults = expecting => {
return checkDetails(expecting);
};
let tabs = [];
let tests = getTests(tabs, expectDefaults);
let windows = [];
let tests = getTests(tabs, windows);
{
let tabId = 0xdeadbeef;
@ -49,15 +46,21 @@ async function runTests(options) {
function nextTest() {
let test = tests.shift();
test(async expecting => {
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 tabs = await browser.tabs.query({active: true, currentWindow: true});
await checkDetails(expecting, tabs[0].id);
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", expecting, tests.length);
browser.test.sendMessage("nextTest", expectTab, windowId, tests.length);
});
}
@ -69,9 +72,9 @@ async function runTests(options) {
nextTest();
});
browser.tabs.query({active: true, currentWindow: true}, resultTabs => {
tabs[0] = resultTabs[0].id;
});
let [{id, windowId}] = await browser.tabs.query({active: true, currentWindow: true});
tabs.push(id);
windows.push(windowId);
}
let extension = ExtensionTestUtils.loadExtension({
@ -84,7 +87,8 @@ async function runTests(options) {
});
let sidebarActionId;
function checkDetails(details) {
function checkDetails(details, windowId) {
let {document} = Services.wm.getOuterWindowWithId(windowId);
if (!sidebarActionId) {
sidebarActionId = `${makeWidgetId(extension.id)}-sidebar-action`;
}
@ -103,8 +107,8 @@ async function runTests(options) {
}
let awaitFinish = new Promise(resolve => {
extension.onMessage("nextTest", (expecting, testsRemaining) => {
checkDetails(expecting);
extension.onMessage("nextTest", (expecting, windowId, testsRemaining) => {
checkDetails(expecting, windowId);
if (testsRemaining) {
extension.sendMessage("runNextTest");
@ -149,7 +153,7 @@ add_task(async function testTabSwitchContext() {
"files": {
"default.html": sidebar,
"default-2.html": sidebar,
"global.html": sidebar,
"2.html": sidebar,
"_locales/en/messages.json": {
@ -165,40 +169,29 @@ add_task(async function testTabSwitchContext() {
},
"default.png": imageBuffer,
"default-2.png": imageBuffer,
"global.png": imageBuffer,
"1.png": imageBuffer,
"2.png": imageBuffer,
},
getTests: function(tabs, expectDefaults) {
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"),
"panel": browser.runtime.getURL("default.html"),
"title": "Default Title",
},
{"icon": browser.runtime.getURL("2.png"),
"panel": browser.runtime.getURL("2.html"),
"title": "Title 2",
},
{"icon": browser.runtime.getURL("1.png"),
"panel": browser.runtime.getURL("default-2.html"),
"title": "Default Title 2",
},
{"icon": browser.runtime.getURL("1.png"),
"panel": browser.runtime.getURL("default-2.html"),
"title": "Default Title 2",
},
{"icon": browser.runtime.getURL("default-2.png"),
"panel": browser.runtime.getURL("default-2.html"),
"title": "Default 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"),
"title": "Default Title 2",
},
];
@ -206,23 +199,20 @@ add_task(async function testTabSwitchContext() {
async expect => {
browser.test.log("Initial state, expect default properties.");
await expectDefaults(details[0]);
expect(details[0]);
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"});
await expectDefaults(details[0]);
expect(details[1]);
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);
await expectDefaults(details[0]);
expect(details[0]);
expect(null, null, null, details[0]);
},
async expect => {
browser.test.log("Change properties. Expect new properties.");
@ -232,8 +222,7 @@ add_task(async function testTabSwitchContext() {
browser.sidebarAction.setPanel({tabId, panel: "2.html"}),
browser.sidebarAction.setTitle({tabId, title: "Title 2"}),
]);
await expectDefaults(details[0]);
expect(details[2]);
expect(details[2], null, null, details[0]);
},
expect => {
browser.test.log("Navigate to a new page. Expect no changes.");
@ -243,7 +232,7 @@ add_task(async function testTabSwitchContext() {
browser.tabs.onUpdated.addListener(function listener(tabId, changed) {
if (tabId == tabs[1] && changed.url) {
browser.tabs.onUpdated.removeListener(listener);
expect(details[2]);
expect(details[2], null, null, details[0]);
}
});
@ -252,53 +241,51 @@ add_task(async function testTabSwitchContext() {
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]);
expect(details[1], null, null, details[0]);
},
async expect => {
browser.test.log("Change default values, expect those changes reflected.");
browser.test.log("Change global values, expect those changes reflected.");
await Promise.all([
browser.sidebarAction.setIcon({path: "default-2.png"}),
browser.sidebarAction.setPanel({panel: "default-2.html"}),
browser.sidebarAction.setTitle({title: "Default Title 2"}),
browser.sidebarAction.setIcon({path: "global.png"}),
browser.sidebarAction.setPanel({panel: "global.html"}),
browser.sidebarAction.setTitle({title: "Global Title"}),
]);
await expectDefaults(details[3]);
expect(details[3]);
expect(details[1], null, details[3], details[0]);
},
async expect => {
browser.test.log("Switch back to tab 2. Expect former value, unaffected by changes to defaults in previous step.");
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});
await expectDefaults(details[3]);
expect(details[2]);
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[4]);
expect(details[1], null, details[3], details[0]);
},
async expect => {
browser.test.log("Create a new tab. Expect new default properties.");
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(details[5]);
expect(null, null, details[3], details[0]);
},
async expect => {
browser.test.log("Delete tab.");
await browser.tabs.remove(tabs[2]);
expect(details[4]);
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[6]);
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[4]);
expect(details[1], null, details[3], details[0]);
},
];
},
@ -323,53 +310,44 @@ add_task(async function testDefaultTitle() {
"icon.png": imageBuffer,
},
getTests: function(tabs, expectGlobals) {
getTests: function(tabs) {
let details = [
{"title": "Foo Extension",
"panel": browser.runtime.getURL("sidebar.html"),
"icon": browser.runtime.getURL("icon.png")},
{"title": "Foo Title",
"panel": browser.runtime.getURL("sidebar.html"),
"icon": browser.runtime.getURL("icon.png")},
{"title": "Bar Title",
"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.");
await expectGlobals(details[0]);
expect(details[0]);
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"});
await expectGlobals(details[0]);
expect(details[1]);
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"});
await expectGlobals(details[2]);
expect(details[1]);
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});
await expectGlobals(details[2]);
expect(details[2]);
expect(null, null, details[2], details[0]);
},
async expect => {
browser.test.log("Clear the global title. Expect default title.");
browser.sidebarAction.setTitle({title: null});
await expectGlobals(details[0]);
expect(details[0]);
expect(null, null, null, details[0]);
},
async expect => {
browser.test.assertRejects(
@ -377,8 +355,7 @@ add_task(async function testDefaultTitle() {
/Access denied for URL about:addons/,
"unable to set panel to about:addons");
await expectGlobals(details[0]);
expect(details[0]);
expect(null, null, null, details[0]);
},
];
},
@ -401,57 +378,66 @@ add_task(async function testPropertyRemoval() {
files: {
"default.html": sidebar,
"p1.html": sidebar,
"p2.html": sidebar,
"p3.html": sidebar,
"global.html": sidebar,
"global2.html": sidebar,
"window.html": sidebar,
"tab.html": sidebar,
"default.png": imageBuffer,
"i1.png": imageBuffer,
"i2.png": imageBuffer,
"i3.png": imageBuffer,
"global.png": imageBuffer,
"global2.png": imageBuffer,
"window.png": imageBuffer,
"tab.png": imageBuffer,
},
getTests: function(tabs, expectGlobals) {
getTests: function(tabs, windows) {
let defaultIcon = "chrome://browser/content/extension.svg";
let details = [
{"icon": browser.runtime.getURL("default.png"),
"panel": browser.runtime.getURL("default.html"),
"title": "Default Title"},
{"icon": browser.runtime.getURL("i1.png"),
"panel": browser.runtime.getURL("p1.html"),
"title": "t1"},
{"icon": browser.runtime.getURL("i2.png"),
"panel": browser.runtime.getURL("p2.html"),
"title": "t2"},
{"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,
"panel": browser.runtime.getURL("p1.html"),
"title": ""},
{"icon": browser.runtime.getURL("i3.png"),
"panel": browser.runtime.getURL("p3.html"),
"title": "t3"},
{"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.");
await expectGlobals(details[0]);
expect(details[0]);
expect(null, null, null, details[0]);
},
async expect => {
browser.test.log("Set global values, expect the new values.");
browser.sidebarAction.setIcon({path: "i1.png"});
browser.sidebarAction.setPanel({panel: "p1.html"});
browser.sidebarAction.setTitle({title: "t1"});
await expectGlobals(details[1]);
expect(details[1]);
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: "i2.png"});
browser.sidebarAction.setPanel({tabId, panel: "p2.html"});
browser.sidebarAction.setTitle({tabId, title: "t2"});
await expectGlobals(details[1]);
expect(details[2]);
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.");
@ -459,33 +445,159 @@ add_task(async function testPropertyRemoval() {
browser.sidebarAction.setIcon({tabId, path: ""});
browser.sidebarAction.setPanel({tabId, panel: ""});
browser.sidebarAction.setTitle({tabId, title: ""});
await expectGlobals(details[1]);
expect(details[3]);
expect(details[4], details[2], details[1], details[0]);
},
async expect => {
browser.test.log("Remove tab values, expect global values.");
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});
await expectGlobals(details[1]);
expect(details[1]);
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: "i3.png"});
browser.sidebarAction.setPanel({panel: "p3.html"});
browser.sidebarAction.setTitle({title: "t3"});
await expectGlobals(details[4]);
expect(details[4]);
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});
await expectGlobals(details[0]);
expect(details[0]);
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 cleared (bug 1451176) and 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(null, details[2], null, details[0]);
},
async expect => {
browser.test.log("Close the tab, expect window values.");
await browser.tabs.remove(tabs[1]);
expect(null, details[2], null, details[0]);
},
async expect => {
browser.test.log("Close the new window and go back to the previous one.");
await browser.windows.remove(windows[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]);
},
];
},