Bug 1896217 - Deprecate tabs.executeScript(), tabs.insertCSS() and tabs.removeCSS() after Manifest V2 and add tests for the scripting API in Manifest V3. r=aleca
The scripting API was added for Manifest V3. This adds tests for this new API. Differential Revision: https://phabricator.services.mozilla.com/D210103 --HG-- rename : mail/components/extensions/test/browser/browser_ext_composeScripts.js => mail/components/extensions/test/browser/browser_ext_composeScripts_mv3.js rename : mail/components/extensions/test/browser/browser_ext_contentScripts.js => mail/components/extensions/test/browser/browser_ext_contentScripts_mv3.js rename : mail/components/extensions/test/browser/browser_ext_messageDisplayScripts.js => mail/components/extensions/test/browser/browser_ext_messageDisplayScripts_mv3.js extra : amend_source : 4eece16a87e9f5e1c61d360d43f9de9cf522429e
This commit is contained in:
Родитель
14b38725b1
Коммит
c2efdabd7d
|
@ -715,6 +715,7 @@
|
|||
{
|
||||
"name": "executeScript",
|
||||
"type": "function",
|
||||
"max_manifest_version": 2,
|
||||
"description": "Injects JavaScript code into a page. For details, see the `programmatic injection <|link-content-scripts|>`__ section of the content scripts doc.",
|
||||
"async": "callback",
|
||||
"parameters": [
|
||||
|
@ -752,6 +753,7 @@
|
|||
{
|
||||
"name": "insertCSS",
|
||||
"type": "function",
|
||||
"max_manifest_version": 2,
|
||||
"description": "Injects CSS into a page. For details, see the `programmatic injection <|link-content-scripts|>`__ section of the content scripts doc.",
|
||||
"async": "callback",
|
||||
"parameters": [
|
||||
|
@ -779,6 +781,7 @@
|
|||
{
|
||||
"name": "removeCSS",
|
||||
"type": "function",
|
||||
"max_manifest_version": 2,
|
||||
"description": "Removes injected CSS from a page. For details, see the `programmatic injection <|link-content-scripts|>`__ section of the content scripts doc.",
|
||||
"async": "callback",
|
||||
"parameters": [
|
||||
|
|
|
@ -67,11 +67,13 @@ support-files = data/cloudFile1.txt data/cloudFile2.txt
|
|||
[browser_ext_composeAction_popup_click_mv3_event_pages.js]
|
||||
[browser_ext_composeAction_properties.js]
|
||||
[browser_ext_composeScripts.js]
|
||||
[browser_ext_composeScripts_mv3.js]
|
||||
[browser_ext_content_handler.js]
|
||||
[browser_ext_content_tabs_navigation_menu.js]
|
||||
support-files = data/content.html
|
||||
tags = contextmenu
|
||||
[browser_ext_contentScripts.js]
|
||||
[browser_ext_contentScripts_mv3.js]
|
||||
[browser_ext_mailTabs_create.js]
|
||||
[browser_ext_mailTabs_folderModes.js]
|
||||
[browser_ext_mailTabs_getListedMessages.js]
|
||||
|
@ -124,6 +126,7 @@ support-files = messages/attachedMessageSample.eml
|
|||
[browser_ext_messageDisplayAction_popup_click_mv3_event_pages.js]
|
||||
[browser_ext_messageDisplayAction_properties.js]
|
||||
[browser_ext_messageDisplayScripts.js]
|
||||
[browser_ext_messageDisplayScripts_mv3.js]
|
||||
[browser_ext_messages_open_attachment.js]
|
||||
[browser_ext_quickFilter.js]
|
||||
[browser_ext_runtime_getContexts.js]
|
||||
|
|
|
@ -0,0 +1,554 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
addIdentity(createAccount());
|
||||
|
||||
async function checkComposeBody(expected, waitForEvent) {
|
||||
const composeWindows = [...Services.wm.getEnumerator("msgcompose")];
|
||||
Assert.equal(composeWindows.length, 1);
|
||||
|
||||
const composeWindow = composeWindows[0];
|
||||
if (waitForEvent) {
|
||||
await BrowserTestUtils.waitForEvent(
|
||||
composeWindow,
|
||||
"extension-scripts-added"
|
||||
);
|
||||
}
|
||||
|
||||
const composeEditor = composeWindow.GetCurrentEditorElement();
|
||||
|
||||
await checkContent(composeEditor, expected);
|
||||
}
|
||||
|
||||
/** Tests browser.scripting.insertCSS and browser.scripting.removeCSS. */
|
||||
add_task(async function testInsertRemoveCSSViaScriptingAPI() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const tab = await browser.compose.beginNew();
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.insertCSS({
|
||||
target: { tabId: tab.id },
|
||||
css: "body { background-color: lime; }",
|
||||
});
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.removeCSS({
|
||||
target: { tabId: tab.id },
|
||||
css: "body { background-color: lime; }",
|
||||
});
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.insertCSS({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.css"],
|
||||
});
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.removeCSS({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.css"],
|
||||
});
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.tabs.remove(tab.id);
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.css": "body { background-color: green; }",
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["compose", "scripting"],
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({ backgroundColor: "rgba(0, 0, 0, 0)" });
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({ backgroundColor: "rgb(0, 255, 0)" });
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({ backgroundColor: "rgba(0, 0, 0, 0)" });
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({ backgroundColor: "rgb(0, 128, 0)" });
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({ backgroundColor: "rgba(0, 0, 0, 0)" });
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await extension.unload();
|
||||
});
|
||||
|
||||
/** Tests browser.scripting.insertCSS fails without the "compose" permission. */
|
||||
add_task(async function testInsertRemoveCSSNoPermissions() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const tab = await browser.compose.beginNew();
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.scripting.insertCSS({
|
||||
target: { tabId: tab.id },
|
||||
css: "body { background-color: darkred; }",
|
||||
}),
|
||||
/Missing host permission for the tab/,
|
||||
"insertCSS without permission should throw"
|
||||
);
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.scripting.insertCSS({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.css"],
|
||||
}),
|
||||
/Missing host permission for the tab/,
|
||||
"insertCSS without permission should throw"
|
||||
);
|
||||
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.tabs.remove(tab.id);
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.css": "body { background-color: red; }",
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["scripting"],
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
textContent: "",
|
||||
});
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await extension.unload();
|
||||
});
|
||||
|
||||
/** Tests browser.scripting.executeScript. */
|
||||
add_task(async function testExecuteScript() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const tab = await browser.compose.beginNew();
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
func: () => {
|
||||
document.body.setAttribute("foo", "bar");
|
||||
},
|
||||
});
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.js"],
|
||||
});
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.tabs.remove(tab.id);
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.js": () => {
|
||||
document.body.textContent = "Hey look, the script ran!";
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["compose", "scripting"],
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({ textContent: "" });
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({ foo: "bar" });
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({
|
||||
foo: "bar",
|
||||
textContent: "Hey look, the script ran!",
|
||||
});
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await extension.unload();
|
||||
});
|
||||
|
||||
/** Tests browser.scripting.executeScript fails without the "compose" permission. */
|
||||
add_task(async function testExecuteScriptNoPermissions() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const tab = await browser.compose.beginNew();
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
func: () => {
|
||||
document.body.setAttribute("foo", "bar");
|
||||
},
|
||||
}),
|
||||
/Missing host permission for the tab/,
|
||||
"executeScript without permission should throw"
|
||||
);
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.js"],
|
||||
}),
|
||||
/Missing host permission for the tab/,
|
||||
"executeScript without permission should throw"
|
||||
);
|
||||
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.tabs.remove(tab.id);
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.js": () => {
|
||||
document.body.textContent = "Hey look, the script ran!";
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["scripting"],
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({ foo: null, textContent: "" });
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await extension.unload();
|
||||
});
|
||||
|
||||
/** Tests the messenger alias is available. */
|
||||
add_task(async function testExecuteScriptAlias() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const tab = await browser.compose.beginNew();
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
func: () => {
|
||||
// eslint-disable-next-line no-undef
|
||||
const id = messenger.runtime.getManifest().applications.gecko.id;
|
||||
document.body.textContent = id;
|
||||
},
|
||||
});
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.tabs.remove(tab.id);
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
browser_specific_settings: { gecko: { id: "compose_scripts@mochitest" } },
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["compose", "scripting"],
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({ textContent: "" });
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({ textContent: "compose_scripts@mochitest" });
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await extension.unload();
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests browser.composeScripts.register correctly adds CSS and JavaScript to
|
||||
* message composition windows opened after it was called. Also tests calling
|
||||
* `unregister` on the returned object.
|
||||
*/
|
||||
add_task(async function testRegisterBeforeCompose() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const registeredScript = await browser.composeScripts.register({
|
||||
css: [{ code: "body { color: white }" }, { file: "test.css" }],
|
||||
js: [
|
||||
{ code: `document.body.setAttribute("foo", "bar");` },
|
||||
{ file: "test.js" },
|
||||
],
|
||||
});
|
||||
|
||||
await browser.compose.beginNew();
|
||||
await window.sendMessage();
|
||||
|
||||
await registeredScript.unregister();
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.css": "body { background-color: green; }",
|
||||
"test.js": () => {
|
||||
document.body.textContent = "Hey look, the script ran!";
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["compose"],
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody(
|
||||
{
|
||||
backgroundColor: "rgb(0, 128, 0)",
|
||||
color: "rgb(255, 255, 255)",
|
||||
foo: "bar",
|
||||
textContent: "Hey look, the script ran!",
|
||||
},
|
||||
true
|
||||
);
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await checkComposeBody({
|
||||
backgroundColor: "rgb(0, 128, 0)",
|
||||
color: "rgb(255, 255, 255)",
|
||||
foo: "bar",
|
||||
textContent: "Hey look, the script ran!",
|
||||
});
|
||||
|
||||
await extension.unload();
|
||||
await checkComposeBody({
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
color: "rgb(0, 0, 0)",
|
||||
foo: "bar",
|
||||
textContent: "Hey look, the script ran!",
|
||||
});
|
||||
|
||||
await BrowserTestUtils.closeWindow(
|
||||
Services.wm.getMostRecentWindow("msgcompose")
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests browser.composeScripts.register correctly adds CSS and JavaScript to
|
||||
* message composition windows already open when it was called. Also tests
|
||||
* calling `unregister` on the returned object.
|
||||
*/
|
||||
add_task(async function testRegisterDuringCompose() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const tab = await browser.compose.beginNew();
|
||||
await window.sendMessage();
|
||||
|
||||
const registeredScript = await browser.composeScripts.register({
|
||||
css: [{ code: "body { color: white }" }, { file: "test.css" }],
|
||||
js: [
|
||||
{ code: `document.body.setAttribute("foo", "bar");` },
|
||||
{ file: "test.js" },
|
||||
],
|
||||
});
|
||||
|
||||
await window.sendMessage();
|
||||
|
||||
await registeredScript.unregister();
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.tabs.remove(tab.id);
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.css": "body { background-color: green; }",
|
||||
"test.js": () => {
|
||||
document.body.textContent = "Hey look, the script ran!";
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["compose"],
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
textContent: "",
|
||||
});
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
textContent: "",
|
||||
});
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
textContent: "",
|
||||
});
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await extension.unload();
|
||||
});
|
||||
|
||||
/** Tests content_scripts in the manifest do not affect compose windows. */
|
||||
async function subtestContentScriptManifest(permissions) {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const tab = await browser.compose.beginNew();
|
||||
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.tabs.remove(tab.id);
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.css": "body { background-color: red; }",
|
||||
"test.js": () => {
|
||||
document.body.textContent = "Hey look, the script ran!";
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions,
|
||||
content_scripts: [
|
||||
{
|
||||
matches: ["<all_urls>"],
|
||||
css: ["test.css"],
|
||||
js: ["test.js"],
|
||||
match_about_blank: true,
|
||||
match_origin_as_fallback: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
// match_origin_as_fallback is not implemented yet. Bug 1475831.
|
||||
ExtensionTestUtils.failOnSchemaWarnings(false);
|
||||
await extension.startup();
|
||||
ExtensionTestUtils.failOnSchemaWarnings(true);
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
textContent: "",
|
||||
});
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await extension.unload();
|
||||
}
|
||||
|
||||
add_task(async function testContentScriptManifestNoPermission() {
|
||||
await subtestContentScriptManifest([]);
|
||||
});
|
||||
add_task(async function testContentScriptManifest() {
|
||||
await subtestContentScriptManifest(["compose"]);
|
||||
});
|
||||
|
||||
/** Tests registered content scripts do not affect compose windows. */
|
||||
async function subtestContentScriptRegister(permissions) {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
await browser.scripting.registerContentScripts([
|
||||
{
|
||||
id: "test",
|
||||
matches: ["<all_urls>"],
|
||||
css: ["test.css"],
|
||||
js: ["test.js"],
|
||||
},
|
||||
]);
|
||||
|
||||
const tab = await browser.compose.beginNew();
|
||||
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.tabs.remove(tab.id);
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.css": "body { background-color: red; }",
|
||||
"test.js": () => {
|
||||
document.body.textContent = "Hey look, the script ran!";
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions,
|
||||
host_permissions: ["<all_urls>"],
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkComposeBody({
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
textContent: "",
|
||||
});
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await extension.unload();
|
||||
}
|
||||
|
||||
add_task(async function testContentScriptRegisterNoPermission() {
|
||||
await subtestContentScriptRegister(["scripting"]);
|
||||
});
|
||||
add_task(async function testContentScriptRegister() {
|
||||
await subtestContentScriptRegister(["scripting", "compose"]);
|
||||
});
|
|
@ -0,0 +1,482 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const CONTENT_PAGE =
|
||||
"http://mochi.test:8888/browser/comm/mail/components/extensions/test/browser/data/content.html";
|
||||
const UNCHANGED_VALUES = {
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
color: "rgb(0, 0, 0)",
|
||||
foo: null,
|
||||
textContent: "\n This is text.\n This is a link with text.\n \n\n\n",
|
||||
};
|
||||
|
||||
/** Tests browser.scripting.insertCSS and browser.scripting.removeCSS. */
|
||||
add_task(async function testInsertRemoveCSS() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const [tab] = await browser.tabs.query({ active: true });
|
||||
|
||||
await browser.scripting.insertCSS({
|
||||
target: { tabId: tab.id },
|
||||
css: "body { background-color: lime; }",
|
||||
});
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.removeCSS({
|
||||
target: { tabId: tab.id },
|
||||
css: "body { background-color: lime; }",
|
||||
});
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.insertCSS({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.css"],
|
||||
});
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.removeCSS({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.css"],
|
||||
});
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.css": "body { background-color: green; }",
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["scripting"],
|
||||
host_permissions: ["*://mochi.test/*"],
|
||||
},
|
||||
});
|
||||
|
||||
const tab = window.openContentTab(CONTENT_PAGE);
|
||||
await awaitBrowserLoaded(tab.browser, CONTENT_PAGE);
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitMessage(); // insertCSS with code
|
||||
await checkContent(tab.browser, { backgroundColor: "rgb(0, 255, 0)" });
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitMessage(); // removeCSS with code
|
||||
await checkContent(tab.browser, UNCHANGED_VALUES);
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitMessage(); // insertCSS with file
|
||||
await checkContent(tab.browser, { backgroundColor: "rgb(0, 128, 0)" });
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitFinish("finished"); // removeCSS with file
|
||||
await checkContent(tab.browser, UNCHANGED_VALUES);
|
||||
|
||||
await extension.unload();
|
||||
|
||||
document.getElementById("tabmail").closeTab(tab);
|
||||
});
|
||||
|
||||
/** Tests browser.scripting.insertCSS fails without the host permission. */
|
||||
add_task(async function testInsertRemoveCSSNoHostPermissions() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const [tab] = await browser.tabs.query({ active: true });
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.scripting.insertCSS({
|
||||
target: { tabId: tab.id },
|
||||
css: "body { background-color: darkred; }",
|
||||
}),
|
||||
/Missing host permission for the tab/,
|
||||
"insertCSS without permission should throw"
|
||||
);
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.scripting.insertCSS({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.css"],
|
||||
}),
|
||||
/Missing host permission for the tab/,
|
||||
"insertCSS without permission should throw"
|
||||
);
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.scripting.insertCSS({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.css"],
|
||||
}),
|
||||
/Missing host permission for the tab/,
|
||||
"insertCSS without permission should throw"
|
||||
);
|
||||
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.css": "body { background-color: red; }",
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["scripting"],
|
||||
},
|
||||
});
|
||||
|
||||
const tab = window.openContentTab(CONTENT_PAGE);
|
||||
await awaitBrowserLoaded(tab.browser, CONTENT_PAGE);
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await checkContent(tab.browser, UNCHANGED_VALUES);
|
||||
|
||||
await extension.unload();
|
||||
|
||||
document.getElementById("tabmail").closeTab(tab);
|
||||
});
|
||||
|
||||
/** Tests browser.scripting.executeScript. */
|
||||
add_task(async function testExecuteScript() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const [tab] = await browser.tabs.query({ active: true });
|
||||
|
||||
await browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
func: () => {
|
||||
document.body.setAttribute("foo", "bar");
|
||||
},
|
||||
});
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.js"],
|
||||
});
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.js": () => {
|
||||
document.body.textContent = "Hey look, the script ran!";
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["scripting"],
|
||||
host_permissions: ["*://mochi.test/*"],
|
||||
},
|
||||
});
|
||||
|
||||
const tab = window.openContentTab(CONTENT_PAGE);
|
||||
await awaitBrowserLoaded(tab.browser, CONTENT_PAGE);
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitMessage(); // executeScript with code
|
||||
await checkContent(tab.browser, { foo: "bar" });
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitFinish("finished"); // executeScript with file
|
||||
await checkContent(tab.browser, {
|
||||
foo: "bar",
|
||||
textContent: "Hey look, the script ran!",
|
||||
});
|
||||
|
||||
await extension.unload();
|
||||
|
||||
document.getElementById("tabmail").closeTab(tab);
|
||||
});
|
||||
|
||||
/** Tests browser.scripting.executeScript fails without the host permission. */
|
||||
add_task(async function testExecuteScriptNoHostPermissions() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const [tab] = await browser.tabs.query({ active: true });
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
func: () => {
|
||||
document.body.setAttribute("foo", "bar");
|
||||
},
|
||||
}),
|
||||
/Missing host permission for the tab/,
|
||||
"executeScript without permission should throw"
|
||||
);
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.js"],
|
||||
}),
|
||||
/Missing host permission for the tab/,
|
||||
"executeScript without permission should throw"
|
||||
);
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.js"],
|
||||
}),
|
||||
/Missing host permission for the tab/,
|
||||
"executeScript without permission should throw"
|
||||
);
|
||||
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.js": () => {
|
||||
document.body.textContent = "Hey look, the script ran!";
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["scripting"],
|
||||
},
|
||||
});
|
||||
|
||||
const tab = window.openContentTab(CONTENT_PAGE);
|
||||
await awaitBrowserLoaded(tab.browser, CONTENT_PAGE);
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await checkContent(tab.browser, UNCHANGED_VALUES);
|
||||
|
||||
await extension.unload();
|
||||
|
||||
document.getElementById("tabmail").closeTab(tab);
|
||||
});
|
||||
|
||||
/** Tests the messenger alias is available. */
|
||||
add_task(async function testExecuteScriptAlias() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const [tab] = await browser.tabs.query({ active: true });
|
||||
|
||||
await browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
func: () => {
|
||||
// eslint-disable-next-line no-undef
|
||||
const id = messenger.runtime.getManifest().applications.gecko.id;
|
||||
document.body.textContent = id;
|
||||
},
|
||||
});
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
browser_specific_settings: { gecko: { id: "content_scripts@mochitest" } },
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["scripting"],
|
||||
host_permissions: ["*://mochi.test/*"],
|
||||
},
|
||||
});
|
||||
|
||||
const tab = window.openContentTab(CONTENT_PAGE);
|
||||
await awaitBrowserLoaded(tab.browser, CONTENT_PAGE);
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await checkContent(tab.browser, { textContent: "content_scripts@mochitest" });
|
||||
|
||||
await extension.unload();
|
||||
|
||||
document.getElementById("tabmail").closeTab(tab);
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests browser.contentScripts.register correctly adds CSS and JavaScript to
|
||||
* message composition windows opened after it was called. Also tests calling
|
||||
* `unregister` on the returned object.
|
||||
*/
|
||||
add_task(async function testRegister() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
await browser.scripting.registerContentScripts([
|
||||
{
|
||||
id: "test",
|
||||
css: ["test.css"],
|
||||
js: ["test.js"],
|
||||
matches: ["*://mochi.test/*"],
|
||||
},
|
||||
]);
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.unregisterContentScripts();
|
||||
await window.sendMessage();
|
||||
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.css": "body { color: white; background-color: green; }",
|
||||
"test.js": () => {
|
||||
document.body.setAttribute("foo", "bar");
|
||||
document.body.textContent = "Hey look, the script ran!";
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["scripting"],
|
||||
host_permissions: ["*://mochi.test/*"],
|
||||
},
|
||||
});
|
||||
|
||||
// Tab 1: loads before the script is registered.
|
||||
const tab1 = window.openContentTab(CONTENT_PAGE + "?tab1");
|
||||
await awaitBrowserLoaded(tab1.browser, CONTENT_PAGE + "?tab1");
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitMessage(); // register
|
||||
// Registering a script will not inject it into already open tabs, wait a moment
|
||||
// to make sure we still get the unchanged values.
|
||||
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
await checkContent(tab1.browser, UNCHANGED_VALUES);
|
||||
|
||||
// Tab 2: loads after the script is registered.
|
||||
const tab2 = window.openContentTab(CONTENT_PAGE + "?tab2");
|
||||
await awaitBrowserLoaded(tab2.browser, CONTENT_PAGE + "?tab2");
|
||||
await checkContent(tab2.browser, {
|
||||
backgroundColor: "rgb(0, 128, 0)",
|
||||
color: "rgb(255, 255, 255)",
|
||||
foo: "bar",
|
||||
textContent: "Hey look, the script ran!",
|
||||
});
|
||||
|
||||
extension.sendMessage();
|
||||
await extension.awaitMessage(); // unregister
|
||||
|
||||
await checkContent(tab2.browser, {
|
||||
backgroundColor: "rgb(0, 128, 0)",
|
||||
color: "rgb(255, 255, 255)",
|
||||
foo: "bar",
|
||||
textContent: "Hey look, the script ran!",
|
||||
});
|
||||
|
||||
// Tab 3: loads after the script is unregistered.
|
||||
const tab3 = window.openContentTab(CONTENT_PAGE + "?tab3");
|
||||
await awaitBrowserLoaded(tab3.browser, CONTENT_PAGE + "?tab3");
|
||||
await checkContent(tab3.browser, UNCHANGED_VALUES);
|
||||
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await extension.unload();
|
||||
|
||||
// Tab 2 should have the CSS removed.
|
||||
await checkContent(tab2.browser, {
|
||||
backgroundColor: UNCHANGED_VALUES.backgroundColor,
|
||||
color: UNCHANGED_VALUES.color,
|
||||
foo: "bar",
|
||||
textContent: "Hey look, the script ran!",
|
||||
});
|
||||
|
||||
const tabmail = document.getElementById("tabmail");
|
||||
tabmail.closeOtherTabs(tabmail.tabInfo[0]);
|
||||
});
|
||||
|
||||
/** Tests content_scripts in the manifest with permission work. */
|
||||
add_task(async function testManifest() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"test.css": "body { background-color: lime; }",
|
||||
"test.js": () => {
|
||||
document.body.textContent = "Hey look, the script ran!";
|
||||
},
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
content_scripts: [
|
||||
{
|
||||
matches: ["<all_urls>"],
|
||||
css: ["test.css"],
|
||||
js: ["test.js"],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
// Tab 1: loads before the script is registered.
|
||||
const tab1 = window.openContentTab(CONTENT_PAGE + "?tab1");
|
||||
await awaitBrowserLoaded(tab1.browser, CONTENT_PAGE + "?tab1");
|
||||
|
||||
// The extension is not running, no script should be injected, wait a moment to
|
||||
// make sure we still get the unchanged values.
|
||||
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
await checkContent(tab1.browser, UNCHANGED_VALUES);
|
||||
|
||||
await extension.startup();
|
||||
|
||||
// The extension started and the content script defined in the manifest should
|
||||
// be injected into the already open tab.
|
||||
await checkContent(tab1.browser, {
|
||||
backgroundColor: "rgb(0, 255, 0)",
|
||||
textContent: "Hey look, the script ran!",
|
||||
});
|
||||
|
||||
// Tab 2: loads after the script is registered.
|
||||
const tab2 = window.openContentTab(CONTENT_PAGE + "?tab2");
|
||||
await awaitBrowserLoaded(tab2.browser, CONTENT_PAGE + "?tab2");
|
||||
await checkContent(tab2.browser, {
|
||||
backgroundColor: "rgb(0, 255, 0)",
|
||||
textContent: "Hey look, the script ran!",
|
||||
});
|
||||
|
||||
await extension.unload();
|
||||
|
||||
// Tab 2 should have the CSS removed.
|
||||
await checkContent(tab2.browser, {
|
||||
backgroundColor: UNCHANGED_VALUES.backgroundColor,
|
||||
textContent: "Hey look, the script ran!",
|
||||
});
|
||||
|
||||
const tabmail = document.getElementById("tabmail");
|
||||
tabmail.closeOtherTabs(tabmail.tabInfo[0]);
|
||||
});
|
||||
|
||||
/** Tests content_scripts match patterns in the manifest. */
|
||||
add_task(async function testManifestNoPermissions() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"test.css": "body { background-color: red; }",
|
||||
"test.js": () => {
|
||||
document.body.textContent = "Hey look, the script ran!";
|
||||
},
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
content_scripts: [
|
||||
{
|
||||
matches: ["*://example.org/*"],
|
||||
css: ["test.css"],
|
||||
js: ["test.js"],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
|
||||
const tab = window.openContentTab(CONTENT_PAGE);
|
||||
await awaitBrowserLoaded(tab.browser, CONTENT_PAGE);
|
||||
await checkContent(tab.browser, UNCHANGED_VALUES);
|
||||
|
||||
await extension.unload();
|
||||
|
||||
document.getElementById("tabmail").closeTab(tab);
|
||||
});
|
|
@ -0,0 +1,920 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
let account, messages;
|
||||
let tabmail, about3Pane, messagePane;
|
||||
|
||||
add_setup(async () => {
|
||||
account = createAccount();
|
||||
const rootFolder = account.incomingServer.rootFolder;
|
||||
rootFolder.createSubfolder("messageDisplayScripts", null);
|
||||
const folder = rootFolder.getChildNamed("messageDisplayScripts");
|
||||
createMessages(folder, 11);
|
||||
messages = [...folder.messages];
|
||||
|
||||
tabmail = document.getElementById("tabmail");
|
||||
about3Pane = tabmail.currentTabInfo.chromeBrowser.contentWindow;
|
||||
about3Pane.displayFolder(folder.URI);
|
||||
messagePane =
|
||||
about3Pane.messageBrowser.contentDocument.getElementById("messagepane");
|
||||
});
|
||||
|
||||
async function checkMessageBody(expected, message, browser) {
|
||||
if (message && "textContent" in expected) {
|
||||
let body = await new Promise(resolve => {
|
||||
window.MsgHdrToMimeMessage(message, null, (msgHdr, mimeMessage) => {
|
||||
resolve(mimeMessage.parts[0].body);
|
||||
});
|
||||
});
|
||||
// Ignore Windows line-endings, they're not important here.
|
||||
body = body.replace(/\r/g, "");
|
||||
expected.textContent = body + expected.textContent;
|
||||
}
|
||||
if (!browser) {
|
||||
browser = messagePane;
|
||||
}
|
||||
|
||||
await checkContent(browser, expected);
|
||||
}
|
||||
|
||||
/** Tests browser.scripting.insertCSS and browser.scripting.removeCSS. */
|
||||
add_task(async function testInsertRemoveCSSViaScriptingAPI() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const [tab] = await browser.tabs.query({ type: ["mail"] });
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.insertCSS({
|
||||
target: { tabId: tab.id },
|
||||
css: "body { background-color: lime; }",
|
||||
});
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.removeCSS({
|
||||
target: { tabId: tab.id },
|
||||
css: "body { background-color: lime; }",
|
||||
});
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.insertCSS({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.css"],
|
||||
});
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.removeCSS({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.css"],
|
||||
});
|
||||
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.css": "body { background-color: green; }",
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["messagesModify", "scripting"],
|
||||
},
|
||||
});
|
||||
|
||||
about3Pane.threadTree.selectedIndex = 2;
|
||||
await awaitBrowserLoaded(messagePane);
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkMessageBody(
|
||||
{ backgroundColor: "rgba(0, 0, 0, 0)" },
|
||||
messages.at(-3)
|
||||
);
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkMessageBody(
|
||||
{ backgroundColor: "rgb(0, 255, 0)" },
|
||||
messages.at(-3)
|
||||
);
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkMessageBody(
|
||||
{ backgroundColor: "rgba(0, 0, 0, 0)" },
|
||||
messages.at(-3)
|
||||
);
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkMessageBody(
|
||||
{ backgroundColor: "rgb(0, 128, 0)" },
|
||||
messages.at(-3)
|
||||
);
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await checkMessageBody(
|
||||
{ backgroundColor: "rgba(0, 0, 0, 0)" },
|
||||
messages.at(-3)
|
||||
);
|
||||
|
||||
await extension.unload();
|
||||
});
|
||||
|
||||
/** Tests browser.scripting.insertCSS fails without the "messagesModify" permission. */
|
||||
add_task(async function testInsertRemoveCSSNoHostPermissions() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const [tab] = await browser.tabs.query({ type: ["mail"] });
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.scripting.insertCSS({
|
||||
target: { tabId: tab.id },
|
||||
css: "body { background-color: darkred; }",
|
||||
}),
|
||||
/Missing host permission for the tab/,
|
||||
"insertCSS without permission should throw"
|
||||
);
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.scripting.insertCSS({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.css"],
|
||||
}),
|
||||
/Missing host permission for the tab/,
|
||||
"insertCSS without permission should throw"
|
||||
);
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.scripting.insertCSS({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.css"],
|
||||
}),
|
||||
/Missing host permission for the tab/,
|
||||
"insertCSS without permission should throw"
|
||||
);
|
||||
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.css": "body { background-color: red; }",
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["scripting"],
|
||||
},
|
||||
});
|
||||
|
||||
about3Pane.threadTree.selectedIndex = 1;
|
||||
await awaitBrowserLoaded(messagePane);
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await checkMessageBody(
|
||||
{
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
textContent: "",
|
||||
},
|
||||
messages.at(-2)
|
||||
);
|
||||
|
||||
await extension.unload();
|
||||
});
|
||||
|
||||
/** Tests browser.scripting.executeScript. */
|
||||
add_task(async function testExecuteScript() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const [tab] = await browser.tabs.query({ type: ["mail"] });
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
func: () => {
|
||||
document.body.setAttribute("foo", "bar");
|
||||
},
|
||||
});
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.js"],
|
||||
});
|
||||
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.js": () => {
|
||||
document.body.querySelector(".moz-text-flowed").textContent +=
|
||||
"Hey look, the script ran!";
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["messagesModify", "scripting"],
|
||||
},
|
||||
});
|
||||
|
||||
about3Pane.threadTree.selectedIndex = 2;
|
||||
await awaitBrowserLoaded(messagePane);
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkMessageBody({ textContent: "" }, messages.at(-3));
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkMessageBody({ foo: "bar" }, messages.at(-3));
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await checkMessageBody(
|
||||
{
|
||||
foo: "bar",
|
||||
textContent: "Hey look, the script ran!",
|
||||
},
|
||||
messages.at(-3)
|
||||
);
|
||||
|
||||
await extension.unload();
|
||||
});
|
||||
|
||||
/** Tests browser.scripting.executeScript fails without the "messagesModify" permission. */
|
||||
add_task(async function testExecuteScriptNoHostPermissions() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const [tab] = await browser.tabs.query({ type: ["mail"] });
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
func: () => {
|
||||
document.body.setAttribute("foo", "bar");
|
||||
},
|
||||
}),
|
||||
/Missing host permission for the tab/,
|
||||
"executeScript without permission should throw"
|
||||
);
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.js"],
|
||||
}),
|
||||
/Missing host permission for the tab/,
|
||||
"executeScript without permission should throw"
|
||||
);
|
||||
|
||||
await browser.test.assertRejects(
|
||||
browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
files: ["test.js"],
|
||||
}),
|
||||
/Missing host permission for the tab/,
|
||||
"executeScript without permission should throw"
|
||||
);
|
||||
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.js": () => {
|
||||
document.body.querySelector(".moz-text-flowed").textContent +=
|
||||
"Hey look, the script ran!";
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["scripting"],
|
||||
},
|
||||
});
|
||||
|
||||
about3Pane.threadTree.selectedIndex = 3;
|
||||
await awaitBrowserLoaded(messagePane);
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await checkMessageBody({ foo: null, textContent: "" }, messages.at(-4));
|
||||
|
||||
await extension.unload();
|
||||
});
|
||||
|
||||
/** Tests the messenger alias is available. */
|
||||
add_task(async function testExecuteScriptAlias() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
const [tab] = await browser.tabs.query({ type: ["mail"] });
|
||||
await window.sendMessage();
|
||||
|
||||
await browser.scripting.executeScript({
|
||||
target: { tabId: tab.id },
|
||||
func: () => {
|
||||
// eslint-disable-next-line no-undef
|
||||
const id = messenger.runtime.getManifest().applications.gecko.id;
|
||||
document.body.querySelector(".moz-text-flowed").textContent += id;
|
||||
},
|
||||
});
|
||||
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
browser_specific_settings: {
|
||||
gecko: { id: "message_display_scripts@mochitest" },
|
||||
},
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["messagesModify", "scripting"],
|
||||
},
|
||||
});
|
||||
|
||||
about3Pane.threadTree.selectedIndex = 3;
|
||||
await awaitBrowserLoaded(messagePane);
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitMessage();
|
||||
await checkMessageBody({ textContent: "" }, messages.at(-4));
|
||||
extension.sendMessage();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await checkMessageBody(
|
||||
{ textContent: "message_display_scripts@mochitest" },
|
||||
messages.at(-4)
|
||||
);
|
||||
|
||||
await extension.unload();
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests browser.messageDisplayScripts.register correctly adds CSS and
|
||||
* JavaScript to message display windows. Also tests calling `unregister`
|
||||
* on the returned object.
|
||||
*/
|
||||
add_task(async function testRegister() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
// Keep track of registered scrips being executed and ready.
|
||||
browser.runtime.onMessage.addListener((message, sender) => {
|
||||
if (message == "LOADED") {
|
||||
window.sendMessage("ScriptLoaded", sender.tab.id);
|
||||
}
|
||||
});
|
||||
|
||||
const registeredScript = await browser.messageDisplayScripts.register({
|
||||
css: [{ code: "body { color: white }" }, { file: "test.css" }],
|
||||
js: [
|
||||
{ code: `document.body.setAttribute("foo", "bar");` },
|
||||
{ file: "test.js" },
|
||||
],
|
||||
});
|
||||
|
||||
browser.test.onMessage.addListener(async (message, data) => {
|
||||
switch (message) {
|
||||
case "Unregister":
|
||||
await registeredScript.unregister();
|
||||
browser.test.notifyPass("finished");
|
||||
break;
|
||||
|
||||
case "RuntimeMessageTest":
|
||||
try {
|
||||
browser.test.assertEq(
|
||||
`Received: ${data.tabId}`,
|
||||
await browser.tabs.sendMessage(data.tabId, data.tabId)
|
||||
);
|
||||
} catch (ex) {
|
||||
browser.test.fail(
|
||||
`Failed to send message to messageDisplayScript: ${ex}`
|
||||
);
|
||||
}
|
||||
browser.test.sendMessage("RuntimeMessageTestDone");
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
window.sendMessage("Ready");
|
||||
},
|
||||
"test.css": "body { background-color: green; }",
|
||||
"test.js": () => {
|
||||
document.body.querySelector(".moz-text-flowed").textContent +=
|
||||
"Hey look, the script ran!";
|
||||
browser.runtime.onMessage.addListener(async message => {
|
||||
return `Received: ${message}`;
|
||||
});
|
||||
browser.runtime.sendMessage("LOADED");
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["messagesModify", "scripting"],
|
||||
host_permissions: ["<all_urls>"],
|
||||
},
|
||||
});
|
||||
|
||||
about3Pane.threadTree.selectedIndex = 5;
|
||||
await awaitBrowserLoaded(messagePane);
|
||||
|
||||
extension.startup();
|
||||
await extension.awaitMessage("Ready");
|
||||
|
||||
// Check a message that was already loaded. This tab has not loaded the
|
||||
// registered scripts.
|
||||
await checkMessageBody(
|
||||
{
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
textContent: "",
|
||||
},
|
||||
messages.at(-6)
|
||||
);
|
||||
|
||||
// Load a new message and check it is modified.
|
||||
let loadPromise = extension.awaitMessage("ScriptLoaded");
|
||||
about3Pane.threadTree.selectedIndex = 6;
|
||||
const tabId = await loadPromise;
|
||||
|
||||
await checkMessageBody(
|
||||
{
|
||||
backgroundColor: "rgb(0, 128, 0)",
|
||||
color: "rgb(255, 255, 255)",
|
||||
foo: "bar",
|
||||
textContent: "Hey look, the script ran!",
|
||||
},
|
||||
messages.at(-7)
|
||||
);
|
||||
// Check runtime messaging.
|
||||
let testDonePromise = extension.awaitMessage("RuntimeMessageTestDone");
|
||||
extension.sendMessage("RuntimeMessageTest", { tabId });
|
||||
await testDonePromise;
|
||||
|
||||
// Open the message in a new tab.
|
||||
loadPromise = extension.awaitMessage("ScriptLoaded");
|
||||
const messageTab = await openMessageInTab(messages.at(-7));
|
||||
const messageTabId = await loadPromise;
|
||||
Assert.equal(tabmail.tabInfo.length, 2);
|
||||
|
||||
await checkMessageBody(
|
||||
{
|
||||
backgroundColor: "rgb(0, 128, 0)",
|
||||
color: "rgb(255, 255, 255)",
|
||||
foo: "bar",
|
||||
textContent: "Hey look, the script ran!",
|
||||
},
|
||||
messages.at(-7),
|
||||
messageTab.browser
|
||||
);
|
||||
// Check runtime messaging.
|
||||
testDonePromise = extension.awaitMessage("RuntimeMessageTestDone");
|
||||
extension.sendMessage("RuntimeMessageTest", { tabId: messageTabId });
|
||||
await testDonePromise;
|
||||
|
||||
// Open a content tab. The CSS and script shouldn't apply.
|
||||
const contentTab = window.openContentTab("http://mochi.test:8888/");
|
||||
// Let's wait a while and see if anything happens:
|
||||
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
await checkMessageBody(
|
||||
{
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
color: "rgb(0, 0, 0)",
|
||||
foo: null,
|
||||
},
|
||||
undefined,
|
||||
contentTab.browser
|
||||
);
|
||||
|
||||
// Closing this tab should bring us back to the message in a tab.
|
||||
tabmail.closeTab(contentTab);
|
||||
Assert.equal(tabmail.currentTabInfo, messageTab);
|
||||
await checkMessageBody(
|
||||
{
|
||||
backgroundColor: "rgb(0, 128, 0)",
|
||||
color: "rgb(255, 255, 255)",
|
||||
foo: "bar",
|
||||
textContent: "Hey look, the script ran!",
|
||||
},
|
||||
messages.at(-7),
|
||||
messageTab.browser
|
||||
);
|
||||
// Check runtime messaging.
|
||||
testDonePromise = extension.awaitMessage("RuntimeMessageTestDone");
|
||||
extension.sendMessage("RuntimeMessageTest", { tabId: messageTabId });
|
||||
await testDonePromise;
|
||||
|
||||
// Open the message in a new window.
|
||||
loadPromise = extension.awaitMessage("ScriptLoaded");
|
||||
const newWindow = await openMessageInWindow(messages.at(-8));
|
||||
const newWindowMessagePane = newWindow.getBrowser();
|
||||
const windowTabId = await loadPromise;
|
||||
|
||||
await checkMessageBody(
|
||||
{
|
||||
backgroundColor: "rgb(0, 128, 0)",
|
||||
color: "rgb(255, 255, 255)",
|
||||
foo: "bar",
|
||||
textContent: "Hey look, the script ran!",
|
||||
},
|
||||
messages.at(-8),
|
||||
newWindowMessagePane
|
||||
);
|
||||
// Check runtime messaging.
|
||||
testDonePromise = extension.awaitMessage("RuntimeMessageTestDone");
|
||||
extension.sendMessage("RuntimeMessageTest", { tabId: windowTabId });
|
||||
await testDonePromise;
|
||||
|
||||
// Unregister.
|
||||
extension.sendMessage("Unregister");
|
||||
await extension.awaitFinish("finished");
|
||||
await extension.unload();
|
||||
|
||||
// Check the CSS is unloaded from the message in a tab.
|
||||
await checkMessageBody(
|
||||
{
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
color: "rgb(0, 0, 0)",
|
||||
foo: "bar",
|
||||
textContent: "Hey look, the script ran!",
|
||||
},
|
||||
messages.at(-7),
|
||||
messageTab.browser
|
||||
);
|
||||
|
||||
// Close the new tab.
|
||||
tabmail.closeTab(messageTab);
|
||||
|
||||
await checkMessageBody(
|
||||
{
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
color: "rgb(0, 0, 0)",
|
||||
foo: "bar",
|
||||
textContent: "Hey look, the script ran!",
|
||||
},
|
||||
messages.at(-7)
|
||||
);
|
||||
|
||||
// Check the CSS is unloaded from the message in a window.
|
||||
await checkMessageBody(
|
||||
{
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
color: "rgb(0, 0, 0)",
|
||||
foo: "bar",
|
||||
textContent: "Hey look, the script ran!",
|
||||
},
|
||||
messages.at(-8),
|
||||
newWindowMessagePane
|
||||
);
|
||||
|
||||
await BrowserTestUtils.closeWindow(newWindow);
|
||||
});
|
||||
|
||||
/** Tests content_scripts in the manifest do not affect message display. */
|
||||
async function subtestContentScriptManifest(message, permissions) {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"test.css": "body { background-color: red; }",
|
||||
"test.js": () => {
|
||||
document.body.textContent += "Hey look, the script ran!";
|
||||
},
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
permissions,
|
||||
content_scripts: [
|
||||
{
|
||||
matches: ["<all_urls>"],
|
||||
css: ["test.css"],
|
||||
js: ["test.js"],
|
||||
match_about_blank: true,
|
||||
match_origin_as_fallback: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
// match_origin_as_fallback is not implemented yet. Bug 1475831.
|
||||
ExtensionTestUtils.failOnSchemaWarnings(false);
|
||||
await extension.startup();
|
||||
ExtensionTestUtils.failOnSchemaWarnings(true);
|
||||
|
||||
await checkMessageBody(
|
||||
{
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
textContent: "",
|
||||
},
|
||||
message
|
||||
);
|
||||
|
||||
await extension.unload();
|
||||
}
|
||||
|
||||
add_task(async function testContentScriptManifestNoPermission() {
|
||||
about3Pane.threadTree.selectedIndex = 7;
|
||||
await awaitBrowserLoaded(messagePane);
|
||||
await subtestContentScriptManifest(messages.at(-8));
|
||||
});
|
||||
add_task(async function testContentScriptManifest() {
|
||||
about3Pane.threadTree.selectedIndex = 8;
|
||||
await awaitBrowserLoaded(messagePane);
|
||||
await subtestContentScriptManifest(messages.at(-9), ["messagesModify"]);
|
||||
});
|
||||
|
||||
/** Tests registered content scripts do not affect message display. */
|
||||
async function subtestContentScriptRegister(message, permissions) {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
await browser.scripting.registerContentScripts([
|
||||
{
|
||||
id: "test",
|
||||
matches: ["<all_urls>"],
|
||||
css: ["test.css"],
|
||||
js: ["test.js"],
|
||||
},
|
||||
]);
|
||||
|
||||
browser.test.notifyPass("finished");
|
||||
},
|
||||
"test.css": "body { background-color: red; }",
|
||||
"test.js": () => {
|
||||
document.body.querySelector(".moz-text-flowed").textContent +=
|
||||
"Hey look, the script ran!";
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions,
|
||||
host_permissions: ["<all_urls>"],
|
||||
},
|
||||
});
|
||||
|
||||
await extension.startup();
|
||||
|
||||
await extension.awaitFinish("finished");
|
||||
await checkMessageBody(
|
||||
{
|
||||
backgroundColor: "rgba(0, 0, 0, 0)",
|
||||
textContent: "",
|
||||
},
|
||||
message
|
||||
);
|
||||
|
||||
await extension.unload();
|
||||
}
|
||||
|
||||
add_task(async function testContentScriptRegisterNoPermission() {
|
||||
about3Pane.threadTree.selectedIndex = 9;
|
||||
await awaitBrowserLoaded(messagePane);
|
||||
await subtestContentScriptRegister(messages.at(-10), ["scripting"]);
|
||||
});
|
||||
add_task(async function testContentScriptRegister() {
|
||||
about3Pane.threadTree.selectedIndex = 10;
|
||||
await awaitBrowserLoaded(messagePane);
|
||||
await subtestContentScriptRegister(messages.at(-11), [
|
||||
"scripting",
|
||||
"messagesModify",
|
||||
]);
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests if scripts are correctly injected according to their runAt option.
|
||||
*/
|
||||
add_task(async function testRunAt() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
files: {
|
||||
"background.js": async () => {
|
||||
// Report script results.
|
||||
browser.runtime.onMessage.addListener((message, sender) => {
|
||||
if (message?.runAt) {
|
||||
window.sendMessage(`ScriptLoaded:${message.runAt}`, {
|
||||
senderTabId: sender.tab.id,
|
||||
...message,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const registeredScripts = new Set();
|
||||
registeredScripts.add(
|
||||
await browser.messageDisplayScripts.register({
|
||||
runAt: "document_start",
|
||||
js: [{ file: "start.js" }],
|
||||
})
|
||||
);
|
||||
|
||||
registeredScripts.add(
|
||||
await browser.messageDisplayScripts.register({
|
||||
runAt: "document_end",
|
||||
js: [{ file: "end.js" }],
|
||||
})
|
||||
);
|
||||
|
||||
registeredScripts.add(
|
||||
await browser.messageDisplayScripts.register({
|
||||
runAt: "document_idle",
|
||||
js: [{ file: "idle.js" }],
|
||||
})
|
||||
);
|
||||
|
||||
browser.test.onMessage.addListener(async message => {
|
||||
switch (message) {
|
||||
case "Unregister":
|
||||
for (const registeredScript of registeredScripts) {
|
||||
await registeredScript.unregister();
|
||||
}
|
||||
browser.test.notifyPass("finished");
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
browser.test.sendMessage("Ready");
|
||||
},
|
||||
"start.js": () => {
|
||||
browser.runtime.sendMessage({
|
||||
runAt: "document_start",
|
||||
readyState: document?.readyState,
|
||||
document: !!document,
|
||||
body: !!document?.body,
|
||||
textContent:
|
||||
document.querySelector(".moz-text-flowed")?.textContent ?? "",
|
||||
});
|
||||
},
|
||||
"end.js": () => {
|
||||
browser.runtime.sendMessage({
|
||||
runAt: "document_end",
|
||||
readyState: document?.readyState,
|
||||
document: !!document,
|
||||
body: !!document?.body,
|
||||
textContent:
|
||||
document.querySelector(".moz-text-flowed")?.textContent ?? "",
|
||||
});
|
||||
},
|
||||
"idle.js": () => {
|
||||
browser.runtime.sendMessage({
|
||||
runAt: "document_idle",
|
||||
readyState: document?.readyState,
|
||||
document: !!document,
|
||||
body: !!document?.body,
|
||||
textContent:
|
||||
document.querySelector(".moz-text-flowed")?.textContent ?? "",
|
||||
});
|
||||
},
|
||||
"utils.js": await getUtilsJS(),
|
||||
},
|
||||
manifest: {
|
||||
manifest_version: 3,
|
||||
background: { scripts: ["utils.js", "background.js"] },
|
||||
permissions: ["messagesModify", "scripting"],
|
||||
host_permissions: ["<all_urls>"],
|
||||
},
|
||||
});
|
||||
|
||||
about3Pane.threadTree.selectedIndex = 2;
|
||||
await awaitBrowserLoaded(messagePane);
|
||||
|
||||
extension.startup();
|
||||
await extension.awaitMessage("Ready");
|
||||
|
||||
function verifyResult(result, expected_individual) {
|
||||
const expected_standard = [
|
||||
{
|
||||
runAt: "document_start",
|
||||
readyState: "loading",
|
||||
document: true,
|
||||
body: false,
|
||||
},
|
||||
{
|
||||
runAt: "document_end",
|
||||
readyState: "interactive",
|
||||
document: true,
|
||||
body: true,
|
||||
},
|
||||
{
|
||||
runAt: "document_idle",
|
||||
readyState: "complete",
|
||||
document: true,
|
||||
body: true,
|
||||
},
|
||||
];
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
Assert.equal(
|
||||
expected_standard[i].runAt,
|
||||
result[i].runAt,
|
||||
`The 'runAt' value for state #${i} should be correct`
|
||||
);
|
||||
Assert.equal(
|
||||
expected_standard[i].readyState,
|
||||
result[i].readyState,
|
||||
`The 'readyState' value at state #${i} should be correct`
|
||||
);
|
||||
Assert.equal(
|
||||
expected_standard[i].document,
|
||||
result[i].document,
|
||||
`The document element at state #${i} ${
|
||||
expected_standard[i].document ? "should" : "should not"
|
||||
} exist`
|
||||
);
|
||||
Assert.equal(
|
||||
expected_standard[i].body,
|
||||
result[i].body,
|
||||
`The body element at state #${i} ${
|
||||
expected_standard[i].body ? "should" : "should not"
|
||||
} exist`
|
||||
);
|
||||
Assert.equal(
|
||||
expected_individual[i].textContent.trim(),
|
||||
result[i].textContent.trim(),
|
||||
`The content at state #${i} should be correct`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Select a new message.
|
||||
const firstLoadPromise = Promise.all([
|
||||
extension.awaitMessage("ScriptLoaded:document_start"),
|
||||
extension.awaitMessage("ScriptLoaded:document_end"),
|
||||
extension.awaitMessage("ScriptLoaded:document_idle"),
|
||||
]);
|
||||
about3Pane.threadTree.selectedIndex = 3;
|
||||
verifyResult(await firstLoadPromise, [
|
||||
{ textContent: "" },
|
||||
{ textContent: "Hello Pete Price!" },
|
||||
{ textContent: "Hello Pete Price!" },
|
||||
]);
|
||||
|
||||
// Select a different message.
|
||||
const secondLoadPromise = Promise.all([
|
||||
extension.awaitMessage("ScriptLoaded:document_start"),
|
||||
extension.awaitMessage("ScriptLoaded:document_end"),
|
||||
extension.awaitMessage("ScriptLoaded:document_idle"),
|
||||
]);
|
||||
about3Pane.threadTree.selectedIndex = 4;
|
||||
verifyResult(await secondLoadPromise, [
|
||||
{ textContent: "" },
|
||||
{ textContent: "Hello Neil Nagel!" },
|
||||
{ textContent: "Hello Neil Nagel!" },
|
||||
]);
|
||||
|
||||
// Open the message in a new tab.
|
||||
const thirdLoadPromise = Promise.all([
|
||||
extension.awaitMessage("ScriptLoaded:document_start"),
|
||||
extension.awaitMessage("ScriptLoaded:document_end"),
|
||||
extension.awaitMessage("ScriptLoaded:document_idle"),
|
||||
]);
|
||||
const messageTab = await openMessageInTab(messages.at(-6));
|
||||
verifyResult(await thirdLoadPromise, [
|
||||
{ textContent: "" },
|
||||
{ textContent: "Hello Lilia Lowe!" },
|
||||
{ textContent: "Hello Lilia Lowe!" },
|
||||
]);
|
||||
Assert.equal(tabmail.tabInfo.length, 2);
|
||||
|
||||
// Open a content tab. The message display scripts should not be injected.
|
||||
// If they DO get injected, we will end up with 3 additional messages from the
|
||||
// extension and the test will fail.
|
||||
const contentTab = window.openContentTab("http://mochi.test:8888/");
|
||||
Assert.equal(tabmail.tabInfo.length, 3);
|
||||
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
// Closing this tab should bring us back to the message in a tab.
|
||||
tabmail.closeTab(contentTab);
|
||||
Assert.equal(tabmail.tabInfo.length, 2);
|
||||
Assert.equal(tabmail.currentTabInfo, messageTab);
|
||||
|
||||
// Open the message in a new window.
|
||||
const fourthLoadPromise = Promise.all([
|
||||
extension.awaitMessage("ScriptLoaded:document_start"),
|
||||
extension.awaitMessage("ScriptLoaded:document_end"),
|
||||
extension.awaitMessage("ScriptLoaded:document_idle"),
|
||||
]);
|
||||
const newWindow = await openMessageInWindow(messages.at(-7));
|
||||
verifyResult(await fourthLoadPromise, [
|
||||
{ textContent: "" },
|
||||
{ textContent: "Hello Johnny Jones!" },
|
||||
{ textContent: "Hello Johnny Jones!" },
|
||||
]);
|
||||
|
||||
// Unregister.
|
||||
extension.sendMessage("Unregister");
|
||||
await extension.awaitFinish("finished");
|
||||
await extension.unload();
|
||||
|
||||
// Close the new tab.
|
||||
tabmail.closeTab(messageTab);
|
||||
await BrowserTestUtils.closeWindow(newWindow);
|
||||
});
|
Загрузка…
Ссылка в новой задаче