From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../browser/browser_ext_messageDisplayScripts.js | 636 +++++++++++++++++++++ 1 file changed, 636 insertions(+) create mode 100644 comm/mail/components/extensions/test/browser/browser_ext_messageDisplayScripts.js (limited to 'comm/mail/components/extensions/test/browser/browser_ext_messageDisplayScripts.js') diff --git a/comm/mail/components/extensions/test/browser/browser_ext_messageDisplayScripts.js b/comm/mail/components/extensions/test/browser/browser_ext_messageDisplayScripts.js new file mode 100644 index 0000000000..3f75bcb61c --- /dev/null +++ b/comm/mail/components/extensions/test/browser/browser_ext_messageDisplayScripts.js @@ -0,0 +1,636 @@ +/* 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(); + let rootFolder = account.incomingServer.rootFolder; + rootFolder.createSubfolder("messageDisplayScripts", null); + let 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.tabs.insertCSS and browser.tabs.removeCSS. */ +add_task(async function testInsertRemoveCSS() { + let extension = ExtensionTestUtils.loadExtension({ + files: { + "background.js": async () => { + let [tab] = await browser.tabs.query({ mailTab: true }); + await window.sendMessage(); + + await browser.tabs.insertCSS(tab.id, { + code: "body { background-color: lime; }", + }); + await window.sendMessage(); + + await browser.tabs.removeCSS(tab.id, { + code: "body { background-color: lime; }", + }); + await window.sendMessage(); + + await browser.tabs.insertCSS(tab.id, { file: "test.css" }); + await window.sendMessage(); + + await browser.tabs.removeCSS(tab.id, { file: "test.css" }); + + browser.test.notifyPass("finished"); + }, + "test.css": "body { background-color: green; }", + "utils.js": await getUtilsJS(), + }, + manifest: { + background: { scripts: ["utils.js", "background.js"] }, + permissions: ["messagesModify"], + }, + }); + + about3Pane.threadTree.selectedIndex = 0; + await awaitBrowserLoaded(messagePane); + + await extension.startup(); + + await extension.awaitMessage(); + await checkMessageBody({ backgroundColor: "rgba(0, 0, 0, 0)" }, messages[0]); + extension.sendMessage(); + + await extension.awaitMessage(); + await checkMessageBody({ backgroundColor: "rgb(0, 255, 0)" }, messages[0]); + extension.sendMessage(); + + await extension.awaitMessage(); + await checkMessageBody({ backgroundColor: "rgba(0, 0, 0, 0)" }, messages[0]); + extension.sendMessage(); + + await extension.awaitMessage(); + await checkMessageBody({ backgroundColor: "rgb(0, 128, 0)" }, messages[0]); + extension.sendMessage(); + + await extension.awaitFinish("finished"); + await checkMessageBody({ backgroundColor: "rgba(0, 0, 0, 0)" }, messages[0]); + + await extension.unload(); +}); + +/** Tests browser.tabs.insertCSS fails without the "messagesModify" permission. */ +add_task(async function testInsertRemoveCSSNoPermissions() { + let extension = ExtensionTestUtils.loadExtension({ + files: { + "background.js": async () => { + let [tab] = await browser.tabs.query({ mailTab: true }); + + await browser.test.assertRejects( + browser.tabs.insertCSS(tab.id, { + code: "body { background-color: darkred; }", + }), + /Missing host permission for the tab/, + "insertCSS without permission should throw" + ); + + await browser.test.assertRejects( + browser.tabs.insertCSS(tab.id, { file: "test.css" }), + /Missing host permission for the tab/, + "insertCSS without permission should throw" + ); + + await browser.test.assertRejects( + browser.tabs.insertCSS(tab.id, { + file: "test.css", + matchAboutBlank: true, + }), + /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: { + background: { scripts: ["utils.js", "background.js"] }, + permissions: [], + }, + }); + + about3Pane.threadTree.selectedIndex = 1; + await awaitBrowserLoaded(messagePane); + + await extension.startup(); + + await extension.awaitFinish("finished"); + await checkMessageBody( + { + backgroundColor: "rgba(0, 0, 0, 0)", + textContent: "", + }, + messages[1] + ); + + await extension.unload(); +}); + +/** Tests browser.tabs.executeScript. */ +add_task(async function testExecuteScript() { + let extension = ExtensionTestUtils.loadExtension({ + files: { + "background.js": async () => { + let [tab] = await browser.tabs.query({ mailTab: true }); + await window.sendMessage(); + + await browser.tabs.executeScript(tab.id, { + code: `document.body.setAttribute("foo", "bar");`, + }); + await window.sendMessage(); + + await browser.tabs.executeScript(tab.id, { file: "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: { + background: { scripts: ["utils.js", "background.js"] }, + permissions: ["messagesModify"], + }, + }); + + about3Pane.threadTree.selectedIndex = 2; + await awaitBrowserLoaded(messagePane); + + await extension.startup(); + + await extension.awaitMessage(); + await checkMessageBody({ textContent: "" }, messages[2]); + extension.sendMessage(); + + await extension.awaitMessage(); + await checkMessageBody({ foo: "bar" }, messages[2]); + extension.sendMessage(); + + await extension.awaitFinish("finished"); + await checkMessageBody( + { + foo: "bar", + textContent: "Hey look, the script ran!", + }, + messages[2] + ); + + await extension.unload(); +}); + +/** Tests browser.tabs.executeScript fails without the "messagesModify" permission. */ +add_task(async function testExecuteScriptNoPermissions() { + let extension = ExtensionTestUtils.loadExtension({ + files: { + "background.js": async () => { + let [tab] = await browser.tabs.query({ mailTab: true }); + + await browser.test.assertRejects( + browser.tabs.executeScript(tab.id, { + code: `document.body.setAttribute("foo", "bar");`, + }), + /Missing host permission for the tab/, + "executeScript without permission should throw" + ); + + await browser.test.assertRejects( + browser.tabs.executeScript(tab.id, { file: "test.js" }), + /Missing host permission for the tab/, + "executeScript without permission should throw" + ); + + await browser.test.assertRejects( + browser.tabs.executeScript(tab.id, { + file: "test.js", + matchAboutBlank: true, + }), + /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: { + background: { scripts: ["utils.js", "background.js"] }, + permissions: [], + }, + }); + + about3Pane.threadTree.selectedIndex = 3; + await awaitBrowserLoaded(messagePane); + + await extension.startup(); + + await extension.awaitFinish("finished"); + await checkMessageBody({ foo: null, textContent: "" }, messages[3]); + + await extension.unload(); +}); + +/** Tests the messenger alias is available. */ +add_task(async function testExecuteScriptAlias() { + let extension = ExtensionTestUtils.loadExtension({ + files: { + "background.js": async () => { + let [tab] = await browser.tabs.query({ mailTab: true }); + await window.sendMessage(); + + await browser.tabs.executeScript(tab.id, { + code: `document.body.querySelector(".moz-text-flowed").textContent += + messenger.runtime.getManifest().applications.gecko.id;`, + }); + + browser.test.notifyPass("finished"); + }, + "utils.js": await getUtilsJS(), + }, + manifest: { + applications: { gecko: { id: "message_display_scripts@mochitest" } }, + background: { scripts: ["utils.js", "background.js"] }, + permissions: ["messagesModify"], + }, + }); + + about3Pane.threadTree.selectedIndex = 4; + await awaitBrowserLoaded(messagePane); + + await extension.startup(); + + await extension.awaitMessage(); + await checkMessageBody({ textContent: "" }, messages[4]); + extension.sendMessage(); + + await extension.awaitFinish("finished"); + await checkMessageBody( + { textContent: "message_display_scripts@mochitest" }, + messages[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() { + let 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); + } + }); + + let 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: { + background: { scripts: ["utils.js", "background.js"] }, + permissions: ["messagesModify", ""], + }, + }); + + 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[5] + ); + + // Load a new message and check it is modified. + let loadPromise = extension.awaitMessage("ScriptLoaded"); + about3Pane.threadTree.selectedIndex = 6; + let tabId = await loadPromise; + + await checkMessageBody( + { + backgroundColor: "rgb(0, 128, 0)", + color: "rgb(255, 255, 255)", + foo: "bar", + textContent: "Hey look, the script ran!", + }, + messages[6] + ); + // 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"); + let messageTab = await openMessageInTab(messages[6]); + let 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[6], + 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. + let 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[6], + 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"); + let newWindow = await openMessageInWindow(messages[7]); + let newWindowMessagePane = newWindow.getBrowser(); + let windowTabId = await loadPromise; + + await checkMessageBody( + { + backgroundColor: "rgb(0, 128, 0)", + color: "rgb(255, 255, 255)", + foo: "bar", + textContent: "Hey look, the script ran!", + }, + messages[7], + 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[6], + 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[6] + ); + + // 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[7], + newWindowMessagePane + ); + + await BrowserTestUtils.closeWindow(newWindow); +}); + +/** Tests content_scripts in the manifest do not affect message display. */ +async function subtestContentScriptManifest(message, ...permissions) { + let extension = ExtensionTestUtils.loadExtension({ + files: { + "test.css": "body { background-color: red; }", + "test.js": () => { + document.body.textContent += "Hey look, the script ran!"; + }, + }, + manifest: { + permissions, + content_scripts: [ + { + matches: [""], + 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[7]); +}); +add_task(async function testContentScriptManifest() { + about3Pane.threadTree.selectedIndex = 8; + await awaitBrowserLoaded(messagePane); + await subtestContentScriptManifest(messages[8], "messagesModify"); +}); + +/** Tests registered content scripts do not affect message display. */ +async function subtestContentScriptRegister(message, ...permissions) { + let extension = ExtensionTestUtils.loadExtension({ + files: { + "background.js": async () => { + await browser.contentScripts.register({ + matches: [""], + css: [{ file: "test.css" }], + js: [{ file: "test.js" }], + matchAboutBlank: true, + }); + + 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: { + background: { scripts: ["utils.js", "background.js"] }, + permissions, + }, + }); + + 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[9], ""); +}); +add_task(async function testContentScriptRegister() { + about3Pane.threadTree.selectedIndex = 10; + await awaitBrowserLoaded(messagePane); + await subtestContentScriptRegister( + messages[10], + "", + "messagesModify" + ); +}); -- cgit v1.2.3