I am using angular-http-auth and the example from http://witoldsz.github.io/angular-http-auth/ to display my login form.
Here is the index.html page:
<!DOCTYPE html>
<html ng-app="rdx">
<head>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
<link rel="stylesheet" href="css/styles.css">
</head>
<body class="auth">
<div id="login-holder" style="display:none">
<div id="loginbox">
<div id="login-inner" ng-controller="UserController">
<div class="row">
<div class="col-sm-6 col-sm-offset-2">
<div class="page-header"><h1>Please Sign In</h1></div>
<div ng-if="message" class="panel panel-danger">
<div class="panel-heading">Error</div>
<div class="panel-body">{{message}}</div>
</div>
<form name="form" ng-submit="submit()">
<div class="form-group">
<label class="control-label">Username</label>
<input class="form-control" ng-model="user.username" type="text" name="username" placeholder="Username" />
</div>
<div class="form-group">
<label class="control-label">Password</label>
<input class="form-control" ng-model="user.password" type="password" name="password" placeholder="Password" />
</div>
<input id="login-button" class="btn btn-primary" type="submit" value="Login" />
</form>
</div>
</div>
<div class="clear"></div>
</div>
</div>
</div>
<div id="content">
<nav class="navbar navbar-inverse" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" href="#">AngularRDX</a>
</div>
<ul class="nav navbar-nav">
<li ng-class="{ active: $state.includes('cases') }"><a ui-sref="cases.list">Cases</a></li>
<li ng-class="{ active: $state.current.name == 'about' }"><a ui-sref="about">About</a></li>
</ul>
<p ng-if="user.name" class="navbar-text navbar-right">Signed in as {{user.name}}</p>
</nav>
<div class="container">
<div ui-view>
</div>
</div>
</div>
<script src="angular/angular.js"></script>
<script src="angular-ui-router/release/angular-ui-router.js"></script>
<script src="angular-animate/angular-animate.js"></script>
<script src="angular-http-auth/src/http-auth-interceptor.js"></script>
<script src="jquery/dist/jquery.js"></script>
<script src="js/app.js"></script>
</body>
</html>
It's handled in a directive like this:
angular.module('rdx.auth')
.directive('auth', function() {
return {
restrict: 'C',
link: function(scope, elem, attrs) {
var login = $('#login-holder');
var main = $('#content');
scope.$on('event:auth-loginRequired', function() {
login.slideDown('slow', function() {
main.hide();
});
scope.$on('event:auth-loginConfirmed', function() {
main.show();
login.slideUp();
});
}
}
});
In my Protactor test I trigger the login event by clicking on a menu item that makes a http request that is protected. The server responds with a 401 and angular-http-auth broadcasts the event event:auth-loginRequired
handled above.
it('should require a login and then display the list of cases', function() {
browser.get('/');
var usernameInput = element(by.model('user.username'));
var passwordInput = element(by.model('user.password'));
element(by.css('.navbar ul li')).click();
expect(element(by.model('user.username')).isPresent()).toBe(true);
//browser.sleep(500);
usernameInput.sendKeys('admin');
passwordInput.sendKeys('doit');
element(by.id('login-button')).click();
expect(element(by.css('.page-header')).isPresent()).toBe(true);
var elems = element(by.repeater('c in cases').column('{{c.name}}'));
expect(elems.getText()).toEqual('bob');
});
Test fails:
==== async task ====
WebElement.sendKeys([object Object])
==== async task ====
Asynchronous test function: it("should require a login and then display the list of cases")
Error
at null.<anonymous> (/Users/csturm/dev/node/angularjs/rdx/test/e2e/cases.js:23:21)
Line 23 is: usernameInput.sendKeys('admin');
This test will work if I uncomment the browser.sleep(500)
.. I believe this is because the jquery slideDown
in the directive has completed by then.
Is there another way I can do this without the sleep? Can I use angular animate instead or somehow block the test until the event:auth-loginRequired
is handled?