diff --git a/lib/browserid/views.js b/lib/browserid/views.js
index fb61705937f09cd74d67686e0d8de7fd151139dd..0ca111100a1211e636c1e17cda6a818486223e0b 100644
--- a/lib/browserid/views.js
+++ b/lib/browserid/views.js
@@ -10,7 +10,8 @@ fs = require('fs'),
 connect = require('connect'),
 config = require('../configuration.js'),
 und = require('underscore'),
-util = require('util');
+util = require('util'),
+httputils = require('../httputils.js');
 
 // all templated content, redirects, and renames are handled here.
 // anything that is not an api, and not static
@@ -154,18 +155,19 @@ exports.setup = function(app) {
     renderCachableView(req, res, 'add_email_address.ejs', {title: 'Verify Email Address', fullpage: false});
   });
 
-  /**
-   *
-   * XXX benadida or lloyd, I tried to use straight up regexp to do this, but.
-   * is there a better way to do this?
-   */
-  function QUnit(req, res) {
-    res.render('test.ejs', {title: 'BrowserID QUnit Test', layout: false});
+  // serve up testing templates.  but NOT in staging or production.  see GH-1044
+  if ([ 'https://browserid.org', 'https://diresworb.org' ].indexOf(config.get('public_url')) === -1) {
+    // serve test.ejs to /test or /test/ or /test/index.html
+    app.get(/^\/test\/(?:index.html)?$/, function (req, res) {
+      res.render('test.ejs', {title: 'BrowserID QUnit Test', layout: false});
+    });
+  } else {
+    // this is stage or production, explicitly disable all resources under /test
+    app.get(/^\/test/, function(req, res) {
+      httputils.notFound("Cannot " + req.method + " " + req.url);
+    });
   }
 
-  app.get("/test", QUnit);
-  app.get("/test/index.html", QUnit);
-
   // REDIRECTS
   REDIRECTS = {
     "/manage": "/",
diff --git a/resources/static/css/style.css b/resources/static/css/style.css
index 0dfb71a30495e00c7a74da99a02c8c5b1a1df328..2b75378bdbc0a133fc700aa3f456892252a6f32d 100644
--- a/resources/static/css/style.css
+++ b/resources/static/css/style.css
@@ -808,3 +808,18 @@ footer {
   bottom: 0;
 }
 
+#newsbanner {
+  background-color: #faca33;
+  line-height: 32px;
+  border-radius: 4px;
+  margin-bottom: 20px;
+  text-align: center;
+  color: #626160;
+  text-shadow: 1px 1px 0 rgba(255,255,255,0.5);
+  height: 32px;
+  -webkit-transition: all 500ms;
+  -moz-transition: all 500ms;
+  -ms-transition: all 500ms;
+  -o-transition: all 500ms;
+  transition: all 500ms;
+}
diff --git a/resources/static/dialog/controllers/pick_email.js b/resources/static/dialog/controllers/pick_email.js
index e68d404a3a7ff1a6941c6c1a1e5ef978c5bf364c..4cdd0a1d376b41637dcb0341e911ab9166774b39 100644
--- a/resources/static/dialog/controllers/pick_email.js
+++ b/resources/static/dialog/controllers/pick_email.js
@@ -64,10 +64,22 @@ BrowserID.Modules.PickEmail = (function() {
     return identities;
   }
 
-  function selectEmail(event) {
-    var target = dom.getAttr(event.currentTarget, "for");
-    if(target) {
-      dom.setAttr("#" + target, "checked", "checked");
+  function proxyEventToInput(event) {
+    // iOS will not select a radio/checkbox button if the user clicks on the
+    // corresponding label.  Because of this, if the user clicks on the label,
+    // an even is manually fired on the the radio button.  This only applies
+    // if the user clicks on the actual label, not on any input elements
+    // contained within the label. This restriction is necessary or else we
+    // would be in a never ending loop that would continually toggle the state
+    // of any check boxes.
+    if(dom.is(event.target, "label")) {
+      // Must prevent standard acting browsers from taking care of the click or
+      // else it acts like two consecutive clicks.  For radio buttons this will
+      // just toggle state.
+      event.preventDefault();
+
+      var target = dom.getAttr(event.target, "for");
+      dom.fireEvent("#" + target, event.type);
     }
   }
 
@@ -100,7 +112,7 @@ BrowserID.Modules.PickEmail = (function() {
       // The click function does not pass the event to the function.  The event
       // is needed for the label handler so that the correct radio button is
       // selected.
-      self.bind("#selectEmail label", "click", selectEmail);
+      self.bind("#selectEmail label", "click", proxyEventToInput);
 
       sc.start.call(self, options);
 
diff --git a/resources/static/dialog/resources/state.js b/resources/static/dialog/resources/state.js
index 9af733f522347cc61b74b628f33538c0a57b2544..846eaddb7e0b4d48302872ca664419e9599bf30b 100644
--- a/resources/static/dialog/resources/state.js
+++ b/resources/static/dialog/resources/state.js
@@ -162,6 +162,8 @@ BrowserID.State = (function() {
     });
 
     subscribe("email_chosen", function(msg, info) {
+      info = info || {};
+
       var email = info.email,
           idInfo = storage.getEmail(email);
 
@@ -214,7 +216,7 @@ BrowserID.State = (function() {
     });
 
     subscribe("authenticated", function(msg, info) {
-      publish("pick_email");
+      publish("email_chosen", info);
     });
 
     subscribe("forgot_password", function(msg, info) {
diff --git a/resources/static/dialog/views/authenticate.ejs b/resources/static/dialog/views/authenticate.ejs
index 7e08dedb9834d0eb6ae564abd7870b173404efe7..38292d152c943183a58aa74908d30a9b37853eea 100644
--- a/resources/static/dialog/views/authenticate.ejs
+++ b/resources/static/dialog/views/authenticate.ejs
@@ -32,7 +32,7 @@
 
           <li id="create_text_section" class="newuser">
               <p><strong><%= gettext('Welcome to BrowserID!') %></strong></p>
-              <p><%= gettext('This email looks new, so let&#39;s get you set up.') %></p>
+              <p><%= gettext("This email looks new, so let's get you set up.") %></p>
           </li>
 
           <li class="returning">
@@ -58,6 +58,6 @@
           <button class="start" tabindex="3"><%= gettext('next') %></button>
           <button class="newuser" tabindex="3"><%= gettext('verify email') %></button>
 
-          <button class="returning" tabindex="3"><%= gettext('select email') %></button>
+          <button class="returning" tabindex="3"><%= gettext('sign in') %></button>
       </div>
   </div>
diff --git a/resources/static/lib/dom-jquery.js b/resources/static/lib/dom-jquery.js
index 889d165bf42ce1080d6326e6559431ba148a0d18..860c033277fa2579044a22216426b7ac88bbd8eb 100644
--- a/resources/static/lib/dom-jquery.js
+++ b/resources/static/lib/dom-jquery.js
@@ -296,6 +296,20 @@ BrowserID.DOM = ( function() {
          */
         focus: function( elementToFocus ) {
           jQuery( elementToFocus ).focus();
+        },
+
+        /**
+         * Check the current matched set of elements against
+         * a selector or element and return true if at least
+         * one of these elements matches the given arguments.
+         * @method is
+         * @param {selector || element} elementToCheck
+         * @param {string} type
+         * @returns {boolean} true if elementToCheck matches the specified
+         * type, false otw.
+         */
+        is: function( elementToCheck, type ) {
+          return jQuery( elementToCheck ).is( type );
         }
 
 
diff --git a/resources/static/test/cases/controllers/authenticate.js.bak b/resources/static/test/cases/controllers/authenticate.js.bak
deleted file mode 100644
index a77ba9c3d829b753c1bcce1feff8aa6e5801f5e5..0000000000000000000000000000000000000000
--- a/resources/static/test/cases/controllers/authenticate.js.bak
+++ /dev/null
@@ -1,257 +0,0 @@
-/*jshint browsers:true, forin: true, laxbreak: true */
-/*global test: true, start: true, stop: true, module: true, ok: true, equal: true, BrowserID:true */
-/* 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/. */
-(function() {
-  "use strict";
-
-  var controller,
-      el = $("body"),
-      bid = BrowserID,
-      storage = bid.Storage,
-      network = bid.Network,
-      xhr = bid.Mocks.xhr,
-      emailRegistered = false,
-      userCreated = true,
-      mediator = bid.Mediator,
-      registrations = [],
-      testHelpers = bid.TestHelpers,
-      register = testHelpers.register,
-      provisioning = bid.Mocks.Provisioning;
-
-  function reset() {
-    emailRegistered = false;
-    userCreated = true;
-  }
-
-  function createController(options) {
-    options = options || {};
-    controller = bid.Modules.Authenticate.create();
-    controller.start(options);
-  }
-
-  module("controllers/authenticate", {
-    setup: function() {
-      reset();
-      testHelpers.setup();
-    },
-
-    teardown: function() {
-      if (controller) {
-        try {
-          controller.destroy();
-        } catch(e) {
-          // may already be destroyed from close inside of the controller.
-        }
-      }
-      reset();
-      testHelpers.teardown();
-    }
-  });
-
-  asyncTest("providing primary email address - only show email address", function() {
-    $("#email").val("");
-    createController({
-      email: "registered@testuser.com",
-      type: "primary",
-      ready: function() {
-        equal($("#email").val(), "registered@testuser.com", "email prefilled");
-        equal(false, "need a test");
-        start();
-      }
-    });
-  });
-
-  asyncTest("providing known secondary - show password", function() {
-    $("#email").val("");
-    createController({
-      email: "registered@testuser.com",
-      type: "secondary",
-      known: true,
-      ready: function() {
-        equal($("#email").val(), "registered@testuser.com", "email prefilled");
-        equal(false, "need a test");
-        start();
-      }
-    });
-  });
-
-  asyncTest("providing unknown secondary address - show email address, nothing more", function() {
-    $("#email").val("");
-    createController({
-      email: "unregistered@testuser.com",
-      type: "secondary",
-      known: false,
-      ready: function() {
-        equal($("#email").val(), "unregistered@testuser.com", "email prefilled");
-        equal(false, "need a test");
-        start();
-      }
-    });
-  });
-
-  function testUserUnregistered() {
-    register("create_user", function() {
-      ok(true, "email was valid, user not registered");
-      start();
-    });
-
-    controller.checkEmail();
-  }
-
-  function testUserUnregistered() {
-    var createUserCalled = false;
-    register("create_user", function() {
-      createUserCalled = true;
-    });
-
-    controller.checkEmail(function() {
-      equal(createUserCalled, true, "create_user was triggered");
-      start();
-    });
-  }
-
-  asyncTest("checkEmail with unknown secondary email, expect 'create_user' message", function() {
-    createController();
-    $("#email").val("unregistered@testuser.com");
-    xhr.useResult("unknown_secondary");
-
-    testUserUnregistered();
-  });
-
-  asyncTest("checkEmail with email with leading/trailing whitespace, user not registered, expect 'create_user' message", function() {
-    createController();
-    $("#email").val("    unregistered@testuser.com   ");
-    xhr.useResult("unknown_secondary");
-
-    testUserUnregistered();
-  });
-
-  asyncTest("checkEmail with normal email, user registered, expect 'enter_password' message", function() {
-    createController();
-    $("#email").val("registered@testuser.com");
-    xhr.useResult("known_secondary");
-
-    register("enter_password", function() {
-      ok(true, "email was valid, user registered");
-      start();
-    });
-
-    controller.checkEmail();
-  });
-
-  asyncTest("checkEmail with email that has IdP support, expect 'primary_user' message", function() {
-    createController();
-    $("#email").val("unregistered@testuser.com");
-    xhr.useResult("primary");
-
-    register("primary_user", function(msg, info) {
-      equal(info.email, "unregistered@testuser.com", "email correctly passed");
-      equal(info.auth, "https://auth_url", "IdP authentication URL passed");
-      equal(info.prov, "https://prov_url", "IdP provisioning URL passed");
-      start();
-    });
-
-    controller.checkEmail();
-  });
-
-  function testAuthenticated() {
-    register("authenticated", function() {
-      ok(true, "user authenticated as expected");
-      start();
-    });
-    controller.authenticate();
-  }
-
-  asyncTest("normal authentication is kosher", function() {
-    createController();
-    $("#email").val("registered@testuser.com");
-    $("#password").val("password");
-
-    testAuthenticated();
-  });
-
-  asyncTest("leading/trailing whitespace on the username is stripped for authentication", function() {
-    createController();
-    $("#email").val("    registered@testuser.com    ");
-    $("#password").val("password");
-
-    testAuthenticated();
-  });
-
-  asyncTest("forgotPassword triggers forgot_password message", function() {
-    createController();
-    $("#email").val("registered@testuser.com");
-
-    register("forgot_password", function(msg, info) {
-      equal(info.email, "registered@testuser.com", "forgot_password with correct email triggered");
-      start();
-    });
-
-    controller.forgotPassword();
-  });
-
-  asyncTest("createUser with valid email", function() {
-    createController();
-    $("#email").val("unregistered@testuser.com");
-    xhr.useResult("unknown_secondary");
-
-    register("user_staged", function(msg, info) {
-      equal(info.email, "unregistered@testuser.com", "user_staged with correct email triggered");
-      start();
-    });
-
-    controller.createUser();
-  });
-
-  asyncTest("createUser with invalid email", function() {
-    createController();
-    $("#email").val("unregistered");
-
-    var handlerCalled = false;
-    register("user_staged", function(msg, info) {
-      handlerCalled = true;
-    });
-
-    controller.createUser(function() {
-      equal(handlerCalled, false, "bad jiji, user_staged should not have been called with invalid email");
-      start();
-    });
-  });
-
-  asyncTest("createUser with valid email but throttling", function() {
-    createController();
-    $("#email").val("unregistered@testuser.com");
-
-    var handlerCalled = false;
-    register("user_staged", function(msg, info) {
-      handlerCalled = true;
-    });
-
-    xhr.useResult("throttle");
-    controller.createUser(function() {
-      equal(handlerCalled, false, "bad jiji, user_staged should not have been called with throttling");
-      equal(bid.Tooltip.shown, true, "tooltip is shown");
-      start();
-    });
-  });
-
-  asyncTest("createUser with valid email, XHR error", function() {
-    createController();
-    $("#email").val("unregistered@testuser.com");
-
-    var handlerCalled = false;
-    register("user_staged", function(msg, info) {
-      handlerCalled = true;
-    });
-
-    xhr.useResult("ajaxError");
-    controller.createUser(function() {
-      equal(handlerCalled, false, "bad jiji, user_staged should not have been called with XHR error");
-      start();
-    });
-  });
-
-}());
-
diff --git a/resources/static/test/cases/controllers/pick_email.js b/resources/static/test/cases/controllers/pick_email.js
index 749047ca42b1ceb76c71422acc2d38d58f529235..8a1309a3762046461dfcca4eae65132bcd713947 100644
--- a/resources/static/test/cases/controllers/pick_email.js
+++ b/resources/static/test/cases/controllers/pick_email.js
@@ -64,7 +64,7 @@
     var radioButton = $("input[type=radio]").eq(0);
     ok(radioButton.is(":checked"), "the email address we specified is checked");
 
-    var label = radioButton.parent();
+    var label = $("label[for=" + radioButton.attr("id") + "]");
     ok(label.hasClass("preselected"), "the label has the preselected class");
   });
 
@@ -155,16 +155,46 @@
     controller.addEmail();
   });
 
-  test("click on an email label - select corresponding radio button", function() {
+  test("click on an email label and radio button - select corresponding radio button", function() {
     storage.addEmail("testuser@testuser.com", {});
     storage.addEmail("testuser2@testuser.com", {});
 
     createController(false);
 
     equal($("#testuser_testuser_com").is(":checked"), false, "radio button is not selected before click.");
-    $("label[for=testuser_testuser_com]").trigger("click");
 
+    // selects testuser@testuser.com
+    $("label[for=testuser_testuser_com]").trigger("click");
     equal($("#testuser_testuser_com").is(":checked"), true, "radio button is correctly selected");
+
+    // selects testuser2@testuser.com
+    $("#testuser2_testuser_com").trigger("click");
+    equal($("#testuser2_testuser_com").is(":checked"), true, "radio button is correctly selected");
+  });
+
+  test("click on the 'Always sign in...' label and checkbox - correct toggling", function() {
+    createController(true);
+
+    var label = $("label[for=remember]"),
+        checkbox = $("#remember").removeAttr("checked");
+
+    equal(checkbox.is(":checked"), false, "checkbox is not yet checked");
+
+    // toggle checkbox to on clicking on label
+    label.trigger("click");
+    equal(checkbox.is(":checked"), true, "checkbox is correctly checked");
+
+    // toggle checkbox to off clicking on label
+    label.trigger("click");
+    equal(checkbox.is(":checked"), false, "checkbox is correctly unchecked");
+
+    // toggle checkbox to on clicking on checkbox
+    checkbox.trigger("click");
+    equal(checkbox.is(":checked"), true, "checkbox is correctly checked");
+
+    // toggle checkbox to off clicking on checkbox
+    checkbox.trigger("click");
+    equal(checkbox.is(":checked"), false, "checkbox is correctly unchecked");
   });
 
 }());
diff --git a/resources/static/test/cases/pages/add_email_address_test.js b/resources/static/test/cases/pages/add_email_address_test.js
index 1d3844b7cb82edec1435f4a9a0e6a30086b2257e..79fe35d5e22cb38c4888550cd30c91643f728d3d 100644
--- a/resources/static/test/cases/pages/add_email_address_test.js
+++ b/resources/static/test/cases/pages/add_email_address_test.js
@@ -133,10 +133,7 @@
   });
 
   asyncTest("password: too long of a password", function() {
-    var tooLong = "";
-    for(var i = 0; i < 81; i++) {
-      tooLong += (i % 10);
-    }
+    var tooLong = testHelpers.generateString(81);
     $("#password").val(tooLong);
     $("#vpassword").val(tooLong);
 
diff --git a/resources/static/test/cases/pages/manage_account.js b/resources/static/test/cases/pages/manage_account.js
index f92596004f3fead7c1b5ad9be2d269a3dc9c97b0..5e1ddb2cca1febf5e0cf97fb6230366a44b176ab 100644
--- a/resources/static/test/cases/pages/manage_account.js
+++ b/resources/static/test/cases/pages/manage_account.js
@@ -201,14 +201,10 @@
   asyncTest("changePassword with too long of a password - tooltip", function() {
     bid.manageAccount(mocks, function() {
       $("#old_password").val("oldpassword");
-      var tooLong = "";
-      for(var i = 0; i < 81; i++) {
-        tooLong += (i % 10);
-      }
-      $("#new_password").val(tooLong);
+      $("#new_password").val(testHelpers.generateString(81));
 
       bid.manageAccount.changePassword(function(status) {
-        equal(status, false, "on too short of a password, status is false");
+        equal(status, false, "on too long of a password, status is false");
         testHelpers.testTooltipVisible();
         start();
       });
diff --git a/resources/static/test/cases/pages/verify_email_address_test.js b/resources/static/test/cases/pages/verify_email_address_test.js
index a4c3ef06d7407dd377bcb79b1310da0c59424357..c11ae2574bd2b46e071d12037a981eed2ca1907c 100644
--- a/resources/static/test/cases/pages/verify_email_address_test.js
+++ b/resources/static/test/cases/pages/verify_email_address_test.js
@@ -11,6 +11,7 @@
       storage = bid.Storage,
       xhr = bid.Mocks.xhr,
       testHelpers = bid.TestHelpers,
+      testTooltipVisible = testHelpers.testTooltipVisible,
       validToken = true;
 
   module("pages/verify_email_address", {
@@ -82,6 +83,35 @@
 
       bid.verifyEmailAddress.submit(function() {
         equal($("#congrats").is(":visible"), false, "congrats is not visible, missing password");
+        testTooltipVisible();
+        start();
+      });
+    });
+  });
+
+  asyncTest("submit with good token, too short of a password", function() {
+    bid.verifyEmailAddress("token", function() {
+      var pass = testHelpers.generateString(6);
+      $("#password").val(pass);
+      $("#vpassword").val(pass);
+
+      bid.verifyEmailAddress.submit(function() {
+        equal($("#congrats").is(":visible"), false, "congrats is not visible, too short of a password");
+        testTooltipVisible();
+        start();
+      });
+    });
+  });
+
+  asyncTest("submit with good token, too long of a password", function() {
+    bid.verifyEmailAddress("token", function() {
+      var pass = testHelpers.generateString(81);
+      $("#password").val(pass);
+      $("#vpassword").val(pass);
+
+      bid.verifyEmailAddress.submit(function() {
+        equal($("#congrats").is(":visible"), false, "congrats is not visible, too long of a password");
+        testTooltipVisible();
         start();
       });
     });
@@ -96,6 +126,7 @@
 
     bid.verifyEmailAddress.submit(function() {
       equal($("#congrats").is(":visible"), false, "congrats is not visible, missing verification password");
+      testTooltipVisible();
       start();
     });
 
@@ -109,6 +140,7 @@
 
     bid.verifyEmailAddress.submit(function() {
       equal($("#congrats").is(":visible"), false, "congrats is not visible, different passwords");
+      testTooltipVisible();
       start();
     });
 
diff --git a/resources/static/test/cases/resources/state.js b/resources/static/test/cases/resources/state.js
index 53c9726695c97d05ee8c092d7e065f3ee2826020..9bdb1d44c3e94365d594914c3ce2a5b2b24bdb5f 100644
--- a/resources/static/test/cases/resources/state.js
+++ b/resources/static/test/cases/resources/state.js
@@ -170,10 +170,11 @@
     ok(actions.called.doEmailChosen, "doEmailChosen called");
   });
 
-  test("authenticated", function() {
-    mediator.publish("authenticated");
+  test("authenticated - call doEmailChosen", function() {
+    storage.addEmail("testuser@testuser.com", {});
+    mediator.publish("authenticated", { email: "testuser@testuser.com" });
 
-    ok(actions.called.doPickEmail, "doPickEmail has been called");
+    ok(actions.called.doEmailChosen, "doEmailChosen has been called");
   });
 
   test("forgot_password", function() {
diff --git a/resources/static/test/testHelpers/helpers.js b/resources/static/test/testHelpers/helpers.js
index 35b33af5901a2a59f1d6a87390fa788444e227ea..493ea1db0756779b69735a7f18c104b51c1d3e26 100644
--- a/resources/static/test/testHelpers/helpers.js
+++ b/resources/static/test/testHelpers/helpers.js
@@ -180,6 +180,17 @@ BrowserID.TestHelpers = (function() {
       }
 
       cb && cb.apply(null, args);
+    },
+
+    /**
+     * Generate a long string
+     */
+    generateString: function(length) {
+      var str = "";
+      for(var i = 0; i < length; i++) {
+        str += (i % 10);
+      }
+      return str;
     }
   };
 
diff --git a/resources/views/add_email_address.ejs b/resources/views/add_email_address.ejs
index 4b704d65ff66a3a4ad4846e6279f2a42fa389d71..979cea68aa1953636faecadd5c2370d81a366722 100644
--- a/resources/views/add_email_address.ejs
+++ b/resources/views/add_email_address.ejs
@@ -10,7 +10,7 @@
         </ul>
 
         <form id="signUpForm" class="cf">
-            <p class="hint siteinfo"><%= gettext('Finish signing into: ') %><strong><span class="website"></span></strong></p>
+            <p class="hint siteinfo"><%= gettext('Finish signing into:') %> <strong><span class="website"></span></strong></p>
 
             <h1 class="serif"><%= gettext('Email Verification') %></h1>
 
diff --git a/resources/views/index.ejs b/resources/views/index.ejs
index b07203f655059f705ee9ea99c8da847928294d35..57f1c8d7b96254292d735fb74bf6bab32639dd4a 100644
--- a/resources/views/index.ejs
+++ b/resources/views/index.ejs
@@ -52,6 +52,10 @@
   </div>
 
   <div id="vAlign" class="display_nonauth">
+      <div id="newsbanner">
+        BrowserID is graduating: we're launching <b>Mozilla Persona</b>. Find out more on <a href="http://identity.mozilla.com/">the identity blog</a>.
+      </div>
+
       <div id="signUp">
           <div id="card"><img src="/i/slit.png"></div>
           <div id="hint"></div>
diff --git a/resources/views/verify_email_address.ejs b/resources/views/verify_email_address.ejs
index 3d776747f9385c9ce317af45c304a3e2c0dc9ea0..e86a1f5b6a41afa004449cae41925c9636ca6104 100644
--- a/resources/views/verify_email_address.ejs
+++ b/resources/views/verify_email_address.ejs
@@ -6,12 +6,12 @@
     <div id="signUpFormWrap">
         <ul class="notifications">
             <li class="notification error" id="cannotconfirm"><%= gettext('There was a problem with your signup link. Has this address already been registered?') %></li>
-            <li class="notification error" id="cannotcommunicate"><%= gettext('Error comunicating with server.') %></li>
+            <li class="notification error" id="cannotcommunicate"><%= gettext('Error communicating with server.') %></li>
             <li class="notification error" id="cannotcomplete"><%= gettext('Error encountered trying to complete registration.') %></li>
         </ul>
 
         <form id="signUpForm" class="cf">
-            <p class="hint siteinfo"><%= gettext('Finish signing into: ') %><strong><span class="website"></span></strong></p>
+            <p class="hint siteinfo"><%= gettext('Finish signing into:') %> <strong><span class="website"></span></strong></p>
             <h1 class="serif"><%= gettext('Last step!') %></h1>
 
             <ul class="inputs">
diff --git a/scripts/browserid.spec b/scripts/browserid.spec
index 87bfbeb9e0f42d5f8414b4a18bea9b253ec0e04a..6ed39bbfd82a3d7c4c310e7b9d8de75e05742771 100644
--- a/scripts/browserid.spec
+++ b/scripts/browserid.spec
@@ -12,7 +12,7 @@ Source0:       %{name}.tar.gz
 BuildRoot:     %{_tmppath}/%{name}-%{version}-%{release}-root
 AutoReqProv:   no
 Requires:      openssl nodejs
-BuildRequires: gcc-c++ git jre make npm openssl-devel expat-devel perl perl-JSON perl-Locale-PO
+BuildRequires: gcc-c++ git jre make npm openssl-devel expat-devel
 
 %description
 browserid server & web home for browserid.org
@@ -37,6 +37,8 @@ mkdir -p %{buildroot}%{_rootdir}
 for f in bin lib locale node_modules resources scripts *.json; do
     cp -rp $f %{buildroot}%{_rootdir}/
 done
+mkdir -p %{buildroot}%{_rootdir}/config
+cp -p config/l10n-all.json %{buildroot}%{_rootdir}/config
 
 %clean
 rm -rf %{buildroot}
diff --git a/tests/page-requests-test.js b/tests/page-requests-test.js
index b4574b1125853925665b0ea6e788447aa3d895ab..0ee2537c058c543df04c5aabcc707c40fbda5a23 100755
--- a/tests/page-requests-test.js
+++ b/tests/page-requests-test.js
@@ -76,7 +76,7 @@ suite.addBatch({
   'GET /primaries/':             respondsWith(302),
   'GET /developers':             respondsWith(302),
   'GET /developers/':            respondsWith(302),
-  'GET /test':                   respondsWith(200),
+  'GET /test':                   respondsWith(301),
   'GET /test/':                  respondsWith(200),
   'GET /include.js':             respondsWith(200),
   'GET /include.orig.js':        respondsWith(200)