0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-03 23:00:14 -05:00

Improved Auth screen markup and validation checks

* Signup now focuses on 'name' on load
* Fixed fade in on auth forms to work with `display: table`
* The 'name' field is required on Sign up forms
* The length check on the Signup form is in order of inputs
* Added check for password length
* Changed the auth form class names to better represent individual pages
* Updated CasperJS tests
This commit is contained in:
Matthew Harrison-Jones 2013-09-12 09:59:58 +01:00
parent f84de01dc0
commit 2678de902d
9 changed files with 102 additions and 63 deletions

View file

@ -1,5 +1,5 @@
/* /*
* These styles control elements specific to the Ghost admin login screen. * These styles control elements specific to the Ghost admin login / signup screens.
* *
* Table of Contents: * Table of Contents:
* *
@ -14,6 +14,7 @@
============================================================================= */ ============================================================================= */
.ghost-login, .ghost-login,
.ghost-signup,
.ghost-forgotten { .ghost-forgotten {
color: $midgrey; color: $midgrey;
background: $darkgrey; background: $darkgrey;
@ -28,7 +29,9 @@
}//.ghost-login }//.ghost-login
.login-box { .login-box,
.signup-box,
.forgotten-box {
max-width: 530px; max-width: 530px;
height: 90%; height: 90%;
margin: 0 auto; margin: 0 auto;

View file

@ -40,7 +40,7 @@
@import "layouts/editor"; @import "layouts/editor";
/* The write/edit post screen. */ /* The write/edit post screen. */
@import "layouts/login"; @import "layouts/auth";
/* The login screen. */ /* The login screen. */
@import "layouts/errors"; @import "layouts/errors";

View file

@ -19,7 +19,7 @@
}, },
signup: function () { signup: function () {
Ghost.currentView = new Ghost.Views.Signup({ el: '.js-login-box' }); Ghost.currentView = new Ghost.Views.Signup({ el: '.js-signup-box' });
}, },
login: function () { login: function () {
@ -27,7 +27,7 @@
}, },
forgotten: function () { forgotten: function () {
Ghost.currentView = new Ghost.Views.Forgotten({ el: '.js-login-box' }); Ghost.currentView = new Ghost.Views.Forgotten({ el: '.js-forgotten-box' });
}, },
blog: function () { blog: function () {

View file

@ -2,17 +2,14 @@
(function () { (function () {
"use strict"; "use strict";
Ghost.Views.Login = Ghost.View.extend({
Ghost.SimpleFormView = Ghost.View.extend({
initialize: function () { initialize: function () {
this.render(); this.render();
$(".js-login-box").fadeIn(500, function () { $(".js-login-box").css({"opacity": 0}).animate({"opacity": 1}, 500, function () {
$("[name='email']").focus(); $("[name='email']").focus();
}); });
} },
});
Ghost.Views.Login = Ghost.SimpleFormView.extend({
templateName: "login", templateName: "login",
@ -48,7 +45,14 @@
} }
}); });
Ghost.Views.Signup = Ghost.SimpleFormView.extend({ Ghost.Views.Signup = Ghost.View.extend({
initialize: function () {
this.render();
$(".js-signup-box").css({"opacity": 0}).animate({"opacity": 1}, 500, function () {
$("[name='name']").focus();
});
},
templateName: "signup", templateName: "signup",
@ -62,29 +66,56 @@
email = this.$el.find('.email').val(), email = this.$el.find('.email').val(),
password = this.$el.find('.password').val(); password = this.$el.find('.password').val();
$.ajax({ if (!name) {
url: '/ghost/signup/', Ghost.notifications.addItem({
type: 'POST', type: 'error',
data: { message: "Please enter a name",
name: name, status: 'passive'
email: email, });
password: password } else if (!email) {
}, Ghost.notifications.addItem({
success: function (msg) { type: 'error',
window.location.href = msg.redirect; message: "Please enter an email",
}, status: 'passive'
error: function (xhr) { });
Ghost.notifications.addItem({ } else if (!password) {
type: 'error', Ghost.notifications.addItem({
message: Ghost.Views.Utils.getRequestErrorMessage(xhr), type: 'error',
status: 'passive' message: "Please enter a password",
}); status: 'passive'
} });
}); } else {
$.ajax({
url: '/ghost/signup/',
type: 'POST',
data: {
name: name,
email: email,
password: password
},
success: function (msg) {
window.location.href = msg.redirect;
},
error: function (xhr) {
Ghost.notifications.addItem({
type: 'error',
message: Ghost.Views.Utils.getRequestErrorMessage(xhr),
status: 'passive'
});
}
});
}
} }
}); });
Ghost.Views.Forgotten = Ghost.SimpleFormView.extend({ Ghost.Views.Forgotten = Ghost.View.extend({
initialize: function () {
this.render();
$(".js-forgotten-box").css({"opacity": 0}).animate({"opacity": 1}, 500, function () {
$("[name='email']").focus();
});
},
templateName: "forgotten", templateName: "forgotten",

View file

@ -116,7 +116,7 @@ adminControllers = {
} }
}, },
'login': function (req, res) { 'login': function (req, res) {
res.render('signup', { res.render('login', {
bodyClass: 'ghost-login', bodyClass: 'ghost-login',
hideNavbar: true, hideNavbar: true,
adminNav: setSelected(adminNavbar, 'login') adminNav: setSelected(adminNavbar, 'login')
@ -161,7 +161,7 @@ adminControllers = {
}, },
'signup': function (req, res) { 'signup': function (req, res) {
res.render('signup', { res.render('signup', {
bodyClass: 'ghost-login', bodyClass: 'ghost-signup',
hideNavbar: true, hideNavbar: true,
adminNav: setSelected(adminNavbar, 'login') adminNav: setSelected(adminNavbar, 'login')
}); });
@ -189,7 +189,7 @@ adminControllers = {
}, },
'forgotten': function (req, res) { 'forgotten': function (req, res) {
res.render('signup', { res.render('forgotten', {
bodyClass: 'ghost-forgotten', bodyClass: 'ghost-forgotten',
hideNavbar: true, hideNavbar: true,
adminNav: setSelected(adminNavbar, 'login') adminNav: setSelected(adminNavbar, 'login')

View file

@ -0,0 +1,4 @@
{{!< default}}
<section class="forgotten-box js-forgotten-box">
</section>

View file

@ -1,4 +1,4 @@
{{!< default}} {{!< default}}
<section class="login-box js-login-box"> <section class="signup-box js-signup-box">
</section> </section>

View file

@ -17,15 +17,13 @@ casper.test.begin('Ensure a User is Registered', 2, function suite(test) {
casper.start(url + 'ghost/signup/').viewport(1280, 1024); casper.start(url + 'ghost/signup/').viewport(1280, 1024);
casper.waitFor(function checkOpaque() { casper.waitForOpaque(".signup-box",
return this.evaluate(function () { function then() {
var loginBox = document.querySelector('.login-box'); this.fill("#signup", newUser, true);
return window.getComputedStyle(loginBox).getPropertyValue('display') === "table" },
&& window.getComputedStyle(loginBox).getPropertyValue('opacity') === "1"; function onTimeout() {
test.fail('Sign up form didn\'t fade in.');
}); });
}, function then() {
this.fill("#signup", user, true);
});
casper.waitForSelectorTextChange('.notification-error', function onSuccess() { casper.waitForSelectorTextChange('.notification-error', function onSuccess() {
test.assertSelectorHasText('.notification-error', 'already registered'); test.assertSelectorHasText('.notification-error', 'already registered');
@ -86,18 +84,13 @@ casper.test.begin("Can't spam it", 4, function suite(test) {
test.assertTitle("", "Ghost admin has no title"); test.assertTitle("", "Ghost admin has no title");
}).viewport(1280, 1024); }).viewport(1280, 1024);
casper.waitFor(function checkOpaque() { casper.waitForOpaque(".login-box",
return this.evaluate(function () { function then() {
var loginBox = document.querySelector('.login-box'); this.fill("#login", falseUser, true);
},
return window.getComputedStyle(loginBox).getPropertyValue('display') === "table" function onTimeout() {
&& window.getComputedStyle(loginBox).getPropertyValue('opacity') === "1"; test.fail('Sign in form didn\'t fade in.');
}); });
}, function then() {
this.fill("#login", falseUser, true);
}, function onTimeout() {
test.fail('Sign in form didn\'t fade in.');
});
casper.wait(200, function doneWait() { casper.wait(200, function doneWait() {
this.fill("#login", falseUser, true); this.fill("#login", falseUser, true);
@ -127,15 +120,10 @@ casper.test.begin("Can login to Ghost", 4, function suite(test) {
test.assertTitle("", "Ghost admin has no title"); test.assertTitle("", "Ghost admin has no title");
}).viewport(1280, 1024); }).viewport(1280, 1024);
casper.waitFor(function checkOpaque() { casper.waitForOpaque(".login-box",
return casper.evaluate(function () { function then() {
var loginBox = document.querySelector('.login-box'); this.fill("#login", user, true);
return window.getComputedStyle(loginBox).getPropertyValue('display') === "table"
&& window.getComputedStyle(loginBox).getPropertyValue('opacity') === "1";
}); });
}, function then() {
this.fill("#login", user, true);
});
casper.waitForResource(/ghost\/$/, function testForDashboard() { casper.waitForResource(/ghost\/$/, function testForDashboard() {
test.assertUrlMatch(/ghost\/$/, 'We got redirected to the Ghost page'); test.assertUrlMatch(/ghost\/$/, 'We got redirected to the Ghost page');

View file

@ -27,6 +27,11 @@ var host = casper.cli.options.host || 'localhost',
email = casper.cli.options.email || 'ghost@tryghost.org', email = casper.cli.options.email || 'ghost@tryghost.org',
password = casper.cli.options.password || 'Sl1m3rson', password = casper.cli.options.password || 'Sl1m3rson',
url = "http://" + host + (noPort ? '/' : ":" + port + "/"), url = "http://" + host + (noPort ? '/' : ":" + port + "/"),
newUser = {
name: "Test User",
email: email,
password: password
},
user = { user = {
email: email, email: email,
password: password password: password
@ -51,6 +56,14 @@ casper.writeContentToCodeMirror = function (content) {
return this; return this;
}; };
casper.waitForOpaque = function (classname, then, timeout) {
casper.waitFor(function checkOpaque() {
return this.evaluate(function (element) {
var target = document.querySelector(element);
return window.getComputedStyle(target).getPropertyValue('opacity') === "1";
}, classname);
}, then, timeout);
};
// ## Debugging // ## Debugging
// output all errors to the console // output all errors to the console