The right way to handle authentication and authorization in Cucumber for Meteor?

I am getting started adding Cucumber testing to a Meteor boilerplate package I want to use, but I am very frustrated with authentication. I seem to need to login for every When, And and Then phrase in every scenario. Is that correct?

What is the correct place to automate the login sequence?

Where can I read an authoritative explanation of dealing with authentication and authorization in Cucumber for Meteor?

1 Like

You shouldn’t have to login for every when and then for sure. The right place is to create a user using a fixture and then login with webdriver.executeAsync(), where you can login in the browser.

The place to do that is in a background step if you want it in all scenarios in a feature, or in individual scenarios.

You can read about it eventually in my book, and the code will be freely available in Letterpress soon.

Yes, picking through the mess I created I realized that one login per scenario is the only thing that makes sense.

I’ve been dunked by several other “too obvious to mention” wobbly stepping-stones :

  • If you restart Meteor, the IP address of the mirror changes (duh!)
  • Cucumber creates its own database copy, so its changes don’t show up in the SUT’s database
  • client-side console.log stuff ain’t gonna show up anywhere if you’re using PhantomJS.
  • (I’ll add more as I remember them)

But! I do have another conceptual question:

Do scenarios run in order, dependably, in order of appearance? Is it legitimate to create a collection in one scenario, with confidence that it will be there as raw material for the next scenario? And … how about from feature to feature?

Short answer, never!

Scenarios (and therefore features) should be completely independent. That’s the best practice, to focus on one part of the journey at a time

@sam love the book so far. Also +1 for having one of the examples be setting up logged in status properly in a Background step.

It seems that 95%+ of my features are for logged on users. I would guess that is fairly common so it would certainly be useful to see how to handle that properly.

Right now I see

But then my mind goes blank when actually trying to imagine how to use webdriver.executeAsync() to do a login while using the useraccounts package within a Background

I’m on it, I promise! I’m working on cucumber 0.7.0 to come out in the next few days, then it’s book time!

I don’t want to leave you empty handed though, so here’s how to do it:

// Feature file
Background
  Given Tom has logged in
// Steps definition file
this.Given(/"([^"]*)" has logged in/, function(name, calback) {

   // 1. create a user
   var userData = {email: name + '@example.com', password: 'abc123456'};
  _createUser(userData, function(createdUser) {

    // 2. Login with that user
    browser.executeAsync(function (user, done) {
      // this code is run in the browser 
      Meteor.loginWithPassword(user.email, user.password, done); // done is what tells the async function to finish
      }, createdUser). // createdUser is passed in as a param to executeAsync
      // 3. Wait for the UI to react
      waitForExist('.logged-in-indicator', true).
      call(callback);

  });

});

function _createUser(user, callback) {
  global.ddp.call('fixtures/user/create', [user], function () {
    callback(user);
  });
}
// Fixture package - see here http://goo.gl/1CvTTa
Meteor.methods({
  resetTestingEnvironment: resetTestingEnvironment,
  'fixtures/user/create': function() {
     return Accounts.createUser(user);
  }
});

Ironically, this is untested code :smile:

1 Like

hey if there are a few bugs, no worries! I was hoping for some general direction so I can’t exactly complain when you give me a map. Thanks a bunch and when I get back on implementing these tests I’ll report back in case of any bugs.

@funkyeah

I’ve written a little package that aids in testing apps with authentication. Take a look: https://github.com/cjsauer/accounts-phony.

There’s some code in the readme that should help you get started. Let me know if you have any problems.

2 Likes

For anyone else who comes across this, ChimpJS has a synchronous API so this is even easier now, especially with accounts-phony, but some of these code samples won’t work without modification.

Readme updated. Thanks for pointing this out.