summaryrefslogtreecommitdiffstats
path: root/comm/mail/test/browser/content-tabs
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/test/browser/content-tabs')
-rw-r--r--comm/mail/test/browser/content-tabs/browser.ini50
-rw-r--r--comm/mail/test/browser/content-tabs/browser_aboutSupport.js587
-rw-r--r--comm/mail/test/browser/content-tabs/browser_addonsMgr.js76
-rw-r--r--comm/mail/test/browser/content-tabs/browser_contentTab.js170
-rw-r--r--comm/mail/test/browser/content-tabs/browser_installXpi.js148
-rw-r--r--comm/mail/test/browser/content-tabs/html/blocklist.xml10
-rw-r--r--comm/mail/test/browser/content-tabs/html/blocklistHard.xml10
-rw-r--r--comm/mail/test/browser/content-tabs/html/blocklist_details.html8
-rw-r--r--comm/mail/test/browser/content-tabs/html/corrupt.xpibin0 -> 695 bytes
-rw-r--r--comm/mail/test/browser/content-tabs/html/dummy.xml4
-rw-r--r--comm/mail/test/browser/content-tabs/html/favicon.icobin0 -> 1394 bytes
-rw-r--r--comm/mail/test/browser/content-tabs/html/installxpi.html13
-rw-r--r--comm/mail/test/browser/content-tabs/html/installxpi.xpibin0 -> 701 bytes
-rw-r--r--comm/mail/test/browser/content-tabs/html/plugin.html9
-rw-r--r--comm/mail/test/browser/content-tabs/html/plugin_crashed_help.html8
-rw-r--r--comm/mail/test/browser/content-tabs/html/plugin_update.html8
-rw-r--r--comm/mail/test/browser/content-tabs/html/test-lwthemes.html44
-rw-r--r--comm/mail/test/browser/content-tabs/html/test.pngbin0 -> 6712 bytes
-rw-r--r--comm/mail/test/browser/content-tabs/html/webextension.xpibin0 -> 323 bytes
-rw-r--r--comm/mail/test/browser/content-tabs/html/whatsnew.html13
-rw-r--r--comm/mail/test/browser/content-tabs/html/whatsnew.pngbin0 -> 633 bytes
-rw-r--r--comm/mail/test/browser/content-tabs/html/whatsnew1.html8
22 files changed, 1166 insertions, 0 deletions
diff --git a/comm/mail/test/browser/content-tabs/browser.ini b/comm/mail/test/browser/content-tabs/browser.ini
new file mode 100644
index 0000000000..ef654157df
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/browser.ini
@@ -0,0 +1,50 @@
+[DEFAULT]
+prefs =
+ mail.account.account1.server=server1
+ mail.account.account2.identities=id1,id2
+ mail.account.account2.server=server2
+ mail.accountmanager.accounts=account1,account2
+ mail.accountmanager.defaultaccount=account2
+ mail.accountmanager.localfoldersserver=server1
+ mail.identity.id1.fullName=Tinderbox
+ mail.identity.id1.htmlSigFormat=false
+ mail.identity.id1.smtpServer=smtp1
+ mail.identity.id1.useremail=tinderbox@foo.invalid
+ mail.identity.id1.valid=true
+ mail.identity.id2.fullName=Tinderboxpushlog
+ mail.identity.id2.htmlSigFormat=true
+ mail.identity.id2.smtpServer=smtp1
+ mail.identity.id2.useremail=tinderboxpushlog@foo.invalid
+ mail.identity.id2.valid=true
+ mail.provider.suppress_dialog_on_startup=true
+ mail.server.server1.hostname=Local_Folders
+ mail.server.server1.type=none
+ mail.server.server1.userName=nobody
+ mail.server.server2.check_new_mail=false
+ mail.server.server2.directory-rel=[ProfD]Mail/tinderbox
+ mail.server.server2.download_on_biff=true
+ mail.server.server2.hostname=tinderbox123
+ mail.server.server2.login_at_startup=false
+ mail.server.server2.name=tinderbox@foo.invalid
+ mail.server.server2.type=pop3
+ mail.server.server2.userName=tinderbox
+ mail.server.server2.whiteListAbURI=
+ mail.shell.checkDefaultClient=false
+ mail.smtp.defaultserver=smtp1
+ mail.smtpserver.smtp1.hostname=tinderbox123
+ mail.smtpserver.smtp1.username=tinderbox
+ mail.smtpservers=smtp1
+ mail.spotlight.firstRunDone=true
+ mail.startup.enabledMailCheckOnce=true
+ mail.winsearch.firstRunDone=true
+ mailnews.start_page.override_url=about:blank
+ mailnews.start_page.url=about:blank
+ datareporting.policy.dataSubmissionPolicyBypassNotification=true
+subsuite = thunderbird
+support-files = html/**
+
+[browser_aboutSupport.js]
+[browser_addonsMgr.js]
+[browser_contentTab.js]
+tags = contextmenu
+[browser_installXpi.js]
diff --git a/comm/mail/test/browser/content-tabs/browser_aboutSupport.js b/comm/mail/test/browser/content-tabs/browser_aboutSupport.js
new file mode 100644
index 0000000000..9be3cf0eab
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/browser_aboutSupport.js
@@ -0,0 +1,587 @@
+/* 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/. */
+
+"use strict";
+
+var utils = ChromeUtils.import("resource://testing-common/mozmill/utils.jsm");
+var { close_compose_window, wait_for_compose_window } = ChromeUtils.import(
+ "resource://testing-common/mozmill/ComposeHelpers.jsm"
+);
+var {
+ assert_content_tab_element_hidden,
+ assert_content_tab_element_visible,
+ assert_content_tab_text_absent,
+ assert_content_tab_text_present,
+ content_tab_e,
+ get_content_tab_element_display,
+ get_element_by_text,
+ open_content_tab_with_click,
+ wait_for_content_tab_element_display,
+} = ChromeUtils.import(
+ "resource://testing-common/mozmill/ContentTabHelpers.jsm"
+);
+
+var { close_tab, mc } = ChromeUtils.import(
+ "resource://testing-common/mozmill/FolderDisplayHelpers.jsm"
+);
+var { click_menus_in_sequence, plan_for_new_window } = ChromeUtils.import(
+ "resource://testing-common/mozmill/WindowHelpers.jsm"
+);
+
+var warningText = new Map();
+
+add_setup(function () {
+ // The wording of the warning message when private data is being exported
+ // from the about:support page.
+ let bundle = Services.strings.createBundle(
+ "chrome://messenger/locale/aboutSupportMail.properties"
+ );
+ // In HTML the warning label and text comprise the textContent of a single element.
+ warningText.set(
+ "text/html",
+ bundle.GetStringFromName("warningLabel") +
+ " " +
+ bundle.GetStringFromName("warningText")
+ );
+ // In plain text the warning label may end up on a separate line so do not match it.
+ warningText.set("text/plain", bundle.GetStringFromName("warningText"));
+});
+
+// After every test we want to close the about:support tab so that failures
+// don't cascade.
+function teardownTest(module) {
+ let tabmail = mc.window.document.getElementById("tabmail");
+ tabmail.closeOtherTabs(tabmail.tabInfo[0]);
+}
+
+/**
+ * Strings found in the about:support HTML or text that should clearly mark the
+ * data as being from about:support.
+ */
+const ABOUT_SUPPORT_STRINGS = [
+ "Application Basics",
+ "Mail and News Accounts",
+ "Add-ons",
+ "Important Modified Preferences",
+ "Graphics",
+ "Accessibility",
+ "Library Versions",
+];
+
+/**
+ * Strings that if found in the about:support text or HTML usually indicate an
+ * error.
+ */
+const ABOUT_SUPPORT_ERROR_STRINGS = new Map([
+ ["text/html", ["undefined", "null"]],
+ ["text/plain", ["undefined"]],
+]);
+
+/*
+ * Helpers
+ */
+
+/**
+ * Opens about:support and waits for it to load.
+ *
+ * @returns the about:support tab.
+ */
+async function open_about_support() {
+ let openAboutSupport = async function () {
+ if (AppConstants.platform == "macosx") {
+ mc.window.document.getElementById("aboutsupport_open").click();
+ } else {
+ // Show menubar so we can click it.
+ document.getElementById("toolbar-menubar").removeAttribute("autohide");
+ let helpMenu = mc.window.document.getElementById("helpMenu");
+ EventUtils.synthesizeMouseAtCenter(helpMenu, {}, helpMenu.ownerGlobal);
+ await click_menus_in_sequence(
+ mc.window.document.getElementById("menu_HelpPopup"),
+ [{ id: "aboutsupport_open" }]
+ );
+ }
+ };
+ let tab = open_content_tab_with_click(openAboutSupport, "about:support");
+
+ // Make sure L10n is done.
+ let l10nDone = false;
+ tab.browser.contentDocument.l10n.ready.then(
+ () => (l10nDone = true),
+ console.error
+ );
+ utils.waitFor(() => l10nDone, "Timeout waiting for L10n to complete.");
+
+ // We have one variable that's asynchronously populated -- wait for it to be
+ // populated.
+ utils.waitFor(
+ () => tab.browser.contentWindow.gAccountDetails !== undefined,
+ "Timeout waiting for about:support's gAccountDetails to populate."
+ );
+
+ utils.waitFor(
+ () => content_tab_e(tab, "accounts-tbody").children.length > 1,
+ "Accounts sections didn't load."
+ );
+ // The population of the info fields is async, so we must wait until
+ // the last one is done.
+ utils.waitFor(
+ () =>
+ content_tab_e(tab, "intl-osprefs-regionalprefs").textContent.trim() != "",
+ "Regional prefs section didn't load."
+ );
+
+ // Wait an additional half-second for some more localisation caused by
+ // runtime changes to the page.
+ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
+ await new Promise(resolve => setTimeout(resolve, 500));
+ return tab;
+}
+
+/**
+ * Opens a compose window containing the troubleshooting information.
+ *
+ * @param aTab The about:support tab.
+ */
+function open_send_via_email(aTab) {
+ let button = content_tab_e(aTab, "send-via-email");
+ plan_for_new_window("msgcompose");
+ EventUtils.synthesizeMouseAtCenter(
+ button,
+ { clickCount: 1 },
+ button.ownerGlobal
+ );
+ let cwc = wait_for_compose_window();
+ return cwc;
+}
+
+/**
+ * Find some element marked as private data.
+ */
+function find_private_element(aTab) {
+ // We use the identity name as an example of a private-only element.
+ // It is currently the second td element with class="data-private" in the table.
+ // The content string must be something unique that is not found anywhere else.
+ let elem = aTab.browser.contentDocument.querySelector(
+ "#accounts-table td.data-private~td.data-private"
+ );
+ Assert.ok(elem != null);
+ Assert.ok(elem.textContent.length > 0);
+ Assert.equal(get_content_tab_element_display(aTab, elem), "none");
+ return elem;
+}
+
+/*
+ * Tests
+ */
+
+/**
+ * Test displaying the about:support page. Also perform a couple of basic tests
+ * to check that no major errors have occurred. The basic tests are by no means
+ * comprehensive.
+ */
+add_task(async function test_display_about_support() {
+ let tab = await open_about_support();
+ // Check that the document has a few strings that indicate that we've loaded
+ // the right page.
+ for (let str of ABOUT_SUPPORT_STRINGS) {
+ assert_content_tab_text_present(tab, str);
+ }
+
+ // Check that error strings aren't present anywhere
+ for (let str of ABOUT_SUPPORT_ERROR_STRINGS.get("text/html")) {
+ assert_content_tab_text_absent(tab, str);
+ }
+
+ // Bug 1339436
+ // Test that the tables in the page are all populated with at least one row
+ // in the tbody element.
+ // An exception in the code could cause some to be empty.
+ let tables = tab.browser.contentDocument.querySelectorAll("tbody");
+ let emptyTables = [
+ "graphics-failures-tbody",
+ "graphics-tbody",
+ "locked-prefs-tbody",
+ "sandbox-syscalls-tbody",
+ "crashes-tbody",
+ "processes-tbody",
+ "support-printing-prefs-tbody",
+ "chat-tbody",
+ ]; // some tables may be empty
+ for (let table of tables) {
+ if (!emptyTables.includes(table.id)) {
+ Assert.ok(
+ table.querySelectorAll("tr").length > 0,
+ "Troubleshooting table '" + table.id + "' is empty!"
+ );
+ }
+ }
+
+ // Mozmill uses a user.js file in the profile, so the warning about the file
+ // should be visible here.
+ let userjsElem = tab.browser.contentDocument.getElementById(
+ "prefs-user-js-section"
+ );
+ Assert.ok(userjsElem.hasChildNodes);
+ Assert.ok(
+ tab.browser.contentDocument.defaultView.getComputedStyle(userjsElem)
+ .display == "block"
+ );
+ Assert.ok(
+ tab.browser.contentDocument.defaultView.getComputedStyle(userjsElem)
+ .visibility == "visible"
+ );
+
+ close_tab(tab);
+});
+
+/**
+ * Test that our accounts are displayed in order.
+ */
+add_task(async function test_accounts_in_order() {
+ let tab = await open_about_support();
+ // This is a really simple test and by no means comprehensive -- test that
+ // "account1" appears before "account2" in the HTML content.
+ assert_content_tab_text_present(tab, "account1");
+ assert_content_tab_text_present(tab, "account2");
+ let html = tab.browser.contentDocument.documentElement.innerHTML;
+ if (html.indexOf("account1") > html.indexOf("account2")) {
+ Assert.report(
+ true,
+ undefined,
+ undefined,
+ "account1 found after account2 in the HTML page"
+ );
+ }
+ close_tab(tab);
+});
+
+var UNIQUE_ID = "3a9e1694-7115-4237-8b1e-1cabe6e35073";
+
+/**
+ * Test that a modified preference on the whitelist but not on the blacklist
+ * shows up.
+ */
+add_task(async function test_modified_pref_on_whitelist() {
+ const PREFIX = "accessibility.";
+ let prefName = PREFIX + UNIQUE_ID;
+ Services.prefs.setBoolPref(prefName, true);
+ let tab = await open_about_support();
+
+ assert_content_tab_text_present(tab, prefName);
+ close_tab(tab);
+ Services.prefs.clearUserPref(prefName);
+});
+
+/**
+ * Test that a modified preference not on the whitelist doesn't show up.
+ */
+add_task(async function test_modified_pref_not_on_whitelist() {
+ Services.prefs.setBoolPref(UNIQUE_ID, true);
+ let tab = await open_about_support();
+ assert_content_tab_text_absent(tab, UNIQUE_ID);
+ close_tab(tab);
+ Services.prefs.clearUserPref(UNIQUE_ID);
+});
+
+/**
+ * Test that a modified preference on the blacklist doesn't show up.
+ */
+add_task(async function test_modified_pref_on_blacklist() {
+ const PREFIX = "network.proxy.";
+ let prefName = PREFIX + UNIQUE_ID;
+ Services.prefs.setBoolPref(prefName, true);
+ let tab = await open_about_support();
+
+ assert_content_tab_text_absent(tab, prefName);
+ close_tab(tab);
+ Services.prefs.clearUserPref(prefName);
+});
+
+/**
+ * Test that private data isn't displayed by default, and that when it is
+ * displayed, it actually shows up.
+ */
+add_task(async function test_private_data() {
+ let tab = await open_about_support();
+ let checkbox = content_tab_e(tab, "check-show-private-data");
+
+ // We use the profile path and some other element as an example
+ // of a private-only element.
+ let privateElem1 = find_private_element(tab);
+ let privateElem2 = content_tab_e(tab, "profile-dir-box");
+ // We use the profile button as an example of a public element.
+ let publicElem = content_tab_e(tab, "profile-dir-button");
+
+ Assert.ok(
+ !checkbox.checked,
+ "Private data checkbox shouldn't be checked by default"
+ );
+ assert_content_tab_element_visible(tab, publicElem);
+ assert_content_tab_element_hidden(tab, privateElem1);
+ assert_content_tab_element_hidden(tab, privateElem2);
+
+ // Now check the checkbox and see what happens.
+ EventUtils.synthesizeMouseAtCenter(
+ checkbox,
+ { clickCount: 1 },
+ checkbox.ownerGlobal
+ );
+ wait_for_content_tab_element_display(tab, privateElem1);
+ wait_for_content_tab_element_display(tab, privateElem2);
+ close_tab(tab);
+});
+
+/**
+ * Checks if text fragment exists in the document.
+ * If it is a node tree, find the element whole contents is the searched text.
+ * If it is plain text string, just check in text is anywhere in it.
+ *
+ * @param aDocument A node tree or a string of plain text data.
+ * @param aText The text to find in the document.
+ */
+function check_text_in_body(aDocument, aText) {
+ if (typeof aDocument == "object") {
+ return get_element_by_text(aDocument, aText) != null;
+ }
+ return aDocument.includes(aText);
+}
+
+/**
+ * Test (well, sort of) the copy to clipboard function with public data.
+ */
+add_task(async function test_copy_to_clipboard_public() {
+ let tab = await open_about_support();
+ let privateElem = find_private_element(tab);
+ // To avoid destroying the current contents of the clipboard, instead of
+ // actually copying to it, we just retrieve what would have been copied to it
+ let transferable = tab.browser.contentWindow.getClipboardTransferable();
+ for (let flavor of ["text/html", "text/plain"]) {
+ let data = {};
+ transferable.getTransferData(flavor, data);
+ let text = data.value.QueryInterface(Ci.nsISupportsString).data;
+ let contentBody;
+ if (flavor == "text/html") {
+ let parser = new DOMParser();
+ contentBody = parser.parseFromString(text, "text/html").body;
+ } else {
+ contentBody = text;
+ }
+
+ for (let str of ABOUT_SUPPORT_STRINGS) {
+ if (!check_text_in_body(contentBody, str)) {
+ Assert.report(
+ true,
+ undefined,
+ undefined,
+ `Unable to find "${str}" in flavor "${flavor}"`
+ );
+ }
+ }
+
+ for (let str of ABOUT_SUPPORT_ERROR_STRINGS.get(flavor)) {
+ if (check_text_in_body(contentBody, str)) {
+ Assert.report(
+ true,
+ undefined,
+ undefined,
+ `Found "${str}" in flavor "${flavor}"`
+ );
+ }
+ }
+
+ // Check that private data isn't in the output.
+ if (check_text_in_body(contentBody, privateElem.textContent)) {
+ Assert.report(
+ true,
+ undefined,
+ undefined,
+ `Found private data in flavor "${flavor}"`
+ );
+ }
+ }
+ close_tab(tab);
+});
+
+/**
+ * Test (well, sort of) the copy to clipboard function with private data.
+ */
+add_task(async function test_copy_to_clipboard_private() {
+ let tab = await open_about_support();
+
+ // Display private data.
+ let privateElem = find_private_element(tab);
+ let show = content_tab_e(tab, "check-show-private-data");
+ EventUtils.synthesizeMouseAtCenter(show, { clickCount: 1 }, show.ownerGlobal);
+ wait_for_content_tab_element_display(tab, privateElem);
+
+ // To avoid destroying the current contents of the clipboard, instead of
+ // actually copying to it, we just retrieve what would have been copied to it
+ let transferable = tab.browser.contentWindow.getClipboardTransferable();
+ for (let flavor of ["text/html", "text/plain"]) {
+ let data = {};
+ transferable.getTransferData(flavor, data);
+ let text = data.value.QueryInterface(Ci.nsISupportsString).data;
+ let contentBody;
+ if (flavor == "text/html") {
+ let parser = new DOMParser();
+ contentBody = parser.parseFromString(text, "text/html").body;
+ } else {
+ contentBody = text;
+ }
+
+ for (let str of ABOUT_SUPPORT_STRINGS) {
+ if (!check_text_in_body(contentBody, str)) {
+ Assert.report(
+ true,
+ undefined,
+ undefined,
+ `Unable to find "${str}" in flavor "${flavor}"`
+ );
+ }
+ }
+
+ for (let str of ABOUT_SUPPORT_ERROR_STRINGS.get(flavor)) {
+ if (check_text_in_body(contentBody, str)) {
+ Assert.report(
+ true,
+ undefined,
+ undefined,
+ `Found "${str}" in flavor "${flavor}"`
+ );
+ }
+ }
+
+ // Check that private data is in the output.
+ if (!check_text_in_body(contentBody, privateElem.textContent)) {
+ Assert.report(
+ true,
+ undefined,
+ undefined,
+ `Unable to find private data in flavor "${flavor}"`
+ );
+ }
+
+ // Check that the warning text is in the output.
+ if (!check_text_in_body(contentBody, warningText.get(flavor))) {
+ Assert.report(
+ true,
+ undefined,
+ undefined,
+ `Unable to find warning text in flavor "${flavor}"`
+ );
+ }
+ }
+ close_tab(tab);
+});
+
+/**
+ * Test opening the compose window with public data.
+ */
+add_task(async function test_send_via_email_public() {
+ let tab = await open_about_support();
+ let privateElem = find_private_element(tab);
+
+ let cwc = open_send_via_email(tab);
+
+ let contentBody =
+ cwc.window.document.getElementById("messageEditor").contentDocument.body;
+
+ for (let str of ABOUT_SUPPORT_STRINGS) {
+ if (!check_text_in_body(contentBody, str)) {
+ Assert.report(
+ true,
+ undefined,
+ undefined,
+ `Unable to find "${str}" in compose window`
+ );
+ }
+ }
+
+ for (let str of ABOUT_SUPPORT_ERROR_STRINGS.get("text/html")) {
+ if (check_text_in_body(contentBody, str)) {
+ Assert.report(
+ true,
+ undefined,
+ undefined,
+ `Found "${str}" in compose window`
+ );
+ }
+ }
+
+ // Check that private data isn't in the output.
+ if (check_text_in_body(contentBody, privateElem.textContent)) {
+ Assert.report(
+ true,
+ undefined,
+ undefined,
+ `Found private data in compose window`
+ );
+ }
+
+ close_compose_window(cwc);
+ close_tab(tab);
+});
+
+/**
+ * Test opening the compose window with private data.
+ */
+add_task(async function test_send_via_email_private() {
+ let tab = await open_about_support();
+
+ // Display private data.
+ let privateElem = find_private_element(tab);
+ let show = content_tab_e(tab, "check-show-private-data");
+ EventUtils.synthesizeMouseAtCenter(show, { clickCount: 1 }, show.ownerGlobal);
+ wait_for_content_tab_element_display(tab, privateElem);
+
+ let cwc = open_send_via_email(tab);
+
+ let contentBody =
+ cwc.window.document.getElementById("messageEditor").contentDocument.body;
+
+ for (let str of ABOUT_SUPPORT_STRINGS) {
+ if (!check_text_in_body(contentBody, str)) {
+ Assert.report(
+ true,
+ undefined,
+ undefined,
+ `Unable to find "${str}" in compose window`
+ );
+ }
+ }
+
+ for (let str of ABOUT_SUPPORT_ERROR_STRINGS.get("text/html")) {
+ if (check_text_in_body(contentBody, str)) {
+ Assert.report(
+ true,
+ undefined,
+ undefined,
+ `Found "${str}" in compose window`
+ );
+ }
+ }
+
+ // Check that private data is in the output.
+ if (!check_text_in_body(contentBody, privateElem.textContent)) {
+ Assert.report(
+ true,
+ undefined,
+ undefined,
+ "Unable to find private data in compose window"
+ );
+ }
+
+ // Check that the warning text is in the output.
+ if (!check_text_in_body(contentBody, warningText.get("text/html"))) {
+ Assert.report(
+ true,
+ undefined,
+ undefined,
+ "Unable to find warning text in compose window"
+ );
+ }
+
+ close_compose_window(cwc);
+ close_tab(tab);
+});
diff --git a/comm/mail/test/browser/content-tabs/browser_addonsMgr.js b/comm/mail/test/browser/content-tabs/browser_addonsMgr.js
new file mode 100644
index 0000000000..411ddb362d
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/browser_addonsMgr.js
@@ -0,0 +1,76 @@
+/* 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/. */
+
+"use strict";
+
+var { content_tab_e, wait_for_content_tab_load } = ChromeUtils.import(
+ "resource://testing-common/mozmill/ContentTabHelpers.jsm"
+);
+var { mc } = ChromeUtils.import(
+ "resource://testing-common/mozmill/FolderDisplayHelpers.jsm"
+);
+var {
+ click_through_appmenu,
+ plan_for_modal_dialog,
+ wait_for_browser_load,
+ wait_for_modal_dialog,
+ wait_for_window_close,
+} = ChromeUtils.import("resource://testing-common/mozmill/WindowHelpers.jsm");
+
+add_task(async function test_open_addons_with_url() {
+ mc.window.openAddonsMgr("addons://list/theme");
+ await new Promise(resolve => setTimeout(resolve));
+
+ let tab = mc.window.document.getElementById("tabmail").currentTabInfo;
+ wait_for_content_tab_load(tab, "about:addons", 10000);
+ let categoriesBox = tab.browser.contentDocument.getElementById("categories");
+ Assert.equal(
+ categoriesBox.selectedChild.getAttribute("viewid"),
+ "addons://list/theme",
+ "Themes category should be selected!"
+ );
+
+ mc.window.document.getElementById("tabmail").switchToTab(0); // switch to 3pane
+ mc.window.document.getElementById("tabmail").closeTab(tab);
+});
+
+/**
+ * Bug 1462923
+ * Check if the "Tools->Add-on Options" menu item works and shows our add-on.
+ * This relies on the MozMill extension having optionsURL defined in install.rdf,
+ * however simplistic the preferences XUL document may be.
+ */
+add_task(function test_addon_prefs() {
+ // Open Add-on Options.
+ const subview = click_through_appmenu(
+ [{ id: "appmenu_addons" }],
+ null,
+ mc.window
+ );
+
+ plan_for_modal_dialog("mozmill-prefs", function (controller) {
+ // Add | await new Promise(resolve => setTimeout(resolve, 1000));|
+ // here to see the popup dialog.
+ controller.window.close();
+ });
+
+ // MozMill add-on should be somewhere in the list. When found, click it.
+ let foundAddon = false;
+ for (let item of subview.children) {
+ if (
+ item.tagName == "toolbarbutton" &&
+ item.getAttribute("collapsed") != "true" &&
+ item.label == "MozMill"
+ ) {
+ foundAddon = true;
+ EventUtils.synthesizeMouseAtCenter(item, { clickCount: 1 }, mc.window);
+ break;
+ }
+ }
+ Assert.ok(foundAddon);
+
+ // Wait for the options dialog to open and close.
+ wait_for_modal_dialog();
+ wait_for_window_close();
+}).skip();
diff --git a/comm/mail/test/browser/content-tabs/browser_contentTab.js b/comm/mail/test/browser/content-tabs/browser_contentTab.js
new file mode 100644
index 0000000000..194378e6af
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/browser_contentTab.js
@@ -0,0 +1,170 @@
+/* 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/. */
+
+"use strict";
+
+var EventUtils = ChromeUtils.import(
+ "resource://testing-common/mozmill/EventUtils.jsm"
+);
+
+var { assert_content_tab_has_favicon, open_content_tab_with_url } =
+ ChromeUtils.import("resource://testing-common/mozmill/ContentTabHelpers.jsm");
+var { assert_element_visible, assert_element_not_visible } = ChromeUtils.import(
+ "resource://testing-common/mozmill/DOMHelpers.jsm"
+);
+
+var { be_in_folder, inboxFolder } = ChromeUtils.import(
+ "resource://testing-common/mozmill/FolderDisplayHelpers.jsm"
+);
+
+var { assert_tab_has_title, close_popup, mc, wait_for_popup_to_open } =
+ ChromeUtils.import(
+ "resource://testing-common/mozmill/FolderDisplayHelpers.jsm"
+ );
+
+var url =
+ "http://mochi.test:8888/browser/comm/mail/test/browser/content-tabs/html/";
+var whatsUrl = url + "whatsnew.html";
+
+add_task(async function test_content_tab_open() {
+ // Need to open the thread pane to load the appropriate context menus.
+ await be_in_folder(inboxFolder);
+ let tab = open_content_tab_with_url(whatsUrl);
+
+ assert_tab_has_title(tab, "What's New Content Test");
+ // Check the location of the what's new image, this is via the link element
+ // and therefore should be set and not favicon.png.
+ // assert_content_tab_has_favicon(tab, url + "whatsnew.png");
+
+ // Check that window.content is set up correctly wrt content-primary and
+ // content-targetable.
+ if (tab.browser.currentURI.spec != whatsUrl) {
+ throw new Error(
+ 'window.content is not set to the url loaded, incorrect type="..."?'
+ );
+ }
+
+ tab.browser.focus();
+});
+
+/**
+ * Just make sure that the context menu does what we expect in content tabs wrt.
+ * spell checking options.
+ */
+add_task(async function test_spellcheck_in_content_tabs() {
+ let tabmail = mc.window.document.getElementById("tabmail");
+
+ // Test a few random items
+ BrowserTestUtils.synthesizeMouseAtCenter(
+ "textarea",
+ {},
+ tabmail.selectedTab.browser
+ );
+ // Bug 364914 causes textareas to not be spell checked until they have been
+ // focused at last once, so give the event loop a chance to spin.
+ // Since bug 1370754 the inline spell checker waits 1 second, so let's
+ // wait 2 seconds to be on the safe side.
+ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
+ await new Promise(resolve => setTimeout(resolve, 2000));
+ BrowserTestUtils.synthesizeMouseAtCenter(
+ "textarea",
+ { type: "contextmenu" },
+ tabmail.selectedTab.browser
+ );
+ let browserContext = mc.window.document.getElementById("browserContext");
+ await wait_for_popup_to_open(browserContext);
+ assert_element_visible("browserContext-spell-dictionaries");
+ assert_element_visible("browserContext-spell-check-enabled");
+ await close_popup(mc, browserContext);
+
+ // Different test
+ BrowserTestUtils.synthesizeMouseAtCenter(
+ "body > :first-child",
+ { type: "contextmenu" },
+ tabmail.selectedTab.browser
+ );
+ await wait_for_popup_to_open(browserContext);
+ assert_element_not_visible("browserContext-spell-dictionaries");
+ assert_element_not_visible("browserContext-spell-check-enabled");
+ await close_popup(mc, browserContext);
+
+ // Right-click on "zombocom" and add to dictionary
+ BrowserTestUtils.synthesizeMouse(
+ "textarea",
+ 5,
+ 5,
+ { type: "contextmenu", button: 2 },
+ tabmail.selectedTab.browser
+ );
+ await wait_for_popup_to_open(browserContext);
+ let suggestions =
+ mc.window.document.getElementsByClassName("spell-suggestion");
+ Assert.ok(suggestions.length > 0, "What, is zombocom a registered word now?");
+ let addToDict = mc.window.document.getElementById(
+ "browserContext-spell-add-to-dictionary"
+ );
+ if (AppConstants.platform == "macosx") {
+ // We need to use click() since the synthesizeMouseAtCenter doesn't work for
+ // context menu items on macos.
+ addToDict.click();
+ } else {
+ EventUtils.synthesizeMouseAtCenter(addToDict, {}, addToDict.ownerGlobal);
+ }
+ await close_popup(mc, browserContext);
+
+ // Now check we don't have any suggestionss
+ BrowserTestUtils.synthesizeMouse(
+ "textarea",
+ 5,
+ 5,
+ { type: "contextmenu", button: 2 },
+ tabmail.selectedTab.browser
+ );
+ await wait_for_popup_to_open(browserContext);
+ suggestions = mc.window.document.getElementsByClassName("spell-suggestion");
+ Assert.ok(suggestions.length == 0, "But I just taught you this word!");
+ await close_popup(mc, browserContext);
+});
+
+add_task(function test_content_tab_default_favicon() {
+ const whatsUrl2 = url + "whatsnew1.html";
+ let tab = open_content_tab_with_url(whatsUrl2);
+
+ assert_tab_has_title(tab, "What's New Content Test 1");
+ // Check the location of the favicon, this should be the site favicon in this
+ // test.
+ assert_content_tab_has_favicon(tab, "http://mochi.test:8888/favicon.ico");
+});
+
+add_task(async function test_content_tab_onbeforeunload() {
+ let tabmail = mc.window.document.getElementById("tabmail");
+ let count = tabmail.tabContainer.allTabs.length;
+ let tab = tabmail.tabInfo[count - 1];
+ await SpecialPowers.spawn(tab.browser, [], () => {
+ content.addEventListener("beforeunload", function (event) {
+ event.returnValue = "Green llama in your car";
+ });
+ });
+
+ const interactionPref = "dom.require_user_interaction_for_beforeunload";
+ Services.prefs.setBoolPref(interactionPref, false);
+
+ let dialogPromise = BrowserTestUtils.promiseAlertDialog("accept");
+ tabmail.closeTab(tab);
+ await dialogPromise;
+
+ Services.prefs.clearUserPref(interactionPref);
+});
+
+// XXX todo
+// - test find bar
+// - window.close within tab
+// - zoom?
+
+registerCleanupFunction(function () {
+ let tabmail = mc.window.document.getElementById("tabmail");
+ while (tabmail.tabInfo.length > 1) {
+ tabmail.closeTab(1);
+ }
+});
diff --git a/comm/mail/test/browser/content-tabs/browser_installXpi.js b/comm/mail/test/browser/content-tabs/browser_installXpi.js
new file mode 100644
index 0000000000..e90b18bca4
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/browser_installXpi.js
@@ -0,0 +1,148 @@
+/* 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/. */
+
+"use strict";
+
+var utils = ChromeUtils.import("resource://testing-common/mozmill/utils.jsm");
+
+var { open_content_tab_with_url } = ChromeUtils.import(
+ "resource://testing-common/mozmill/ContentTabHelpers.jsm"
+);
+var { mc } = ChromeUtils.import(
+ "resource://testing-common/mozmill/FolderDisplayHelpers.jsm"
+);
+
+var url =
+ "http://mochi.test:8888/browser/comm/mail/test/browser/content-tabs/html/";
+
+var gDocument;
+var gNewTab;
+
+add_setup(function () {
+ gDocument = mc.window.document;
+ gNewTab = open_content_tab_with_url(url + "installxpi.html");
+});
+
+registerCleanupFunction(function () {
+ mc.window.document.getElementById("tabmail").closeTab(gNewTab);
+});
+
+async function waitForNotification(id, buttonToClickSelector, callback) {
+ let notificationSelector = `#notification-popup > #${id}-notification`;
+ let notification;
+ utils.waitFor(() => {
+ notification = gDocument.querySelector(notificationSelector);
+ return notification && !notification.hidden;
+ });
+ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
+ await new Promise(resolve => setTimeout(resolve, 500));
+ if (callback) {
+ callback();
+ }
+ if (buttonToClickSelector) {
+ let button = notification.querySelector(buttonToClickSelector);
+ EventUtils.synthesizeMouseAtCenter(button, { clickCount: 1 }, mc.window);
+ }
+ utils.waitFor(() => !gDocument.querySelector(notificationSelector));
+}
+
+add_task(async function test_install_corrupt_xpi() {
+ // This install with give us a corrupt xpi warning.
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ "#corruptlink",
+ {},
+ gNewTab.browser
+ );
+ await waitForNotification(
+ "addon-install-blocked",
+ ".popup-notification-primary-button"
+ );
+ await waitForNotification(
+ "addon-install-failed",
+ ".popup-notification-primary-button"
+ );
+});
+
+add_task(async function test_install_xpi_offer() {
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ "#installlink",
+ {},
+ gNewTab.browser
+ );
+ await waitForNotification(
+ "addon-install-blocked",
+ ".popup-notification-primary-button"
+ );
+ await waitForNotification(
+ "addon-install-failed",
+ ".popup-notification-primary-button"
+ );
+});
+
+add_task(async function test_xpinstall_disabled() {
+ Services.prefs.setBoolPref("xpinstall.enabled", false);
+
+ // Try installation again - this time we'll get an install has been disabled message.
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ "#installlink",
+ {},
+ gNewTab.browser
+ );
+ await waitForNotification(
+ "xpinstall-disabled",
+ ".popup-notification-secondary-button"
+ );
+
+ Services.prefs.clearUserPref("xpinstall.enabled");
+});
+
+add_task(async function test_xpinstall_actually_install() {
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ "#installlink",
+ {},
+ gNewTab.browser
+ );
+ await waitForNotification(
+ "addon-install-blocked",
+ ".popup-notification-primary-button"
+ );
+ await waitForNotification(
+ "addon-install-failed",
+ ".popup-notification-primary-button"
+ );
+});
+
+add_task(async function test_xpinstall_webext_actually_install() {
+ await BrowserTestUtils.synthesizeMouseAtCenter(
+ "#installwebextlink",
+ {},
+ gNewTab.browser
+ );
+ await waitForNotification(
+ "addon-install-blocked",
+ ".popup-notification-primary-button"
+ );
+ await waitForNotification("addon-progress");
+ await waitForNotification(
+ "addon-webext-permissions",
+ ".popup-notification-primary-button",
+ () => {
+ let permission = gDocument.getElementById(
+ "addon-webext-perm-single-entry"
+ );
+ Assert.ok(!permission.hidden);
+ }
+ );
+ await waitForNotification(
+ "addon-installed",
+ ".popup-notification-primary-button"
+ );
+
+ Assert.report(
+ false,
+ undefined,
+ undefined,
+ "Test ran to completion successfully"
+ );
+});
diff --git a/comm/mail/test/browser/content-tabs/html/blocklist.xml b/comm/mail/test/browser/content-tabs/html/blocklist.xml
new file mode 100644
index 0000000000..cc0a0c69df
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/blocklist.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
+ <pluginItems>
+ <pluginItem>
+ <match name="name" exp="Test Plug-in"/>
+ <versionRange severity="0"/>
+ </pluginItem>
+ </pluginItems>
+</blocklist>
diff --git a/comm/mail/test/browser/content-tabs/html/blocklistHard.xml b/comm/mail/test/browser/content-tabs/html/blocklistHard.xml
new file mode 100644
index 0000000000..daeb1dc935
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/blocklistHard.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
+ <pluginItems>
+ <pluginItem blockID="p9999">
+ <match name="name" exp="Test Plug-in"/>
+ <versionRange severity="2"/>
+ </pluginItem>
+ </pluginItems>
+</blocklist>
diff --git a/comm/mail/test/browser/content-tabs/html/blocklist_details.html b/comm/mail/test/browser/content-tabs/html/blocklist_details.html
new file mode 100644
index 0000000000..8d86ac8028
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/blocklist_details.html
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>Plugin Blocklist Details</title>
+ </head>
+ <body bgcolor="#FFFFFF">
+ <h1>Plugin Blocklist Details Page</h1>
+ </body>
+</html>
diff --git a/comm/mail/test/browser/content-tabs/html/corrupt.xpi b/comm/mail/test/browser/content-tabs/html/corrupt.xpi
new file mode 100644
index 0000000000..0d9fb59d08
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/corrupt.xpi
Binary files differ
diff --git a/comm/mail/test/browser/content-tabs/html/dummy.xml b/comm/mail/test/browser/content-tabs/html/dummy.xml
new file mode 100644
index 0000000000..0261794f8a
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/dummy.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
+</blocklist>
diff --git a/comm/mail/test/browser/content-tabs/html/favicon.ico b/comm/mail/test/browser/content-tabs/html/favicon.ico
new file mode 100644
index 0000000000..0815759685
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/favicon.ico
Binary files differ
diff --git a/comm/mail/test/browser/content-tabs/html/installxpi.html b/comm/mail/test/browser/content-tabs/html/installxpi.html
new file mode 100644
index 0000000000..51679600a1
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/installxpi.html
@@ -0,0 +1,13 @@
+<html>
+ <head>
+ <title>Test xpi installation</title>
+ </head>
+ <body bgcolor="#FFFFFF">
+ <h1>Test xpi installation</h1>
+
+ <a id="corruptlink" href="corrupt.xpi">Install this corrupt xpi</a>
+ <a id="installlink" href="installxpi.xpi">Install this xpi</a>
+ <a id="installwebextlink" href="webextension.xpi">Install this webextension xpi</a>
+
+ </body>
+</html>
diff --git a/comm/mail/test/browser/content-tabs/html/installxpi.xpi b/comm/mail/test/browser/content-tabs/html/installxpi.xpi
new file mode 100644
index 0000000000..854e1bafdf
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/installxpi.xpi
Binary files differ
diff --git a/comm/mail/test/browser/content-tabs/html/plugin.html b/comm/mail/test/browser/content-tabs/html/plugin.html
new file mode 100644
index 0000000000..83c83bb4b7
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/plugin.html
@@ -0,0 +1,9 @@
+<html>
+ <head>
+ <title>Plugin Test</title>
+ </head>
+ <body bgcolor="#FFFFFF">
+ <h1>Plugin Test</h1>
+ <embed id="test-plugin" type="application/x-test" width="500" height="500"></embed>
+ </body>
+</html>
diff --git a/comm/mail/test/browser/content-tabs/html/plugin_crashed_help.html b/comm/mail/test/browser/content-tabs/html/plugin_crashed_help.html
new file mode 100644
index 0000000000..f938036d88
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/plugin_crashed_help.html
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>Plugin Crashed Help</title>
+ </head>
+ <body bgcolor="#FFFFFF">
+ <h1>Plugin Crashed Help</h1>
+ </body>
+</html>
diff --git a/comm/mail/test/browser/content-tabs/html/plugin_update.html b/comm/mail/test/browser/content-tabs/html/plugin_update.html
new file mode 100644
index 0000000000..49c935f288
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/plugin_update.html
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>Plugin Update Page</title>
+ </head>
+ <body bgcolor="#FFFFFF">
+ <h1>Plugin Update Page</h1>
+ </body>
+</html>
diff --git a/comm/mail/test/browser/content-tabs/html/test-lwthemes.html b/comm/mail/test/browser/content-tabs/html/test-lwthemes.html
new file mode 100644
index 0000000000..a43eb0062f
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/test-lwthemes.html
@@ -0,0 +1,44 @@
+<html><head>
+<title>test lightweight themes</title>
+</head><body>
+<script>
+var themes = [
+ {
+ id: "test-01",
+ name: "Test 01",
+ headerURL: "test.png",
+ footerURL: "test.png",
+ textcolor: "#fff",
+ accentcolor: "#6b6b6b",
+ },
+ {
+ id: "test-02",
+ name: "Test 02",
+ headerURL: "test.png",
+ footerURL: "test.png",
+ textcolor: "#bcf",
+ accentcolor: "#8888FF",
+ },
+];
+
+const INSTALL = "InstallBrowserTheme";
+const PREVIEW = "PreviewBrowserTheme";
+const RESET_PREVIEW = "ResetBrowserThemePreview";
+
+function setTheme(node, theme, action) {
+ node.setAttribute("data-browsertheme", JSON.stringify(themes[theme]));
+ dump("dispatching " + action + "\n");
+ node.dispatchEvent(new Event(action, { bubbles: true, cancelable: false }));
+}
+</script>
+
+<button id="install1"
+ onclick="setTheme(this, 0, INSTALL);"
+ onmouseover="setTheme(this, 0, PREVIEW);"
+ onmouseout="setTheme(this, 0, RESET_PREVIEW);">Test 01</button>
+<button id="install2"
+ onclick="setTheme(this, 1, INSTALL);"
+ onmouseover="setTheme(this, 1, PREVIEW);"
+ onmouseout="setTheme(this, 1, RESET_PREVIEW);">Test 02</button>
+</body>
+</html>
diff --git a/comm/mail/test/browser/content-tabs/html/test.png b/comm/mail/test/browser/content-tabs/html/test.png
new file mode 100644
index 0000000000..e3988bfc76
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/test.png
Binary files differ
diff --git a/comm/mail/test/browser/content-tabs/html/webextension.xpi b/comm/mail/test/browser/content-tabs/html/webextension.xpi
new file mode 100644
index 0000000000..d4e4f27507
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/webextension.xpi
Binary files differ
diff --git a/comm/mail/test/browser/content-tabs/html/whatsnew.html b/comm/mail/test/browser/content-tabs/html/whatsnew.html
new file mode 100644
index 0000000000..bb5dab4006
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/whatsnew.html
@@ -0,0 +1,13 @@
+<html>
+ <head>
+ <title>What's New Content Test</title>
+ <link rel="icon shortcut" href="whatsnew.png"/>
+ </head>
+ <body bgcolor="#FFFFFF">
+ <menu type="context" id="pageContextMenu">
+ <menuitem label="Click me!" id="pageMenuItem"/>
+ </menu>
+ <h1 contextmenu="pageContextMenu">What's New Content Test</h1>
+ <textarea>Zombocom</textarea>
+ </body>
+</html>
diff --git a/comm/mail/test/browser/content-tabs/html/whatsnew.png b/comm/mail/test/browser/content-tabs/html/whatsnew.png
new file mode 100644
index 0000000000..bb3ff3b069
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/whatsnew.png
Binary files differ
diff --git a/comm/mail/test/browser/content-tabs/html/whatsnew1.html b/comm/mail/test/browser/content-tabs/html/whatsnew1.html
new file mode 100644
index 0000000000..a1579dd3ee
--- /dev/null
+++ b/comm/mail/test/browser/content-tabs/html/whatsnew1.html
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>What's New Content Test 1</title>
+ </head>
+ <body bgcolor="#FFFFFF">
+ <h1>What's New Content Test 1</h1>
+ </body>
+</html>