summaryrefslogtreecommitdiffstats
path: root/comm/mail/test/browser/folder-display/browser_rightClickMiddleClickMessages.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/test/browser/folder-display/browser_rightClickMiddleClickMessages.js')
-rw-r--r--comm/mail/test/browser/folder-display/browser_rightClickMiddleClickMessages.js564
1 files changed, 564 insertions, 0 deletions
diff --git a/comm/mail/test/browser/folder-display/browser_rightClickMiddleClickMessages.js b/comm/mail/test/browser/folder-display/browser_rightClickMiddleClickMessages.js
new file mode 100644
index 0000000000..50033f0e7e
--- /dev/null
+++ b/comm/mail/test/browser/folder-display/browser_rightClickMiddleClickMessages.js
@@ -0,0 +1,564 @@
+/* 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 the many horrors involving right-clicks, middle clicks, and selections.
+ */
+
+"use strict";
+
+var {
+ add_message_sets_to_folders,
+ assert_displayed,
+ assert_message_not_in_view,
+ assert_message_pane_focused,
+ assert_messages_not_in_view,
+ assert_nothing_selected,
+ assert_selected,
+ assert_selected_and_displayed,
+ assert_selected_tab,
+ assert_thread_tree_focused,
+ be_in_folder,
+ close_popup,
+ close_tab,
+ collapse_all_threads,
+ create_folder,
+ create_thread,
+ delete_via_popup,
+ expand_all_threads,
+ focus_thread_tree,
+ get_about_3pane,
+ make_display_threaded,
+ make_message_sets_in_folders,
+ mc,
+ middle_click_on_row,
+ reset_context_menu_background_tabs,
+ right_click_on_row,
+ select_click_row,
+ select_none,
+ select_shift_click_row,
+ set_context_menu_background_tabs,
+ switch_tab,
+ wait_for_message_display_completion,
+ wait_for_popup_to_open,
+} = ChromeUtils.import(
+ "resource://testing-common/mozmill/FolderDisplayHelpers.jsm"
+);
+
+var folder, threadedFolder;
+var tabmail = document.getElementById("tabmail");
+
+/**
+ * The number of messages in the thread we use to test.
+ */
+var NUM_MESSAGES_IN_THREAD = 6;
+
+add_setup(async function () {
+ folder = await create_folder("RightClickMiddleClickA");
+ threadedFolder = await create_folder("RightClickMiddleClickB");
+ // we want exactly as many messages as we plan to delete, so that we can test
+ // that the message window and tabs close when they run out of things to
+ // to display.
+ await make_message_sets_in_folders([folder], [{ count: 20 }]);
+ // Create a few messages and one thread (the order is important here, as it
+ // determines where the thread is placed. We want it placed right at the
+ // end.)
+ await make_message_sets_in_folders([threadedFolder], [{ count: 50 }]);
+ let thread = create_thread(NUM_MESSAGES_IN_THREAD);
+ await add_message_sets_to_folders([threadedFolder], [thread]);
+
+ registerCleanupFunction(function () {
+ reset_context_menu_background_tabs();
+ });
+});
+
+/**
+ * Make sure that a right-click when there is nothing currently selected does
+ * not cause us to display something, as well as correctly causing a transient
+ * selection to occur.
+ */
+add_task(async function test_right_click_with_nothing_selected() {
+ await be_in_folder(folder);
+
+ select_none();
+ assert_nothing_selected();
+
+ await right_click_on_row(1);
+ // Check that the popup opens.
+ await wait_for_popup_to_open(getMailContext());
+
+ assert_selected(1);
+ assert_displayed();
+
+ await close_popup(mc, getMailContext());
+ assert_nothing_selected();
+}).skip();
+
+/**
+ * Test that clicking on the column header shows the column picker.
+ */
+add_task(async function test_right_click_column_header_shows_col_picker() {
+ await be_in_folder(folder);
+
+ // The treecolpicker element itself doesn't have an id, so we have to walk
+ // down from the parent to find it.
+ // treadCols
+ // |- hbox item 0
+ // |- treecolpicker <-- item 1 this is the one we want
+ let threadCols = mc.window.document.getElementById("threadCols");
+ let treeColPicker = threadCols.querySelector("treecolpicker");
+ let popup = treeColPicker.querySelector("[anonid=popup]");
+
+ // Right click the subject column header
+ // This should show the column picker popup.
+ let subjectCol = mc.window.document.getElementById("subjectCol");
+ EventUtils.synthesizeMouseAtCenter(
+ subjectCol,
+ { type: "contextmenu", button: 2 },
+ subjectCol.ownerGlobal
+ );
+
+ // Check that the popup opens.
+ await wait_for_popup_to_open(popup);
+ // Hide it again, we just wanted to know it was going to be shown.
+ await close_popup(mc, popup);
+}).skip();
+
+/**
+ * One-thing selected, right-click on something else.
+ */
+add_task(async function test_right_click_with_one_thing_selected() {
+ await be_in_folder(folder);
+
+ select_click_row(0);
+ assert_selected_and_displayed(0);
+
+ await right_click_on_row(1);
+ assert_selected(1);
+ assert_displayed(0);
+
+ await close_popup(mc, getMailContext());
+ assert_selected_and_displayed(0);
+}).skip();
+
+/**
+ * Many things selected, right-click on something that is not in that selection.
+ */
+add_task(async function test_right_click_with_many_things_selected() {
+ await be_in_folder(folder);
+
+ select_click_row(0);
+ select_shift_click_row(5);
+ assert_selected_and_displayed([0, 5]);
+
+ await right_click_on_row(6);
+ assert_selected(6);
+ assert_displayed([0, 5]);
+
+ await close_popup(mc, getMailContext());
+ assert_selected_and_displayed([0, 5]);
+}).skip();
+
+/**
+ * One thing selected, right-click on that.
+ */
+add_task(async function test_right_click_on_existing_single_selection() {
+ await be_in_folder(folder);
+
+ select_click_row(3);
+ assert_selected_and_displayed(3);
+
+ await right_click_on_row(3);
+ assert_selected_and_displayed(3);
+
+ await close_popup(mc, getMailContext());
+ assert_selected_and_displayed(3);
+});
+
+/**
+ * Many things selected, right-click somewhere in the selection.
+ */
+add_task(async function test_right_click_on_existing_multi_selection() {
+ await be_in_folder(folder);
+
+ select_click_row(3);
+ select_shift_click_row(6);
+ assert_selected_and_displayed([3, 6]);
+
+ await right_click_on_row(5);
+ assert_selected_and_displayed([3, 6]);
+
+ await close_popup(mc, getMailContext());
+ assert_selected_and_displayed([3, 6]);
+});
+
+/**
+ * Middle clicking should open a message in a tab, but not affect our selection.
+ */
+async function _middle_click_with_nothing_selected_helper(aBackground) {
+ await be_in_folder(folder);
+
+ select_none();
+ assert_nothing_selected();
+ let folderTab = mc.window.document.getElementById("tabmail").currentTabInfo;
+ // Focus the thread tree -- we're going to make sure it's focused when we
+ // come back
+ focus_thread_tree();
+ let [tabMessage, curMessage] = middle_click_on_row(1);
+ if (aBackground) {
+ // Make sure we haven't switched to the new tab.
+ assert_selected_tab(folderTab);
+ // Now switch to the new tab and check
+ await switch_tab(tabMessage);
+ } else {
+ wait_for_message_display_completion();
+ }
+
+ assert_selected_and_displayed(curMessage);
+ assert_message_pane_focused();
+ close_tab(tabMessage);
+
+ assert_nothing_selected();
+ assert_thread_tree_focused();
+}
+
+add_task(async function test_middle_click_with_nothing_selected_fg() {
+ set_context_menu_background_tabs(false);
+ await _middle_click_with_nothing_selected_helper(false);
+});
+
+add_task(async function test_middle_click_with_nothing_selected_bg() {
+ set_context_menu_background_tabs(true);
+ await _middle_click_with_nothing_selected_helper(true);
+});
+
+/**
+ * One-thing selected, middle-click on something else.
+ */
+async function _middle_click_with_one_thing_selected_helper(aBackground) {
+ await be_in_folder(folder);
+
+ select_click_row(0);
+ assert_selected_and_displayed(0);
+
+ let folderTab = mc.window.document.getElementById("tabmail").currentTabInfo;
+ let [tabMessage, curMessage] = middle_click_on_row(1);
+ if (aBackground) {
+ // Make sure we haven't switched to the new tab.
+ assert_selected_tab(folderTab);
+ // Now switch to the new tab and check
+ await switch_tab(tabMessage);
+ } else {
+ wait_for_message_display_completion();
+ }
+
+ assert_selected_and_displayed(curMessage);
+ assert_message_pane_focused();
+ close_tab(tabMessage);
+
+ assert_selected_and_displayed(0);
+ assert_thread_tree_focused();
+}
+
+add_task(async function test_middle_click_with_one_thing_selected_fg() {
+ set_context_menu_background_tabs(false);
+ await _middle_click_with_one_thing_selected_helper(false);
+});
+
+add_task(async function test_middle_click_with_one_thing_selected_bg() {
+ set_context_menu_background_tabs(true);
+ await _middle_click_with_one_thing_selected_helper(true);
+});
+
+/**
+ * Many things selected, middle-click on something that is not in that
+ * selection.
+ */
+async function _middle_click_with_many_things_selected_helper(aBackground) {
+ await be_in_folder(folder);
+
+ select_click_row(0);
+ select_shift_click_row(5);
+ assert_selected_and_displayed([0, 5]);
+
+ let folderTab = mc.window.document.getElementById("tabmail").currentTabInfo;
+ let [tabMessage] = middle_click_on_row(1);
+ if (aBackground) {
+ // Make sure we haven't switched to the new tab.
+ assert_selected_tab(folderTab);
+ // Now switch to the new tab and check
+ await switch_tab(tabMessage);
+ } else {
+ wait_for_message_display_completion();
+ }
+
+ assert_message_pane_focused();
+ tabmail.closeOtherTabs(0);
+
+ assert_selected_and_displayed([0, 5]);
+ assert_thread_tree_focused();
+}
+
+add_task(async function test_middle_click_with_many_things_selected_fg() {
+ set_context_menu_background_tabs(false);
+ await _middle_click_with_many_things_selected_helper(false);
+});
+
+add_task(async function test_middle_click_with_many_things_selected_bg() {
+ set_context_menu_background_tabs(true);
+ await _middle_click_with_many_things_selected_helper(true);
+});
+
+/**
+ * One thing selected, middle-click on that.
+ */
+async function _middle_click_on_existing_single_selection_helper(aBackground) {
+ await be_in_folder(folder);
+
+ select_click_row(3);
+ assert_selected_and_displayed(3);
+
+ let folderTab = mc.window.document.getElementById("tabmail").currentTabInfo;
+ let [tabMessage, curMessage] = middle_click_on_row(3);
+ if (aBackground) {
+ // Make sure we haven't switched to the new tab.
+ assert_selected_tab(folderTab);
+ // Now switch to the new tab and check
+ await switch_tab(tabMessage);
+ } else {
+ wait_for_message_display_completion();
+ }
+
+ assert_selected_and_displayed(curMessage);
+ assert_message_pane_focused();
+ close_tab(tabMessage);
+
+ assert_selected_and_displayed(3);
+ assert_thread_tree_focused();
+}
+
+add_task(async function test_middle_click_on_existing_single_selection_fg() {
+ set_context_menu_background_tabs(false);
+ await _middle_click_on_existing_single_selection_helper(false);
+});
+
+add_task(async function test_middle_click_on_existing_single_selection_bg() {
+ set_context_menu_background_tabs(true);
+ await _middle_click_on_existing_single_selection_helper(true);
+});
+
+/**
+ * Many things selected, middle-click somewhere in the selection.
+ */
+async function _middle_click_on_existing_multi_selection_helper(aBackground) {
+ await be_in_folder(folder);
+
+ select_click_row(3);
+ select_shift_click_row(6);
+ assert_selected_and_displayed([3, 6]);
+
+ let folderTab = mc.window.document.getElementById("tabmail").currentTabInfo;
+ let [tabMessage, curMessage] = middle_click_on_row(6);
+ if (aBackground) {
+ // Make sure we haven't switched to the new tab.
+ assert_selected_tab(folderTab);
+ // Now switch to the new tab and check
+ await switch_tab(tabMessage);
+ } else {
+ wait_for_message_display_completion();
+ }
+
+ assert_selected_and_displayed(curMessage);
+ assert_message_pane_focused();
+ tabmail.closeOtherTabs(0);
+
+ assert_selected_and_displayed([3, 6]);
+ assert_thread_tree_focused();
+}
+
+add_task(async function test_middle_click_on_existing_multi_selection_fg() {
+ set_context_menu_background_tabs(false);
+ await _middle_click_on_existing_multi_selection_helper(false);
+});
+
+add_task(async function test_middle_click_on_existing_multi_selection_bg() {
+ set_context_menu_background_tabs(true);
+ await _middle_click_on_existing_multi_selection_helper(true);
+});
+
+/**
+ * Middle-click on the root of a collapsed thread, making sure that we don't
+ * jump around in the thread tree.
+ */
+async function _middle_click_on_collapsed_thread_root_helper(aBackground) {
+ await be_in_folder(threadedFolder);
+ make_display_threaded();
+ collapse_all_threads();
+
+ let folderTab = mc.window.document.getElementById("tabmail").currentTabInfo;
+
+ let tree = get_about_3pane().threadTree;
+ // Note the first visible row
+ let preFirstRow = tree.getFirstVisibleIndex();
+
+ // Since reflowing a tree (eg when switching tabs) ensures that the current
+ // index is brought into view, we need to set the current index so that we
+ // don't scroll because of it. So click on the first visible row.
+ select_click_row(preFirstRow);
+
+ if (!aBackground) {
+ wait_for_message_display_completion();
+ // Switch back to the folder tab
+ await switch_tab(folderTab);
+ }
+ if (tree.getFirstVisibleIndex() != preFirstRow) {
+ throw new Error(
+ "The first visible row should have been " +
+ preFirstRow +
+ ", but is actually " +
+ tree.getFirstVisibleIndex() +
+ "."
+ );
+ }
+ tabmail.closeOtherTabs(0);
+}
+
+add_task(async function test_middle_click_on_collapsed_thread_root_fg() {
+ set_context_menu_background_tabs(false);
+ await _middle_click_on_collapsed_thread_root_helper(false);
+});
+
+add_task(async function test_middle_click_on_collapsed_thread_root_bg() {
+ set_context_menu_background_tabs(true);
+ await _middle_click_on_collapsed_thread_root_helper(true);
+});
+
+/**
+ * Middle-click on the root of an expanded thread, making sure that we don't
+ * jump around in the thread tree.
+ */
+async function _middle_click_on_expanded_thread_root_helper(aBackground) {
+ await be_in_folder(threadedFolder);
+ make_display_threaded();
+ expand_all_threads();
+
+ let folderTab = mc.window.document.getElementById("tabmail").currentTabInfo;
+
+ let tree = get_about_3pane().threadTree;
+ // Note the first visible row
+ let preFirstRow = tree.getFirstVisibleIndex();
+
+ // Since reflowing a tree (eg when switching tabs) ensures that the current
+ // index is brought into view, we need to set the current index so that we
+ // don't scroll because of it. So click on the first visible row.
+ select_click_row(preFirstRow);
+
+ // Middle-click on the root of the expanded thread, which is the row with
+ // index (number of rows - number of messages in thread).
+ let [tabMessage] = middle_click_on_row(
+ tree.view.rowCount - NUM_MESSAGES_IN_THREAD
+ );
+
+ if (!aBackground) {
+ wait_for_message_display_completion();
+ // Switch back to the folder tab
+ await switch_tab(folderTab);
+ }
+
+ // Make sure the first visible row is still the same
+ if (tree.getFirstVisibleIndex() != preFirstRow) {
+ throw new Error(
+ "The first visible row should have been " +
+ preFirstRow +
+ ", but is actually " +
+ tree.getFirstVisibleIndex() +
+ "."
+ );
+ }
+
+ close_tab(tabMessage);
+}
+
+add_task(async function test_middle_click_on_expanded_thread_root_fg() {
+ set_context_menu_background_tabs(false);
+ await _middle_click_on_expanded_thread_root_helper(false);
+});
+
+add_task(async function test_middle_click_on_expanded_thread_root_bg() {
+ set_context_menu_background_tabs(true);
+ await _middle_click_on_expanded_thread_root_helper(true);
+});
+
+/**
+ * Right-click on something and delete it, having no selection previously.
+ */
+add_task(async function test_right_click_deletion_nothing_selected() {
+ await be_in_folder(folder);
+
+ select_none();
+ assert_selected_and_displayed();
+
+ let delMessage = await right_click_on_row(3);
+ await delete_via_popup();
+ // eh, might as well make sure the deletion worked while we are here
+ assert_message_not_in_view(delMessage);
+
+ assert_selected_and_displayed();
+}).skip();
+
+/**
+ * We want to make sure that the selection post-delete still includes the same
+ * message (and that it is displayed). In order for this to be interesting,
+ * we want to make sure that we right-click delete a message above the selected
+ * message so there is a shift in row numbering.
+ */
+add_task(async function test_right_click_deletion_one_other_thing_selected() {
+ await be_in_folder(folder);
+
+ let curMessage = select_click_row(5);
+
+ let delMessage = await right_click_on_row(3);
+ await delete_via_popup();
+ assert_message_not_in_view(delMessage);
+
+ assert_selected_and_displayed(curMessage);
+}).skip();
+
+add_task(async function test_right_click_deletion_many_other_things_selected() {
+ await be_in_folder(folder);
+
+ select_click_row(4);
+ let messages = select_shift_click_row(6);
+
+ let delMessage = await right_click_on_row(2);
+ await delete_via_popup();
+ assert_message_not_in_view(delMessage);
+
+ assert_selected_and_displayed(messages);
+}).skip();
+
+add_task(async function test_right_click_deletion_of_one_selected_thing() {
+ await be_in_folder(folder);
+
+ let curMessage = select_click_row(2);
+
+ await right_click_on_row(2);
+ await delete_via_popup();
+ assert_message_not_in_view(curMessage);
+
+ // Assert.notEqual(mc.window.document.getElementById("tabmail").currentTabInfo.browser.contentWindow.gDBView.selection.count, 0, "We should have tried to select something!");
+});
+
+add_task(async function test_right_click_deletion_of_many_selected_things() {
+ await be_in_folder(folder);
+
+ select_click_row(2);
+ let messages = select_shift_click_row(4);
+
+ await right_click_on_row(3);
+ await delete_via_popup();
+ assert_messages_not_in_view(messages);
+
+ // Assert.notEqual(mc.window.document.getElementById("tabmail").currentTabInfo.browser.contentWindow.gDBView.selection.count, 0, "We should have tried to select something!");
+});