Search code examples
angularkarma-jasmineshim

Invalid System.register call when setting up Karma with angular2


I'm trying to setup karma on an Angular2 project and I'm attempting to reference the angular2 quickstart which runs karma with jasmine successfully.

So far I've imported the karma-test-shim, modified my karma.conf.js file to what I believe I need. I believe I am pulling in the tests successfully but karma complains with this error

Uncaught TypeError: Invalid System.register call. Anonymous System.register calls can only be made by modules loaded by SystemJS.import and not via script tags.

Here are the shim and configure file

karma.conf.js

module.exports = function(config) {
var client = './src/client/',
    clientApp = client + 'app/';

config.set({
    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: './',

    // frameworks to use
    // some available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],

    plugins:[
        require('karma-jasmine'),
        require('karma-phantomjs-launcher'),
        require('karma-chrome-launcher'),
        require('karma-htmlfile-reporter')
    ],

    // list of files / patterns to load in the browser
    files: [
        'node_modules/systemjs/dist/system.src.js',

        //Polyfills
        'node_modules/es6-shim/es6-shim.min.js',
        'node_modules/systemjs/dist/system-polyfills.js',

        // Reflect and Zone.js dependencies

        'node_modules/reflect-metadata/Reflect.js',
        'node_modules/zone.js/dist/zone.js',
        'node_modules/zone.js/dist/jasmine-patch.js',
        'node_modules/zone.js/dist/async-test.js',
        'node_modules/zone.js/dist/fake-async-test.js',

        // RxJs.
        {pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false},
        {pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false},

        //paths loaded by module loaders
        {pattern: 'node_modules/@angular/**/*.js', included: false, watched: false},
        {pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: false},

        {pattern: 'systemjs.config.js', included: false, watched: false},

        {pattern: 'karma-test-shim.js', included: false, watched: false},

        // transpiled application & spec code paths loaded via module imports
        {pattern: clientApp + '**/**/*.js', included: true, watched: false},
        {pattern: clientApp + '**/**/*.spec.js', included: true, watched: true},

        // asset (HTML & CSS) paths loaded via Angular's component compiler
        // (these paths need to be rewritten, see proxies section)
        {pattern: clientApp + '**/**/*.html', included: false, watched: true},
        {pattern: clientApp + '**/**/*.css', included: false, watched: true},

        // paths for debugging with source maps in dev tools
        {pattern: clientApp + '**/**/*.ts', included: false, watched: false},
        {pattern: clientApp + '**//***.js.map', included: false, watched: false}
    ],

    // list of files to exclude
    exclude: [],

    proxies: {
        "/app/": clientApp
    },

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {},

    // test results reporter to use
    // possible values: 'dots', 'progress', 'coverage'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress', 'html'],

    htmlReporter: {
        outputFile: 'reports/unitTests.html',

        // Optional
        pageTitle: 'Unit Tests',
        subPageTitle: __dirname
    },

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR ||
    // config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    //        browsers: ['Chrome', 'ChromeCanary', 'FirefoxAurora', 'Safari', 'PhantomJS'],
    browsers: ['Chrome'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false
});

};

and the karma-test-shim.js

// /*global jasmine, __karma__, window*/
Error.stackTraceLimit = Infinity;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;

__karma__.loaded = function () {
};

function isJsFile(path) {
    return path.slice(-3) == '.js';
}

function isSpecFile(path) {
    return /\.spec\.js$/.test(path);
}

function isBuiltFile(path) {
    var builtPath = '/src/client';
    return isJsFile(path) && (path.substr(0, builtPath.length) == builtPath);
}

var allSpecFiles = Object.keys(window.__karma__.files)
    .filter(isSpecFile)
    .filter(isBuiltFile);

System.config({
    baseURL: ' ',
    packageWithIndex: true // sadly, we can't use umd packages (yet?)
});

System.import('systemjs.config.js')
    .then(function () {
        return Promise.all([
            System.import('@angular/core/testing'),
            System.import('@angular/platform-browser-dynamic/testing')
        ])
    })
    .then(function (providers) {
        var testing = providers[0];
        var testingBrowser = providers[1];

        testing.setBaseTestProviders(
            testingBrowser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
            testingBrowser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);

    })
    .then(function() {
        // Finally, load all spec files.
        // This will run the tests directly.
        return Promise.all(
            allSpecFiles.map(function (moduleName) {
                return System.import(moduleName);
            }));
    })
    .then(__karma__.start, __karma__.error);

My app structure is like so

./src
    /client
          /app/components
              /directives
              /etc...
              main

So far I'm just trying to run a sanity test without any imports like so

describe('1st tests', function () {
it('true is true', function () { return expect(true).toEqual(true); });
});

Something I've noticed is that the source on dev tools only seems to find the typescript of the spec files.


Solution

  • Problem was that I hadn't configured my systemJs.config file correctly. changed the path for 'app' to 'src/client/app' and karma runs successfully.

    EDIT

    The change needs to be made in your map file in systemjs.config like so:

    var map = { 'app': 'src/client/app', // 'dist', 'rxjs': 'node_modules/rxjs', '@angular': 'node_modules/@angular',

    We we're using a build folder named dist in this project.