diff --git a/resources/static/test/cases/dialog/js/misc/state.js b/resources/static/test/cases/dialog/js/misc/state.js
index eabca0b5089db9cb4676578c79593e42fb702ec4..eaec7deb5cc6a0dd5583b7448d34a5969fe930f8 100644
--- a/resources/static/test/cases/dialog/js/misc/state.js
+++ b/resources/static/test/cases/dialog/js/misc/state.js
@@ -179,7 +179,7 @@
     testVerifyStagedAddress("user_staged", "doConfirmUser");
   });
 
-  test("user_confirmed - redirect to email_chosen", function() {
+  asyncTest("user_confirmed - redirect to email_chosen", function() {
     mediator.subscribe("email_chosen", function(msg, info) {
       equal(info.email, TEST_EMAIL, "correct email passed");
       start();
@@ -188,6 +188,7 @@
     // simulate the flow of a user being staged through to confirmation. Since
     // we are not actually doing the middle bits and saving off a cert for the
     // email address, we get an invalid email exception thrown.
+    storage.addSecondaryEmail(TEST_EMAIL);
     mediator.publish("user_staged", { email: TEST_EMAIL });
     try {
       mediator.publish("user_confirmed");
@@ -334,23 +335,24 @@
     });
   });
 
-  test("email_valid_and_ready, do not need to ask user whether it's their computer - redirect to email_ready", function() {
+  asyncTest("email_valid_and_ready, do not need to ask user whether it's their computer - redirect to generate_assertion", function() {
     setContextInfo("password");
     // First, set up the context info for the email.
 
     storage.addEmail(TEST_EMAIL, {});
-    mediator.subscribe("email_ready", function() {
-      ok(true, "redirect to email_ready");
+    mediator.subscribe("generate_assertion", function() {
+      ok(true, "redirect to generate_assertion");
       start();
     });
     mediator.publish("email_valid_and_ready", { email: TEST_EMAIL });
   });
 
-  test("email_confirmed", function() {
+  asyncTest("email_confirmed", function() {
     mediator.subscribe("email_chosen", function(msg, info) {
       equal(info.email, TEST_EMAIL, "correct email passed");
       start();
     });
+    storage.addSecondaryEmail(TEST_EMAIL);
     mediator.publish("email_staged", { email: TEST_EMAIL });
     // simulate the flow of a user being staged through to confirmation. Since
     // we are not actually doing the middle bits and saving off a cert for the
@@ -551,7 +553,7 @@
     testActionStarted("doStageReverifyEmail", { email: TEST_EMAIL });
   });
 
-  test("reverify_email_staged - call doConfirmReverifyEmail", function() {
+  asyncTest("reverify_email_staged - call doConfirmReverifyEmail", function() {
     testVerifyStagedAddress("reverify_email_staged", "doConfirmReverifyEmail");
   });
 
diff --git a/resources/static/test/qunit/qunit.js b/resources/static/test/qunit/qunit.js
index e00cca902b44fd2c8854e5f680ac6b78f2080a1d..041620126e878f33ec370e2d25e6af7a59cc1c81 100644
--- a/resources/static/test/qunit/qunit.js
+++ b/resources/static/test/qunit/qunit.js
@@ -396,6 +396,16 @@ var QUnit = {
 		if (config.semaphore < 0) {
 			// ignore if start is called more often then stop
 			config.semaphore = 0;
+
+
+      // Keep track of the number of unmatched starts that happen, it should
+      // equal the number of stops called.  The first time QUnit is run, it
+      // will call start without first calling stop, so let that one through.
+      config.unmatched = config.unmatched || 0;
+      if ( config.unmatched ) {
+        throw new Error("Unmatched start: " + config.unmatched);
+      }
+      config.unmatched++;
 		}
 		// A slight delay, to avoid any current callbacks
 		if ( defined.setTimeout ) {