Camilo
Camilo

Reputation: 2853

How to test Meteor router or Iron router with laika

I'm using laika for testing and the meteor-router package for routing. I want to do tests that navigate to some page, fill a form, submit it and check for a success message, but I'm stuck on the navigation part. This was my first attempt:

var assert = require('assert');

suite('Router', function() {
  test('navigate', function(done, server, client) {
    client.eval(function() {
      Meteor.Router.to('test');
      var title = $('h1').text();
      emit('title', title);        
    })
    .once('title', function(title) {
      assert.equal(title, 'Test');
      done();
    });
  });
});

This doesn't work because Meteor.Router.to doesn't have a callback and I don't know how to execute the next line when the new page is loaded.

I tried also with something like this

var page = require('webpage').create();

page.open('http://localhost:3000/test', function () { 
  ... 
}

but I got the error Error: Cannot find module 'webpage'

Edit

I'm moving to iron router, so any answer with that also will be helpful.

Upvotes: 5

Views: 504

Answers (2)

JJJ
JJJ

Reputation: 33153

Laika now includes a waitForDOM() function you can set up to wait for a specific DOM element to appear, which in this case would be an element in the page you're loading.

client.eval(function() {
    Router.go( 'test' );
    waitForDOM( 'h1', function() {
        var title = $('h1').text();
        emit( 'title', title ); 
    });
});

The first parameter is a jQuery selector.

Upvotes: 0

user3252261
user3252261

Reputation: 779

I had the same problem. I needed to navigate to some page before running my tests. I'm using iron router as well. I figured you can't just execute Router.go('foo') and that's it. You need to wait until the actual routing took place. Fortunately the router exposes a method Router.current() which is a reactive data source that will change as soon as your page is ready. So, in order to navigate to a specific route before running my tests, I firstly run the following code block:

// route to /some/path
client.evalSync(function() {
    // react on route change
    Deps.autorun(function() {
        if (Router.current().path == '/some/path') {
            emit('return');
            this.stop();
        }
    });
    Router.go('/some/path');
});

Since this is within an evalSync()everything that follows this block will be executed after the routing has finished.
Hope this helps.

Upvotes: 0

Related Questions