I had meteor-cucumber previously be setup in a similar way where it ran inside the app, but I later moved it to be outside. From a philosophical point of view, I like to keep galvanic isolation between test-code and the system under test (SUT). Mainly because the tests should act like the consumer acts on the SUT. But I understand that everyone has their preference of course!
I really like the Widgets in Pioneer and Sanjo and I are talking about borrowing them We already do far too much stuff with starting phantom/selenium/saucelabs/appium to move away from our cuke-monkey library, so we’ll see if there’s a good integration point. Another option I was considering lately is to allow the user to specify the cucumber runner, so they can use cucumberjs or pioneerjs and still get the benefits of cuke-monkey.
I totally agree that you shouldn’t have to click on each and every step and you need to quickly get setup to be able to test the thing you’re interested in.
There are two good patterns we use for keeping test code private. The first is using fixture files. These files are loaded into the mirror only by Velocity from the /tests/FRAMEWORK/anything-fixture.(js|coffee)
. This pattern is the quick and easy option, but there’s a far more powerful pattern which is to use debugOnly
packages. These will not get bundled by Meteor which means they stay out of production, but still have full access to your app. See here.
By using these fixture packages, the same email mocking code you have above can be used by your Jasmine tests as well as your cucumber test, which is a genuine use-case for DRYing up your test code.
To answer your question, here’s how I would do what you’ve done with a complete galvanic isolation:
The package xolvio:inbox-stub is a debugOnly
package that overrides the Email.send
like you have (but only in the mirror) and provides DDP endpoints for control. See the code here.
So after you add the package, you can now in your hooks say something like:
disclaimer: I’m only using coffee to be nice so don’t judge me, I never use coffeescript!
@Before '@email', ->
@mirror.call 'resetInbox'
and in your scenarios:
@When /^I enter my email and click subscribe$/, ->
@browser.type('#email', 'hello@there.com').click('#subscribe')
@Then /^I should receive a welcome email$/, ->
@mirror.call('getEmailsFromInboxStub').should.eventually.contain 'Welcome to Prisma!'
Isn’t that clean?
With meteor-cucumber we actually a promisified both cucumber and the node DDP client, and baked in chai-as-promised, this allows us to do cool stuff like the syntax above without callbacks. Just returning the mirror.call is enough.
Of course you can also chain the mirror.call
with another method that uses the returned objects directly so that you don’t have to throw ids around.
The combination of mirror DDP + fixture packages pattern + promises everywhere = a great mix for clean reusable test code.
I’m super happy that you want to integrate with Velocity, I’ll contact you privately and we can have a hangout to discuss.