nathanboktae / mocha-phantomjs-core

Easiest way to run client-side Mocha tests in PhantomJS or SlimerJS :ghost:

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support for async loading of mocha.

jaridmargolin opened this issue · comments

nathanboktae/mocha-phantomjs#5 sheds a little light on my issue. Essentially using require.js, mocha won't immediately be available on the page. Using require.js mocha loads async.

page.onLoadFinished = function(status) {

page.onLoadFinished = function(status) {
  if (status !== 'success') {
    fail('Failed to load the page. Check the url: ' + url)
  } else if (!configured) {
    fail('Failed to run any tests.')
  }
}

I wanted to submit a PR, but I am not sure what the correct solution would actually be. Setting a arbitrary timeout may solve the issue but now the tests are not tolerant of poor connections. This solution would require mocha to be available on the page once the timeout expires. Repeatedly polling forever solves the latency issue but now a client without a mocha test suite will just hang forever as it waits for mocha to land on the page.

I have a few libraries that use grunt-moch-phantomjs, which now uses mocha-phantomjs-core. It would be great to find a solution.

Thanks.

hmm I've been using require.js and mocha together for years but never used it to load my tests. Is describe, it and all those globals available in that case? just curious.

Setting a arbitrary timeout may solve the issue but now the tests are not tolerant of poor connections.

That's what we had before with the mochaPhantomJS style. It also was creating lots of bugs because some options in mocha like timeout will get duplicated per tests as the tests load, so it could not set the timeout correctly. Now that mocha-phantomjs-core monkey patches it right away, it works correctly and transparently.

One solution is mocha-phantomjs-core could expose an API to call to explicitly do it's setup that you could call right after mocha is initialized... maybe. Does every test file you have do define(['mocha', ....], function() { .... ? the order would be undeterministic. You'd have to do something like

require(['mocha'], function(mocha) {
  if ('callPhantom' in window) {
     // notify mocha-phantomjs-core to initialize
  }
  require(['test1', 'test2', .....], function() {
    mocha.run()
  })
})

or you just put mocha in the page before requirejs and add <script>define('mocha', [], mocha)</script> and be done with it.

hmm I've been using require.js and mocha together for years but never used it to load my tests. Is describe, it and all those globals available in that case? just curious.

describe and it become available after loading mocha. Almost identical to what you have shown in your example. My current setup looks like:

require(['mocha'], function(mocha) {
  require(['test1', 'test2', .....], function() {
    mocha.run()
  })
})

or you just put mocha in the page before requirejs and add <script>define('mocha', [], mocha)</script> and be done with it.

Maybe the easiest way to get back up and running?

Yeah you could have this code wrap itself in an initMocha function to call if Mocha and mocha are not defined yet, then your code can call that initMocha function after it requires mocha. I believe the code in the original post would need some modification still with some timer... hmm

Maybe the easiest way to get back up and running?

Yes.

So I have resolved the core of this by allowing mocha-phantomjs-core a timeout before failing the tests due to mocha.run() not being called. (I realized this also allowed for an infinite hang without the code so it was much needed!). However, browser-shim attempts to monkey-patch mocha, and if it's loaded with require.js, the require.js callback fires first before mocha-phantomjs so it's not patched before my test case was doing it. So you'll need to load mocha.js as a direct script tag. You could call callPhantom({ configureMocha: true }) directly yourself too, however I can't guarantee the support of this going forward.

Also mocha isn't an AMD module anyways, so you don't gain anything. Moreover, I highly recommend your tests be templated in the .html file by a server-side process so that when you write a new tests, you don't run the risk of it not being included. Even without that, wrapping your tests in define calls is unnessecary boilerplate. I also found out chai registers as a named module so loading it dynamically is not possible unless you put it in your requirejs config, then you're putting test config with your production... Anyways you're bundling for production, right? You should be running tests on minified, bundled code too to catch those bugs you won't otherwise see at developing locally. I love require.js and have been using it for years but there is nothing to gain and lots to loose by using it for tests and test dependencies.