diff options
Diffstat (limited to 'comm/mail/test/browser/folder-display/browser_rightClickMiddleClickMessages.js')
-rw-r--r-- | comm/mail/test/browser/folder-display/browser_rightClickMiddleClickMessages.js | 564 |
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!"); +}); |