Bug 964377 - Make waiting for notification in test-attachment-reminder.js more robust. r=mkmelin, a=me
authoraceman <acelists@atlas.sk>
Mon, 09 Jun 2014 12:31:00 -0400
changeset 16321 1ac4de6dc08154e1bafc2405d90eb8c6cf1381e0
parent 16320 ec1a45397e17d922dbdc19d27ca18fd94d1b2566
child 16322 a56084a6704764480ed4c5aeec77dd4c0f8d585e
push id10197
push userryanvm@gmail.com
push dateMon, 09 Jun 2014 19:46:03 +0000
treeherdercomm-central@1ac4de6dc081 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin, me
bugs964377
Bug 964377 - Make waiting for notification in test-attachment-reminder.js more robust. r=mkmelin, a=me
mail/test/mozmill/composition/test-attachment-reminder.js
mail/test/mozmill/shared-modules/test-notificationbox-helpers.js
--- a/mail/test/mozmill/composition/test-attachment-reminder.js
+++ b/mail/test/mozmill/composition/test-attachment-reminder.js
@@ -15,17 +15,16 @@ const MODULE_REQUIRES = ["folder-display
                          "notificationbox-helpers",
                          "keyboard-helpers"];
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource:///modules/mailServices.js");
 
 const kBoxId = "attachmentNotificationBox";
 const kNotificationId = "attachmentReminder";
-const notificationSlackTime = 2000;
 
 function setupModule(module) {
   for (let lib of MODULE_REQUIRES) {
     collector.getModule(lib).installInto(module);
   }
 };
 
 function setupComposeWin(aCwc, toAddr, subj, body) {
@@ -42,16 +41,36 @@ function setupComposeWin(aCwc, toAddr, s
  *
  * @return        If the bar is shown, return the notification object.
  */
 function assert_automatic_reminder_state(aCwc, aShown) {
   return assert_notification_displayed(aCwc, kBoxId, kNotificationId, aShown);
 }
 
 /**
+ * Waits for the attachment reminder bar to change into the wished state.
+ *
+ * @param aCwc    A compose window controller.
+ * @param aShown  True for waiting for the bar to be shown, false otherwise.
+ */
+function wait_for_reminder_state(aCwc, aShown) {
+  if (aShown) {
+    // This waits up to 30 seconds for the notification to appear.
+    wait_for_notification_to_show(aCwc, kBoxId, kNotificationId);
+  } else if (check_notification_displayed(aCwc, kBoxId, kNotificationId)) {
+    // This waits up to 30 seconds for the notification to disappear.
+    wait_for_notification_to_stop(aCwc, kBoxId, kNotificationId);
+  } else {
+    // This waits 5 seconds during which the notification must not appear.
+    aCwc.sleep(5000);
+    assert_automatic_reminder_state(aCwc, false);
+  }
+}
+
+/**
  * Check whether the manual reminder is in the proper state.
  *
  * @param aCwc      A compose window controller.
  * @param aChecked  Whether the reminder should be enabled.
  */
 function assert_manual_reminder_state(aCwc, aChecked) {
   // Check the reminder is really enabled.
   let attachment_menu = aCwc.click_menus_in_sequence(aCwc.e("button-attachPopup"),
@@ -73,23 +92,22 @@ function test_attachment_reminder_appear
 
   // There should be no notification yet.
   assert_automatic_reminder_state(cwc, false);
 
   setupComposeWin(cwc, "test@example.org", "Testing automatic reminder!",
                   "Hello! ");
 
   // Give the notification time to appear. It shouldn't.
-  cwc.sleep(notificationSlackTime);
-  assert_automatic_reminder_state(cwc, false);
+  wait_for_reminder_state(cwc, false);
 
   cwc.type(cwc.eid("content-frame"), "Seen this cool attachment?");
 
   // Give the notification time to appear. It should now.
-  wait_for_notification_to_show(cwc, kBoxId, kNotificationId);
+  wait_for_reminder_state(cwc, true);
 
   // The manual reminder should be disabled yet.
   assert_manual_reminder_state(cwc, false);
 
   // Click ok to be notified on send if no attachments are attached.
   cwc.click(cwc.eid(kBoxId, {tagName: "button", label: "Remind Me Later"}));
 
   // The manual reminder should be enabled now.
@@ -115,17 +133,17 @@ function test_attachment_reminder_dismis
 
   // There should be no notification yet.
   assert_automatic_reminder_state(cwc, false);
 
   setupComposeWin(cwc, "test@example.org", "popping up, eh?",
                   "Hi there, remember the attachment!");
 
   // Give the notification time to appear.
-  wait_for_notification_to_show(cwc, kBoxId, kNotificationId);
+  wait_for_reminder_state(cwc, true);
 
   // We didn't click the "Remind Me Later" - the alert should pop up
   // on send anyway.
   plan_for_modal_dialog("commonDialog", click_oh_i_did);
   cwc.click(cwc.eid("button-send"));
   wait_for_modal_dialog("commonDialog");
 
   let notification = assert_automatic_reminder_state(cwc, true);
@@ -151,17 +169,17 @@ function test_attachment_reminder_aggres
   let cwc = open_compose_new_mail();
 
   // There should be no notification yet.
   assert_automatic_reminder_state(cwc, false);
 
   setupComposeWin(cwc, "test@example.org", "aggressive?",
                   "Check this attachment!");
 
-  wait_for_notification_to_show(cwc, kBoxId, kNotificationId);
+  wait_for_reminder_state(cwc, true);
   click_send_and_handle_send_error(cwc);
 
   close_compose_window(cwc);
 
   // Now reset the pref back to original value.
   if (Services.prefs.prefHasUserValue(kPref))
     Services.prefs.clearUserPref(kPref);
 }
@@ -175,17 +193,17 @@ test_attachment_reminder_aggressive_pref
  */
 function test_no_send_now_sends() {
   let cwc = open_compose_new_mail();
 
   setupComposeWin(cwc, "test@example.org",
                   "will the 'No, Send Now' button work?",
                   "Hello, i got your attachment!");
 
-  wait_for_notification_to_show(cwc, kBoxId, kNotificationId);
+  wait_for_reminder_state(cwc, true);
 
   // Click the send button again, this time choose "No, Send Now".
   plan_for_modal_dialog("commonDialog", click_no_send_now);
   cwc.click(cwc.eid("button-send"));
   wait_for_modal_dialog("commonDialog");
 
   // After clicking "Send Now" sending is proceeding, just handle the error.
   click_send_and_handle_send_error(cwc, true);
@@ -261,17 +279,17 @@ function test_manual_attachment_reminder
   cwc.click(cwc.eid("button-send"));
   wait_for_modal_dialog("commonDialog");
 
   // We were alerted once and the manual reminder is automatically turned off.
   assert_manual_reminder_state(cwc, false);
 
   // Enable the manual reminder and disable it again to see if it toggles right.
   click_manual_reminder(cwc, true);
-  cwc.sleep(notificationSlackTime);
+  cwc.sleep(2000);
   click_manual_reminder(cwc, false);
 
   // Now try to send again, there should be no more alert.
   click_send_and_handle_send_error(cwc);
 
   close_compose_window(cwc);
 
   // Delete the leftover draft message.
@@ -290,41 +308,38 @@ function test_manual_automatic_attachmen
   // There should be no attachment notification.
   assert_automatic_reminder_state(cwc, false);
 
   // Add some attachment keywords.
   setupComposeWin(cwc, "test@example.invalid", "Testing manual reminder!",
                   "Expect an attachment here...");
 
   // The automatic attachment notification should pop up.
-  wait_for_notification_to_show(cwc, kBoxId, kNotificationId);
+  wait_for_reminder_state(cwc, true);
 
   // Now enable the manual reminder.
   click_manual_reminder(cwc, true);
   // The attachment notification should disappear.
-  wait_for_notification_to_stop(cwc, kBoxId, kNotificationId);
+  wait_for_reminder_state(cwc, false);
 
   // Add some more text with another keyword so the automatic notification
   // could potentially show up.
   setupComposeWin(cwc, "", "", " and find it attached!");
   // Give the notification time to appear. It shouldn't.
-  cwc.sleep(notificationSlackTime);
-  assert_automatic_reminder_state(cwc, false);
+  wait_for_reminder_state(cwc, false);
 
   // Now disable the manual reminder.
   click_manual_reminder(cwc, false);
   // Give the notification time to appear. It shouldn't.
-  cwc.sleep(notificationSlackTime);
-  assert_automatic_reminder_state(cwc, false);
+  wait_for_reminder_state(cwc, false);
 
   // Add some more text without any new keyword.
   setupComposeWin(cwc, "", "", " Did I write anything?");
   // Give the notification time to appear. It should now.
-  cwc.sleep(notificationSlackTime);
-  assert_automatic_reminder_state(cwc, true);
+  wait_for_reminder_state(cwc, true);
 
   close_compose_window(cwc);
 }
 
 /**
  * Assert if there is any notification in the compose window.
  *
  * @param aCwc         Compose Window Controller
@@ -378,24 +393,23 @@ function test_attachment_reminder_in_sub
   // There should be no attachment notification.
   assert_automatic_reminder_state(cwc, false);
 
   // Add some attachment keyword in subject.
   setupComposeWin(cwc, "test@example.invalid", "Testing attachment reminder!",
                   "There is no keyword in this body...");
 
   // The automatic attachment notification should pop up.
-  wait_for_notification_to_show(cwc, kBoxId, kNotificationId);
+  wait_for_reminder_state(cwc, true);
 
   // Now clear the subject
   delete_all_existing(cwc, cwc.eid("msgSubject"));
 
   // Give the notification time to disappear.
-  cwc.sleep(notificationSlackTime);
-  assert_automatic_reminder_state(cwc, false);
+  wait_for_reminder_state(cwc, false);
 
   close_compose_window(cwc);
 }
 
 /**
  * Bug 944643
  * Test the attachment reminder coming up when keyword is in subject line
  * and also body.
@@ -408,24 +422,23 @@ function test_attachment_reminder_in_sub
   // There should be no attachment notification.
   assert_automatic_reminder_state(cwc, false);
 
   // Add some attachment keyword in subject.
   setupComposeWin(cwc, "test@example.invalid", "Testing attachment reminder!",
                   "There should be an attached file in this body...");
 
   // The automatic attachment notification should pop up.
-  wait_for_notification_to_show(cwc, kBoxId, kNotificationId);
+  wait_for_reminder_state(cwc, true);
 
   // Now clear only the subject
   delete_all_existing(cwc, cwc.eid("msgSubject"));
 
   // Give the notification some time. It should not disappear.
-  cwc.sleep(notificationSlackTime);
-  assert_automatic_reminder_state(cwc, true);
+  wait_for_reminder_state(cwc, true);
 
   close_compose_window(cwc);
 }
 
 /**
  * Click the send button and handle the send error dialog popping up.
  * It will return us back to the compose window.
  *
--- a/mail/test/mozmill/shared-modules/test-notificationbox-helpers.js
+++ b/mail/test/mozmill/shared-modules/test-notificationbox-helpers.js
@@ -2,60 +2,77 @@
  * 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/. */
 
 const MODULE_NAME = "notificationbox-helpers";
 
 const RELATIVE_ROOT = "../shared-modules";
 const MODULE_REQUIRES = [];
 
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
 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;
 }
 
 /**
  * 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 notificaiton box
- * @param aValue the value of the notification to look for
- * @param aDisplayed true if the notification should be displayed, false
- *                   otherwise
- * @returns the notification if we're asserting that the notification is
- *          displayed, and it actually shows up. Returns null otherwise
+ * @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
+ * @param aNotification  an optional out parameter: object that will pass the
+ *                       notification element out of this function in its
+ *                       'notification' property
+ *
+ * @return  True/false depending on the state of the notification.
  */
-function assert_notification_displayed(aController, aBoxId, aValue, aDisplayed) {
+function check_notification_displayed(aController, aBoxId, aValue, aNotification) {
   let nb = aController.window.document.getElementById(aBoxId);
   if (!nb)
      throw new Error("Couldn't find a notification box for id=" + aBoxId);
 
-  let hasNotification = false;
   let notification = nb.getNotificationWithValue(aValue);
-  let hasNotification = (notification != null)
+  if (aNotification)
+    aNotification.notification = notification;
+  return (notification != null);
+}
 
+/**
+ * A helper function ensuring whether or not a notification with
+ * a particular value is being displayed. Throws if the state is
+ * not the expected one.
+ *
+ * @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
+ * @param aDisplayed true if the notification should be displayed, false
+ *                   otherwise
+ * @return  the notification if we're asserting that the notification is
+ *          displayed, and it actually shows up. Throws otherwise.
+ */
+function assert_notification_displayed(aController, aBoxId, aValue, aDisplayed) {
+  let notification = {};
+  let hasNotification = check_notification_displayed(aController, aBoxId, aValue, notification);
   if (hasNotification != aDisplayed)
     throw new Error("Expected the notification with value " + aValue +
                     " to be " + (aDisplayed ? "shown" : "not shown"));
 
-  return notification;
+  return notification.notification;
 }
 
 /**
  * A helper function for closing a notification if one is currently displayed
  * in the window.
  *
  * @param aController the controller for the window with the notification
- * @param aBoxId the id of the notificaiton box
+ * @param aBoxId the id of the notification box
  * @param aValue the value of the notification to close
  */
 function close_notification(aController, aBoxId, aValue) {
   let nb = aController.window.document.getElementById(aBoxId);
   if (!nb)
     throw new Error("Couldn't find a notification box for id=" + aBoxId);
 
   let notification = nb.getNotificationWithValue(aValue);
@@ -63,17 +80,17 @@ function close_notification(aController,
     notification.close();
 }
 
 /**
  * A helper function that waits for a notification with value aValue
  * to stop displaying in the window.
  *
  * @param aController the controller for the window with the notification
- * @param aBoxId the id of the notificaiton box
+ * @param aBoxId the id of the notification box
  * @param aValue the value of the notification to wait to stop
  */
 function wait_for_notification_to_stop(aController, aBoxId, aValue) {
   let nb = aController.window.document.getElementById(aBoxId);
   if (!nb)
     throw new Error("Couldn't find a notification box for id=" + aBoxId);
   aController.waitFor(function() !nb.getNotificationWithValue(aValue),
                       "Timed out waiting for notification with value " +
@@ -81,17 +98,17 @@ function wait_for_notification_to_stop(a
 }
 
 /**
  * A helper function that waits for a notification with value aValue
  * to show in the window.
  *
  * @param aController the controller for the compose window that we want
  *                    the notification to appear in
- * @param aBoxId the id of the notificaiton box
+ * @param aBoxId the id of the notification box
  * @param aValue the value of the notification to wait for
  */
 function wait_for_notification_to_show(aController, aBoxId, aValue) {
   let nb = aController.window.document.getElementById(aBoxId);
   if (!nb)
     throw new Error("Couldn't find a notification box for id=" + aBoxId);
   aController.waitFor(function() nb.getNotificationWithValue(aValue) != null,
                       "Timed out waiting for notification with value " +