在使用Cucumber / Selenium进行测试时登录时,Meteor app会挂起

时间:2015-11-18 16:36:55

标签: selenium meteor cucumber meteor-velocity

我是Cucumber和Velocity的新手,想要测试注册用户的登录流程。当用户登录时,加载微调器就会永远挂起。 Meteor.loggingIn()返回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');
            }
        });
    }
});

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

不确定这是否对您有所帮助,但这是我的一组步骤定义,它完美无缺。不要担心this.clientclient之间的区别。最后我查了一下,我的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();
  }
});

答案 1 :(得分:0)

所以我在浏览router.js文件后发现了问题的解决方案。事实证明,当我在常规应用程序中注册用户时,在登录时引用的用户对象中设置字段以确定用户应该去哪里。我的fixture.js _createUser Meteor方法中未设置此字段。因此,当运行测试并且创建没有此特定字段的用户时,用户将继续重定向回/login

对我来说,这是一个很好的例子,说明为什么测试很重要,因为它会让人质疑为什么该字段首先在注册时设置,而不是在应用程序中设置的位置。