I am new to Cucumber and Velocity and want to test the login flow for a registered user. When the user logs in, the loading spinner just hangs there forever. Meteor.loggingIn()
returns false
. I can see the user in meteor-cucumber
collection and if I type in any fake email & password, it instantly alerts me that the login attempt failed.
Here is a part of my login-user.feature
Background:
Given the user database is reset
And the user is logged out
And the user is at '/login'
@dev
Scenario: a registered user with a verified email address wants to login
Given the user is registered and verified
When the user has entered the required login information
And the clicks the "Login" button
Then the user will be viewing the 'story-of-the-day' template
And here are my step definitions:
this.Given(/^the user database is reset$/, function () {
server.call('_clearUsers');
});
this.Given(/^the user is logged out$/, function () {
server.call('_logout');
});
this.When(/^the user is at '\/login'$/, function () {
client.url(path.join(process.env.ROOT_URL, '/login'));
client.waitForExist('.template-login');
});
this.Given(/^the user is registered and verified$/, function () {
userID = server.call('_createUser');
expect(userID).toBeDefined();
var result = server.call('_setVerifiedEmail', userID);
expect(result).toBe(1);
});
this.When(/^the user has entered the required login information$/, function () {
client.setValue("#login-email", "[email protected]");
client.setValue("#login-password", "Password123");
});
this.When(/^the clicks the "([^"]*)" button$/, function () {
client.submitForm("form");
});
this.Then(/^the user will be viewing the 'story\-of\-the\-day' template$/, function () {
client.waitForExist('.template-story-of-the-day');
});
Here are the relevant Meteor methods:
Meteor.methods({
_createUser: function() {
return Accounts.createUser({
username: "PMoons",
email: "[email protected]",
password: "Password123",
profile: {
first_name: "Peter",
last_name: "Mooney"
}
});
},
_getUserID: function() {
return Meteor.users.findOne()._id;
},
_sendVerificationEmail: function(userID) {
Accounts.sendVerificationEmail(userID);
},
_getVerificationToken: function(userID) {
return Meteor.users.findOne(userID).services.email.verificationTokens[0].token;
},
_setVerifiedEmail: function(userID) {
return Meteor.users.update({'_id': userID}, {$set: {'emails.0.verified': true}});
},
_logout: function() {
Meteor.users.update({}, {$set: { "services.resume.loginTokens" : [] }});
},
_clearUsers: function() {
Meteor.users.remove({});
}
});
And here is the login logic in the app:
Template.login.events({
'submit form': function(event, template) {
event.preventDefault();
$(event.target).blur();
var email = template.find('#login-email').value;
var password = template.find('#login-password').value;
Meteor.loginWithPassword(email, password, function(error){
if(error){
alert('Login attempt failed. Please try again.');
} else {
Router.go('/dashboard');
}
});
}
});
Any help would be greatly appreciated.
So I discovered the solution to the problem after poking around my router.js
file. It turns out when I register a user in the regular app, a field gets set in the user object that is referenced upon login to determine where the user should go. This field was not set in my fixture.js
_createUser
Meteor method. Therefore when the test is run and the user is created without this specific field, the user keeps getting redirected back to /login
.
For me, this was a good example of why testing is important because it brought into question why that field was being set at registration in the first place and not later on in the app where it should be.