The solution I ended up finding involved using grunt and writing some custom grunt tasks. The process goes like this:
Create a grunt task to build a bootstrap requirejs file by finding all specs using a file pattern, looping through them and building out a traditional AMD style require block and creating a temporary file with code like this:
require(['spec/example1_spec.js'
,'spec/example2_spec.js',
,'spec/example3_spec.js'
],function(a1,a2){
// this space intentionally left blank
}, "", true);
Create a RequireJS grunt task that compiles the above bootstrap file and outputs a single js file that will effectively include all source code, specs, and libraries.
requirejs: { tests: { options: { baseUrl: './test', paths: {}, // paths object for libraries shim: {}, // shim object for non-AMD libraries // I pulled in almond using npm name: '../node_modules/almond/almond.min', // This is the file we created above include: 'tmp/require-tests', // This is the output file that we will serve to karma out: 'test/tmp/tests.js', optimize: 'none', // This translates commonjs syntax to AMD require blocks cjsTranslate: true } } }
Create a grunt task that manually starts a karma server and serve the single compiled js file that we now have for testing.
Additionally, I was able to ditch the REQUIRE_ADAPTER
in the karma.conf.js
file and then only include the single compiled js file instead of the patterns that matched all source code and specs, so it looks like this now:
// base path, that will be used to resolve files and exclude
basePath = '';
// list of files / patterns to load in the browser
files = [
JASMINE,
JASMINE_ADAPTER,
REQUIRE,
'tmp/tests.js'
];
// list of files to exclude
exclude = [];
// test results reporter to use
// possible values: 'dots', 'progress', 'junit'
reporters = ['progress'];
// web server port
port = 9876;
// cli runner port
runnerPort = 9100;
// enable / disable colors in the output (reporters and logs)
colors = true;
// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel = LOG_INFO;
// enable / disable watching file and executing tests whenever any file changes
autoWatch = true;
// Start these browsers, currently available:
browsers = ['PhantomJS'];
// If browser does not capture in given timeout [ms], kill it
captureTimeout = 60000;
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun = true;
In the grunt task configuration for the requirejs compilation, it was also necessary to use almond in order to start the test execution (test execution would hang without it). You can see this used in the requirejs grunt task config above.