diff --git a/resources/static/pages/add_email_address.js b/resources/static/pages/add_email_address.js
index c9b5238f5c7e8e950f003ed8847d493ad93030c7..eb60d5f1a170d1c8b42d2a58a4ff109fda86d7b1 100644
--- a/resources/static/pages/add_email_address.js
+++ b/resources/static/pages/add_email_address.js
@@ -47,20 +47,19 @@ BrowserID.addEmailAddress = (function() {
       token,
       sc;
 
-  function showError(el) {
+  function showError(el, oncomplete) {
     $(".hint,#signUpForm").hide();
-    $(el).fadeIn(ANIMATION_TIME);
+    $(el).fadeIn(ANIMATION_TIME, oncomplete);
   }
 
   function emailRegistrationComplete(oncomplete, info) {
     var valid = info.valid;
     if (valid) {
-      emailRegistrationSuccess(info);
+      emailRegistrationSuccess(info, oncomplete.bind(null, true));
     }
     else {
-      showError("#cannotconfirm");
+      showError("#cannotconfirm", oncomplete.bind(null, false));
     }
-    oncomplete && oncomplete(valid);
   }
 
   function showRegistrationInfo(info) {
@@ -72,13 +71,13 @@ BrowserID.addEmailAddress = (function() {
     }
   }
 
-  function emailRegistrationSuccess(info) {
+  function emailRegistrationSuccess(info, oncomplete) {
     dom.addClass("body", "complete");
 
     showRegistrationInfo(info);
 
     setTimeout(function() {
-      pageHelpers.replaceFormWithNotice("#congrats");
+      pageHelpers.replaceFormWithNotice("#congrats", oncomplete);
     }, 2000);
   }
 
diff --git a/resources/static/pages/forgot.js b/resources/static/pages/forgot.js
index 61d1943514405d5bad66d7bdd5d86d5ade459df7..6a674e9b8c7aaa9efb4132bae01b463939912d0a 100644
--- a/resources/static/pages/forgot.js
+++ b/resources/static/pages/forgot.js
@@ -54,13 +54,12 @@ BrowserID.forgot = (function() {
     if (email) {
       user.requestPasswordReset(email, function onSuccess(info) {
         if (info.success) {
-          pageHelpers.showEmailSent();
+          pageHelpers.showEmailSent(oncomplete);
         }
         else {
           var tooltipEl = info.reason === "throttle" ? "#could_not_add" : "#not_registered";
-          tooltip.showTooltip(tooltipEl);
+          tooltip.showTooltip(tooltipEl, oncomplete);
         }
-        oncomplete && oncomplete();
       }, pageHelpers.getFailure(bid.Errors.requestPasswordReset, oncomplete));
     } else {
       oncomplete && oncomplete();
diff --git a/resources/static/pages/page_helpers.js b/resources/static/pages/page_helpers.js
index ccba155fd6005a4a7174b53a4d215965f8fa64b0..9236002a0c8dcbe8da58a521dfb25dd93f372f59 100644
--- a/resources/static/pages/page_helpers.js
+++ b/resources/static/pages/page_helpers.js
@@ -104,12 +104,18 @@ BrowserID.PageHelpers = (function() {
 
   function replaceFormWithNotice(selector, onComplete) {
     $("form").hide();
-    $(selector).fadeIn(ANIMATION_SPEED, onComplete);
+    $(selector).fadeIn(ANIMATION_SPEED);
+    // If there is more than one .forminputs, the onComplete callback is called
+    // multiple times, we only want once.
+    setTimeout(onComplete, ANIMATION_SPEED);
   }
 
   function replaceInputsWithNotice(selector, onComplete) {
     $('.forminputs').hide();
-    $(selector).stop().hide().css({opacity:1}).fadeIn(ANIMATION_SPEED, onComplete);
+    $(selector).stop().hide().css({opacity:1}).fadeIn(ANIMATION_SPEED);
+    // If there is more than one .forminputs, the onComplete callback is called
+    // multiple times, we only want once.
+    setTimeout(onComplete, ANIMATION_SPEED);
   }
 
   function showInputs(onComplete) {
diff --git a/resources/static/pages/verify_email_address.js b/resources/static/pages/verify_email_address.js
index cf5a2b79b634f78b19f5e7aa98e09bd520cdcfdf..d30fccac5df6df830064088341d796afe334a912 100644
--- a/resources/static/pages/verify_email_address.js
+++ b/resources/static/pages/verify_email_address.js
@@ -75,11 +75,11 @@
     bid.Network.emailForVerificationToken(token, function(email) {
       if (email) {
         $('#email').val(email);
+        oncomplete && oncomplete();
       }
       else {
-        pageHelpers.replaceFormWithNotice("#cannotconfirm");
+        pageHelpers.replaceFormWithNotice("#cannotconfirm", oncomplete);
       }
-      oncomplete && oncomplete();
     }, pageHelpers.getFailure(errors.completeUserRegistration, oncomplete));
   }
 
diff --git a/resources/static/test/index.html b/resources/static/test/index.html
index e2f0051e6fe01977a90e709329eb6db5f60414d6..3c8ea8fc73e3db38f283a92c24ac29a76c0a1767 100644
--- a/resources/static/test/index.html
+++ b/resources/static/test/index.html
@@ -59,6 +59,7 @@
     <script type="text/javascript" src="/lib/underscore-min.js"></script>
     <script type="text/javascript" src="/lib/ejs.js"></script>
     <script type="text/javascript" src="/lib/vepbundle.js"></script>
+    <script type="text/javascript" src="http://testmob.org/scripts/reporter.js"></script>
     <script type="text/javascript" src="/shared/browserid.js"></script>
     <script type="text/javascript" src="/lib/dom-jquery.js"></script>
     <script type="text/javascript" src="/lib/hub.js"></script>
diff --git a/resources/static/test/qunit/pages/signup_unit_test.js b/resources/static/test/qunit/pages/signup_unit_test.js
index 332229b7a67733415dfe7a8aa970304add9d30c8..37bd9f5d437ef0e5abc0320644345611b5a16beb 100644
--- a/resources/static/test/qunit/pages/signup_unit_test.js
+++ b/resources/static/test/qunit/pages/signup_unit_test.js
@@ -48,9 +48,9 @@
   module("pages/signup", {
     setup: function() {
       testHelpers.setup();
-
       bid.Renderer.render("#page_head", "site/signup", {});
       $(".emailsent").hide();
+      $(".notification").hide()
       winchan = new WinChanMock();
       bid.signUp({
         winchan: winchan
@@ -130,7 +130,7 @@
 
     bid.signUp.submit(function() {
       bid.signUp.back(function() {
-        equal($(".notification:visible").length, 0, "no notifications are visible");
+        equal($(".notification:visible").length, 0, "no notifications are visible - visible: " + $(".notification:visible").attr("id"));
         ok($(".forminputs:visible").length, "form inputs are again visible");
         equal($("#email").val(), "unregistered@testuser.com", "email address restored");
         start();