summaryrefslogtreecommitdiffstats
path: root/comm/mail/test/browser/folder-display/browser_columns.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/test/browser/folder-display/browser_columns.js')
-rw-r--r--comm/mail/test/browser/folder-display/browser_columns.js955
1 files changed, 955 insertions, 0 deletions
diff --git a/comm/mail/test/browser/folder-display/browser_columns.js b/comm/mail/test/browser/folder-display/browser_columns.js
new file mode 100644
index 0000000000..836f5c3fa4
--- /dev/null
+++ b/comm/mail/test/browser/folder-display/browser_columns.js
@@ -0,0 +1,955 @@
+/* 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/. */
+
+/*
+ * Test column default logic and persistence logic. Persistence comes in both
+ * tab-switching (because of the multiplexed implementation) and
+ * folder-switching forms.
+ */
+
+"use strict";
+
+var {
+ be_in_folder,
+ close_tab,
+ create_folder,
+ create_virtual_folder,
+ enter_folder,
+ inboxFolder,
+ make_message_sets_in_folders,
+ mc,
+ open_folder_in_new_tab,
+ switch_tab,
+ wait_for_all_messages_to_load,
+ select_click_row,
+ delete_messages,
+} = ChromeUtils.import(
+ "resource://testing-common/mozmill/FolderDisplayHelpers.jsm"
+);
+var { click_menus_in_sequence } = ChromeUtils.import(
+ "resource://testing-common/mozmill/WindowHelpers.jsm"
+);
+
+// needed to zero inter-folder processing delay
+var { MailUtils } = ChromeUtils.import("resource:///modules/MailUtils.jsm");
+
+var { GlodaSyntheticView } = ChromeUtils.import(
+ "resource:///modules/gloda/GlodaSyntheticView.jsm"
+);
+
+var folderInbox, folderSent, folderVirtual, folderA, folderB;
+// INBOX_DEFAULTS sans 'dateCol' but gains 'tagsCol'
+var columnsB;
+
+// these are for the reset/apply to other/apply to other+child tests.
+var folderSource, folderParent, folderChild1, folderChild2;
+
+var gColumnStateUpdated = false;
+
+var useCorrespondent;
+var INBOX_DEFAULTS;
+var CARDS_INBOX_DEFAULT;
+var SENT_DEFAULTS;
+var CARDS_SENT_DEFAULTS;
+var VIRTUAL_DEFAULTS;
+var GLODA_DEFAULTS;
+
+add_setup(async function () {
+ useCorrespondent = Services.prefs.getBoolPref(
+ "mail.threadpane.use_correspondents"
+ );
+ INBOX_DEFAULTS = [
+ "threadCol",
+ "flaggedCol",
+ "attachmentCol",
+ "subjectCol",
+ "unreadButtonColHeader",
+ useCorrespondent ? "correspondentCol" : "senderCol",
+ "junkStatusCol",
+ "dateCol",
+ ];
+ CARDS_INBOX_DEFAULT = ["subjectCol", "senderCol", "dateCol", "tagsCol"];
+ SENT_DEFAULTS = [
+ "threadCol",
+ "flaggedCol",
+ "attachmentCol",
+ "subjectCol",
+ "unreadButtonColHeader",
+ useCorrespondent ? "correspondentCol" : "recipientCol",
+ "junkStatusCol",
+ "dateCol",
+ ];
+ CARDS_SENT_DEFAULTS = ["subjectCol", "recipientCol", "dateCol", "tagsCol"];
+ VIRTUAL_DEFAULTS = [
+ "threadCol",
+ "flaggedCol",
+ "attachmentCol",
+ "subjectCol",
+ "unreadButtonColHeader",
+ useCorrespondent ? "correspondentCol" : "senderCol",
+ "junkStatusCol",
+ "dateCol",
+ "locationCol",
+ ];
+ GLODA_DEFAULTS = [
+ "threadCol",
+ "flaggedCol",
+ "subjectCol",
+ useCorrespondent ? "correspondentCol" : "senderCol",
+ "dateCol",
+ "locationCol",
+ ];
+
+ // create the source
+ folderSource = await create_folder("ColumnsApplySource");
+
+ registerCleanupFunction(async () => {
+ await ensure_cards_view();
+ });
+});
+
+/**
+ * Get the currently visible threadTree columns.
+ *
+ * @returns {string[]}
+ */
+function get_visible_threadtree_columns() {
+ let tabmail = document.getElementById("tabmail");
+ let about3Pane = tabmail.currentAbout3Pane;
+
+ let columns = about3Pane.threadPane.columns;
+ return columns.filter(column => !column.hidden).map(column => column.id);
+}
+
+/**
+ * Verify that the provided list of columns is visible in the given order,
+ * throwing an exception if it is not the case.
+ *
+ * @param {string[]} desiredColumns - A list of column ID strings for columns
+ * that should be visible in the order that they should be visible.
+ */
+function assert_visible_columns(desiredColumns) {
+ let tabmail = document.getElementById("tabmail");
+ let about3Pane = tabmail.currentAbout3Pane;
+
+ let columns = about3Pane.threadPane.columns;
+ let visibleColumns = columns
+ .filter(column => !column.hidden)
+ .map(column => column.id);
+ let failCol = visibleColumns.filter(x => !desiredColumns.includes(x));
+ if (failCol.length) {
+ throw new Error(
+ `Found unexpected visible columns: '${failCol}'!\ndesired list: ${desiredColumns}\nactual list: ${visibleColumns}`
+ );
+ }
+}
+
+/**
+ * Verify that the provided list of columns is the expected list for the cards
+ * view.
+ *
+ * @param {string[]} desiredColumns - A list of column ID strings for columns
+ * that should be visible.
+ */
+function assert_visible_cards_columns(desiredColumns) {
+ const tabmail = document.getElementById("tabmail");
+ const about3Pane = tabmail.currentAbout3Pane;
+
+ const columns = about3Pane.threadPane.cardColumns;
+ const failCol = columns.filter(x => !desiredColumns.includes(x));
+ if (failCol.length) {
+ throw new Error(
+ `Found unexpected cards columns: '${failCol}'!\ndesired list: ${desiredColumns}\nactual list: ${columns}`
+ );
+ }
+}
+
+/**
+ * Toggle the column visibility .
+ *
+ * @param {string} columnID - Id of the thread column element to click.
+ */
+async function toggleColumn(columnID) {
+ let tabmail = document.getElementById("tabmail");
+ let about3Pane = tabmail.currentAbout3Pane;
+
+ let colPicker = about3Pane.document.querySelector(
+ `th[is="tree-view-table-column-picker"] button`
+ );
+ let colPickerPopup = about3Pane.document.querySelector(
+ `th[is="tree-view-table-column-picker"] menupopup`
+ );
+
+ let shownPromise = BrowserTestUtils.waitForEvent(
+ colPickerPopup,
+ "popupshown"
+ );
+ EventUtils.synthesizeMouseAtCenter(colPicker, {}, about3Pane);
+ await shownPromise;
+ let hiddenPromise = BrowserTestUtils.waitForEvent(
+ colPickerPopup,
+ "popuphidden",
+ undefined,
+ event => event.originalTarget == colPickerPopup
+ );
+
+ const menuItem = colPickerPopup.querySelector(`[value="${columnID}"]`);
+ let checkedState = menuItem.getAttribute("checked");
+ let checkedStateChanged = TestUtils.waitForCondition(
+ () => checkedState != menuItem.getAttribute("checked"),
+ "The checked status changed"
+ );
+ colPickerPopup.activateItem(menuItem);
+ await checkedStateChanged;
+
+ // The column picker menupopup doesn't close automatically on purpose.
+ EventUtils.synthesizeKey("VK_ESCAPE", {}, about3Pane);
+ await hiddenPromise;
+}
+
+/**
+ * Make sure we set the proper defaults for an Inbox.
+ */
+add_task(async function test_column_defaults_inbox() {
+ // just use the inbox; comes from test-folder-display-helpers
+ folderInbox = inboxFolder;
+ await enter_folder(folderInbox);
+ await ensure_table_view();
+ assert_visible_columns(INBOX_DEFAULTS);
+ assert_visible_cards_columns(CARDS_INBOX_DEFAULT);
+});
+
+add_task(async function test_keypress_on_columns() {
+ const [messageSet] = await make_message_sets_in_folders(
+ [folderInbox],
+ [{ count: 1 }]
+ );
+ registerCleanupFunction(async () => {
+ await delete_messages(messageSet);
+ });
+
+ let tabmail = document.getElementById("tabmail");
+ let about3Pane = tabmail.currentAbout3Pane;
+
+ // Select the first row.
+ let row = about3Pane.threadTree.getRowAtIndex(0);
+ EventUtils.synthesizeMouseAtCenter(row, {}, about3Pane);
+
+ // Press SHIFT+TAB and LEFT to focus on the column picker.
+ EventUtils.synthesizeKey("VK_TAB", { shiftKey: true }, about3Pane);
+ EventUtils.synthesizeKey("KEY_ArrowLeft", {}, about3Pane);
+
+ Assert.equal(
+ about3Pane.document.activeElement,
+ about3Pane.document.querySelector(
+ `th[is="tree-view-table-column-picker"] button`
+ ),
+ "The column picker should be focused"
+ );
+
+ Assert.equal(tabmail.tabInfo.length, 1, "Only 1 tab should be visible");
+
+ let colPickerPopup = about3Pane.document.querySelector(
+ `th[is="tree-view-table-column-picker"] menupopup`
+ );
+ let shownPromise = BrowserTestUtils.waitForEvent(
+ colPickerPopup,
+ "popupshown"
+ );
+ // Pressing Enter should open the column picker popup.
+ EventUtils.synthesizeKey("VK_RETURN", {}, about3Pane);
+ await shownPromise;
+
+ Assert.equal(
+ tabmail.tabInfo.length,
+ 1,
+ "The selected message shouldn't be opened in another tab"
+ );
+
+ let hiddenPromise = BrowserTestUtils.waitForEvent(
+ colPickerPopup,
+ "popuphidden",
+ undefined,
+ event => event.originalTarget == colPickerPopup
+ );
+ // Close the column picker.
+ EventUtils.synthesizeKey("VK_ESCAPE", {}, about3Pane);
+ await hiddenPromise;
+
+ // Move the focus to another column.
+ EventUtils.synthesizeKey("KEY_ArrowLeft", {}, about3Pane);
+ Assert.notEqual(
+ about3Pane.document.activeElement,
+ about3Pane.document.querySelector(
+ `th[is="tree-view-table-column-picker"] button`
+ ),
+ "The column picker should not be focused"
+ );
+
+ shownPromise = BrowserTestUtils.waitForEvent(colPickerPopup, "popupshown");
+ // Right clicking on a column header should trigger the column picker
+ // menupopup.
+ EventUtils.synthesizeMouseAtCenter(
+ about3Pane.document.activeElement,
+ { type: "contextmenu" },
+ about3Pane
+ );
+ await shownPromise;
+
+ hiddenPromise = BrowserTestUtils.waitForEvent(
+ colPickerPopup,
+ "popuphidden",
+ undefined,
+ event => event.originalTarget == colPickerPopup
+ );
+ // Close the column picker.
+ EventUtils.synthesizeKey("VK_ESCAPE", {}, about3Pane);
+ await hiddenPromise;
+});
+
+/**
+ * Make sure we set the proper defaults for a Sent folder.
+ */
+add_task(async function test_column_defaults_sent() {
+ folderSent = await create_folder("ColumnsSent");
+ folderSent.setFlag(Ci.nsMsgFolderFlags.SentMail);
+
+ await be_in_folder(folderSent);
+ assert_visible_columns(SENT_DEFAULTS);
+ assert_visible_cards_columns(CARDS_SENT_DEFAULTS);
+});
+
+/**
+ * Make sure we set the proper defaults for a multi-folder virtual folder.
+ */
+add_task(async function test_column_defaults_cross_folder_virtual_folder() {
+ folderVirtual = create_virtual_folder(
+ [folderInbox, folderSent],
+ {},
+ true,
+ "ColumnsVirtual"
+ );
+
+ await be_in_folder(folderVirtual);
+ assert_visible_columns(VIRTUAL_DEFAULTS);
+});
+
+/**
+ * Make sure that we initialize our columns from the inbox and that they persist
+ * after that and don't follow the inbox. This also does a good workout of the
+ * persistence logic.
+ */
+add_task(async function test_column_defaults_inherit_from_inbox() {
+ folderA = await create_folder("ColumnsA");
+ // - the folder should inherit from the inbox...
+ await be_in_folder(folderA);
+ assert_visible_columns(INBOX_DEFAULTS);
+
+ // - if we go back to the inbox and change things then the folder's settings
+ // should not change.
+ await be_in_folder(folderInbox);
+ // show tags, hide date
+ await toggleColumn("dateCol");
+ await toggleColumn("tagsCol");
+ // (paranoia verify)
+ columnsB = INBOX_DEFAULTS.slice(0, -1);
+ columnsB.push("tagsCol");
+ assert_visible_columns(columnsB);
+
+ // make sure A did not change; it should still have dateCol.
+ await be_in_folder(folderA);
+ assert_visible_columns(INBOX_DEFAULTS);
+
+ // and a newly created folder always gets the default set.
+ folderB = await create_folder("ColumnsB");
+ await be_in_folder(folderB);
+ assert_visible_columns(INBOX_DEFAULTS);
+ // Now change the columns for folder B so we can use it later.
+ await toggleColumn("dateCol");
+ await toggleColumn("tagsCol");
+
+ // - and if we restore the inbox, folder B should stay modified too.
+ await be_in_folder(folderInbox);
+ await toggleColumn("dateCol");
+ await toggleColumn("tagsCol");
+ assert_visible_columns(INBOX_DEFAULTS);
+
+ await be_in_folder(folderB);
+ assert_visible_columns(columnsB);
+});
+
+/**
+ * Make sure that when we change tabs that things persist/restore correctly.
+ */
+add_task(async function test_column_visibility_persists_through_tab_changes() {
+ let tabA = await be_in_folder(folderA);
+ assert_visible_columns(INBOX_DEFAULTS);
+
+ let tabB = await open_folder_in_new_tab(folderB);
+ assert_visible_columns(columnsB);
+
+ // - switch back and forth among the loaded and verify
+ await switch_tab(tabA);
+ assert_visible_columns(INBOX_DEFAULTS);
+
+ await switch_tab(tabB);
+ assert_visible_columns(columnsB);
+
+ // - change things and make sure the changes stick
+ // B gain accountCol
+ let bWithExtra = columnsB.concat(["accountCol"]);
+ await toggleColumn("accountCol");
+ assert_visible_columns(bWithExtra);
+
+ await switch_tab(tabA);
+ assert_visible_columns(INBOX_DEFAULTS);
+
+ // A loses junk
+ let aSansJunk = INBOX_DEFAULTS.slice(0, -2); // nukes junk, date
+ await toggleColumn("junkStatusCol");
+ aSansJunk.push("dateCol"); // put date back
+ assert_visible_columns(aSansJunk);
+
+ await switch_tab(tabB);
+ assert_visible_columns(bWithExtra);
+ // B goes back to normal
+ await toggleColumn("accountCol");
+
+ await switch_tab(tabA);
+ assert_visible_columns(aSansJunk);
+ // A goes back to "normal"
+ await toggleColumn("junkStatusCol");
+ assert_visible_columns(INBOX_DEFAULTS);
+
+ close_tab(tabB);
+});
+
+/**
+ * Make sure that when we change folders that things persist/restore correctly.
+ */
+add_task(
+ async function test_column_visibility_persists_through_folder_changes() {
+ await be_in_folder(folderA);
+ assert_visible_columns(INBOX_DEFAULTS);
+
+ // more for A
+ let aWithExtra = INBOX_DEFAULTS.concat(["sizeCol", "tagsCol"]);
+ await toggleColumn("sizeCol");
+ await toggleColumn("tagsCol");
+ assert_visible_columns(aWithExtra);
+
+ await be_in_folder(folderB);
+ assert_visible_columns(columnsB);
+
+ // B gain accountCol
+ let bWithExtra = columnsB.concat(["accountCol"]);
+ await toggleColumn("accountCol");
+ assert_visible_columns(bWithExtra);
+
+ // check A
+ await be_in_folder(folderA);
+ assert_visible_columns(aWithExtra);
+
+ // check B
+ await be_in_folder(folderB);
+ assert_visible_columns(bWithExtra);
+
+ // restore B
+ await toggleColumn("accountCol");
+
+ // restore A
+ await be_in_folder(folderA);
+ await toggleColumn("sizeCol");
+ await toggleColumn("tagsCol");
+
+ // check B
+ await be_in_folder(folderB);
+ assert_visible_columns(columnsB);
+
+ // check A
+ await be_in_folder(folderA);
+ assert_visible_columns(INBOX_DEFAULTS);
+ }
+);
+
+/**
+ * Test that reordering persists through tab changes and folder changes.
+ */
+add_task(async function test_column_reordering_persists() {
+ let tabA = await be_in_folder(folderA);
+ let tabB = await open_folder_in_new_tab(folderB);
+
+ let tabmail = document.getElementById("tabmail");
+ let about3Pane = tabmail.currentAbout3Pane;
+
+ // Move the tags column before the junk.
+ let tagsColButton = about3Pane.document.getElementById("tagsColButton");
+ tagsColButton.focus();
+ // Press Alt + Arrow Left twice to move the tags column before the junk
+ // status column.
+ EventUtils.synthesizeKey(
+ "KEY_ArrowLeft",
+ { altKey: true },
+ about3Pane.window
+ );
+ EventUtils.synthesizeKey(
+ "KEY_ArrowLeft",
+ { altKey: true },
+ about3Pane.window
+ );
+
+ // The columns in folderB should reflect the new order.
+ let reorderdB = columnsB.concat();
+ info(reorderdB);
+ reorderdB.splice(5, 0, reorderdB.splice(7, 1)[0]);
+ info(reorderdB);
+ assert_visible_columns(reorderdB);
+
+ // Move the tags column after the junk, the focus should still be on the
+ // tags button.
+ EventUtils.synthesizeKey(
+ "KEY_ArrowRight",
+ { altKey: true },
+ about3Pane.window
+ );
+
+ reorderdB.splice(6, 0, reorderdB.splice(5, 1)[0]);
+ assert_visible_columns(reorderdB);
+
+ await switch_tab(tabA);
+ assert_visible_columns(INBOX_DEFAULTS);
+
+ await switch_tab(tabB);
+ assert_visible_columns(reorderdB);
+
+ await be_in_folder(folderInbox);
+ assert_visible_columns(INBOX_DEFAULTS);
+
+ await be_in_folder(folderB);
+ assert_visible_columns(reorderdB);
+
+ close_tab(tabB);
+});
+
+async function invoke_column_picker_option(aActions) {
+ let tabmail = document.getElementById("tabmail");
+ let about3Pane = tabmail.currentAbout3Pane;
+
+ let colPicker = about3Pane.document.querySelector(
+ `th[is="tree-view-table-column-picker"] button`
+ );
+ let colPickerPopup = about3Pane.document.querySelector(
+ `th[is="tree-view-table-column-picker"] menupopup`
+ );
+
+ let shownPromise = BrowserTestUtils.waitForEvent(
+ colPickerPopup,
+ "popupshown"
+ );
+ EventUtils.synthesizeMouseAtCenter(colPicker, {}, about3Pane);
+ await shownPromise;
+ await click_menus_in_sequence(colPickerPopup, aActions);
+}
+
+/**
+ * The column picker's "reset columns to default" option should set our state
+ * back to the natural state.
+ */
+add_task(async function test_reset_to_inbox() {
+ // We should be in the inbox folder and have the default set unchanged.
+ assert_visible_columns(INBOX_DEFAULTS);
+
+ // Show the size column.
+ let conExtra = INBOX_DEFAULTS.concat(["sizeCol"]);
+ await toggleColumn("sizeCol");
+ assert_visible_columns(conExtra);
+
+ // Trigger a reset.
+ await invoke_column_picker_option([{ label: "Restore column order" }]);
+ // Ensure the default set was restored.
+ assert_visible_columns(INBOX_DEFAULTS);
+});
+
+async function _apply_to_folder_common(aChildrenToo, folder) {
+ let notificatonPromise;
+ if (aChildrenToo) {
+ notificatonPromise = TestUtils.topicObserved(
+ "msg-folder-columns-propagated"
+ );
+ }
+
+ const menuItems = [
+ { class: "applyTo-menu" },
+ {
+ class: aChildrenToo
+ ? "applyToFolderAndChildren-menu"
+ : "applyToFolder-menu",
+ },
+ { label: "Local Folders" },
+ ];
+ if (!folder.isServer) {
+ menuItems.push({ label: folder.name });
+ }
+ menuItems.push(menuItems.at(-1));
+
+ const dialogPromise = BrowserTestUtils.promiseAlertDialog("accept");
+ await invoke_column_picker_option(menuItems);
+ await dialogPromise;
+
+ if (notificatonPromise) {
+ await notificatonPromise;
+ }
+}
+
+/**
+ * Change settings in a folder, apply them to another folder that also has
+ * children. Make sure the folder changes but the children do not.
+ */
+add_task(async function test_apply_to_folder_no_children() {
+ folderParent = await create_folder("ColumnsApplyParent");
+ folderParent.createSubfolder("Child1", null);
+ folderChild1 = folderParent.getChildNamed("Child1");
+ folderParent.createSubfolder("Child2", null);
+ folderChild2 = folderParent.getChildNamed("Child2");
+
+ await be_in_folder(folderSource);
+
+ // reset!
+ await invoke_column_picker_option([{ label: "Restore column order" }]);
+
+ // permute!
+ let conExtra = INBOX_DEFAULTS.concat(["sizeCol"]);
+ await toggleColumn("sizeCol");
+ assert_visible_columns(conExtra);
+
+ // apply to the one dude
+ await _apply_to_folder_common(false, folderParent);
+
+ // make sure it copied to the parent
+ await be_in_folder(folderParent);
+ assert_visible_columns(conExtra);
+
+ // but not the children
+ await be_in_folder(folderChild1);
+ assert_visible_columns(INBOX_DEFAULTS);
+ await be_in_folder(folderChild2);
+ assert_visible_columns(INBOX_DEFAULTS);
+});
+
+/**
+ * Change settings in a folder, apply them to another folder and its children.
+ * Make sure the folder and its children change.
+ */
+add_task(async function test_apply_to_folder_and_children() {
+ // no need to throttle ourselves during testing.
+ MailUtils.INTER_FOLDER_PROCESSING_DELAY_MS = 0;
+
+ await be_in_folder(folderSource);
+
+ // reset!
+ await invoke_column_picker_option([{ label: "Restore column order" }]);
+ let cols = get_visible_threadtree_columns();
+
+ // permute!
+ let conExtra = cols.concat(["tagsCol"]);
+ await toggleColumn("tagsCol");
+ assert_visible_columns(conExtra);
+
+ // apply to the dude and his offspring
+ await _apply_to_folder_common(true, folderParent);
+
+ // make sure it copied to the parent and his children
+ await be_in_folder(folderParent);
+ assert_visible_columns(conExtra);
+ await be_in_folder(folderChild1);
+ assert_visible_columns(conExtra);
+ await be_in_folder(folderChild2);
+ assert_visible_columns(conExtra);
+});
+
+/**
+ * Change settings in an incoming folder, apply them to an outgoing folder that
+ * also has children. Make sure the folder changes but the children do not.
+ */
+add_task(async function test_apply_to_folder_no_children_swapped() {
+ folderParent = await create_folder("ColumnsApplyParentOutgoing");
+ folderParent.setFlag(Ci.nsMsgFolderFlags.SentMail);
+ folderParent.createSubfolder("Child1", null);
+ folderChild1 = folderParent.getChildNamed("Child1");
+ folderParent.createSubfolder("Child2", null);
+ folderChild2 = folderParent.getChildNamed("Child2");
+
+ await be_in_folder(folderSource);
+
+ // reset!
+ await invoke_column_picker_option([{ label: "Restore column order" }]);
+
+ // permute!
+ let conExtra = [...INBOX_DEFAULTS];
+ if (useCorrespondent) {
+ conExtra[5] = "senderCol";
+ await toggleColumn("correspondentCol");
+ await toggleColumn("senderCol");
+ } else {
+ conExtra[5] = "correspondentCol";
+ await toggleColumn("senderCol");
+ await toggleColumn("correspondentCol");
+ }
+ assert_visible_columns(conExtra);
+
+ // Apply to the one dude.
+ await _apply_to_folder_common(false, folderParent);
+
+ // Make sure it copied to the parent.
+ let conExtraSwapped = [...SENT_DEFAULTS];
+ conExtraSwapped[5] = useCorrespondent ? "recipientCol" : "correspondentCol";
+ await be_in_folder(folderParent);
+ assert_visible_columns(conExtraSwapped);
+
+ // But not the children.
+ await be_in_folder(folderChild1);
+ assert_visible_columns(SENT_DEFAULTS);
+ await be_in_folder(folderChild2);
+ assert_visible_columns(SENT_DEFAULTS);
+});
+
+/**
+ * Change settings in an incoming folder, apply them to an outgoing folder and
+ * its children. Make sure the folder and its children change.
+ */
+add_task(async function test_apply_to_folder_and_children_swapped() {
+ // No need to throttle ourselves during testing.
+ MailUtils.INTER_FOLDER_PROCESSING_DELAY_MS = 0;
+
+ await be_in_folder(folderSource);
+
+ // reset order!
+ await invoke_column_picker_option([{ label: "Restore column order" }]);
+
+ // permute!
+ let conExtra = [...INBOX_DEFAULTS];
+ if (useCorrespondent) {
+ conExtra[5] = "senderCol";
+ await toggleColumn("correspondentCol");
+ await toggleColumn("senderCol");
+ } else {
+ conExtra[5] = "correspondentCol";
+ await toggleColumn("senderCol");
+ await toggleColumn("correspondentCol");
+ }
+ assert_visible_columns(conExtra);
+
+ // Apply to the dude and his offspring.
+ await _apply_to_folder_common(true, folderParent);
+
+ // Make sure it copied to the parent and his children.
+ let conExtraSwapped = [...SENT_DEFAULTS];
+ conExtraSwapped[5] = useCorrespondent ? "recipientCol" : "correspondentCol";
+ await be_in_folder(folderParent);
+ assert_visible_columns(conExtraSwapped);
+ await be_in_folder(folderChild1);
+ assert_visible_columns(conExtraSwapped);
+ await be_in_folder(folderChild2);
+ assert_visible_columns(conExtraSwapped);
+});
+
+/**
+ * Change settings in a folder, apply them to the root folder and its children.
+ * Make sure the children change.
+ */
+add_task(async function test_apply_to_root_folder_and_children() {
+ // No need to throttle ourselves during testing.
+ MailUtils.INTER_FOLDER_PROCESSING_DELAY_MS = 0;
+
+ await be_in_folder(folderSource);
+
+ // Reset!
+ await invoke_column_picker_option([{ label: "Restore column order" }]);
+ const cols = get_visible_threadtree_columns();
+
+ // Permute!
+ const conExtra = cols.concat(["locationCol"]);
+ await toggleColumn("locationCol");
+ assert_visible_columns(conExtra);
+
+ // Apply to the root folder and its descendants.
+ await _apply_to_folder_common(true, folderSource.rootFolder);
+
+ // Make sure it is copied to all folders of this server.
+ for (const folder of folderSource.rootFolder.descendants) {
+ await be_in_folder(folder);
+ assert_visible_columns(conExtra);
+ folder.msgDatabase = null;
+ }
+});
+
+/**
+ * Create a fake gloda collection.
+ */
+class FakeCollection {
+ constructor() {
+ this.items = [];
+ }
+}
+
+add_task(async function test_column_defaults_gloda_collection() {
+ let tabmail = document.getElementById("tabmail");
+ let tab = tabmail.openTab("mail3PaneTab", {
+ folderPaneVisible: false,
+ syntheticView: new GlodaSyntheticView({
+ collection: new FakeCollection(),
+ }),
+ title: "Test gloda results",
+ });
+ await BrowserTestUtils.waitForCondition(
+ () => tab.chromeBrowser.contentWindow.gViewWrapper?.isSynthetic,
+ "synthetic view loaded"
+ );
+ assert_visible_columns(GLODA_DEFAULTS);
+ close_tab(tab);
+});
+
+add_task(async function test_persist_columns_gloda_collection() {
+ let fakeCollection = new FakeCollection();
+ let tabmail = document.getElementById("tabmail");
+ let tab1 = tabmail.openTab("mail3PaneTab", {
+ folderPaneVisible: false,
+ syntheticView: new GlodaSyntheticView({
+ collection: fakeCollection,
+ }),
+ title: "Test gloda results 1",
+ });
+ await BrowserTestUtils.waitForCondition(
+ () => tab1.chromeBrowser.contentWindow.gViewWrapper?.isSynthetic,
+ "synthetic view loaded"
+ );
+
+ await toggleColumn("locationCol");
+ await toggleColumn("accountCol");
+
+ // GLODA_DEFAULTS sans 'locationCol' but gains 'accountCol'
+ let glodaColumns = GLODA_DEFAULTS.slice(0, -1);
+ glodaColumns.push("accountCol");
+
+ let tab2 = tabmail.openTab("mail3PaneTab", {
+ folderPaneVisible: false,
+ syntheticView: new GlodaSyntheticView({
+ collection: fakeCollection,
+ }),
+ title: "Test gloda results 2",
+ });
+ await BrowserTestUtils.waitForCondition(
+ () => tab2.chromeBrowser.contentWindow.gViewWrapper?.isSynthetic,
+ "synthetic view loaded"
+ );
+ assert_visible_columns(glodaColumns);
+
+ // Restore default gloda columns for debug ease.
+ await toggleColumn("locationCol");
+ await toggleColumn("accountCol");
+
+ close_tab(tab2);
+ close_tab(tab1);
+});
+
+add_task(async function test_reset_columns_gloda_collection() {
+ let fakeCollection = new FakeCollection();
+ let tabmail = document.getElementById("tabmail");
+ let tab1 = tabmail.openTab("mail3PaneTab", {
+ folderPaneVisible: false,
+ syntheticView: new GlodaSyntheticView({
+ collection: fakeCollection,
+ }),
+ title: "Test gloda results 1",
+ });
+ await BrowserTestUtils.waitForCondition(
+ () => tab1.chromeBrowser.contentWindow.gViewWrapper?.isSynthetic,
+ "synthetic view loaded"
+ );
+
+ await toggleColumn("locationCol");
+ await toggleColumn("accountCol");
+
+ // GLODA_DEFAULTS sans 'locationCol' but gains 'accountCol'
+ let glodaColumns = GLODA_DEFAULTS.slice(0, -1);
+ glodaColumns.push("accountCol");
+
+ assert_visible_columns(glodaColumns);
+
+ // reset order!
+ await invoke_column_picker_option([{ label: "Restore column order" }]);
+
+ assert_visible_columns(GLODA_DEFAULTS);
+
+ let tab2 = tabmail.openTab("mail3PaneTab", {
+ folderPaneVisible: false,
+ syntheticView: new GlodaSyntheticView({
+ collection: fakeCollection,
+ }),
+ title: "Test gloda results 2",
+ });
+ await BrowserTestUtils.waitForCondition(
+ () => tab2.chromeBrowser.contentWindow.gViewWrapper?.isSynthetic,
+ "synthetic view loaded"
+ );
+ assert_visible_columns(GLODA_DEFAULTS);
+
+ // Restore default gloda columns for debug ease.
+ await toggleColumn("locationCol");
+ await toggleColumn("accountCol");
+
+ close_tab(tab2);
+ close_tab(tab1);
+
+ Assert.report(
+ false,
+ undefined,
+ undefined,
+ "Test ran to completion successfully"
+ );
+});
+
+add_task(async function test_double_click_column_picker() {
+ let doubleClickFolder = await create_folder("double click folder");
+ await make_message_sets_in_folders([doubleClickFolder], [{ count: 1 }]);
+ await be_in_folder(doubleClickFolder);
+ await select_click_row(0);
+
+ let tabmail = document.getElementById("tabmail");
+ const currentTabInfo = tabmail.currentTabInfo;
+ let about3Pane = tabmail.currentAbout3Pane;
+
+ let colPicker = about3Pane.document.querySelector(
+ `th[is="tree-view-table-column-picker"] button`
+ );
+ let colPickerPopup = about3Pane.document.querySelector(
+ `th[is="tree-view-table-column-picker"] menupopup`
+ );
+
+ let shownPromise = BrowserTestUtils.waitForEvent(
+ colPickerPopup,
+ "popupshown"
+ );
+ EventUtils.synthesizeMouseAtCenter(colPicker, {}, about3Pane);
+ await shownPromise;
+ let hiddenPromise = BrowserTestUtils.waitForEvent(
+ colPickerPopup,
+ "popuphidden",
+ undefined,
+ event => event.originalTarget == colPickerPopup
+ );
+
+ const menuItem = colPickerPopup.querySelector('[value="threadCol"]');
+ menuItem.dispatchEvent(new MouseEvent("dblclick", { button: 0 }));
+
+ // The column picker menupopup doesn't close automatically on purpose.
+ EventUtils.synthesizeKey("VK_ESCAPE", {}, about3Pane);
+ await hiddenPromise;
+
+ Assert.deepEqual(
+ tabmail.currentTabInfo,
+ currentTabInfo,
+ "No message was opened in a tab"
+ );
+});