在使用 Cucumber / Selenium 进行测试时登录时 Meteor 应用程序挂起
Meteor app hangs when logging in when testing with Cucumber / Selenium
我是 Cucumber 和 Velocity 的新手,想测试注册用户的登录流程。当用户登录时,加载微调器就永远挂在那里。 Meteor.loggingIn()
returns false
。我可以在 meteor-cucumber
集合中看到用户,如果我输入任何虚假的电子邮件和密码,它会立即提醒我登录尝试失败。
这是我的一部分 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
这是我的步骤定义:
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", "xdzcaslm@sharklasers.com");
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');
});
以下是相关的 Meteor 方法:
Meteor.methods({
_createUser: function() {
return Accounts.createUser({
username: "PMoons",
email: "xdzcaslm@sharklasers.com",
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({});
}
});
这是应用程序中的登录逻辑:
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');
}
});
}
});
如有任何帮助,我们将不胜感激。
不确定这是否对您有帮助,但这是我的一组步骤定义,并且效果很好。不用担心 this.client
和 client
之间的区别。最后我检查了一下,我的 xolvio:cucumber
版本坏了,client
停止工作了。我想如果你看看下面的内容并借鉴它,你应该能够让你的测试工作。
编辑:这些可能会得到改进。我没有像我应该的那样等待输入字段出现。
this.Given(/^I am on the site$/, function () {
this.client.url(process.env.ROOT_URL);
});
this.Given(/^my account exists$/, function () {
server.call('createTestAccount');
});
this.Given(/^I am not currently logged in$/, function () {
this.client.executeAsync(function (done) {
Meteor.logout(done);
});
});
this.Given(/^I am on the login page$/, function () {
this.client.url(process.env.ROOT_URL + 'artist/login');
});
this.When(/^I correctly fill out the form and click submit$/, function () {
this.client.setValue('#email', 'test@user.com');
this.client.setValue('#password', 'test123');
this.client.submitForm('#login-form');
});
this.Then(/^I am logged in and redirected to the artist dashboard$/, function () {
var client = this.client;
client.waitUntil(function () {
return client.url().value === process.env.ROOT_URL + 'artist/dashboard';
});
});
然后是其他一些额外内容:
/tests/cucumber/features/support/hooks.js
module.exports = function () {
this.Before(function () {
server.call('reset');
});
};
/tests/cucumber/fixtures/user-fixtures.js
Meteor.methods({
'reset': function () {
Meteor.users.remove({});
},
'createTestAccount': function () {
Accounts.createUser({
email: 'test@user.com',
password: 'test123',
profile: {
firstName: 'Test',
lastName: 'User'
}
});
},
'isLoggedIn': function () {
return !!Meteor.userId();
}
});
所以我在查看我的 router.js
文件后发现了问题的解决方案。事实证明,当我在常规应用程序中注册用户时,会在登录时引用的用户对象中设置一个字段,以确定用户应该去哪里。我的 fixture.js
_createUser
Meteor 方法中未设置此字段。因此,当测试为 运行 并且在没有此特定字段的情况下创建用户时,用户会不断被重定向回 /login
。
对我来说,这是一个很好的例子,说明为什么测试很重要,因为它让人质疑为什么该字段首先在注册时设置,而不是后来在应用程序中设置。
我是 Cucumber 和 Velocity 的新手,想测试注册用户的登录流程。当用户登录时,加载微调器就永远挂在那里。 Meteor.loggingIn()
returns false
。我可以在 meteor-cucumber
集合中看到用户,如果我输入任何虚假的电子邮件和密码,它会立即提醒我登录尝试失败。
这是我的一部分 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
这是我的步骤定义:
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", "xdzcaslm@sharklasers.com");
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');
});
以下是相关的 Meteor 方法:
Meteor.methods({
_createUser: function() {
return Accounts.createUser({
username: "PMoons",
email: "xdzcaslm@sharklasers.com",
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({});
}
});
这是应用程序中的登录逻辑:
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');
}
});
}
});
如有任何帮助,我们将不胜感激。
不确定这是否对您有帮助,但这是我的一组步骤定义,并且效果很好。不用担心 this.client
和 client
之间的区别。最后我检查了一下,我的 xolvio:cucumber
版本坏了,client
停止工作了。我想如果你看看下面的内容并借鉴它,你应该能够让你的测试工作。
编辑:这些可能会得到改进。我没有像我应该的那样等待输入字段出现。
this.Given(/^I am on the site$/, function () {
this.client.url(process.env.ROOT_URL);
});
this.Given(/^my account exists$/, function () {
server.call('createTestAccount');
});
this.Given(/^I am not currently logged in$/, function () {
this.client.executeAsync(function (done) {
Meteor.logout(done);
});
});
this.Given(/^I am on the login page$/, function () {
this.client.url(process.env.ROOT_URL + 'artist/login');
});
this.When(/^I correctly fill out the form and click submit$/, function () {
this.client.setValue('#email', 'test@user.com');
this.client.setValue('#password', 'test123');
this.client.submitForm('#login-form');
});
this.Then(/^I am logged in and redirected to the artist dashboard$/, function () {
var client = this.client;
client.waitUntil(function () {
return client.url().value === process.env.ROOT_URL + 'artist/dashboard';
});
});
然后是其他一些额外内容:
/tests/cucumber/features/support/hooks.js
module.exports = function () {
this.Before(function () {
server.call('reset');
});
};
/tests/cucumber/fixtures/user-fixtures.js
Meteor.methods({
'reset': function () {
Meteor.users.remove({});
},
'createTestAccount': function () {
Accounts.createUser({
email: 'test@user.com',
password: 'test123',
profile: {
firstName: 'Test',
lastName: 'User'
}
});
},
'isLoggedIn': function () {
return !!Meteor.userId();
}
});
所以我在查看我的 router.js
文件后发现了问题的解决方案。事实证明,当我在常规应用程序中注册用户时,会在登录时引用的用户对象中设置一个字段,以确定用户应该去哪里。我的 fixture.js
_createUser
Meteor 方法中未设置此字段。因此,当测试为 运行 并且在没有此特定字段的情况下创建用户时,用户会不断被重定向回 /login
。
对我来说,这是一个很好的例子,说明为什么测试很重要,因为它让人质疑为什么该字段首先在注册时设置,而不是后来在应用程序中设置。