From 35d0e108c002c905bcc3be6737f94c18cc373fd8 Mon Sep 17 00:00:00 2001 From: Shane Tomlinson <stomlinson@mozilla.com> Date: Tue, 13 Dec 2011 15:27:24 +0000 Subject: [PATCH] Adding a wait screen while the assertion is being generated. Important on slow devices/browsers. * Using CSS transitions to bring the screen in after 0.5 seconds. * Cleaning up the screen code, its tests, and anything that attaches to Screens. * Adding a generic errorDisplayed() function to TestHelpers. close #706 --- resources/static/dialog/controllers/page.js | 12 ++-- resources/static/dialog/css/popup.css | 59 +++++++++++++++++-- resources/static/dialog/resources/helpers.js | 3 + resources/static/pages/page_helpers.js | 2 +- resources/static/shared/screens.js | 44 ++++++-------- resources/static/test/index.html | 1 + .../checkregistration_unit_test.js | 9 +-- .../controllers/required_email_unit_test.js | 9 +-- .../qunit/pages/manage_account_unit_test.js | 22 +++---- .../test/qunit/shared/screens_unit_test.js | 29 +++++---- .../static/test/qunit/testHelpers/helpers.js | 10 +++- 11 files changed, 127 insertions(+), 73 deletions(-) diff --git a/resources/static/dialog/controllers/page.js b/resources/static/dialog/controllers/page.js index 7a09282ea..b26e43727 100644 --- a/resources/static/dialog/controllers/page.js +++ b/resources/static/dialog/controllers/page.js @@ -114,20 +114,18 @@ BrowserID.Modules.PageModule = (function() { }, renderDialog: function(body, body_vars) { - screens.form(body, body_vars); - $("#wait, #error").stop().fadeOut(ANIMATION_TIME); + screens.wait.hide(); + screens.error.hide(); + screens.form.show(body, body_vars); dom.focus("input:visible:eq(0)"); }, renderWait: function(body, body_vars) { - screens.wait(body, body_vars); - $("body").css('opacity', 1); - $("#wait").stop().hide().fadeIn(ANIMATION_TIME); + screens.wait.show(body, body_vars); }, renderError: function(body, body_vars) { - screens.error(body, body_vars); - $("#error").stop().css('opacity', 1).hide().fadeIn(ANIMATION_TIME); + screens.error.show(body, body_vars); /** * TODO XXX - Use the error-display for this. diff --git a/resources/static/dialog/css/popup.css b/resources/static/dialog/css/popup.css index 2a97db5aa..32b57adb6 100644 --- a/resources/static/dialog/css/popup.css +++ b/resources/static/dialog/css/popup.css @@ -50,20 +50,69 @@ section > .contents { #wait { text-align: center; - z-index: 1; background-image: url("/i/bg.png"); + z-index: -1; + opacity: 0; + + -webkit-transition-property: opacity; + -moz-transition-property: opacity; + -ms-transition-property: opacity; + -o-transition-property: opacity; + transition-property: opacity; + + -webkit-transition-duration: 0.25s; + -moz-transition-duration: 0.25s; + -ms-transition-duration: 0.25s; + -o-transition-duration: 0.25s; + transition-duration: 0.25s; + + /* Set this to .25s for Android browser, 0.5 seconds makes it so that it + * does not show */ + -webkit-transition-delay: 0.25s; + -moz-transition-delay: 0.5s; + -ms-transition-delay: 0.5s; + -o-transition-delay: 0.5s; + transition-delay: 0.5s; +} + +.waiting #wait { + z-index: 1; + opacity: 1; } #error { - position: absolute; text-align: center; + z-index: -1; + background-color: #fff; display: none; + + -webkit-transition-property: opacity; + -moz-transition-property: opacity; + -ms-transition-property: opacity; + -o-transition-property: opacity; + transition-property: opacity; + + -webkit-transition-duration: 0.25s; + -moz-transition-duration: 0.25s; + -ms-transition-duration: 0.25s; + -o-transition-duration: 0.25s; + transition-duration: 0.25s; + + -webkit-transition-delay: 0.25s; + -moz-transition-delay: 0.25s; + -ms-transition-delay: 0.25s; + -o-transition-delay: 0.25s; + transition-delay: 0.25s; +} + +.error #error { + display: block; z-index: 2; - background-color: #fff; + opacity: 1; } #error ul, #error li { - list-style-type: none; + list-style-type: none; } #wait strong, #error strong { @@ -265,7 +314,7 @@ header { font-weight: bold; background-color: rgba(0,0,0,0.05); border-bottom: 1px solid rgba(0,0,0,0.15); - + -webkit-box-shadow: 0 -5px 5px -5px rgba(0, 0, 0, 0.1) inset; -moz-box-shadow: 0 -5px 5px -5px rgba(0, 0, 0, 0.1) inset; -o-box-shadow: 0 -5px 5px -5px rgba(0, 0, 0, 0.1) inset; diff --git a/resources/static/dialog/resources/helpers.js b/resources/static/dialog/resources/helpers.js index 4c991ab7a..a986ab8ee 100644 --- a/resources/static/dialog/resources/helpers.js +++ b/resources/static/dialog/resources/helpers.js @@ -64,8 +64,11 @@ function getAssertion(email, callback) { var self=this; + var wait = bid.Screens.wait; + wait.show("wait", bid.Wait.generateKey); user.getAssertion(email, function(assert) { assert = assert || null; + wait.hide(); animateClose(function() { self.close("assertion_generated", { assertion: assert diff --git a/resources/static/pages/page_helpers.js b/resources/static/pages/page_helpers.js index 619ef7e6f..c18b2817c 100644 --- a/resources/static/pages/page_helpers.js +++ b/resources/static/pages/page_helpers.js @@ -90,7 +90,7 @@ BrowserID.PageHelpers = (function() { function getFailure(error, callback) { return function onFailure(info) { info = $.extend(info, { action: error, dialog: false }); - bid.Screens.error("error", info); + bid.Screens.error.show("error", info); $("#errorBackground").stop().fadeIn(); $("#error").stop().fadeIn(); diff --git a/resources/static/shared/screens.js b/resources/static/shared/screens.js index 97338199f..3ebf72b69 100644 --- a/resources/static/shared/screens.js +++ b/resources/static/shared/screens.js @@ -3,38 +3,28 @@ BrowserID.Screens = (function() { var bid = BrowserID, dom = BrowserID.DOM, - renderer = bid.Renderer; + renderer = bid.Renderer, + BODY = "body"; - function render(target, body, vars) { - renderer.render(target + " .contents", body, vars); - } - - function form(template, vars) { - render("#formWrap", template, vars); - dom.removeClass("body", "error"); - dom.removeClass("body", "waiting"); - dom.addClass("body", "form"); - } + function Screen(target, className) { + return { + show: function(template, vars) { + renderer.render(target + " .contents", template, vars); + dom.addClass(BODY, className); + this.visible = true; + }, - function wait(template, vars) { - render("#wait", template, vars); - dom.removeClass("body", "error"); - dom.removeClass("body", "form"); - dom.addClass("body", "waiting"); + hide: function() { + dom.removeClass(BODY, className); + this.visible = false; + } + } } - function error(template, vars) { - render("#error", template, vars); - dom.removeClass("body", "waiting"); - dom.removeClass("body", "form"); - dom.addClass("body", "error"); - - bid.ErrorDisplay.start("#error"); - } return { - form: form, - wait: wait, - error: error + form: new Screen("#formWrap", "form"), + wait: new Screen("#wait", "waiting"), + error: new Screen("#error", "error") }; }()); diff --git a/resources/static/test/index.html b/resources/static/test/index.html index b56abd10d..9be2191ec 100644 --- a/resources/static/test/index.html +++ b/resources/static/test/index.html @@ -93,6 +93,7 @@ <script type="text/javascript" src="/shared/mediator.js"></script> <script type="text/javascript" src="/shared/screens.js"></script> <script type="text/javascript" src="/shared/browser-support.js"></script> + <script type="text/javascript" src="/shared/wait-messages.js"></script> <script type="text/javascript" src="/shared/error-messages.js"></script> <script type="text/javascript" src="/shared/error-display.js"></script> <script type="text/javascript" src="/shared/storage.js"></script> diff --git a/resources/static/test/qunit/controllers/checkregistration_unit_test.js b/resources/static/test/qunit/controllers/checkregistration_unit_test.js index 6fa6920cf..4ee5076b6 100644 --- a/resources/static/test/qunit/controllers/checkregistration_unit_test.js +++ b/resources/static/test/qunit/controllers/checkregistration_unit_test.js @@ -41,7 +41,8 @@ bid = BrowserID, xhr = bid.Mocks.xhr, network = bid.Network, - register = bid.TestHelpers.register; + testHelpers = bid.TestHelpers, + register = testHelpers.register; function createController(verifier, message) { controller = bid.Modules.CheckRegistration.create(); @@ -54,11 +55,11 @@ module("controllers/checkregistration_controller", { setup: function() { - bid.TestHelpers.setup(); + testHelpers.setup(); }, teardown: function() { - bid.TestHelpers.teardown(); + testHelpers.teardown(); if (controller) { try { // Controller may have already destroyed itself. @@ -102,7 +103,7 @@ controller.startCheck(); setTimeout(function() { - ok($("#error").is(":visible"), "Error message is visible"); + ok(testHelpers.errorVisible(), "Error message is visible"); start(); }, 500); }); diff --git a/resources/static/test/qunit/controllers/required_email_unit_test.js b/resources/static/test/qunit/controllers/required_email_unit_test.js index 8ffc24add..43fa76ffb 100644 --- a/resources/static/test/qunit/controllers/required_email_unit_test.js +++ b/resources/static/test/qunit/controllers/required_email_unit_test.js @@ -42,12 +42,13 @@ bid = BrowserID, xhr = bid.Mocks.xhr, user = bid.User, - register = bid.TestHelpers.register; + testHelpers = bid.TestHelpers, + register = testHelpers.register; module("controllers/required_email", { setup: function() { el = $("body"); - bid.TestHelpers.setup(); + testHelpers.setup(); xhr.setContextInfo({ authenticated: false }); @@ -63,7 +64,7 @@ } controller = null; } - bid.TestHelpers.setup(); + testHelpers.setup(); } }); @@ -134,7 +135,7 @@ }); setTimeout(function() { - ok($("#error").is(":visible"), "Error message is visible"); + ok(testHelpers.errorVisible(), "Error message is visible"); start(); }, 500); }); diff --git a/resources/static/test/qunit/pages/manage_account_unit_test.js b/resources/static/test/qunit/pages/manage_account_unit_test.js index 8893a8588..ef3871ea4 100644 --- a/resources/static/test/qunit/pages/manage_account_unit_test.js +++ b/resources/static/test/qunit/pages/manage_account_unit_test.js @@ -38,10 +38,10 @@ "use strict"; var bid = BrowserID, - network = bid.Network, - storage = bid.Storage, user = bid.User, xhr = bid.Mocks.xhr, + errorScreen = bid.Screens.error, + testHelpers = bid.TestHelpers, validToken = true, TEST_ORIGIN = "http://browserid.org", mocks = { @@ -51,20 +51,14 @@ module("pages/manage_account", { setup: function() { - network.setXHR(xhr); - xhr.useResult("valid"); + testHelpers.setup(); user.setOrigin(TEST_ORIGIN); $("#emailList").empty(); - $(".error").removeClass("error"); - $("#error").hide(); mocks.document.location = ""; - storage.clear(); }, teardown: function() { - network.setXHR($); $("#emailList").empty(); - $(".error").removeClass("error"); - $("#error").hide(); + testHelpers.teardown(); } }); @@ -88,7 +82,7 @@ xhr.useResult("ajaxError"); bid.manageAccount(mocks, function() { - equal($("#error").is(":visible"), true, "error message is visible on XHR error"); + equal(testHelpers.errorVisible(), true, "error message is visible on XHR error"); start(); }); }); @@ -114,7 +108,7 @@ bid.manageAccount(mocks, function() { xhr.useResult("ajaxError"); bid.manageAccount.removeEmail("testuser@testuser.com", function() { - equal($("#error").is(":visible"), true, "error message is visible on XHR error"); + equal(testHelpers.errorVisible(), true, "error message is visible on XHR error"); start(); }); }); @@ -136,7 +130,7 @@ xhr.useResult("ajaxError"); bid.manageAccount.removeEmail("testuser@testuser.com", function() { - equal($("#error").is(":visible"), true, "error message is visible on XHR error"); + equal(testHelpers.errorVisible(), true, "error message is visible on XHR error"); start(); }); }); @@ -155,7 +149,7 @@ bid.manageAccount(mocks, function() { xhr.useResult("ajaxError"); bid.manageAccount.cancelAccount(function() { - equal($("#error").is(":visible"), true, "error message is visible on XHR error"); + equal(testHelpers.errorVisible(), true, "error message is visible on XHR error"); start(); }); }); diff --git a/resources/static/test/qunit/shared/screens_unit_test.js b/resources/static/test/qunit/shared/screens_unit_test.js index e82bc0dfd..499d457bd 100644 --- a/resources/static/test/qunit/shared/screens_unit_test.js +++ b/resources/static/test/qunit/shared/screens_unit_test.js @@ -56,41 +56,50 @@ test("form", function() { el = $("#formWrap .contents"); el.empty(); - screens.form("testBodyTemplate"); + screens.form.show("testBodyTemplate"); ok($("#templateInput").length, "the template has been written"); - equal($("body").hasClass("error"), false, "error class taken off of body"); - equal($("body").hasClass("waiting"), false, "waiting class taken off of body"); equal($("body").hasClass("form"), true, "form class added to body"); + equal(screens.form.visible, true, "screen is visible"); + + screens.form.hide(); + equal($("body").hasClass("form"), false, "form class removed from body"); + equal(screens.form.visible, false, "screen is not visible"); }); test("wait", function() { var el = $("#wait .contents"); el.empty(); - screens.wait("testBodyTemplate"); + screens.wait.show("testBodyTemplate"); ok($("#templateInput").length, "the template has been written"); - equal($("body").hasClass("error"), false, "error class taken off of body"); - equal($("body").hasClass("form"), false, "form class taken off of body"); equal($("body").hasClass("waiting"), true, "waiting class added to body"); + equal(screens.wait.visible, true, "screen is visible"); + + screens.wait.hide(); + equal($("body").hasClass("waiting"), false, "waiting class removed from body"); + equal(screens.wait.visible, false, "screen is not visible"); }); test("error", function() { var el = $("#error .contents"); el.empty(); - screens.error("testBodyTemplate"); + screens.error.show("testBodyTemplate"); ok($("#templateInput").length, "the template has been written"); - equal($("body").hasClass("waiting"), false, "waiting class taken off of body"); - equal($("body").hasClass("form"), false, "form class taken off of body"); equal($("body").hasClass("error"), true, "error class added to body"); + equal(screens.error.visible, true, "screen is visible"); + + screens.error.hide(); + equal($("body").hasClass("error"), false, "error class removed from body"); + equal(screens.error.visible, false, "screen is not visible"); }); test("XHR 503 (server unavailable) error", function() { var el = $("#error .contents"); el.empty(); - screens.error("error", { + screens.error.show("error", { network: { status: 503 } diff --git a/resources/static/test/qunit/testHelpers/helpers.js b/resources/static/test/qunit/testHelpers/helpers.js index 0e7617968..a55d94804 100644 --- a/resources/static/test/qunit/testHelpers/helpers.js +++ b/resources/static/test/qunit/testHelpers/helpers.js @@ -4,6 +4,7 @@ network = bid.Network, storage = bid.Storage, xhr = bid.Mocks.xhr, + screens = bid.Screens, registrations = []; calls = {}; @@ -40,6 +41,8 @@ unregisterAll(); mediator.reset(); + screens.wait.hide(); + screens.error.hide(); }, teardown: function() { @@ -48,8 +51,13 @@ network.setXHR($); storage.clear(); $("#error").html("<div class='contents'></div>").hide(); + screens.wait.hide(); + screens.error.hide(); }, - register: register + register: register, + errorVisible: function() { + return screens.error.visible; + } }; }()); -- GitLab