Merge pull request #910 from jloveland/hide-password-validator

Hide the password strength progress when the field is empty
This commit is contained in:
Ilan Biala
2015-10-16 23:34:55 -04:00
11 changed files with 816 additions and 60 deletions

View File

@@ -258,6 +258,26 @@ module.exports = function (grunt) {
});
});
// Drops the MongoDB database, used in e2e testing
grunt.task.registerTask('dropdb', 'drop the database', function () {
// async mode
var done = this.async();
// Use mongoose configuration
var mongoose = require('./config/lib/mongoose.js');
mongoose.connect(function (db) {
db.connection.db.dropDatabase(function (err) {
if (err) {
console.log(err);
} else {
console.log('Successfully dropped db: ', db.connection.db.databaseName);
}
db.connection.db.close(done);
});
});
});
grunt.task.registerTask('server', 'Starting the server', function () {
// Get the callback
var done = this.async();
@@ -279,7 +299,7 @@ module.exports = function (grunt) {
grunt.registerTask('test', ['env:test', 'lint', 'mkdir:upload', 'copy:localConfig', 'server', 'mochaTest', 'karma:unit', 'protractor']);
grunt.registerTask('test:server', ['env:test', 'lint', 'server', 'mochaTest']);
grunt.registerTask('test:client', ['env:test', 'lint', 'server', 'karma:unit']);
grunt.registerTask('test:e2e', ['env:test', 'lint', 'server', 'protractor']);
grunt.registerTask('test:e2e', ['env:test', 'lint', 'dropdb', 'server', 'protractor']);
// Run project coverage
grunt.registerTask('coverage', ['env:test', 'lint', 'mocha_istanbul:coverage']);

View File

@@ -199,6 +199,23 @@ gulp.task('karma', function (done) {
}));
});
// Drops the MongoDB database, used in e2e testing
gulp.task('dropdb', function (done) {
// Use mongoose configuration
var mongoose = require('./config/lib/mongoose.js');
mongoose.connect(function (db) {
db.connection.db.dropDatabase(function (err) {
if(err) {
console.log(err);
} else {
console.log('Successfully dropped db: ', db.connection.db.databaseName);
}
db.connection.db.close(done);
});
});
});
// Downloads the selenium webdriver
gulp.task('webdriver_update', webdriver_update);
@@ -248,7 +265,7 @@ gulp.task('test:client', function (done) {
});
gulp.task('test:e2e', function (done) {
runSequence('env:test', 'lint', 'nodemon', 'protractor', done);
runSequence('env:test', 'lint', 'dropdb', 'nodemon', 'protractor', done);
});
// Run the project in development mode

View File

@@ -4,39 +4,41 @@ angular.module('users')
.directive('passwordValidator', ['PasswordValidator', function(PasswordValidator) {
return {
require: 'ngModel',
link: function(scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.unshift(function (password) {
var result = PasswordValidator.getResult(password);
var strengthIdx = 0;
link: function(scope, element, attrs, ngModel) {
ngModel.$validators.requirements = function (password) {
var status = true;
if (password) {
var result = PasswordValidator.getResult(password);
var requirementsIdx = 0;
// Strength Meter - visual indicator for users
var strengthMeter = [
{ color: 'danger', progress: '20' },
{ color: 'warning', progress: '40' },
{ color: 'info', progress: '60' },
{ color: 'primary', progress: '80' },
{ color: 'success', progress: '100' }
];
var strengthMax = strengthMeter.length;
// Requirements Meter - visual indicator for users
var requirementsMeter = [
{ color: 'danger', progress: '20' },
{ color: 'warning', progress: '40' },
{ color: 'info', progress: '60' },
{ color: 'primary', progress: '80' },
{ color: 'success', progress: '100' }
];
if (result.errors.length < strengthMeter.length) {
strengthIdx = strengthMeter.length - result.errors.length - 1;
if (result.errors.length < requirementsMeter.length) {
requirementsIdx = requirementsMeter.length - result.errors.length - 1;
}
scope.requirementsColor = requirementsMeter[requirementsIdx].color;
scope.requirementsProgress = requirementsMeter[requirementsIdx].progress;
if (result.errors.length) {
scope.popoverMsg = PasswordValidator.getPopoverMsg();
scope.passwordErrors = result.errors;
status = false;
} else {
scope.popoverMsg = '';
scope.passwordErrors = [];
status = true;
}
}
scope.strengthColor = strengthMeter[strengthIdx].color;
scope.strengthProgress = strengthMeter[strengthIdx].progress;
if (result.errors.length) {
scope.popoverMsg = PasswordValidator.getPopoverMsg();
scope.passwordErrors = result.errors;
modelCtrl.$setValidity('strength', false);
return undefined;
} else {
scope.popoverMsg = '';
modelCtrl.$setValidity('strength', true);
return password;
}
});
return status;
};
}
};
}]);

View File

@@ -7,25 +7,20 @@ angular.module('users')
scope: {
passwordVerify: '='
},
link: function(scope, element, attrs, modelCtrl) {
link: function(scope, element, attrs, ngModel) {
var status = true;
scope.$watch(function() {
var combined;
if (scope.passwordVerify || modelCtrl.$viewValue) {
combined = scope.passwordVerify + '_' + modelCtrl.$viewValue;
if (scope.passwordVerify || ngModel) {
combined = scope.passwordVerify + '_' + ngModel;
}
return combined;
}, function(value) {
if (value) {
modelCtrl.$parsers.unshift(function(viewValue) {
ngModel.$validators.passwordVerify = function (password) {
var origin = scope.passwordVerify;
if (origin !== viewValue) {
modelCtrl.$setValidity('passwordVerify', false);
return undefined;
} else {
modelCtrl.$setValidity('passwordVerify', true);
return viewValue;
}
});
return (origin !== password) ? false : true;
};
}
});
}

View File

@@ -38,13 +38,13 @@
<div ng-messages="userForm.password.$error" role="alert">
<p class="help-block error-text" ng-message="required">Password is required.</p>
<div ng-repeat="passwordError in passwordErrors">
<p class="help-block error-text" ng-show="userForm.password.$error.strength">{{passwordError}}</p>
<p class="help-block error-text" ng-show="userForm.password.$error.requirements">{{passwordError}}</p>
</div>
</div>
</div>
<div class="form-group" ng-show="!userForm.password.$pristine">
<label>Password Strength</label>
<progressbar value="strengthProgress" type="{{strengthColor}}"><span style="color:white; white-space:nowrap;">{{strengthProgress}}%</span></progressbar>
<div class="form-group" ng-show="!userForm.password.$error.required">
<label>Password Requirements</label>
<progressbar value="requirementsProgress" type="{{requirementsColor}}"><span style="color:white; white-space:nowrap;">{{requirementsProgress}}%</span></progressbar>
</div>
<div class="text-center form-group">
<button type="submit" class="btn btn-primary">Sign up</button>

View File

@@ -9,7 +9,7 @@
<div ng-messages="resetPasswordForm.newPassword.$error" role="alert">
<p class="help-block error-text" ng-message="required">Enter a new password.</p>
<div ng-repeat="passwordError in passwordErrors">
<p class="help-block error-text" ng-show="resetPasswordForm.newPassword.$error.strength">{{passwordError}}</p>
<p class="help-block error-text" ng-show="resetPasswordForm.newPassword.$error.requirements">{{passwordError}}</p>
</div>
</div>
</div>
@@ -21,9 +21,9 @@
<p class="help-block error-text" ng-show=resetPasswordForm.verifyPassword.$error.passwordVerify>Passwords do not match.</p>
</div>
</div>
<div class="form-group" ng-show="!resetPasswordForm.newPassword.$pristine">
<label>Password Strength</label>
<progressbar value="strengthProgress" type="{{strengthColor}}"><span style="color:white; white-space:nowrap;">{{strengthProgress}}%</span></progressbar>
<div class="form-group" ng-show="!resetPasswordForm.newPassword.$error.required">
<label>Password Requirements</label>
<progressbar value="requirementsProgress" type="{{requirementsColor}}"><span style="color:white; white-space:nowrap;">{{requirementsProgress}}%</span></progressbar>
</div>
<div class="text-center form-group">
<button type="submit" class="btn btn-primary">Update Password</button>

View File

@@ -15,7 +15,7 @@
<div ng-messages="passwordForm.newPassword.$error" role="alert">
<p class="help-block error-text" ng-message="required">Enter a new password.</p>
<div ng-repeat="passwordError in passwordErrors">
<p class="help-block error-text" ng-show="passwordForm.newPassword.$error.strength">{{passwordError}}</p>
<p class="help-block error-text" ng-show="passwordForm.newPassword.$error.requirements">{{passwordError}}</p>
</div>
</div>
</div>
@@ -27,9 +27,9 @@
<p class="help-block error-text" ng-show=passwordForm.verifyPassword.$error.passwordVerify>Passwords do not match.</p>
</div>
</div>
<div class="form-group" ng-show="!passwordForm.newPassword.$pristine">
<label>Password Strength</label>
<progressbar value="strengthProgress" type="{{strengthColor}}"><span style="color:white; white-space:nowrap;">{{strengthProgress}}%</span></progressbar>
<div class="form-group" ng-show="!passwordForm.newPassword.$error.required">
<label>Password Requirements</label>
<progressbar value="requirementsProgress" type="{{requirementsColor}}"><span style="color:white; white-space:nowrap;">{{requirementsProgress}}%</span></progressbar>
</div>
<div class="text-center form-group">
<button type="submit" class="btn btn-primary">Save Password</button>

View File

@@ -0,0 +1,208 @@
'use strict';
(function() {
// Password Validator Directive Spec
describe('PasswordValidatorDirective', function() {
// Initialize global variables
var scope,
element,
$compile,
form;
// Load the main application module
beforeEach(module(ApplicationConfiguration.applicationModuleName));
beforeEach(inject(function(_$rootScope_, _$compile_) {
// Set a new global scope
scope = _$rootScope_.$new();
$compile = _$compile_;
scope.passwordMock = {
password: 'P@ssw0rd!!'
};
}));
function compileDirective(template) {
// function to compile a fresh directive with the given template, or a default one
// input form with directive
if (!template) template = '<input type="password" id="password" name="password" ng-model="passwordMock.password" password-validator required>';
template = '<form name="form"><div>' + template + '<input type="submit">submit form</input></div></form>';
// inject allows you to use AngularJS dependency injection
// to retrieve and use other services
inject(function($compile) {
var form = $compile(template)(scope);
element = form.find('div');
// $digest is necessary to finalize the directive generation
scope.$digest();
});
}
describe('Initialize', function() {
beforeEach(function () {
compileDirective();
});
it('should produce the password input', function () {
expect(element.find('input').length).toEqual(2);
});
it('should check form validity upon initializing', function () {
expect(scope.form.$valid).toBeTruthy();
});
});
it('should set form to invalid with empty password', function () {
scope.passwordMock.password = '';
compileDirective();
scope.$digest();
expect(scope.form.password.$valid).toBeFalsy();
expect(scope.form.password.$error.required).toBeTruthy();
expect(scope.requirementsColor).toEqual(undefined);
expect(scope.requirementsProgress).toEqual(undefined);
});
it('should be valid when password meets requirements - "P@ssw0rd!!""', function() {
scope.passwordMock.password = 'P@ssw0rd!!';
compileDirective();
scope.$digest();
expect(scope.form.password.$valid).toBeTruthy();
expect(scope.form.password.$error).toEqual({});
expect(scope.requirementsColor).toEqual('success');
expect(scope.requirementsProgress).toEqual('100');
});
it('should be valid when password meets requirements with a passphrase', function() {
scope.passwordMock.password = 'Open-Source Full-Stack Solution for MEAN';
compileDirective();
scope.$digest();
expect(scope.form.password.$valid).toBeTruthy();
expect(scope.form.password.$error).toEqual({});
expect(scope.requirementsColor).toEqual('success');
expect(scope.requirementsProgress).toEqual('100');
});
it('should not allow a less than 10 characters long - "P@$$w0rd!"', function() {
scope.passwordMock.password = 'P@$$w0rd!';
compileDirective();
scope.$digest();
expect(scope.form.password.$valid).toBeFalsy();
expect(scope.form.password.$error.required).toBeFalsy();
expect(scope.passwordErrors).toEqual(['The password must be at least 10 characters long.']);
expect(scope.requirementsColor).toEqual('primary');
expect(scope.requirementsProgress).toEqual('80');
});
it('should not allow a greater than 128 characters long', function() {
scope.passwordMock.password = ')!/uLT="lh&:`6X!]|15o!$!TJf,.13l?vG].-j],lFPe/QhwN#{Z<[*1nX@n1^?WW-%_.*D)m$toB+N7z}kcN#B_d(f41h%w@0F!]igtSQ1gl~6sEV&r~}~1ub>If1c+';
compileDirective();
scope.$digest();
expect(scope.form.password.$valid).toBeFalsy();
expect(scope.form.password.$error.required).toBeFalsy();
expect(scope.passwordErrors).toEqual(['The password must be fewer than 128 characters.']);
expect(scope.requirementsColor).toEqual('primary');
expect(scope.requirementsProgress).toEqual('80');
});
it('should not allow more than 3 or more repeating characters - "P@$$w0rd!!!"', function() {
scope.passwordMock.password = 'P@$$w0rd!!!';
compileDirective();
scope.$digest();
expect(scope.form.password.$valid).toBeFalsy();
expect(scope.form.password.$error.required).toBeFalsy();
expect(scope.passwordErrors).toEqual(['The password may not contain sequences of three or more repeated characters.']);
expect(scope.requirementsColor).toEqual('primary');
expect(scope.requirementsProgress).toEqual('80');
});
it('should not allow a password with no uppercase letters - "p@$$w0rd!!"', function() {
scope.passwordMock.password = 'p@$$w0rd!!';
compileDirective();
scope.$digest();
expect(scope.form.password.$valid).toBeFalsy();
expect(scope.form.password.$error.required).toBeFalsy();
expect(scope.passwordErrors).toEqual(['The password must contain at least one uppercase letter.']);
expect(scope.requirementsColor).toEqual('primary');
expect(scope.requirementsProgress).toEqual('80');
});
it('should not allow a password with less than one number - "P@$$word!!"', function() {
scope.passwordMock.password = 'P@$$word!!';
compileDirective();
scope.$digest();
expect(scope.form.password.$valid).toBeFalsy();
expect(scope.form.password.$error.required).toBeFalsy();
expect(scope.passwordErrors).toEqual(['The password must contain at least one number.']);
expect(scope.requirementsColor).toEqual('primary');
expect(scope.requirementsProgress).toEqual('80');
});
it('should not allow a password with less than one special character - "Passw0rdss"', function() {
scope.passwordMock.password = 'Passw0rdss';
compileDirective();
scope.$digest();
expect(scope.form.password.$valid).toBeFalsy();
expect(scope.form.password.$error.required).toBeFalsy();
expect(scope.passwordErrors).toEqual(['The password must contain at least one special character.']);
expect(scope.requirementsColor).toEqual('primary');
expect(scope.requirementsProgress).toEqual('80');
});
it('should show 20% progress and "danger" color', function() {
scope.passwordMock.password = 'P';
compileDirective();
scope.$digest();
expect(scope.requirementsColor).toEqual('danger');
expect(scope.requirementsProgress).toEqual('20');
});
it('should show 40% progress and "warning" color', function() {
scope.passwordMock.password = 'Pa';
compileDirective();
scope.$digest();
expect(scope.requirementsColor).toEqual('warning');
expect(scope.requirementsProgress).toEqual('40');
});
it('should show 60% progress and "info" color', function() {
scope.passwordMock.password = 'Pa$';
compileDirective();
scope.$digest();
expect(scope.requirementsColor).toEqual('info');
expect(scope.requirementsProgress).toEqual('60');
});
it('should show 80% progress and "primary" color', function() {
scope.passwordMock.password = 'Pa$$w0rd';
compileDirective();
scope.$digest();
expect(scope.requirementsColor).toEqual('primary');
expect(scope.requirementsProgress).toEqual('80');
});
it('should show 100% progress and "success" color', function() {
scope.passwordMock.password = 'Pa$$w0rd!!';
compileDirective();
scope.$digest();
expect(scope.requirementsColor).toEqual('success');
expect(scope.requirementsProgress).toEqual('100');
});
});
}());

View File

@@ -0,0 +1,86 @@
'use strict';
(function() {
// Password Verify Directive Spec
describe('PasswordVerifyDirective', function() {
// Initialize global variables
var scope,
element,
$compile,
form;
// Load the main application module
beforeEach(module(ApplicationConfiguration.applicationModuleName));
beforeEach(inject(function(_$rootScope_, _$compile_) {
// Set a new global scope
scope = _$rootScope_.$new();
$compile = _$compile_;
scope.passwordMock = {
newPassword: 'P@ssw0rd!!',
verifyPassword: 'P@ssw0rd!!'
};
}));
function compileDirective(template) {
// function to compile a fresh directive with the given template, or a default one
// input form with directive
if (!template) template = '<input type="password" id="newPassword" name="newPassword" class="form-control" ng-model="passwordMock.newPassword" placeholder="New Password" autocomplete="new-password" popover="{{popoverMsg}}" popover-trigger="focus" popover-placement="top" password-validator required>' +
'<input type="password" id="verifyPassword" name="verifyPassword" class="form-control" ng-model="passwordMock.verifyPassword" placeholder="Verify Password" password-verify="passwordMock.newPassword" required>';
template = '<form name="form"><div>' + template + '<input type="submit">submit form</input></div></form>';
// inject allows you to use AngularJS dependency injection
// to retrieve and use other services
inject(function($compile) {
var form = $compile(template)(scope);
element = form.find('div');
// $digest is necessary to finalize the directive generation
scope.$digest();
});
}
describe('Initialize', function() {
beforeEach(function () {
compileDirective();
});
it('should produce the password input', function () {
expect(element.find('input').length).toEqual(3);
});
it('should check form validity upon initializing', function () {
expect(scope.form.$valid).toBeTruthy();
});
});
it('should not show error when passwords match', function () {
compileDirective();
scope.passwordMock.newPassword = 'P@ssw0rd!!';
scope.passwordMock.verifyPassword = 'P@ssw0rd!!';
scope.$digest();
expect(scope.form.newPassword.$valid).toBeTruthy();
expect(scope.form.newPassword.$error).toEqual({});
expect(scope.form.verifyPassword.$valid).toBeTruthy();
expect(scope.form.verifyPassword.$error).toEqual({});
expect(scope.form.$valid).toBeTruthy();
});
it('should show error when passwords do not match', function () {
compileDirective();
scope.passwordMock.newPassword = 'P@ssw0rd!!';
scope.passwordMock.verifyPassword = 'P@ssw0rd!';
scope.$digest();
expect(scope.form.newPassword.$valid).toBeTruthy();
expect(scope.form.newPassword.$error).toEqual({});
expect(scope.form.verifyPassword.$valid).toBeFalsy();
expect(scope.form.verifyPassword.$error.passwordVerify).toBeTruthy();
expect(scope.form.$valid).toBeFalsy();
});
});
}());

View File

@@ -1,7 +1,7 @@
'use strict';
(function() {
// Authentication controller Spec
// Password controller Spec
describe('PasswordController', function() {
// Initialize global variables
var PasswordController,

View File

@@ -1,14 +1,442 @@
'use strict';
describe('Users E2E Tests:', function () {
describe('Signin Validation', function () {
it('Should report missing credentials', function () {
browser.get('http://localhost:3001/authentication/signin');
var user1 = {
firstName: 'test',
lastName: 'user',
email: 'test.user@meanjs.com',
username: 'testUser',
password: 'P@$$w0rd!!'
};
var user2 = {
firstName: 'test',
lastName: 'user2',
email: 'test.user2@meanjs.com',
username: 'testUser2',
password: 'P@$$w0rd!!'
};
var signout = function () {
// Make sure user is signed out first
browser.get('http://localhost:3001/authentication/signout');
// Delete all cookies
browser.driver.manage().deleteAllCookies();
};
describe('Signup Validation', function () {
it('Should report missing first name', function () {
browser.get('http://localhost:3001/authentication/signup');
// Enter Last Name
element(by.model('credentials.lastName')).sendKeys(user1.lastName);
// Enter Email
element(by.model('credentials.email')).sendKeys(user1.email);
// Enter Username
element(by.model('credentials.username')).sendKeys(user1.username);
// Enter Password
element(by.model('credentials.password')).sendKeys(user1.password);
// Click Submit button
element(by.css('button[type=submit]')).click();
// First Name Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('First name is required.');
});
it('Should report missing last name', function () {
browser.get('http://localhost:3001/authentication/signup');
// Enter First Name
element(by.model('credentials.firstName')).sendKeys(user1.firstName);
// Enter Email
element(by.model('credentials.email')).sendKeys(user1.email);
// Enter Username
element(by.model('credentials.username')).sendKeys(user1.username);
// Enter Password
element(by.model('credentials.password')).sendKeys(user1.password);
// Click Submit button
element(by.css('button[type=submit]')).click();
// Last Name Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('Last name is required.');
});
it('Should report missing email address', function () {
browser.get('http://localhost:3001/authentication/signup');
// Enter First Name
element(by.model('credentials.firstName')).sendKeys(user1.firstName);
// Enter Last Name
element(by.model('credentials.lastName')).sendKeys(user1.lastName);
// Enter Username
element(by.model('credentials.username')).sendKeys(user1.username);
// Enter Password
element(by.model('credentials.password')).sendKeys(user1.password);
// Click Submit button
element(by.css('button[type=submit]')).click();
// Email address error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('Email address is required.');
});
it('Should report invalid email address - "123"', function () {
browser.get('http://localhost:3001/authentication/signup');
// Enter First Name
element(by.model('credentials.firstName')).sendKeys(user1.firstName);
// Enter Last Name
element(by.model('credentials.lastName')).sendKeys(user1.lastName);
// Enter Email
element(by.model('credentials.email')).sendKeys('123');
// Enter Username
element(by.model('credentials.username')).sendKeys(user1.username);
// Enter Password
element(by.model('credentials.password')).sendKeys(user1.password);
// Click Submit button
element(by.css('button[type=submit]')).click();
// Email address error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('Email address is invalid.');
});
/**
* Note: 123@123 is a valid email adress according to HTML5.
* However, 123@123@123 is an invalid email address.
*/
it('Should report invalid email address - "123@123@123"', function () {
browser.get('http://localhost:3001/authentication/signup');
// Enter First Name
element(by.model('credentials.firstName')).sendKeys(user1.firstName);
// Enter Last Name
element(by.model('credentials.lastName')).sendKeys(user1.lastName);
// Enter Email
element(by.model('credentials.email')).sendKeys('123@123@123');
// Enter Username
element(by.model('credentials.username')).sendKeys(user1.username);
// Enter Password
element(by.model('credentials.password')).sendKeys(user1.password);
// Click Submit button
element(by.css('button[type=submit]')).click();
// Email address error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('Email address is invalid.');
});
it('Should report missing username', function () {
browser.get('http://localhost:3001/authentication/signup');
// Enter First Name
element(by.model('credentials.firstName')).sendKeys(user1.firstName);
// Enter Last Name
element(by.model('credentials.lastName')).sendKeys(user1.lastName);
// Enter Email
element(by.model('credentials.email')).sendKeys(user1.email);
// Enter Password
element(by.model('credentials.password')).sendKeys(user1.password);
// Click Submit button
element(by.css('button[type=submit]')).click();
// Username Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('Username is required.');
});
it('Should report a password with less than 10 characters long - "P@$$w0rd!"', function () {
browser.get('http://localhost:3001/authentication/signup');
// Enter First Name
element(by.model('credentials.firstName')).sendKeys(user1.firstName);
// Enter Last Name
element(by.model('credentials.lastName')).sendKeys(user1.lastName);
// Enter Email
element(by.model('credentials.email')).sendKeys(user1.email);
// Enter Username
element(by.model('credentials.username')).sendKeys(user1.username);
// Enter Invalid Password
element(by.model('credentials.password')).sendKeys('P@$$w0rd!');
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must be at least 10 characters long.');
});
it('Should report a password with greater than 128 characters long.', function () {
browser.get('http://localhost:3001/authentication/signup');
// Enter First Name
element(by.model('credentials.firstName')).sendKeys(user1.firstName);
// Enter Last Name
element(by.model('credentials.lastName')).sendKeys(user1.lastName);
// Enter Email
element(by.model('credentials.email')).sendKeys(user1.email);
// Enter Username
element(by.model('credentials.username')).sendKeys(user1.username);
// Enter Invalid Password
element(by.model('credentials.password')).sendKeys(')!/uLT="lh&:`6X!]|15o!$!TJf,.13l?vG].-j],lFPe/QhwN#{Z<[*1nX@n1^?WW-%_.*D)m$toB+N7z}kcN#B_d(f41h%w@0F!]igtSQ1gl~6sEV&r~}~1ub>If1c+');
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must be fewer than 128 characters.');
});
it('Should report a password with more than 3 or more repeating characters - "P@$$w0rd!!!"', function () {
browser.get('http://localhost:3001/authentication/signup');
// Enter First Name
element(by.model('credentials.firstName')).sendKeys(user1.firstName);
// Enter Last Name
element(by.model('credentials.lastName')).sendKeys(user1.lastName);
// Enter Email
element(by.model('credentials.email')).sendKeys(user1.email);
// Enter Username
element(by.model('credentials.username')).sendKeys(user1.username);
// Enter Invalid Password
element(by.model('credentials.password')).sendKeys('P@$$w0rd!!!');
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password may not contain sequences of three or more repeated characters.');
});
it('Should report a password with no uppercase letters - "p@$$w0rd!!"', function () {
browser.get('http://localhost:3001/authentication/signup');
// Enter First Name
element(by.model('credentials.firstName')).sendKeys(user1.firstName);
// Enter Last Name
element(by.model('credentials.lastName')).sendKeys(user1.lastName);
// Enter Email
element(by.model('credentials.email')).sendKeys(user1.email);
// Enter Username
element(by.model('credentials.username')).sendKeys(user1.username);
// Enter Invalid Password
element(by.model('credentials.password')).sendKeys('p@$$w0rd!!');
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must contain at least one uppercase letter.');
});
it('Should report a password with less than one number - "P@$$word!!"', function () {
browser.get('http://localhost:3001/authentication/signup');
// Enter First Name
element(by.model('credentials.firstName')).sendKeys(user1.firstName);
// Enter Last Name
element(by.model('credentials.lastName')).sendKeys(user1.lastName);
// Enter Email
element(by.model('credentials.email')).sendKeys(user1.email);
// Enter Username
element(by.model('credentials.username')).sendKeys(user1.username);
// Enter Invalid Password
element(by.model('credentials.password')).sendKeys('P@$$word!!');
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must contain at least one number.');
});
it('Should report a password with less than one special character - "Passw0rdss"', function () {
browser.get('http://localhost:3001/authentication/signup');
// Enter First Name
element(by.model('credentials.firstName')).sendKeys(user1.firstName);
// Enter Last Name
element(by.model('credentials.lastName')).sendKeys(user1.lastName);
// Enter Email
element(by.model('credentials.email')).sendKeys(user1.email);
// Enter Username
element(by.model('credentials.username')).sendKeys(user1.username);
// Enter Invalid Password
element(by.model('credentials.password')).sendKeys('Passw0rdss');
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must contain at least one special character.');
});
it('Should Successfully register new user', function () {
browser.get('http://localhost:3001/authentication/signup');
// Enter FirstName
element(by.model('credentials.firstName')).sendKeys(user1.firstName);
// Enter LastName
element(by.model('credentials.lastName')).sendKeys(user1.lastName);
// Enter Email
element(by.model('credentials.email')).sendKeys(user1.email);
// Enter UserName
element(by.model('credentials.username')).sendKeys(user1.username);
// Enter Password
element(by.model('credentials.password')).sendKeys(user1.password);
// Click Submit button
element(by.css('button[type="submit"]')).click();
expect(browser.getCurrentUrl()).toEqual('http://localhost:3001/');
});
it('Should report Email already exists', function () {
// Make sure user is signed out first
signout();
// Signup
browser.get('http://localhost:3001/authentication/signup');
// Enter First Name
element(by.model('credentials.firstName')).sendKeys(user2.firstName);
// Enter Last Name
element(by.model('credentials.lastName')).sendKeys(user2.lastName);
// Enter Email
element(by.model('credentials.email')).sendKeys(user1.email);
// Enter Username
element(by.model('credentials.username')).sendKeys(user2.username);
// Enter Invalid Password
element(by.model('credentials.password')).sendKeys(user2.password);
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Error
expect(element.all(by.css('strong')).get(0).getText()).toBe('Email already exists');
});
it('Should report Username already exists', function () {
// Signup
browser.get('http://localhost:3001/authentication/signup');
// Enter First Name
element(by.model('credentials.firstName')).sendKeys(user2.firstName);
// Enter Last Name
element(by.model('credentials.lastName')).sendKeys(user2.lastName);
// Enter Email
element(by.model('credentials.email')).sendKeys(user2.email);
// Enter Username
element(by.model('credentials.username')).sendKeys(user1.username);
// Enter Invalid Password
element(by.model('credentials.password')).sendKeys(user2.password);
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Error
expect(element.all(by.css('strong')).get(0).getText()).toBe('Username already exists');
});
});
describe('Signin Validation', function () {
it('Should report missing credentials', function () {
//Make sure user is signed out first
signout();
//Sign in
browser.get('http://localhost:3001/authentication/signin');
// Click Submit button
element(by.css('button[type="submit"]')).click();
// Username Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('Username is required.');
// Password Error
expect(element.all(by.css('.error-text')).get(1).getText()).toBe('Password is required.');
});
it('Verify that the user is logged in', function() {
//Make sure user is signed out first
signout();
//Sign in
browser.get('http://localhost:3001/authentication/signin');
// Enter UserName
element(by.model('credentials.username')).sendKeys(user1.username);
// Enter Password
element(by.model('credentials.password')).sendKeys(user1.password);
// Click Submit button
element(by.css('button[type="submit"]')).click();
expect(browser.getCurrentUrl()).toEqual('http://localhost:3001/');
});
});
describe ('Change Password Settings Validation', function () {
it('Should report missing passwords', function () {
browser.get('http://localhost:3001/settings/password');
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Errors
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('Your current password is required.');
expect(element.all(by.css('.error-text')).get(1).getText()).toBe('Enter a new password.');
expect(element.all(by.css('.error-text')).get(2).getText()).toBe('Verify your new password.');
});
it('Should report a password with less than 10 characters long - "P@$$w0rd!"', function () {
browser.get('http://localhost:3001/settings/password');
// Enter Current Password
element(by.model('passwordDetails.currentPassword')).sendKeys(user1.password);
// Enter Invalid Password
element(by.model('passwordDetails.newPassword')).sendKeys('P@$$w0rd!');
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must be at least 10 characters long.');
});
it('Should report a password with greater than 128 characters long.', function () {
browser.get('http://localhost:3001/settings/password');
// Enter Current Password
element(by.model('passwordDetails.currentPassword')).sendKeys(user1.password);
// Enter Invalid Password
element(by.model('passwordDetails.newPassword')).sendKeys(')!/uLT="lh&:`6X!]|15o!$!TJf,.13l?vG].-j],lFPe/QhwN#{Z<[*1nX@n1^?WW-%_.*D)m$toB+N7z}kcN#B_d(f41h%w@0F!]igtSQ1gl~6sEV&r~}~1ub>If1c+');
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must be fewer than 128 characters.');
});
it('Should report a password with more than 3 or more repeating characters - "P@$$w0rd!!!"', function () {
browser.get('http://localhost:3001/settings/password');
// Enter Current Password
element(by.model('passwordDetails.currentPassword')).sendKeys(user1.password);
// Enter Invalid Password
element(by.model('passwordDetails.newPassword')).sendKeys('P@$$w0rd!!!');
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password may not contain sequences of three or more repeated characters.');
});
it('Should report a password with no uppercase letters - "p@$$w0rd!!"', function () {
browser.get('http://localhost:3001/settings/password');
// Enter Current Password
element(by.model('passwordDetails.currentPassword')).sendKeys(user1.password);
// Enter Invalid Password
element(by.model('passwordDetails.newPassword')).sendKeys('p@$$w0rd!!');
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must contain at least one uppercase letter.');
});
it('Should report a password with less than one number - "P@$$word!!"', function () {
browser.get('http://localhost:3001/settings/password');
// Enter Current Password
element(by.model('passwordDetails.currentPassword')).sendKeys(user1.password);
// Enter Invalid Password
element(by.model('passwordDetails.newPassword')).sendKeys('P@$$word!!');
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must contain at least one number.');
});
it('Should report a password with less than one special character - "Passw0rdss"', function () {
browser.get('http://localhost:3001/settings/password');
// Enter Current Password
element(by.model('passwordDetails.currentPassword')).sendKeys(user1.password);
// Enter Invalid Password
element(by.model('passwordDetails.newPassword')).sendKeys('Passw0rdss');
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must contain at least one special character.');
});
it('Should report passwords do not match', function () {
browser.get('http://localhost:3001/settings/password');
// Enter Current Password
element(by.model('passwordDetails.currentPassword')).sendKeys(user1.password);
// Enter New Password
element(by.model('passwordDetails.newPassword')).sendKeys('P@$$w0rds!!');
// Verify New Password
element(by.model('passwordDetails.verifyPassword')).sendKeys(user1.password);
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Errors
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('Passwords do not match.');
});
it('Should change the password to - "P@$$w0rds!!"', function () {
browser.get('http://localhost:3001/settings/password');
// Enter Current Password
element(by.model('passwordDetails.currentPassword')).sendKeys(user1.password);
// Enter New Password
element(by.model('passwordDetails.newPassword')).sendKeys('P@$$w0rds!!');
// Verify New Password
element(by.model('passwordDetails.verifyPassword')).sendKeys('P@$$w0rds!!');
// Click Submit button
element(by.css('button[type=submit]')).click();
// Password Changed
expect(element.all(by.css('.text-success')).get(0).getText()).toBe('Password Changed Successfully');
});
});
});