summaryrefslogtreecommitdiffstats
path: root/comm/mail/test/browser/folder-display/browser_deletionWithMultipleDisplays.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/test/browser/folder-display/browser_deletionWithMultipleDisplays.js')
-rw-r--r--comm/mail/test/browser/folder-display/browser_deletionWithMultipleDisplays.js787
1 files changed, 787 insertions, 0 deletions
diff --git a/comm/mail/test/browser/folder-display/browser_deletionWithMultipleDisplays.js b/comm/mail/test/browser/folder-display/browser_deletionWithMultipleDisplays.js
new file mode 100644
index 0000000000..1bc4e67e49
--- /dev/null
+++ b/comm/mail/test/browser/folder-display/browser_deletionWithMultipleDisplays.js
@@ -0,0 +1,787 @@
+/* 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 that deleting a message in a given tab or window properly updates both
+ * that tab/window as well as all other tabs/windows. We also test that the
+ * message tab title updates appropriately through all of this. We do all of
+ * this both for tabs that have ever been opened in the foreground, and tabs
+ * that haven't (and thus might have fake selections).
+ */
+
+"use strict";
+
+var {
+ assert_selected_and_displayed,
+ assert_tab_titled_from,
+ be_in_folder,
+ close_message_window,
+ close_tab,
+ create_folder,
+ get_about_3pane,
+ get_about_message,
+ make_message_sets_in_folders,
+ mc,
+ open_selected_message_in_new_tab,
+ open_selected_message_in_new_window,
+ press_delete,
+ select_click_row,
+ select_control_click_row,
+ select_shift_click_row,
+ switch_tab,
+} = ChromeUtils.import(
+ "resource://testing-common/mozmill/FolderDisplayHelpers.jsm"
+);
+var { plan_for_window_close, wait_for_window_close } = ChromeUtils.import(
+ "resource://testing-common/mozmill/WindowHelpers.jsm"
+);
+
+var folder,
+ lastMessageFolder,
+ oneBeforeFolder,
+ oneAfterFolder,
+ multipleDeletionFolder1,
+ multipleDeletionFolder2,
+ multipleDeletionFolder3,
+ multipleDeletionFolder4;
+
+// Adjust timeout to take care of code coverage runs needing twice as long.
+requestLongerTimeout(AppConstants.MOZ_CODE_COVERAGE ? 4 : 2);
+
+add_setup(async function () {
+ folder = await create_folder("DeletionA");
+ lastMessageFolder = await create_folder("DeletionB");
+ oneBeforeFolder = await create_folder("DeletionC");
+ oneAfterFolder = await create_folder("DeletionD");
+ multipleDeletionFolder1 = await create_folder("DeletionE");
+ multipleDeletionFolder2 = await create_folder("DeletionF");
+ multipleDeletionFolder3 = await create_folder("DeletionG");
+ multipleDeletionFolder4 = await create_folder("DeletionH");
+ // 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: 4 }]);
+
+ // since we don't test window close here, it doesn't really matter how many
+ // messages these have
+
+ await make_message_sets_in_folders([lastMessageFolder], [{ count: 4 }]);
+ await make_message_sets_in_folders([oneBeforeFolder], [{ count: 10 }]);
+ await make_message_sets_in_folders([oneAfterFolder], [{ count: 10 }]);
+ await make_message_sets_in_folders(
+ [multipleDeletionFolder1],
+ [{ count: 30 }]
+ );
+
+ // We're depending on selecting the last message here, so these do matter
+ await make_message_sets_in_folders(
+ [multipleDeletionFolder2],
+ [{ count: 10 }]
+ );
+ await make_message_sets_in_folders(
+ [multipleDeletionFolder3],
+ [{ count: 10 }]
+ );
+ await make_message_sets_in_folders(
+ [multipleDeletionFolder4],
+ [{ count: 10 }]
+ );
+});
+
+var tabFolder, tabMessage, tabMessageBackground, curMessage, nextMessage;
+
+/**
+ * The message window controller. Short names because controllers get used a
+ * lot.
+ */
+var msgc;
+
+/**
+ * Open up the message at aIndex in all our display mechanisms, and check to see
+ * if the displays are all correct. This also sets up all our globals.
+ */
+async function _open_message_in_all_four_display_mechanisms_helper(
+ aFolder,
+ aIndex
+) {
+ // - Select the message in this tab.
+ tabFolder = await be_in_folder(aFolder);
+ curMessage = select_click_row(aIndex);
+ assert_selected_and_displayed(curMessage);
+
+ // - Open the tab with the message
+ tabMessage = await open_selected_message_in_new_tab();
+ assert_selected_and_displayed(curMessage);
+ assert_tab_titled_from(tabMessage, curMessage);
+
+ // go back to the folder tab
+ await switch_tab(tabFolder);
+
+ // - Open another tab with the message, this time in the background
+ tabMessageBackground = await open_selected_message_in_new_tab(true);
+ assert_tab_titled_from(tabMessageBackground, curMessage);
+
+ // - Open the window with the message
+ // need to go back to the folder tab. (well, should.)
+ await switch_tab(tabFolder);
+ msgc = await open_selected_message_in_new_window();
+ assert_selected_and_displayed(msgc, curMessage);
+}
+
+// Check whether this message is displayed in the folder tab
+var VERIFY_FOLDER_TAB = 0x1;
+// Check whether this message is displayed in the foreground message tab
+var VERIFY_MESSAGE_TAB = 0x2;
+// Check whether this message is displayed in the background message tab
+var VERIFY_BACKGROUND_MESSAGE_TAB = 0x4;
+// Check whether this message is displayed in the message window
+var VERIFY_MESSAGE_WINDOW = 0x8;
+var VERIFY_ALL = 0xf;
+
+/**
+ * Verify that the message is displayed in the given tabs. The index is
+ * optional.
+ */
+async function _verify_message_is_displayed_in(aFlags, aMessage, aIndex) {
+ if (aFlags & VERIFY_FOLDER_TAB) {
+ await switch_tab(tabFolder);
+ Assert.equal(
+ get_about_message().gMessage,
+ aMessage,
+ "folder tab shows the correct message"
+ );
+ assert_selected_and_displayed(aMessage);
+ if (aIndex !== undefined) {
+ assert_selected_and_displayed(aIndex);
+ }
+ }
+ if (aFlags & VERIFY_MESSAGE_TAB) {
+ // Verify the title first
+ assert_tab_titled_from(tabMessage, aMessage);
+ await switch_tab(tabMessage);
+ // Verify the title again, just in case
+ Assert.equal(
+ get_about_message().gMessageURI,
+ aMessage.folder.getUriForMsg(aMessage)
+ );
+ assert_tab_titled_from(tabMessage, aMessage);
+ Assert.equal(
+ get_about_message().gMessage,
+ aMessage,
+ "message tab shows the correct message"
+ );
+ assert_selected_and_displayed(aMessage);
+ if (aIndex !== undefined) {
+ assert_selected_and_displayed(aIndex);
+ }
+ }
+ if (aFlags & VERIFY_BACKGROUND_MESSAGE_TAB) {
+ // Only verify the title
+ assert_tab_titled_from(tabMessageBackground, aMessage);
+ }
+ if (aFlags & VERIFY_MESSAGE_WINDOW) {
+ Assert.equal(
+ get_about_message(msgc.window).gMessage,
+ aMessage,
+ "message window shows the correct message"
+ );
+ assert_selected_and_displayed(msgc, aMessage);
+ if (aIndex !== undefined) {
+ assert_selected_and_displayed(msgc, aIndex);
+ }
+ }
+}
+
+/**
+ * Have a message displayed in a folder tab, message tab (foreground and
+ * background), and message window. The idea is that as we delete from the
+ * various sources, they should all advance in lock-step through their messages,
+ * simplifying our lives (but making us explode forevermore the first time any
+ * of the tests fail.)
+ */
+add_task(
+ async function test_open_first_message_in_all_four_display_mechanisms() {
+ await _open_message_in_all_four_display_mechanisms_helper(folder, 0);
+ }
+);
+
+/**
+ * Perform a deletion from the folder tab, verify the others update correctly
+ * (advancing to the next message).
+ */
+add_task(async function test_delete_in_folder_tab() {
+ let about3Pane = get_about_3pane();
+ // - plan to end up on the guy who is currently at index 1
+ curMessage = about3Pane.gDBView.getMsgHdrAt(1);
+ // while we're at it, figure out who is at 2 for the next step
+ nextMessage = about3Pane.gDBView.getMsgHdrAt(2);
+ // - delete the message
+ press_delete();
+ // - verify all displays
+ await _verify_message_is_displayed_in(VERIFY_ALL, curMessage, 0);
+});
+
+/**
+ * Perform a deletion from the message tab, verify the others update correctly
+ * (advancing to the next message).
+ */
+add_task(async function test_delete_in_message_tab() {
+ await switch_tab(tabMessage);
+ // nextMessage is the guy we want to see once the delete completes.
+ press_delete();
+ curMessage = nextMessage;
+
+ // - verify all displays
+ await _verify_message_is_displayed_in(VERIFY_ALL, curMessage, 0);
+
+ // figure out the next guy...
+ nextMessage = get_about_message().gDBView.getMsgHdrAt(1);
+ if (!nextMessage) {
+ throw new Error("We ran out of messages early?");
+ }
+});
+
+/**
+ * Perform a deletion from the message window, verify the others update
+ * correctly (advancing to the next message).
+ */
+add_task(async function test_delete_in_message_window() {
+ // - delete
+ press_delete(msgc);
+ curMessage = nextMessage;
+ // - verify all displays
+ await _verify_message_is_displayed_in(VERIFY_ALL, curMessage, 0);
+});
+
+/**
+ * Delete the last message in that folder, which should close all message
+ * displays.
+ */
+add_task(async function test_delete_last_message_closes_message_displays() {
+ // - since we have both foreground and background message tabs, we don't need
+ // to open yet another tab to test
+
+ // - prep for the message window disappearing
+ plan_for_window_close(msgc);
+
+ // - let's arbitrarily perform the deletion on this message tab
+ await switch_tab(tabMessage);
+ press_delete();
+
+ // - the message window should have gone away...
+ // (this also helps ensure that the 3pane gets enough event loop time to do
+ // all that it needs to accomplish)
+ wait_for_window_close(msgc);
+ msgc = null;
+
+ // - and we should now be on the folder tab and there should be no other tabs
+ if (mc.window.document.getElementById("tabmail").tabInfo.length != 1) {
+ throw new Error("There should only be one tab left!");
+ }
+ // the below check is implied by the previous check if things are sane-ish
+ if (
+ mc.window.document.getElementById("tabmail").currentTabInfo != tabFolder
+ ) {
+ throw new Error("We should be on the folder tab!");
+ }
+});
+
+/*
+ * Now we retest everything, but while deleting the last message in our
+ * selection. We need to make sure we select the previously next-to-last message
+ * in that case.
+ */
+
+/**
+ * Have the last message displayed in a folder tab, message tab (foreground and
+ * background), and message window. The idea is that as we delete from the
+ * various sources, they should all advance in lock-step through their messages,
+ * simplifying our lives (but making us explode forevermore the first time any
+ * of the tests fail.)
+ */
+add_task(
+ async function test_open_last_message_in_all_four_display_mechanisms() {
+ // since we have four messages, index 3 is the last message.
+ await _open_message_in_all_four_display_mechanisms_helper(
+ lastMessageFolder,
+ 3
+ );
+ }
+);
+
+/**
+ * Perform a deletion from the folder tab, verify the others update correctly
+ * (advancing to the next message).
+ */
+add_task(async function test_delete_last_message_in_folder_tab() {
+ let about3Pane = get_about_3pane();
+ // - plan to end up on the guy who is currently at index 2
+ curMessage = about3Pane.gDBView.getMsgHdrAt(2);
+ // while we're at it, figure out who is at 1 for the next step
+ nextMessage = about3Pane.gDBView.getMsgHdrAt(1);
+ // - delete the message
+ press_delete();
+
+ // - verify all displays
+ await _verify_message_is_displayed_in(VERIFY_ALL, curMessage, 2);
+});
+
+/**
+ * Perform a deletion from the message tab, verify the others update correctly
+ * (advancing to the next message).
+ */
+add_task(async function test_delete_last_message_in_message_tab() {
+ // (we're still on the message tab, and nextMessage is the guy we want to see
+ // once the delete completes.)
+ press_delete();
+ curMessage = nextMessage;
+
+ // - verify all displays
+ await _verify_message_is_displayed_in(VERIFY_ALL, curMessage, 1);
+ // figure out the next guy...
+
+ nextMessage = get_about_message().gDBView.getMsgHdrAt(0);
+ if (!nextMessage) {
+ throw new Error("We ran out of messages early?");
+ }
+});
+
+/**
+ * Perform a deletion from the message window, verify the others update
+ * correctly (advancing to the next message).
+ */
+add_task(async function test_delete_last_message_in_message_window() {
+ // Vary this up. Switch to the folder tab instead of staying on the message
+ // tab
+ await switch_tab(tabFolder);
+ // - delete
+ press_delete(msgc);
+ curMessage = nextMessage;
+ // - verify all displays
+ await _verify_message_is_displayed_in(VERIFY_ALL, curMessage, 0);
+
+ // - clean up, close the message window and displays
+ close_message_window(msgc);
+ close_tab(tabMessage);
+ close_tab(tabMessageBackground);
+ await switch_tab(tabFolder);
+});
+
+/*
+ * Our next job is to open up a message, then delete the message one before it
+ * in another view. The other selections shouldn't be affected.
+ */
+
+/**
+ * Test "one before" deletion in the folder tab.
+ */
+add_task(async function test_delete_one_before_message_in_folder_tab() {
+ // Open up message 4 in message tabs and a window (we'll delete message 3).
+ await _open_message_in_all_four_display_mechanisms_helper(oneBeforeFolder, 4);
+
+ let expectedMessage = get_about_3pane().gDBView.getMsgHdrAt(4);
+ select_click_row(3);
+ press_delete();
+
+ // The message tab, background message tab and window shouldn't have changed
+ await _verify_message_is_displayed_in(
+ VERIFY_MESSAGE_TAB | VERIFY_BACKGROUND_MESSAGE_TAB | VERIFY_MESSAGE_WINDOW,
+ expectedMessage
+ );
+
+ // Clean up, close everything
+ close_message_window(msgc);
+ close_tab(tabMessage);
+ close_tab(tabMessageBackground);
+ await switch_tab(tabFolder);
+});
+
+/**
+ * Test "one before" deletion in the message tab.
+ */
+add_task(async function test_delete_one_before_message_in_message_tab() {
+ // Open up 3 in a message tab, then select and open up 4 in a background tab
+ // and window.
+ select_click_row(3);
+ tabMessage = await open_selected_message_in_new_tab(true);
+ let expectedMessage = select_click_row(4);
+ tabMessageBackground = await open_selected_message_in_new_tab(true);
+ msgc = await open_selected_message_in_new_window(true);
+
+ // Switch to the message tab, and delete.
+ await switch_tab(tabMessage);
+ press_delete();
+
+ // The folder tab, background message tab and window shouldn't have changed
+ await _verify_message_is_displayed_in(
+ VERIFY_FOLDER_TAB | VERIFY_BACKGROUND_MESSAGE_TAB | VERIFY_MESSAGE_WINDOW,
+ expectedMessage
+ );
+
+ // Clean up, close everything
+ close_message_window(msgc);
+ close_tab(tabMessage);
+ close_tab(tabMessageBackground);
+ await switch_tab(tabFolder);
+});
+
+/**
+ * Test "one before" deletion in the message window.
+ */
+add_task(async function test_delete_one_before_message_in_message_window() {
+ // Open up 3 in a message window, then select and open up 4 in a background
+ // and a foreground tab.
+ select_click_row(3);
+ msgc = await open_selected_message_in_new_window();
+ let expectedMessage = select_click_row(4);
+ tabMessage = await open_selected_message_in_new_tab();
+ await switch_tab(tabFolder);
+ tabMessageBackground = await open_selected_message_in_new_tab(true);
+
+ // Press delete in the message window.
+ press_delete(msgc);
+
+ // The folder tab, message tab and background message tab shouldn't have
+ // changed
+ await _verify_message_is_displayed_in(
+ VERIFY_FOLDER_TAB | VERIFY_MESSAGE_TAB | VERIFY_BACKGROUND_MESSAGE_TAB,
+ expectedMessage
+ );
+
+ // Clean up, close everything
+ close_message_window(msgc);
+ close_tab(tabMessage);
+ close_tab(tabMessageBackground);
+ await switch_tab(tabFolder);
+});
+
+/*
+ * Now do all of that again, but this time delete the message _after_ the open one.
+ */
+
+/**
+ * Test "one after" deletion in the folder tab.
+ */
+add_task(async function test_delete_one_after_message_in_folder_tab() {
+ // Open up message 4 in message tabs and a window (we'll delete message 5).
+ await _open_message_in_all_four_display_mechanisms_helper(oneAfterFolder, 4);
+
+ let expectedMessage = get_about_3pane().gDBView.getMsgHdrAt(4);
+ select_click_row(5);
+ press_delete();
+
+ // The message tab, background message tab and window shouldn't have changed
+ await _verify_message_is_displayed_in(
+ VERIFY_MESSAGE_TAB | VERIFY_BACKGROUND_MESSAGE_TAB | VERIFY_MESSAGE_WINDOW,
+ expectedMessage
+ );
+
+ // Clean up, close everything
+ close_message_window(msgc);
+ close_tab(tabMessage);
+ close_tab(tabMessageBackground);
+ await switch_tab(tabFolder);
+});
+
+/**
+ * Test "one after" deletion in the message tab.
+ */
+add_task(async function test_delete_one_after_message_in_message_tab() {
+ // Open up 5 in a message tab, then select and open up 4 in a background tab
+ // and window.
+ select_click_row(5);
+ tabMessage = await open_selected_message_in_new_tab(true);
+ let expectedMessage = select_click_row(4);
+ tabMessageBackground = await open_selected_message_in_new_tab(true);
+ msgc = await open_selected_message_in_new_window(true);
+
+ // Switch to the message tab, and delete.
+ await switch_tab(tabMessage);
+ press_delete();
+
+ // The folder tab, background message tab and window shouldn't have changed
+ await _verify_message_is_displayed_in(
+ VERIFY_FOLDER_TAB | VERIFY_BACKGROUND_MESSAGE_TAB | VERIFY_MESSAGE_WINDOW,
+ expectedMessage
+ );
+
+ // Clean up, close everything
+ close_message_window(msgc);
+ close_tab(tabMessage);
+ close_tab(tabMessageBackground);
+ await switch_tab(tabFolder);
+});
+
+/**
+ * Test "one after" deletion in the message window.
+ */
+add_task(async function test_delete_one_after_message_in_message_window() {
+ // Open up 5 in a message window, then select and open up 4 in a background
+ // and a foreground tab.
+ select_click_row(5);
+ msgc = await open_selected_message_in_new_window();
+ let expectedMessage = select_click_row(4);
+ tabMessage = await open_selected_message_in_new_tab();
+ await switch_tab(tabFolder);
+ tabMessageBackground = await open_selected_message_in_new_tab(true);
+
+ // Press delete in the message window.
+ press_delete(msgc);
+
+ // The folder tab, message tab and background message tab shouldn't have
+ // changed
+ await _verify_message_is_displayed_in(
+ VERIFY_FOLDER_TAB | VERIFY_MESSAGE_TAB | VERIFY_BACKGROUND_MESSAGE_TAB,
+ expectedMessage
+ );
+
+ // Clean up, close everything
+ close_message_window(msgc);
+ close_tab(tabMessage);
+ close_tab(tabMessageBackground);
+ await switch_tab(tabFolder);
+});
+
+/*
+ * Delete multiple messages in a folder tab. Make sure message displays at the
+ * beginning, middle and end of a selection work out.
+ */
+
+/**
+ * Test deleting multiple messages in a folder tab, with message displays open
+ * to the beginning of a selection.
+ */
+add_task(
+ async function test_delete_multiple_messages_with_first_selected_message_open() {
+ // Open up 2 in a message tab, background tab, and message window.
+ await _open_message_in_all_four_display_mechanisms_helper(
+ multipleDeletionFolder1,
+ 2
+ );
+
+ // We'll select 2-5, 8, 9 and 10. We expect 6 to be the next displayed
+ // message.
+ select_click_row(2);
+ select_shift_click_row(5);
+ select_control_click_row(8);
+ select_control_click_row(9);
+ select_control_click_row(10);
+ let expectedMessage = get_about_3pane().gDBView.getMsgHdrAt(6);
+
+ // Delete the selected messages
+ press_delete();
+
+ // All the displays should now be showing the expectedMessage
+ await _verify_message_is_displayed_in(VERIFY_ALL, expectedMessage);
+
+ // Clean up, close everything
+ close_message_window(msgc);
+ close_tab(tabMessage);
+ close_tab(tabMessageBackground);
+ await switch_tab(tabFolder);
+ }
+);
+
+/**
+ * Test deleting multiple messages in a folder tab, with message displays open
+ * to somewhere in the middle of a selection.
+ */
+add_task(
+ async function test_delete_multiple_messages_with_nth_selected_message_open() {
+ // Open up 9 in a message tab, background tab, and message window.
+ await _open_message_in_all_four_display_mechanisms_helper(
+ multipleDeletionFolder1,
+ 9
+ );
+
+ // We'll select 2-5, 8, 9 and 10. We expect 11 to be the next displayed
+ // message.
+ select_click_row(2);
+ select_shift_click_row(5);
+ select_control_click_row(8);
+ select_control_click_row(9);
+ select_control_click_row(10);
+ let expectedMessage = get_about_3pane().gDBView.getMsgHdrAt(11);
+
+ // Delete the selected messages
+ press_delete();
+
+ // The folder tab should now be showing message 2
+ assert_selected_and_displayed(2);
+
+ // The other displays should now be showing the expectedMessage
+ await _verify_message_is_displayed_in(
+ VERIFY_MESSAGE_TAB |
+ VERIFY_BACKGROUND_MESSAGE_TAB |
+ VERIFY_MESSAGE_WINDOW,
+ expectedMessage
+ );
+
+ // Clean up, close everything
+ close_message_window(msgc);
+ close_tab(tabMessage);
+ close_tab(tabMessageBackground);
+ await switch_tab(tabFolder);
+ }
+);
+
+/**
+ * Test deleting multiple messages in a folder tab, with message displays open
+ * to the end of a selection.
+ */
+add_task(
+ async function test_delete_multiple_messages_with_last_selected_message_open() {
+ // Open up 10 in a message tab, background tab, and message window.
+ await _open_message_in_all_four_display_mechanisms_helper(
+ multipleDeletionFolder1,
+ 9
+ );
+
+ // We'll select 2-5, 8, 9 and 10. We expect 11 to be the next displayed
+ // message.
+ select_click_row(2);
+ select_shift_click_row(5);
+ select_control_click_row(8);
+ select_control_click_row(9);
+ select_control_click_row(10);
+ let expectedMessage = get_about_3pane().gDBView.getMsgHdrAt(11);
+
+ // Delete the selected messages
+ press_delete();
+
+ // The folder tab should now be showing message 2
+ assert_selected_and_displayed(2);
+
+ // The other displays should now be showing the expectedMessage
+ await _verify_message_is_displayed_in(
+ VERIFY_MESSAGE_TAB |
+ VERIFY_BACKGROUND_MESSAGE_TAB |
+ VERIFY_MESSAGE_WINDOW,
+ expectedMessage
+ );
+ // Clean up, close everything
+ close_message_window(msgc);
+ close_tab(tabMessage);
+ close_tab(tabMessageBackground);
+ await switch_tab(tabFolder);
+ }
+);
+
+/**
+ * Test deleting multiple messages in a folder tab (including the last one!),
+ * with message displays open to the beginning of a selection.
+ */
+add_task(
+ async function test_delete_multiple_messages_including_the_last_one_with_first_open() {
+ // 10 messages in this folder. Open up message 1 everywhere.
+ await _open_message_in_all_four_display_mechanisms_helper(
+ multipleDeletionFolder2,
+ 1
+ );
+
+ // We'll select 1-4, 7, 8 and 9. We expect 5 to be the next displayed message.
+ select_click_row(1);
+ select_shift_click_row(4);
+ select_control_click_row(7);
+ select_control_click_row(8);
+ select_control_click_row(9);
+ let expectedMessage = get_about_3pane().gDBView.getMsgHdrAt(5);
+
+ // Delete the selected messages
+ press_delete();
+
+ // All the displays should now be showing the expectedMessage
+ await _verify_message_is_displayed_in(VERIFY_ALL, expectedMessage);
+
+ // Clean up, close everything
+ close_message_window(msgc);
+ close_tab(tabMessage);
+ close_tab(tabMessageBackground);
+ await switch_tab(tabFolder);
+ }
+);
+
+/**
+ * Test deleting multiple messages in a folder tab (including the last one!),
+ * with message displays open to the middle of a selection.
+ */
+add_task(
+ async function test_delete_multiple_messages_including_the_last_one_with_nth_open() {
+ // 10 messages in this folder. Open up message 7 everywhere.
+ await _open_message_in_all_four_display_mechanisms_helper(
+ multipleDeletionFolder3,
+ 7
+ );
+
+ // We'll select 1-4, 7, 8 and 9. We expect 6 to be the next displayed message.
+ select_click_row(1);
+ select_shift_click_row(4);
+ select_control_click_row(7);
+ select_control_click_row(8);
+ select_control_click_row(9);
+ let expectedMessage = get_about_3pane().gDBView.getMsgHdrAt(6);
+
+ // Delete the selected messages
+ press_delete();
+
+ // The folder tab should now be showing message 1
+ assert_selected_and_displayed(1);
+
+ // The other displays should now be showing the expectedMessage
+ await _verify_message_is_displayed_in(
+ VERIFY_MESSAGE_TAB |
+ VERIFY_BACKGROUND_MESSAGE_TAB |
+ VERIFY_MESSAGE_WINDOW,
+ expectedMessage
+ );
+
+ // Clean up, close everything
+ close_message_window(msgc);
+ close_tab(tabMessage);
+ close_tab(tabMessageBackground);
+ await switch_tab(tabFolder);
+ }
+);
+
+/**
+ * Test deleting multiple messages in a folder tab (including the last one!),
+ * with message displays open to the end of a selection.
+ */
+add_task(
+ async function test_delete_multiple_messages_including_the_last_one_with_last_open() {
+ // 10 messages in this folder. Open up message 9 everywhere.
+ await _open_message_in_all_four_display_mechanisms_helper(
+ multipleDeletionFolder4,
+ 9
+ );
+
+ // We'll select 1-4, 7, 8 and 9. We expect 6 to be the next displayed message.
+ select_click_row(1);
+ select_shift_click_row(4);
+ select_control_click_row(7);
+ select_control_click_row(8);
+ select_control_click_row(9);
+ let expectedMessage = get_about_3pane().gDBView.getMsgHdrAt(6);
+
+ // Delete the selected messages
+ press_delete();
+
+ // The folder tab should now be showing message 1
+ assert_selected_and_displayed(1);
+
+ // The other displays should now be showing the expectedMessage
+ await _verify_message_is_displayed_in(
+ VERIFY_MESSAGE_TAB |
+ VERIFY_BACKGROUND_MESSAGE_TAB |
+ VERIFY_MESSAGE_WINDOW,
+ expectedMessage
+ );
+
+ // Clean up, close everything
+ close_message_window(msgc);
+ close_tab(tabMessage);
+ close_tab(tabMessageBackground);
+ await switch_tab(tabFolder);
+ }
+);