New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mocha-helper is being injected after `mocha.run` is called #5

Closed
mklabs opened this Issue Jul 5, 2012 · 6 comments

Comments

Projects
None yet
2 participants
@mklabs

mklabs commented Jul 5, 2012

Hi there,

I've been playing a bit with grunt-mocha and wasn't able to get it working.

I'm using the latest mocha (1.2.2), and got the typical timeout error.

After a bit of investigation, I managed to get it working but it required some changes to how the runner is hooked in the grunt / phantomjs system. I may also very well miss something simple.

I wasn't able to find any information on the mocha version grunt-mocha was designed to work for. Should I use the latest? Should I use a specific version?

It may be handy to write down this information somewhere. Also, maybe that a working example directly from within the repo might help a lot new users getting started quickly (as a reference, even though your gist is there and great to get a better idea).

Anyway, thanks for creating this plugin! It has been of great help.

@kmiyashiro

This comment has been minimized.

Owner

kmiyashiro commented Jul 5, 2012

Any version should work, I'm also using 1.2.2 and have been using it since 0.9.

If your tests are getting timeouts in grunt-mocha and not getting timeouts when you open your spec files in the browser, something's wrong.

You shouldn't have to do anything except create a valid HTML page that runs mocha. What changes did you have to make?

I'll try creating a simple example.

@kmiyashiro

This comment has been minimized.

Owner

kmiyashiro commented Jul 5, 2012

Argh, I see what's going on. The injected grunt reporter is being injected after mocha.run is invoked in the HTML. I guess using AMD slows it down enough (or async nature means inject is triggered earlier) that mocha.run is called after the injection. A hack would be to check for the PHANTOMJS flag I add to global and call mocha.run from the phantomjs runner, but I'd rather not add anything grunt/phantom specific to the HTML itself...

What did you end up doing?

@ghost ghost assigned kmiyashiro Jul 5, 2012

@kmiyashiro

This comment has been minimized.

Owner

kmiyashiro commented Jul 5, 2012

Annnd, I ended up working on this during lunch. I believe I have a fix, it may be broken for some edge case AMD uses, but it works for my use of AMD and normal usage.

@kmiyashiro kmiyashiro closed this in 1482b5a Jul 6, 2012

@mklabs

This comment has been minimized.

mklabs commented Jul 6, 2012

Great, let me try this out.

The injected grunt reporter is being injected after mocha.run is invoked in the HTML. I guess using AMD slows it down enough (or async nature means inject is triggered earlier) that mocha.run is called after the injection.

Indeed, while tying to debug, I saw the helper injection and tried to wrap the mocha.run in a slight setTimeout, to avoid this potential async issue. But no luck =( I was still unable to get mocha sending messages to grunt.

It may very well be specific to my system (CentOS6 during these tests, I'll check on other system too when I get the chance), but seems like the GruntReporter wasn't properly initialized by mocha.

What I ended up doing is pretty much what you wanted to avoid :) I get back the reference to the mocha runner, and listen for the same event than GruntReporter (and using the handy PHANTOMJS flag you expose), something like:

(function() {
  var runner = mocha.run();

  if(!window.PHANTOMJS) return;

  runner.on('test', function(test) {
    sendMessage('testStart', test.title);
  });

  runner.on('test end', function(test) {
    sendMessage('testDone', test.title, test.state);
  });

  runner.on('suite', function(suite) {
    sendMessage('suiteStart', suite.title);
  });

  runner.on('suite end', function(suite) {
    if (suite.root) return;
    sendMessage('suiteDone', suite.title);
  });

  runner.on('fail', function(test, err) {
    sendMessage('testFail', test.title, err);
  });

  runner.on('end', function() {
    var output = {
      failed  : this.failures,
      passed  : this.total - this.failures,
      total   : this.total
    };

    sendMessage('done', output.failed,output.passed, output.total);
  });

  function sendMessage() {
    var args = [].slice.call(arguments);
    alert(JSON.stringify(args));
  }
})();

I was thinking of some API changes in mocha that would have landed, and how the reporter are hooked in the system. That's why I initially though about a version mismatch. Note that I'm not familiar at all with custom reporters, so I may have missed something.

I'll try running your example and double-check a few things.

Thanks for taking the time to answer to my few questions :)

@mklabs

This comment has been minimized.

mklabs commented Jul 6, 2012

Okay, ended up using the tasks/mocha/mocha-helper.js instead of this custom runner.js. Works similarly.

The example and associated comment you had are very handy. Thanks again.

@kmiyashiro

This comment has been minimized.

Owner

kmiyashiro commented Jul 6, 2012

Cool. I tried something like your customized runner, but it looked like mocha.run being run twice on a page was actually only reporting every other test to grunt, not all of them. Very strange and I have no idea why.

It's true that GruntReporter is never set for mocha since mocha.run is called on the page before the injection occurs normally in PhantomJS. I tried injecting onResourceLoaded and stage=end for mocha.js, but apparently that's too early and PhantomJS has not evaluated mocha.js yet at that point... no idea why they would have an event like that. This isn't system specific.

In the end, including the grunt reporter as a helper is the most reliable for vanilla usage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment