Features
It’s real
laika
runs tests against your real running app. So It works everytime.
Isolated testing
each test runs on against a separate instance of your meteor
app and a clean mongodb
database.
Works with both meteor and meteorite
You can use meteor
or meteorite
as your development workflow. laika can work with both without any additional work for you.
evaluate codes on both server and client at once
You can evaluate codes at both the server and client on a single test. It helps to test unique meteor features like * permission * subscriptions * method calls
Example
test('using both client and the server', function(done, server, client) {
server.eval(function() {
Posts.find().observe({
added: addedNewPost
});
function addedNewPost(post) {
emit('post', post);
}
}).once('post', function(post) {
assert.equal(post.title, 'hello title');
done();
});
client.eval(function() {
Posts.insert({title: 'hello title'});
});
});
Tests with multiple clients
Meteor is all about realtime. So we need to test with multiple client. laika
simply allows you to test with unlimited
(theoretically) no of clients. See usage below.
test('using both client and the server', function(done, server, c1, c2, c3, c4) {
});
laika
will inspect no of arguments you specified and inject client
connector for each.
See example using multiple clients
EventEmitter like communication pattern between your test an evaluate code
Running a piece of code on the server or client and get the result is not ideal. It should be event based. So we’ve a event emitter like api pattern to communicate with the server and client.
Example
server.eval(function() {
emit('return', 10);
Meteor.setTimeout(function() {
emit('after-2-secs');
}, 2000);
});
server.once('return', function(value) {
assert.equal(value, 10);
});
server.once('after-2-secs', function() {
});
Pass runtime values to evaluated code
We can pass runtime values to evaluated code via arguments.
Example
server.eval(function(a, b) {
emit('sum', a + b);
}, 10, 20);
server.once('sum', function(value) {
assert.equal(value, 30);
});
Waiting for templates to render
If you’re using Iron Router, and doing end-to-end or UI tests, you might run into the problem that the UI elements you want to interact with aren’t in the DOM yet at the time your test runs.
You can asynchronously wait for a given element to be present, and only then emit your events. If you’re using jQuery, you can pass in any jQuery selector; otherwise, an element ID as a string in the CSS/jQuery format (#id
). Either way, you can also pass a test function that should return true once the element is detected.
Example
describe('Landing page', function() {
it('Should load for unauthenticated users', function(done, server, client) {
client.eval(function() {
waitForDOM('h1', function() {
emit('login-link-text', $('#login-sign-in-link').text());
var h1 = $('h1');
emit('h1-len', h1.length);
emit('full-text', $('body').text());
emit('return');
});
}).once('login-link-text', function(text) {
return assert.equal(text, 'Sign in ▾');
}).once('h1-len', function(len) {
return assert.equal(len, 1);
}).once('full-text', function(text) {
return assert.equal(text.match(/my games/i), null);
}).once('return', function() {
return done();
});
});
});