Bug 1582056 part 1 - Convert some Mozmill helper modules to JSMs; r=mkmelin
authorGeoff Lankow <geoff@darktrojan.net>
Wed, 25 Sep 2019 20:59:47 +1200
changeset 36943 0ee0e21ccb1b19e9b54f2d50c1e1895a2d711187
parent 36942 27b964c4d5310a1584726612f4f290e282b1ba90
child 36944 19ae7a021b57cc3d81b5f95a8aa3f911c4301348
push id395
push userclokep@gmail.com
push dateMon, 02 Dec 2019 19:38:57 +0000
reviewersmkmelin
bugs1582056
Bug 1582056 part 1 - Convert some Mozmill helper modules to JSMs; r=mkmelin
calendar/test/mozmill/invitations/test-imip-bar-eml.js
mail/test/mozmill/account/test-ab-whitelist.js
mail/test/mozmill/account/test-account-port-setting.js
mail/test/mozmill/account/test-account-values.js
mail/test/mozmill/account/test-mail-account-setup-wizard.js
mail/test/mozmill/account/test-retest-config.js
mail/test/mozmill/addrbook/test-address-book.js
mail/test/mozmill/attachment/test-attachment-events.js
mail/test/mozmill/attachment/test-attachment-menus.js
mail/test/mozmill/attachment/test-attachment-size.js
mail/test/mozmill/cloudfile/test-cloudfile-attachment-item.js
mail/test/mozmill/cloudfile/test-cloudfile-attachment-urls.js
mail/test/mozmill/cloudfile/test-cloudfile-notifications.js
mail/test/mozmill/composition/test-attachment-reminder.js
mail/test/mozmill/composition/test-blocked-content.js
mail/test/mozmill/composition/test-charset-edit.js
mail/test/mozmill/composition/test-draft-identity.js
mail/test/mozmill/composition/test-drafts.js
mail/test/mozmill/composition/test-forward-headers.js
mail/test/mozmill/composition/test-image-insertion-dialog.js
mail/test/mozmill/composition/test-reply-signature.js
mail/test/mozmill/composition/test-save-changes-on-quit.js
mail/test/mozmill/content-policy/test-compose-mailto.js
mail/test/mozmill/content-policy/test-general-content-policy.js
mail/test/mozmill/downloads/test-about-downloads.js
mail/test/mozmill/folder-widget/test-message-filters.js
mail/test/mozmill/instrumentation/test-instrument-setup.js
mail/test/mozmill/message-header/test-phishing-bar.js
mail/test/mozmill/message-header/test-return-receipt.js
mail/test/mozmill/newmailaccount/test-newmailaccount.js
mail/test/mozmill/shared-modules/AttachmentHelpers.jsm
mail/test/mozmill/shared-modules/KeyboardHelpers.jsm
mail/test/mozmill/shared-modules/MessageHelpers.jsm
mail/test/mozmill/shared-modules/MockObjectHelpers.jsm
mail/test/mozmill/shared-modules/NotificationBoxHelpers.jsm
mail/test/mozmill/shared-modules/PromptHelpers.jsm
mail/test/mozmill/shared-modules/moz.build
mail/test/mozmill/shared-modules/test-attachment-helpers.js
mail/test/mozmill/shared-modules/test-content-tab-helpers.js
mail/test/mozmill/shared-modules/test-keyboard-helpers.js
mail/test/mozmill/shared-modules/test-message-helpers.js
mail/test/mozmill/shared-modules/test-mock-object-helpers.js
mail/test/mozmill/shared-modules/test-newmailaccount-helpers.js
mail/test/mozmill/shared-modules/test-notificationbox-helpers.js
mail/test/mozmill/shared-modules/test-observer-helpers.js
mail/test/mozmill/shared-modules/test-prompt-helpers.js
mail/test/mozmill/shared-modules/test-subscribe-window-helpers.js
--- a/calendar/test/mozmill/invitations/test-imip-bar-eml.js
+++ b/calendar/test/mozmill/invitations/test-imip-bar-eml.js
@@ -6,17 +6,17 @@
  * Test that the IMIP bar behaves properly for eml files.
  */
 
 // make -C calendar/test/mozmill SOLO_TEST=invitations/test-imip-bar-eml.js mozmill-one
 
 var MODULE_NAME = "testInvitations";
 
 var RELATIVE_ROOT = "../shared-modules";
-var MODULE_REQUIRES = ["folder-display-helpers", "window-helpers", "notificationbox-helpers"];
+var MODULE_REQUIRES = ["folder-display-helpers", "window-helpers"];
 
 var os = ChromeUtils.import("chrome://mozmill/content/stdlib/os.jsm");
 
 /* globals open_message_from_file, close_window */
 
 function setupModule(module) {
   for (let dep of MODULE_REQUIRES) {
     collector.getModule(dep).installInto(module);
--- a/mail/test/mozmill/account/test-ab-whitelist.js
+++ b/mail/test/mozmill/account/test-ab-whitelist.js
@@ -1,26 +1,24 @@
 /* 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";
 
 /* import-globals-from ../shared-modules/test-account-manager-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-keyboard-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-ab-whitelist";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "window-helpers",
   "account-manager-helpers",
-  "keyboard-helpers",
 ];
 
 var mozmill = ChromeUtils.import(
   "chrome://mozmill/content/modules/mozmill.jsm"
 );
 var controller = ChromeUtils.import(
   "chrome://mozmill/content/modules/controller.jsm"
 );
--- a/mail/test/mozmill/account/test-account-port-setting.js
+++ b/mail/test/mozmill/account/test-account-port-setting.js
@@ -1,32 +1,34 @@
 /* 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";
 
 /* import-globals-from ../shared-modules/test-account-manager-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-keyboard-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-account-port-setting";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "window-helpers",
   "account-manager-helpers",
-  "keyboard-helpers",
 ];
 
 var elib = ChromeUtils.import(
   "chrome://mozmill/content/modules/elementslib.jsm"
 );
 
+var { input_value, delete_all_existing } = ChromeUtils.import(
+  "resource://testing-common/mozmill/KeyboardHelpers.jsm"
+);
+
 var PORT_NUMBERS_TO_TEST = [
   "110", // The original port number. We don't input this though.
   "456", // Random port number.
   "995", // The SSL port number.
   "110", // Back to the original.
 ];
 
 var gTestNumber;
--- a/mail/test/mozmill/account/test-account-values.js
+++ b/mail/test/mozmill/account/test-account-values.js
@@ -6,32 +6,34 @@
  * This test checks proper operation of the account settings panes
  * when certain special or invalid values are entered into the fields.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-account-manager-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-keyboard-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-account-values";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "window-helpers",
   "account-manager-helpers",
-  "keyboard-helpers",
 ];
 
 var elib = ChromeUtils.import(
   "chrome://mozmill/content/modules/elementslib.jsm"
 );
 
+var { input_value, delete_all_existing } = ChromeUtils.import(
+  "resource://testing-common/mozmill/KeyboardHelpers.jsm"
+);
+
 var gPopAccount, gOriginalAccountCount;
 
 function setupModule(module) {
   for (let lib of MODULE_REQUIRES) {
     collector.getModule(lib).installInto(module);
   }
 
   // There may be pre-existing accounts from other tests.
--- a/mail/test/mozmill/account/test-mail-account-setup-wizard.js
+++ b/mail/test/mozmill/account/test-mail-account-setup-wizard.js
@@ -1,39 +1,42 @@
 /* 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";
 
 /* import-globals-from ../shared-modules/test-account-manager-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-keyboard-helpers.js */
-/* import-globals-from ../shared-modules/test-prompt-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-mail-account-setup-wizard";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "window-helpers",
   "account-manager-helpers",
-  "keyboard-helpers",
-  "prompt-helpers",
 ];
 
+var elib = ChromeUtils.import(
+  "chrome://mozmill/content/modules/elementslib.jsm"
+);
+
+var { input_value, delete_all_existing } = ChromeUtils.import(
+  "resource://testing-common/mozmill/KeyboardHelpers.jsm"
+);
+var { gMockPromptService } = ChromeUtils.import(
+  "resource://testing-common/mozmill/PromptHelpers.jsm"
+);
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 
-var elib = ChromeUtils.import(
-  "chrome://mozmill/content/modules/elementslib.jsm"
-);
-
 var user = {
   name: "Yamato Nadeshiko",
   email: "yamato.nadeshiko@example.com",
   password: "abc12345",
   incomingHost: "testin.example.com",
   outgoingHost: "testout.example.com",
 };
 
--- a/mail/test/mozmill/account/test-retest-config.js
+++ b/mail/test/mozmill/account/test-retest-config.js
@@ -1,31 +1,34 @@
 /* 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";
 
 /* import-globals-from ../shared-modules/test-account-manager-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-keyboard-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-retest-config";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "window-helpers",
-  "keyboard-helpers",
   "account-manager-helpers",
 ];
 
 var elib = ChromeUtils.import(
   "chrome://mozmill/content/modules/elementslib.jsm"
 );
+
+var { input_value, delete_all_existing } = ChromeUtils.import(
+  "resource://testing-common/mozmill/KeyboardHelpers.jsm"
+);
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 var user = {
   name: "test",
   email: "test@momo.invalid",
   altEmail: "test2@momo.invalid",
 };
 
--- a/mail/test/mozmill/addrbook/test-address-book.js
+++ b/mail/test/mozmill/addrbook/test-address-book.js
@@ -6,29 +6,31 @@
  * Tests for the address book.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-address-book-helpers.js */
 /* import-globals-from ../shared-modules/test-compose-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-prompt-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-address-book";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "address-book-helpers",
   "compose-helpers",
   "window-helpers",
-  "prompt-helpers",
 ];
 
+var { gMockPromptService } = ChromeUtils.import(
+  "resource://testing-common/mozmill/PromptHelpers.jsm"
+);
+
 var { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 
--- a/mail/test/mozmill/attachment/test-attachment-events.js
+++ b/mail/test/mozmill/attachment/test-attachment-events.js
@@ -3,36 +3,37 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * Ensures that attachment events are fired properly
  */
 
 "use strict";
 
-/* import-globals-from ../shared-modules/test-attachment-helpers.js */
 /* import-globals-from ../shared-modules/test-compose-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-observer-helpers.js */
-/* import-globals-from ../shared-modules/test-prompt-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-attachment-events";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "compose-helpers",
   "window-helpers",
-  "attachment-helpers",
-  "observer-helpers",
-  "prompt-helpers",
 ];
 
 var os = ChromeUtils.import("chrome://mozmill/content/stdlib/os.jsm");
 
+var { select_attachments } = ChromeUtils.import(
+  "resource://testing-common/mozmill/AttachmentHelpers.jsm"
+);
+var { gMockPromptService } = ChromeUtils.import(
+  "resource://testing-common/mozmill/PromptHelpers.jsm"
+);
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { fixIterator } = ChromeUtils.import(
   "resource:///modules/iteratorUtils.jsm"
 );
 
 var kAttachmentsAdded = "attachments-added";
 var kAttachmentsRemoved = "attachments-removed";
 var kAttachmentRenamed = "attachment-renamed";
--- a/mail/test/mozmill/attachment/test-attachment-menus.js
+++ b/mail/test/mozmill/attachment/test-attachment-menus.js
@@ -1,38 +1,42 @@
 /* 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";
 
-/* import-globals-from ../shared-modules/test-attachment-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-attachment-menus";
 var RELATIVE_ROOT = "../shared-modules";
-var MODULE_REQUIRES = [
-  "folder-display-helpers",
-  "window-helpers",
-  "attachment-helpers",
-];
+var MODULE_REQUIRES = ["folder-display-helpers", "window-helpers"];
 
 var folder;
 var messenger;
 var epsilon;
 
 var elib = ChromeUtils.import(
   "chrome://mozmill/content/modules/elementslib.jsm"
 );
 var os = ChromeUtils.import("chrome://mozmill/content/stdlib/os.jsm");
 var controller = ChromeUtils.import(
   "chrome://mozmill/content/modules/controller.jsm"
 );
 
+var {
+  create_body_part,
+  create_deleted_attachment,
+  create_detached_attachment,
+  create_enclosure_attachment,
+} = ChromeUtils.import(
+  "resource://testing-common/mozmill/AttachmentHelpers.jsm"
+);
+
 var textAttachment =
   "Can't make the frug contest, Helen; stomach's upset. I'll fix you, " +
   "Ubik! Ubik drops you back in the thick of things fast. Taken as " +
   "directed, Ubik speeds relief to head and stomach. Remember: Ubik is " +
   "only seconds away. Avoid prolonged use.";
 
 var detachedName = "./attachment.txt";
 var missingName = "./nonexistent.txt";
@@ -174,18 +178,16 @@ var messages = [
   },
 ];
 
 function setupModule(module) {
   let fdh = collector.getModule("folder-display-helpers");
   fdh.installInto(module);
   let wh = collector.getModule("window-helpers");
   wh.installInto(module);
-  let ah = collector.getModule("attachment-helpers");
-  ah.installInto(module);
 
   messenger = Cc["@mozilla.org/messenger;1"].createInstance(Ci.nsIMessenger);
 
   /* Today's gory details (thanks to Jonathan Protzenko): libmime somehow
    * counts the trailing newline for an attachment MIME part. Most of the time,
    * assuming attachment has N bytes (no matter what's inside, newlines or
    * not), libmime will return N + 1 bytes. On Linux and Mac, this always
    * holds. However, on Windows, if the attachment is not encoded (that is, is
--- a/mail/test/mozmill/attachment/test-attachment-size.js
+++ b/mail/test/mozmill/attachment/test-attachment-size.js
@@ -1,35 +1,38 @@
 /* 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";
 
-/* import-globals-from ../shared-modules/test-attachment-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-attachment-size";
 var RELATIVE_ROOT = "../shared-modules";
-var MODULE_REQUIRES = [
-  "folder-display-helpers",
-  "window-helpers",
-  "attachment-helpers",
-];
+var MODULE_REQUIRES = ["folder-display-helpers", "window-helpers"];
 
 var folder;
 var messenger;
 var epsilon;
 
 var os = ChromeUtils.import("chrome://mozmill/content/stdlib/os.jsm");
 var controller = ChromeUtils.import(
   "chrome://mozmill/content/modules/controller.jsm"
 );
 
+var {
+  create_body_part,
+  create_deleted_attachment,
+  create_detached_attachment,
+} = ChromeUtils.import(
+  "resource://testing-common/mozmill/AttachmentHelpers.jsm"
+);
+
 var textAttachment =
   "Can't make the frug contest, Helen; stomach's upset. I'll fix you, " +
   "Ubik! Ubik drops you back in the thick of things fast. Taken as " +
   "directed, Ubik speeds relief to head and stomach. Remember: Ubik is " +
   "only seconds away. Avoid prolonged use.";
 
 var binaryAttachment = textAttachment;
 
--- a/mail/test/mozmill/cloudfile/test-cloudfile-attachment-item.js
+++ b/mail/test/mozmill/cloudfile/test-cloudfile-attachment-item.js
@@ -6,27 +6,33 @@
  * Tests Filelink attachment item behaviour.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
 /* import-globals-from ../shared-modules/test-compose-helpers.js */
 /* import-globals-from ../shared-modules/test-cloudfile-helpers.js */
-/* import-globals-from ../shared-modules/test-attachment-helpers.js */
 
 var MODULE_NAME = "test-cloudfile-attachment-item";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "compose-helpers",
   "cloudfile-helpers",
-  "attachment-helpers",
 ];
 
+var {
+  gMockFilePicker,
+  gMockFilePickReg,
+  select_attachments,
+} = ChromeUtils.import(
+  "resource://testing-common/mozmill/AttachmentHelpers.jsm"
+);
+
 var kAttachmentItemContextID = "msgComposeAttachmentItemContext";
 
 var { cloudFileAccounts } = ChromeUtils.import(
   "resource:///modules/cloudFileAccounts.jsm"
 );
 
 function setupModule(module) {
   for (let lib of MODULE_REQUIRES) {
--- a/mail/test/mozmill/cloudfile/test-cloudfile-attachment-urls.js
+++ b/mail/test/mozmill/cloudfile/test-cloudfile-attachment-urls.js
@@ -6,31 +6,37 @@
  * Tests Filelink URL insertion behaviours in compose windows.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
 /* import-globals-from ../shared-modules/test-compose-helpers.js */
 /* import-globals-from ../shared-modules/test-cloudfile-helpers.js */
-/* import-globals-from ../shared-modules/test-attachment-helpers.js */
 /* import-globals-from ../shared-modules/test-dom-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-cloudfile-attachment-urls";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "compose-helpers",
   "cloudfile-helpers",
-  "attachment-helpers",
   "dom-helpers",
   "window-helpers",
 ];
 
+var {
+  gMockFilePicker,
+  gMockFilePickReg,
+  select_attachments,
+} = ChromeUtils.import(
+  "resource://testing-common/mozmill/AttachmentHelpers.jsm"
+);
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 
 var kUploadedFile = "attachment-uploaded";
 var kHtmlPrefKey = "mail.identity.default.compose_html";
 var kReplyOnTopKey = "mail.identity.default.reply_on_top";
--- a/mail/test/mozmill/cloudfile/test-cloudfile-notifications.js
+++ b/mail/test/mozmill/cloudfile/test-cloudfile-notifications.js
@@ -6,31 +6,43 @@
  * Tests that the cloudfile notifications work as they should.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
 /* import-globals-from ../shared-modules/test-compose-helpers.js */
 /* import-globals-from ../shared-modules/test-cloudfile-helpers.js */
-/* import-globals-from ../shared-modules/test-attachment-helpers.js */
-/* import-globals-from ../shared-modules/test-prompt-helpers.js */
-/* import-globals-from ../shared-modules/test-notificationbox-helpers.js */
 
 var MODULE_NAME = "test-cloudfile-notifications";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "compose-helpers",
   "cloudfile-helpers",
-  "attachment-helpers",
-  "prompt-helpers",
-  "notificationbox-helpers",
 ];
 
+var {
+  gMockFilePicker,
+  gMockFilePickReg,
+  select_attachments,
+} = ChromeUtils.import(
+  "resource://testing-common/mozmill/AttachmentHelpers.jsm"
+);
+var {
+  assert_notification_displayed,
+  close_notification,
+  wait_for_notification_to_stop,
+} = ChromeUtils.import(
+  "resource://testing-common/mozmill/NotificationBoxHelpers.jsm"
+);
+var { gMockPromptService } = ChromeUtils.import(
+  "resource://testing-common/mozmill/PromptHelpers.jsm"
+);
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { cloudFileAccounts } = ChromeUtils.import(
   "resource:///modules/cloudFileAccounts.jsm"
 );
 
 var maxSize, oldInsertNotificationPref;
 
 var kOfferThreshold = "mail.compose.big_attachments.threshold_kb";
--- a/mail/test/mozmill/composition/test-attachment-reminder.js
+++ b/mail/test/mozmill/composition/test-attachment-reminder.js
@@ -5,30 +5,39 @@
 /**
  * Tests that the attachment reminder works properly.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-compose-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-keyboard-helpers.js */
-/* import-globals-from ../shared-modules/test-notificationbox-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-attachment-reminder";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "compose-helpers",
   "window-helpers",
-  "notificationbox-helpers",
-  "keyboard-helpers",
 ];
 
+var { delete_all_existing } = ChromeUtils.import(
+  "resource://testing-common/mozmill/KeyboardHelpers.jsm"
+);
+var {
+  assert_notification_displayed,
+  check_notification_displayed,
+  get_notification_button,
+  wait_for_notification_to_show,
+  wait_for_notification_to_stop,
+} = ChromeUtils.import(
+  "resource://testing-common/mozmill/NotificationBoxHelpers.jsm"
+);
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 
 var kBoxId = "compose-notification-bottom";
 var kNotificationId = "attachmentReminder";
 var kReminderPref = "mail.compose.attachment_reminder";
--- a/mail/test/mozmill/composition/test-blocked-content.js
+++ b/mail/test/mozmill/composition/test-blocked-content.js
@@ -5,29 +5,32 @@
 /**
  * Tests that we do the right thing wrt. blocked resources during composition.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-compose-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-notificationbox-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-blocked-content";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "window-helpers",
   "compose-helpers",
-  "notificationbox-helpers",
 ];
 
 var os = ChromeUtils.import("chrome://mozmill/content/stdlib/os.jsm");
+
+var { wait_for_notification_to_show } = ChromeUtils.import(
+  "resource://testing-common/mozmill/NotificationBoxHelpers.jsm"
+);
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 var { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
 
 var gOutboxFolder;
 
--- a/mail/test/mozmill/composition/test-charset-edit.js
+++ b/mail/test/mozmill/composition/test-charset-edit.js
@@ -6,38 +6,41 @@
  * Tests that we do the right thing wrt. message encoding when editing or
  * replying to messages.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-compose-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-notificationbox-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-charset-edit";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "compose-helpers",
   "window-helpers",
-  "notificationbox-helpers",
 ];
 
+var elib = ChromeUtils.import(
+  "chrome://mozmill/content/modules/elementslib.jsm"
+);
 var os = ChromeUtils.import("chrome://mozmill/content/stdlib/os.jsm");
+var utils = ChromeUtils.import("chrome://mozmill/content/modules/utils.jsm");
+
+var { wait_for_notification_to_show } = ChromeUtils.import(
+  "resource://testing-common/mozmill/NotificationBoxHelpers.jsm"
+);
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 var { MimeParser } = ChromeUtils.import("resource:///modules/mimeParser.jsm");
-var elib = ChromeUtils.import(
-  "chrome://mozmill/content/modules/elementslib.jsm"
-);
-var utils = ChromeUtils.import("chrome://mozmill/content/modules/utils.jsm");
 
 var gDrafts;
 
 function setupModule(module) {
   for (let req of MODULE_REQUIRES) {
     collector.getModule(req).installInto(module);
   }
 
--- a/mail/test/mozmill/composition/test-draft-identity.js
+++ b/mail/test/mozmill/composition/test-draft-identity.js
@@ -6,28 +6,33 @@
  * Tests that compose new message chooses the correct initial identity when
  * called from the context of an open composer.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-compose-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-notificationbox-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-draft-identity";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "window-helpers",
   "compose-helpers",
-  "notificationbox-helpers",
 ];
 
+var {
+  assert_notification_displayed,
+  wait_for_notification_to_show,
+} = ChromeUtils.import(
+  "resource://testing-common/mozmill/NotificationBoxHelpers.jsm"
+);
+
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 
 var gDrafts;
 var gAccount;
 
 // The first identity should become the default in the account.
--- a/mail/test/mozmill/composition/test-drafts.js
+++ b/mail/test/mozmill/composition/test-drafts.js
@@ -6,28 +6,30 @@
  * Tests draft related functionality:
  * - that we don't allow opening multiple copies of a draft.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-compose-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-notificationbox-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-drafts";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "compose-helpers",
   "window-helpers",
-  "notificationbox-helpers",
 ];
 
+var { wait_for_notification_to_show } = ChromeUtils.import(
+  "resource://testing-common/mozmill/NotificationBoxHelpers.jsm"
+);
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 
 var kBoxId = "mail-notification-top";
 var draftsFolder;
 
--- a/mail/test/mozmill/composition/test-forward-headers.js
+++ b/mail/test/mozmill/composition/test-forward-headers.js
@@ -6,43 +6,43 @@
  * Tests that headers like References and X-Forwarded-Message-Id are
  * set properly when forwarding messages.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-compose-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-message-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-forward-headers";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "compose-helpers",
   "window-helpers",
-  "message-helpers",
 ];
 
+var { to_mime_message } = ChromeUtils.import(
+  "resource://testing-common/mozmill/MessageHelpers.jsm"
+);
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 var cwc = null; // compose window controller
 var folder;
 var gDrafts;
 
 function setupModule(module) {
   let fdh = collector.getModule("folder-display-helpers");
   fdh.installInto(module);
   let composeHelper = collector.getModule("compose-helpers");
   composeHelper.installInto(module);
   let wh = collector.getModule("window-helpers");
   wh.installInto(module);
-  let mh = collector.getModule("message-helpers");
-  mh.installInto(module);
 
   folder = create_folder("Test");
   let thread1 = create_thread(10);
   add_sets_to_folders([folder], [thread1]);
 
   gDrafts = get_special_folder(Ci.nsMsgFolderFlags.Drafts, true);
 
   // Don't create paragraphs in the test.
--- a/mail/test/mozmill/composition/test-image-insertion-dialog.js
+++ b/mail/test/mozmill/composition/test-image-insertion-dialog.js
@@ -5,43 +5,43 @@
 /**
  * Tests the image insertion dialog functionality.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-compose-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-keyboard-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-image-insertion-dialog";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "compose-helpers",
   "window-helpers",
-  "keyboard-helpers",
 ];
 
 var elib = ChromeUtils.import(
   "chrome://mozmill/content/modules/elementslib.jsm"
 );
 
-var fdh, ch, wh, kh;
+var { input_value } = ChromeUtils.import(
+  "resource://testing-common/mozmill/KeyboardHelpers.jsm"
+);
+
+var fdh, ch, wh;
 
 function setupModule(module) {
   fdh = collector.getModule("folder-display-helpers");
   fdh.installInto(module);
   ch = collector.getModule("compose-helpers");
   ch.installInto(module);
   wh = collector.getModule("window-helpers");
   wh.installInto(module);
-  kh = collector.getModule("keyboard-helpers");
-  kh.installInto(module);
 }
 
 function test_image_insertion_dialog_persist() {
   let cwc = open_compose_new_mail();
 
   // First focus on the editor element
   cwc.e("content-frame").focus();
 
--- a/mail/test/mozmill/composition/test-reply-signature.js
+++ b/mail/test/mozmill/composition/test-reply-signature.js
@@ -5,26 +5,24 @@
 /**
  * Tests the mail.strip_sig_on_reply pref.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-compose-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-message-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-reply-signature";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "compose-helpers",
   "window-helpers",
-  "message-helpers",
 ];
 
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 var sig = "roses are red";
 var folder;
 
 function setupModule(module) {
--- a/mail/test/mozmill/composition/test-save-changes-on-quit.js
+++ b/mail/test/mozmill/composition/test-save-changes-on-quit.js
@@ -7,32 +7,34 @@
  * try to quit/close with an open compose window with unsaved changes, and
  * that we don't prompt if there are no changes.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-compose-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-prompt-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-save-changes-on-quit";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "compose-helpers",
-  "prompt-helpers",
   "window-helpers",
 ];
 
 var SAVE = 0;
 var CANCEL = 1;
 var DONT_SAVE = 2;
 
+var { gMockPromptService } = ChromeUtils.import(
+  "resource://testing-common/mozmill/PromptHelpers.jsm"
+);
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 var cwc = null; // compose window controller
 var folder = null;
 
 function setupModule(module) {
   for (let lib of MODULE_REQUIRES) {
     collector.getModule(lib).installInto(module);
--- a/mail/test/mozmill/content-policy/test-compose-mailto.js
+++ b/mail/test/mozmill/content-policy/test-compose-mailto.js
@@ -2,46 +2,46 @@
  * 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";
 
 /* import-globals-from ../shared-modules/test-compose-helpers.js */
 /* import-globals-from ../shared-modules/test-content-tab-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-keyboard-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-compose-mailto";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "compose-helpers",
   "window-helpers",
-  "keyboard-helpers",
   "content-tab-helpers",
 ];
 
+var { input_value } = ChromeUtils.import(
+  "resource://testing-common/mozmill/KeyboardHelpers.jsm"
+);
+
 var folder = null;
 var composeHelper = null;
 var windowHelper = null;
 var gMsgNo = 0;
 var gComposeWin;
 var gNewTab;
 var gPreCount;
 
 // RELATIVE_ROOT messes with the collector, so we have to bring the path back
 // so we get the right path for the resources.
 var url = collector.addHttpResource("../content-policy/html", "content");
 
 function setupModule(module) {
   let fdh = collector.getModule("folder-display-helpers");
   fdh.installInto(module);
-  let kh = collector.getModule("keyboard-helpers");
-  kh.installInto(module);
   composeHelper = collector.getModule("compose-helpers");
   composeHelper.installInto(module);
   windowHelper = collector.getModule("window-helpers");
   windowHelper.installInto(module);
   let cth = collector.getModule("content-tab-helpers");
   cth.installInto(module);
 }
 
--- a/mail/test/mozmill/content-policy/test-general-content-policy.js
+++ b/mail/test/mozmill/content-policy/test-general-content-policy.js
@@ -17,36 +17,43 @@
  * - Feed message
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-compose-helpers.js */
 /* import-globals-from ../shared-modules/test-content-tab-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-keyboard-helpers.js */
-/* import-globals-from ../shared-modules/test-notificationbox-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-general-content-policy";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "window-helpers",
   "compose-helpers",
   "content-tab-helpers",
-  "keyboard-helpers",
-  "notificationbox-helpers",
 ];
 
 var elib = ChromeUtils.import(
   "chrome://mozmill/content/modules/elementslib.jsm"
 );
 var os = ChromeUtils.import("chrome://mozmill/content/stdlib/os.jsm");
 
+var { input_value } = ChromeUtils.import(
+  "resource://testing-common/mozmill/KeyboardHelpers.jsm"
+);
+var {
+  get_notification_button,
+  wait_for_notification_to_show,
+  wait_for_notification_to_stop,
+} = ChromeUtils.import(
+  "resource://testing-common/mozmill/NotificationBoxHelpers.jsm"
+);
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 
 var folder = null;
 var gMsgNo = 0;
 
--- a/mail/test/mozmill/downloads/test-about-downloads.js
+++ b/mail/test/mozmill/downloads/test-about-downloads.js
@@ -3,37 +3,38 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  * Test about:downloads.
  */
 
 "use strict";
 
-/* import-globals-from ../shared-modules/test-attachment-helpers.js */
 /* import-globals-from ../shared-modules/test-content-tab-helpers.js */
 /* import-globals-from ../shared-modules/test-dom-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-prompt-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-about-downloads";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
-  "attachment-helpers",
   "content-tab-helpers",
   "dom-helpers",
   "folder-display-helpers",
-  "prompt-helpers",
   "window-helpers",
 ];
 
 var elementslib = ChromeUtils.import(
   "chrome://mozmill/content/modules/elementslib.jsm"
 );
+
+var { gMockFilePicker, gMockFilePickReg } = ChromeUtils.import(
+  "resource://testing-common/mozmill/AttachmentHelpers.jsm"
+);
+
 var downloads = ChromeUtils.import("resource://gre/modules/Downloads.jsm");
 
 var downloadsTab;
 
 var attachmentFileNames = [
   "Attachment#1.txt",
   "Attachment#2.txt",
   "Attachment#3.txt",
--- a/mail/test/mozmill/folder-widget/test-message-filters.js
+++ b/mail/test/mozmill/folder-widget/test-message-filters.js
@@ -6,32 +6,35 @@
  * Test various properties of the message filters.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-address-book-helpers.js */
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
 /* import-globals-from ../shared-modules/test-nntp-helpers.js */
-/* import-globals-from ../shared-modules/test-prompt-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-message-filters";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "window-helpers",
   "nntp-helpers",
   "address-book-helpers",
-  "prompt-helpers",
 ];
 
 var elib = ChromeUtils.import(
   "chrome://mozmill/content/modules/elementslib.jsm"
 );
+
+var { gMockPromptService } = ChromeUtils.import(
+  "resource://testing-common/mozmill/PromptHelpers.jsm"
+);
+
 var folderA;
 
 function setupModule(module) {
   for (let lib of MODULE_REQUIRES) {
     collector.getModule(lib).installInto(module);
   }
 
   setupNNTPDaemon();
--- a/mail/test/mozmill/instrumentation/test-instrument-setup.js
+++ b/mail/test/mozmill/instrumentation/test-instrument-setup.js
@@ -1,29 +1,29 @@
 /* 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";
 
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-keyboard-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-instrument-setup";
 var RELATIVE_ROOT = "../shared-modules";
-var MODULE_REQUIRES = [
-  "folder-display-helpers",
-  "window-helpers",
-  "keyboard-helpers",
-];
+var MODULE_REQUIRES = ["folder-display-helpers", "window-helpers"];
 
 var elib = ChromeUtils.import(
   "chrome://mozmill/content/modules/elementslib.jsm"
 );
+
+var { input_value } = ChromeUtils.import(
+  "resource://testing-common/mozmill/KeyboardHelpers.jsm"
+);
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 var user = {
   name: "Roger Sterling",
   email: "roger.sterling@example.com",
   incomingHost: "testin.example.com",
   outgoingHost: "testout.example.com",
 };
--- a/mail/test/mozmill/message-header/test-phishing-bar.js
+++ b/mail/test/mozmill/message-header/test-phishing-bar.js
@@ -4,29 +4,33 @@
 
 /**
  * Test that phishing notifications behave properly.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-notificationbox-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-phishing-bar";
 var RELATIVE_ROOT = "../shared-modules";
-var MODULE_REQUIRES = [
-  "folder-display-helpers",
-  "window-helpers",
-  "notificationbox-helpers",
-];
+var MODULE_REQUIRES = ["folder-display-helpers", "window-helpers"];
 
 var os = ChromeUtils.import("chrome://mozmill/content/stdlib/os.jsm");
 
+var {
+  assert_notification_displayed,
+  get_notification_button,
+  wait_for_notification_to_show,
+  wait_for_notification_to_stop,
+} = ChromeUtils.import(
+  "resource://testing-common/mozmill/NotificationBoxHelpers.jsm"
+);
+
 var folder;
 
 var kBoxId = "mail-notification-top";
 var kNotificationValue = "maybeScam";
 
 function setupModule(module) {
   for (let dep of MODULE_REQUIRES) {
     collector.getModule(dep).installInto(module);
--- a/mail/test/mozmill/message-header/test-return-receipt.js
+++ b/mail/test/mozmill/message-header/test-return-receipt.js
@@ -4,36 +4,34 @@
 
 /*
  * Test return receipt (MDN) stuff.
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
-/* import-globals-from ../shared-modules/test-notificationbox-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 
 var MODULE_NAME = "test-return-receipt";
 var RELATIVE_ROOT = "../shared-modules";
-var MODULE_REQUIRES = [
-  "folder-display-helpers",
-  "window-helpers",
-  "notificationbox-helpers",
-];
+var MODULE_REQUIRES = ["folder-display-helpers", "window-helpers"];
+
+var { assert_notification_displayed } = ChromeUtils.import(
+  "resource://testing-common/mozmill/NotificationBoxHelpers.jsm"
+);
 
 var folder;
 
 var kBoxId = "mail-notification-top";
 var kNotificationValue = "mdnRequested";
 
 function setupModule(module) {
   collector.getModule("folder-display-helpers").installInto(module);
   collector.getModule("window-helpers").installInto(module);
-  collector.getModule("notificationbox-helpers").installInto(module);
 
   folder = create_folder("ReturnReceiptTest");
 
   // Create a message that requests a return receipt.
   let msg0 = create_message({
     from: ["Ake", "ake@example.com"],
     clobberHeaders: { "Disposition-Notification-To": "ake@example.com" },
   });
--- a/mail/test/mozmill/newmailaccount/test-newmailaccount.js
+++ b/mail/test/mozmill/newmailaccount/test-newmailaccount.js
@@ -7,33 +7,32 @@
  */
 
 "use strict";
 
 /* import-globals-from ../shared-modules/test-folder-display-helpers.js */
 /* import-globals-from ../shared-modules/test-content-tab-helpers.js */
 /* import-globals-from ../shared-modules/test-window-helpers.js */
 /* import-globals-from ../shared-modules/test-newmailaccount-helpers.js */
-/* import-globals-from ../shared-modules/test-keyboard-helpers.js */
 /* import-globals-from ../shared-modules/test-dom-helpers.js */
 
 var MODULE_NAME = "test-newmailaccount";
 var RELATIVE_ROOT = "../shared-modules";
 var MODULE_REQUIRES = [
   "folder-display-helpers",
   "content-tab-helpers",
   "window-helpers",
   "newmailaccount-helpers",
-  "keyboard-helpers",
   "dom-helpers",
 ];
 
 var elib = ChromeUtils.import(
   "chrome://mozmill/content/modules/elementslib.jsm"
 );
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 var { HttpServer } = ChromeUtils.import(
   "chrome://mozmill/content/stdlib/httpd.jsm"
 );
 
rename from mail/test/mozmill/shared-modules/test-attachment-helpers.js
rename to mail/test/mozmill/shared-modules/AttachmentHelpers.jsm
--- a/mail/test/mozmill/shared-modules/test-attachment-helpers.js
+++ b/mail/test/mozmill/shared-modules/AttachmentHelpers.jsm
@@ -1,46 +1,34 @@
 /* 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 MODULE_NAME = "attachment-helpers";
-var RELATIVE_ROOT = "../shared-modules";
-var MODULE_REQUIRES = ["mock-object-helpers"];
+this.EXPORTED_SYMBOLS = [
+  "create_body_part",
+  "create_deleted_attachment",
+  "create_detached_attachment",
+  "create_enclosure_attachment",
+  "gMockFilePicker",
+  "gMockFilePickReg",
+  "select_attachments",
+];
 
-var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-var { XPCOMUtils } = ChromeUtils.import(
-  "resource://gre/modules/XPCOMUtils.jsm"
+var { MockObjectReplacer } = ChromeUtils.import(
+  "resource://testing-common/mozmill/MockObjectHelpers.jsm"
 );
 
-var gMockFilePickReg;
-
-function setupModule(module) {
-  let moh = collector.getModule("mock-object-helpers");
-
-  gMockFilePickReg = new moh.MockObjectReplacer(
-    "@mozilla.org/filepicker;1",
-    MockFilePickerConstructor
-  );
-}
+var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
-function installInto(module) {
-  setupModule(module);
-
-  // Now copy helper functions
-  module.create_body_part = create_body_part;
-  module.create_detached_attachment = create_detached_attachment;
-  module.create_deleted_attachment = create_deleted_attachment;
-  module.create_enclosure_attachment = create_enclosure_attachment;
-  module.gMockFilePickReg = gMockFilePickReg;
-  module.gMockFilePicker = gMockFilePicker;
-  module.select_attachments = select_attachments;
-}
+var gMockFilePickReg = new MockObjectReplacer(
+  "@mozilla.org/filepicker;1",
+  MockFilePickerConstructor
+);
 
 function MockFilePickerConstructor() {
   return gMockFilePicker;
 }
 
 var gMockFilePicker = {
   QueryInterface: ChromeUtils.generateQI([Ci.nsIFilePicker]),
   defaultExtension: "",
rename from mail/test/mozmill/shared-modules/test-keyboard-helpers.js
rename to mail/test/mozmill/shared-modules/KeyboardHelpers.jsm
--- a/mail/test/mozmill/shared-modules/test-keyboard-helpers.js
+++ b/mail/test/mozmill/shared-modules/KeyboardHelpers.jsm
@@ -1,22 +1,19 @@
 /* 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 MODULE_NAME = "keyboard-helpers";
-
-function installInto(module) {
-  // Now copy helper functions
-  module.input_value = input_value;
-  module.delete_existing = delete_existing;
-  module.delete_all_existing = delete_all_existing;
-}
+this.EXPORTED_SYMBOLS = [
+  "input_value",
+  "delete_existing",
+  "delete_all_existing",
+];
 
 /**
  * Emulates manual input
  *
  * @param aController The window controller to input keypresses into
  * @param aStr        The string to input into the control element
  * @param aElement    (optional) Element on which to perform the input
  */
rename from mail/test/mozmill/shared-modules/test-message-helpers.js
rename to mail/test/mozmill/shared-modules/MessageHelpers.jsm
--- a/mail/test/mozmill/shared-modules/test-message-helpers.js
+++ b/mail/test/mozmill/shared-modules/MessageHelpers.jsm
@@ -3,42 +3,37 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * Helpers to deal with message (nsIMsgDBHdr) parsing.
  */
 
 "use strict";
 
-var MODULE_NAME = "message-helpers";
+this.EXPORTED_SYMBOLS = ["to_mime_message"];
 
 var frame = ChromeUtils.import("chrome://mozmill/content/modules/frame.jsm");
 var utils = ChromeUtils.import("chrome://mozmill/content/modules/utils.jsm");
 
 var { MsgHdrToMimeMessage } = ChromeUtils.import(
   "resource:///modules/gloda/mimemsg.js"
 );
 
-function installInto(module) {
-  module.to_mime_message = to_mime_message;
-}
-
 /**
  * Given a message header, converts it to a MimeMessage. If aCallback throws,
  * the test will be marked failed. See the documentation for MsgHdrToMimeMessage
  * for more details.
  */
 function to_mime_message(
   aMsgHdr,
   aCallbackThis,
   aCallback,
   aAllowDownload,
   aOptions
 ) {
-  new frame.Runner(collector);
   let called = false;
   let currentTest = frame.events.currentTest;
   MsgHdrToMimeMessage(
     aMsgHdr,
     aCallbackThis,
     function(aRecdMsgHdr, aMimeMsg) {
       try {
         aCallback(aRecdMsgHdr, aMimeMsg);
rename from mail/test/mozmill/shared-modules/test-mock-object-helpers.js
rename to mail/test/mozmill/shared-modules/MockObjectHelpers.jsm
--- a/mail/test/mozmill/shared-modules/test-mock-object-helpers.js
+++ b/mail/test/mozmill/shared-modules/MockObjectHelpers.jsm
@@ -1,33 +1,28 @@
 /* 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 MODULE_NAME = "mock-object-helpers";
+this.EXPORTED_SYMBOLS = ["MockObjectReplacer", "MockObjectRegisterer"];
 
 var Cm = Components.manager;
 
 const { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 XPCOMUtils.defineLazyServiceGetter(
   this,
   "UUIDGen",
   "@mozilla.org/uuid-generator;1",
   "nsIUUIDGenerator"
 );
 
-function installInto(module) {
-  module.MockObjectReplacer = MockObjectReplacer;
-  module.MockObjectRegisterer = MockObjectRegisterer;
-}
-
 function MockObjectRegisterer(aContractID, aCID, aComponent) {
   this._contractID = aContractID;
   this._cid = Components.ID("{" + aCID + "}");
   this._component = aComponent;
 }
 
 MockObjectRegisterer.prototype = {
   register: function MOR_register() {
rename from mail/test/mozmill/shared-modules/test-notificationbox-helpers.js
rename to mail/test/mozmill/shared-modules/NotificationBoxHelpers.jsm
--- a/mail/test/mozmill/shared-modules/test-notificationbox-helpers.js
+++ b/mail/test/mozmill/shared-modules/NotificationBoxHelpers.jsm
@@ -1,24 +1,22 @@
 /* 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 MODULE_NAME = "notificationbox-helpers";
-
-function installInto(module) {
-  module.check_notification_displayed = check_notification_displayed;
-  module.assert_notification_displayed = assert_notification_displayed;
-  module.close_notification = close_notification;
-  module.wait_for_notification_to_stop = wait_for_notification_to_stop;
-  module.wait_for_notification_to_show = wait_for_notification_to_show;
-  module.get_notification_button = get_notification_button;
-}
+this.EXPORTED_SYMBOLS = [
+  "check_notification_displayed",
+  "assert_notification_displayed",
+  "close_notification",
+  "wait_for_notification_to_stop",
+  "wait_for_notification_to_show",
+  "get_notification_button",
+];
 
 /**
  * A helper function for determining whether or not a notification with
  * a particular value is being displayed.
  *
  * @param aController    the controller of the window to check
  * @param aBoxId         the id of the notification box
  * @param aValue         the value of the notification to look for
rename from mail/test/mozmill/shared-modules/test-prompt-helpers.js
rename to mail/test/mozmill/shared-modules/PromptHelpers.jsm
--- a/mail/test/mozmill/shared-modules/test-prompt-helpers.js
+++ b/mail/test/mozmill/shared-modules/PromptHelpers.jsm
@@ -1,45 +1,37 @@
 /* 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 MODULE_NAME = "prompt-helpers";
-var RELATIVE_ROOT = "../shared-modules";
-var MODULE_REQUIRES = ["mock-object-helpers"];
+this.EXPORTED_SYMBOLS = [
+  "gMockPromptService",
+  "gMockAuthPromptReg",
+  "gMockAuthPrompt",
+];
+
+var { MockObjectReplacer } = ChromeUtils.import(
+  "resource://testing-common/mozmill/MockObjectHelpers.jsm"
+);
 
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { XPCOMUtils } = ChromeUtils.import(
   "resource://gre/modules/XPCOMUtils.jsm"
 );
 
 var kMockPromptServiceName = "Mock Prompt Service";
 var kPromptServiceContractID = "@mozilla.org/embedcomp/prompt-service;1";
 var kPromptServiceName = "Prompt Service";
 
-var gMockAuthPromptReg;
-
-function setupModule() {
-  let moh = collector.getModule("mock-object-helpers");
-  gMockAuthPromptReg = new moh.MockObjectReplacer(
-    "@mozilla.org/prompter;1",
-    MockAuthPromptFactoryConstructor
-  );
-}
-
-function installInto(module) {
-  setupModule();
-
-  // Now copy helper functions
-  module.gMockPromptService = gMockPromptService;
-  module.gMockAuthPromptReg = gMockAuthPromptReg;
-  module.gMockAuthPrompt = gMockAuthPrompt;
-}
+var gMockAuthPromptReg = new MockObjectReplacer(
+  "@mozilla.org/prompter;1",
+  MockAuthPromptFactoryConstructor
+);
 
 function MockAuthPromptFactoryConstructor() {
   return gMockAuthPromptFactory;
 }
 
 var gMockAuthPromptFactory = {
   QueryInterface: ChromeUtils.generateQI([Ci.nsIPromptFactory]),
   getPrompt(aParent, aIID, aResult) {
--- a/mail/test/mozmill/shared-modules/moz.build
+++ b/mail/test/mozmill/shared-modules/moz.build
@@ -4,8 +4,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 # Copies the files in this folder to a staging directory in the objdir.
 # The calendar mozmill test files are run from there and use some files
 # from this folder.
 TEST_HARNESS_FILES.mozmill.stage['shared-modules'] += [
     'test*.js',
 ]
+
+TESTING_JS_MODULES.mozmill += [
+    'AttachmentHelpers.jsm',
+    'KeyboardHelpers.jsm',
+    'MessageHelpers.jsm',
+    'MockObjectHelpers.jsm',
+    'NotificationBoxHelpers.jsm',
+    'PromptHelpers.jsm',
+]
--- a/mail/test/mozmill/shared-modules/test-content-tab-helpers.js
+++ b/mail/test/mozmill/shared-modules/test-content-tab-helpers.js
@@ -1,26 +1,27 @@
 /* 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 MODULE_NAME = "content-tab-helpers";
 var RELATIVE_ROOT = "../shared-modules";
-var MODULE_REQUIRES = [
-  "folder-display-helpers",
-  "window-helpers",
-  "mock-object-helpers",
-];
+var MODULE_REQUIRES = ["folder-display-helpers", "window-helpers"];
 
 var elib = ChromeUtils.import(
   "chrome://mozmill/content/modules/elementslib.jsm"
 );
 var utils = ChromeUtils.import("chrome://mozmill/content/modules/utils.jsm");
+
+var { MockObjectReplacer } = ChromeUtils.import(
+  "resource://testing-common/mozmill/MockObjectHelpers.jsm"
+);
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 var NORMAL_TIMEOUT = 6000;
 var FAST_TIMEOUT = 1000;
 var FAST_INTERVAL = 100;
 var EXT_PROTOCOL_SVC_CID = "@mozilla.org/uriloader/external-protocol-service;1";
 
 var folderDisplayHelper;
@@ -34,18 +35,17 @@ var mark_failure;
 var gMockExtProtSvcReg;
 
 function setupModule() {
   folderDisplayHelper = collector.getModule("folder-display-helpers");
   mc = folderDisplayHelper.mc;
   mark_failure = folderDisplayHelper.mark_failure;
 
   wh = collector.getModule("window-helpers");
-  let moh = collector.getModule("mock-object-helpers");
-  gMockExtProtSvcReg = new moh.MockObjectReplacer(
+  gMockExtProtSvcReg = new MockObjectReplacer(
     EXT_PROTOCOL_SVC_CID,
     MockExtProtConstructor
   );
 }
 
 function installInto(module) {
   setupModule();
 
--- a/mail/test/mozmill/shared-modules/test-newmailaccount-helpers.js
+++ b/mail/test/mozmill/shared-modules/test-newmailaccount-helpers.js
@@ -1,39 +1,39 @@
 /* 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 MODULE_NAME = "newmailaccount-helpers";
 var RELATIVE_ROOT = "../shared-modules";
-var MODULE_REQUIRES = [
-  "folder-display-helpers",
-  "keyboard-helpers",
-  "dom-helpers",
-];
+var MODULE_REQUIRES = ["folder-display-helpers", "dom-helpers"];
 
 var elib = ChromeUtils.import(
   "chrome://mozmill/content/modules/elementslib.jsm"
 );
+
+var { input_value } = ChromeUtils.import(
+  "resource://testing-common/mozmill/KeyboardHelpers.jsm"
+);
+
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { fixIterator } = ChromeUtils.import(
   "resource:///modules/iteratorUtils.jsm"
 );
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
 
-var mc, fdh, kbh, dh;
+var mc, fdh, dh;
 
 function setupModule(module) {
   fdh = collector.getModule("folder-display-helpers");
   fdh.installInto(module);
-  kbh = collector.getModule("keyboard-helpers");
   dh = collector.getModule("dom-helpers");
   mc = fdh.mc;
 }
 
 function installInto(module) {
   setupModule(module);
 
   module.wait_for_provider_list_loaded = wait_for_provider_list_loaded;
@@ -171,17 +171,17 @@ function remove_email_account(aAddress) 
  * @param aController the controller for the Account Provisioner dialog.
  * @param aName the name to type in.
  */
 function type_in_search_name(aController, aName) {
   aController.e("name").focus();
   aController.keypress(null, "a", { accelKey: true });
   aController.keypress(null, "VK_BACK_SPACE", {});
 
-  kbh.input_value(aController, aName);
+  input_value(aController, aName);
 }
 
 /* A listener for the Error Console, which allows us to ensure that certain
  * messages appear in the console.
  */
 var gConsoleListener = {
   QueryInterface: ChromeUtils.generateQI([Ci.nsIConsoleListener]),
   _msg: null,
deleted file mode 100644
--- a/mail/test/mozmill/shared-modules/test-observer-helpers.js
+++ /dev/null
@@ -1,146 +0,0 @@
-/* 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 MODULE_NAME = "observer-helpers";
-
-function installInto(module) {
-  module.ObservationRecorder = ObservationRecorder;
-}
-
-/**
- * ObservationRecorder observes events, and records its observations for
- * later analysis.
- */
-function ObservationRecorder() {
-  this.reset();
-}
-
-ObservationRecorder.prototype = {
-  /**
-   * Called by the Observer Service when an event is fired.
-   */
-  observe: function OR_observe(aSubject, aTopic, aData) {
-    if (this._topics.includes(aTopic)) {
-      if (!(aTopic in this.saw)) {
-        this.saw[aTopic] = 0;
-      }
-
-      this.saw[aTopic] += 1;
-
-      if (!(aTopic in this.subject)) {
-        this.subject[aTopic] = [];
-      }
-
-      this.subject[aTopic].push(aSubject);
-
-      if (!(aTopic in this.data)) {
-        this.data[aTopic] = [];
-      }
-
-      this.data[aTopic].push(aData);
-    }
-  },
-
-  /**
-   * Puts the observer back into its starting state.
-   */
-  reset: function OR_reset() {
-    this.saw = {};
-    this.data = {};
-    this.subject = {};
-    this._topics = [];
-  },
-
-  /**
-   * Resets observations for one or more particular topics.
-   *
-   * @param aTopics A string representing the topic that we should
-   *                be resetting observations for.  You can also
-   *                pass in an Array of strings.
-   *
-   * Example:  obs.resetTopic("topic");
-   *           obs.resetTopic(["topic1", "topic2"]);
-   */
-  resetTopic: function OR_resetTopic(aTopics) {
-    if (!Array.isArray(aTopics)) {
-      aTopics = [aTopics];
-    }
-
-    for (let topic of aTopics.entries()) {
-      if (topic in this.saw) {
-        delete this.saw[topic];
-      }
-      if (topic in this.subject) {
-        delete this.subject[topic];
-      }
-      if (topic in this.data) {
-        delete this.data[topic];
-      }
-    }
-  },
-
-  /**
-   * Gets the ObservationRecorder ready to observe events.  Must be called
-   * before any recording can be done. Subsequent calls to planFor will
-   * add to the list of topics that the ObservationRecorder is ready for.
-   *
-   * @param aTopics A string representing the topic that the ObservationRecorder
-   *                should be observing.  You can also pass in an Array of
-   *                strings.
-   *
-   * Example:  obs.planFor("topic");
-   *           obs.planFor(["topic1", "topic2"]);
-   */
-  planFor: function OR_planFor(aTopics) {
-    if (!Array.isArray(aTopics)) {
-      aTopics = [aTopics];
-    }
-
-    this._topics = this._topics.concat(aTopics);
-  },
-
-  /**
-   * Stops the ObservationRecorder from noticing events previously
-   * planned for.  Does not erase any recorded data for these
-   * events.
-   *
-   * @param aTopics A string representing the topic that the ObservationRecorder
-   *                is already observing.  You can also pass in an Array of
-   *                strings.
-   *
-   * Example:  obs.stopNoticing("topic");
-   *           obs.stopNoticing(["topic1", "topic2"]);
-   */
-  stopNoticing: function OR_stopNoticing(aTopics) {
-    if (!Array.isArray(aTopics)) {
-      aTopics = [aTopics];
-    }
-
-    this._topics = this._topics.filter(topic => !aTopics.includes(topic));
-  },
-
-  /**
-   * Returns true of a particular topic was observed at least once.
-   *
-   * @param aTopic the topic to check if the ObservationRecorder saw.
-   */
-  didSee: function OR_didSee(aTopic) {
-    return aTopic in this.saw && this.saw[aTopic];
-  },
-
-  /**
-   * Returns the number of times a particular topic was observed.
-   *
-   * @param aTopic the topic to count the number of observations of.
-   */
-  numSightings: function OR_numSightings(aTopic) {
-    if (!(aTopic in this.saw)) {
-      return 0;
-    }
-
-    return this.saw[aTopic];
-  },
-};
--- a/mail/test/mozmill/shared-modules/test-subscribe-window-helpers.js
+++ b/mail/test/mozmill/shared-modules/test-subscribe-window-helpers.js
@@ -1,32 +1,30 @@
 /* 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 MODULE_NAME = "subscribe-window-helpers";
 var RELATIVE_ROOT = "../shared-modules";
-var MODULE_REQUIRES = [
-  "window-helpers",
-  "folder-display-helpers",
-  "keyboard-helpers",
-];
+var MODULE_REQUIRES = ["window-helpers", "folder-display-helpers"];
+
+var { input_value, delete_all_existing } = ChromeUtils.import(
+  "resource://testing-common/mozmill/KeyboardHelpers.jsm"
+);
 
 var folderDisplayHelper;
 var mc;
 var windowHelper;
-var kh;
 
 function setupModule() {
   folderDisplayHelper = collector.getModule("folder-display-helpers");
   mc = folderDisplayHelper.mc;
   windowHelper = collector.getModule("window-helpers");
-  kh = collector.getModule("keyboard-helpers");
 }
 
 function installInto(module) {
   setupModule();
 
   // Now copy helper functions
   module.open_subscribe_window_from_context_menu = open_subscribe_window_from_context_menu;
   module.enter_text_in_search_box = enter_text_in_search_box;
@@ -56,18 +54,18 @@ function open_subscribe_window_from_cont
 /**
  * Enter a string in the text box for the search value.
  *
  * @param swc A controller for a subscribe dialog
  * @param text The text to enter
  */
 function enter_text_in_search_box(swc, text) {
   let textbox = swc.eid("namefield");
-  kh.delete_all_existing(swc, textbox);
-  kh.input_value(swc, text, textbox);
+  delete_all_existing(swc, textbox);
+  input_value(swc, text, textbox);
 }
 
 /**
  * Check that the search view is currently displayed.
  *
  * @param swc A controller for the subscribe window.
  * @returns {Boolean} Result of the check.
  */