Search code examples
javascriptjqueryajaxtestingintern

Intern AJAX Unit Tests


I've run into a problem with how Intern runs tests, and attempting to test units that use AJAX calls with jQuery. Since Intern serves the test client to the WebDriver server (In this case phantomjs --webdriver=8910), I end up with tests running on localhost:9000. This obviously causes Same-Origin Policy problems.

I can get around this and make cross-domain requests, but once an authentication cookie is required I'm blocked because obviously our backend is not setting cookies for localhost, so I have no access to these cookies.

I've tried changing the proxyUrl option to point to our server in several different permutations, but so far nothing has worked:

https://my.server.com/
https://my.server.com/js/
https://my.server.com/js/intern/
https://my.server.com/js/intern/client.html
https://my.server.com/js/intern/client.html?config=tests/intern

Watching the WebDriver logs I've noticed that Intern tells the server to load http://localhost:9000/__intern/client.html?config=.... I've attempted to then set proxyUrl to https://my.server.com/js/ and symlink __intern to intern, but either the tests are not being run or they aren't being reported back to runner.js. The PhantomJS logs when I run this way look something like this:

[DEBUG - 2013-05-24T15:17:50.930Z] SessionReqHand - _postUrlCommand - Session '194ff0a0-c485-11e2-9c64-9986b0c95ae1' is about to load URL: https://my.server.com/js/__intern/client.html?config=tests%2Fintern&sessionId=194ff0a0-c485-11e2-9c64-9986b0c95ae1&reporters=webdriver
[DEBUG - 2013-05-24T15:17:50.943Z] Session [194ff0a0-c485-11e2-9c64-9986b0c95ae1] - _execFuncAndWaitForLoadDecorator - Page Loading in Session: true
[DEBUG - 2013-05-24T15:17:50.962Z] Session [194ff0a0-c485-11e2-9c64-9986b0c95ae1] - _oneShotCallback - onLoadFinished
[DEBUG - 2013-05-24T15:17:50.962Z] Session [194ff0a0-c485-11e2-9c64-9986b0c95ae1] - _execFuncAndWaitForLoadDecorator - onLoadFinished: success
[DEBUG - 2013-05-24T15:17:51.051Z] Session [194ff0a0-c485-11e2-9c64-9986b0c95ae1] - _execFuncAndWaitForLoadDecorator - Page Loading in Session: false
[DEBUG - 2013-05-24T15:17:51.051Z] Session [194ff0a0-c485-11e2-9c64-9986b0c95ae1] - _resetOneShotCallbacksDecorator
[DEBUG - 2013-05-24T15:17:51.052Z] SessionReqHand - _SuccessHandler - status: success
[DEBUG - 2013-05-24T15:17:51.184Z] Session [194ff0a0-c485-11e2-9c64-9986b0c95ae1] - page.onConsoleMessage - Tests complete

The test runner then hangs and never receives the results of the tests, however, since the proxyUrl is not pointed at the proxy server that Intern runs.

EDIT 5/28

It's worth mentioning that a lot of this can be circumvented through back end modifications (though ideally a test stack should be configurable to fit the code base, rather than forcing the code base to conform), but let's just say that in this case that's not an option.

Ideally I would want Intern to be configurable to load client.html from a specified URL, and then have the reporter POST to the localhost:9000 proxy via some cross-origin-compatible means, like JSONP. I can't find any other reasonable alternative, so it looks like at the moment Intern simply does not fully support unit tests that communicate with a back end through AJAX.


Solution

  • When you are changing the URL to the Intern proxy to point to another server, it needs to be a server that is actually proxying back to the Intern server that runs at localhost:9000. It can’t just be a plain Web server with a symlink to the Intern directory.

    Doing this is the same as any other sort of proxying to another backend (CouchDB, Apache, Node.js, whatever). For nginx, it means using the HttpProxyModule to proxy_pass http://localhost:9000/;. For Apache, mod_proxy and ProxyPass / http://localhost:9000/. Keep in mind that if you do not allow the Intern server to serve your JavaScript (i.e. you only proxy to __intern), you will not receive code coverage data, so it is best to proxy everything except the service URLs you are trying to test.

    More complete information on proxying to Intern to test Web services can be found on the wiki page Using Intern to unit test Ajax calls.