Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
PromiseTestUtils.allowMatchingRejectionsGlobally(/packaging errors/);
// Test that an error is thrown when providing invalid icon sizes
add_task(async function testInvalidIconSizes() {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
browser_action: {
default_area: "navbar",
},
page_action: {},
},
background: function () {
browser.tabs.query({ active: true, currentWindow: true }, tabs => {
let tabId = tabs[0].id;
let promises = [];
for (let api of ["pageAction", "browserAction"]) {
// helper function to run setIcon and check if it fails
let assertSetIconThrows = function (detail) {
detail.tabId = tabId;
browser.test.assertThrows(
() => browser[api].setIcon(detail),
/an unexpected .* property/,
"setIcon with invalid icon size"
);
};
let imageData = new ImageData(1, 1);
// test invalid icon size inputs
for (let type of ["path", "imageData"]) {
let img = type == "imageData" ? imageData : "test.png";
assertSetIconThrows({ [type]: { abcdef: img } });
assertSetIconThrows({ [type]: { "48px": img } });
assertSetIconThrows({ [type]: { 20.5: img } });
assertSetIconThrows({ [type]: { "5.0": img } });
assertSetIconThrows({ [type]: { "-300": img } });
assertSetIconThrows({ [type]: { abc: img, 5: img } });
}
assertSetIconThrows({
imageData: { abcdef: imageData },
path: { 5: "test.png" },
});
assertSetIconThrows({
path: { abcdef: "test.png" },
imageData: { 5: imageData },
});
}
Promise.all(promises).then(() => {
browser.test.notifyPass("setIcon with invalid icon size");
});
});
},
});
await Promise.all([
extension.startup(),
extension.awaitFinish("setIcon with invalid icon size"),
]);
await extension.unload();
});
// Test that default icon details in the manifest.json file are handled
// correctly.
add_task(async function testDefaultDetails() {
// TODO: Test localized variants.
let icons = [
"foo/bar.png",
"/foo/bar.png",
{ 38: "foo/bar.png" },
{ 70: "foo/bar.png" },
];
if (window.devicePixelRatio > 1) {
icons.push({ 38: "baz/quux.png", 70: "foo/bar.png" });
} else {
icons.push({ 38: "foo/bar.png", 70: "baz/quux@2x.png" });
}
let expectedURL = new RegExp(
);
for (let icon of icons) {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
browser_action: { default_icon: icon, default_area: "navbar" },
page_action: { default_icon: icon },
},
background: function () {
browser.tabs.query({ active: true, currentWindow: true }, tabs => {
let tabId = tabs[0].id;
browser.pageAction.show(tabId).then(() => {
browser.test.sendMessage("ready");
});
});
},
files: {
"foo/bar.png": imageBuffer,
"baz/quux.png": imageBuffer,
"baz/quux@2x.png": imageBuffer,
},
});
await Promise.all([extension.startup(), extension.awaitMessage("ready")]);
let browserActionId = makeWidgetId(extension.id) + "-browser-action";
let pageActionId = BrowserPageActions.urlbarButtonNodeIDForActionID(
makeWidgetId(extension.id)
);
await promiseAnimationFrame();
let browserActionButton =
document.getElementById(browserActionId).firstElementChild;
let image = getListStyleImage(browserActionButton);
ok(
expectedURL.test(image),
`browser action image ${image} matches ${expectedURL}`
);
let pageActionImage = document.getElementById(pageActionId);
image = getListStyleImage(pageActionImage);
ok(
expectedURL.test(image),
`page action image ${image} matches ${expectedURL}`
);
await extension.unload();
let node = document.getElementById(pageActionId);
is(node, null, "pageAction image removed from document");
}
});
// Check that attempts to load a privileged URL as an icon image fail.
add_task(async function testSecureURLsDenied() {
// Test URLs passed to setIcon.
let extension = ExtensionTestUtils.loadExtension({
manifest: {
browser_action: { default_area: "navbar" },
page_action: {},
},
background: function () {
browser.tabs.query({ active: true, currentWindow: true }, tabs => {
let tabId = tabs[0].id;
let urls = [
"javascript:true",
];
let promises = [];
for (let url of urls) {
for (let api of ["pageAction", "browserAction"]) {
promises.push(
browser.test.assertRejects(
browser[api].setIcon({ tabId, path: url }),
/Illegal URL/,
`Load of '${url}' should fail.`
)
);
}
}
Promise.all(promises).then(() => {
browser.test.notifyPass("setIcon security tests");
});
});
},
});
await extension.startup();
await extension.awaitFinish("setIcon security tests");
await extension.unload();
});
add_task(async function testSecureManifestURLsDenied() {
// Test URLs included in the manifest.
let urls = ["chrome://browser/content/browser.xhtml", "javascript:true"];
let apis = ["browser_action", "page_action"];
for (let url of urls) {
for (let api of apis) {
info(`TEST ${api} icon url: ${url}`);
let matchURLForbidden = () => ({
message: new RegExp(`match the format "strictRelativeUrl"`),
});
let messages = [matchURLForbidden(url)];
let waitForConsole = new Promise(resolve => {
// Not necessary in browser-chrome tests, but monitorConsole gripes
// if we don't call it.
SimpleTest.waitForExplicitFinish();
SimpleTest.monitorConsole(resolve, messages);
});
let extension = ExtensionTestUtils.loadExtension({
manifest: {
[api]: {
default_icon: url,
default_area: "navbar",
},
},
});
await Assert.rejects(
extension.startup(),
/startup failed/,
"Manifest rejected"
);
SimpleTest.endMonitorConsole();
await waitForConsole;
}
}
});