5

I am trying to setup Angular2 (RC1 version) project with Karma. I was able to do this setup for ng2 beta.17, but for RC1 I am getting the following error:

Error: Error: XHR error (404 Not Found) loading http://localhost:9876/@angular/core/testing at XMLHttpRequest.wrapFn [as _onreadystatechange] (http://localhost:9876/base/node_modules/zone.js/dist/zone.js?11128be53f306ea156f04e90b0fb7f23fc2104a5:748:30) at ZoneDelegate.invokeTask (http://localhost:9876/base/node_modules/ zone.js/dist/zone.js?11128be53f306ea156f04e90b0fb7f23fc2104a5:341:38) at Zone.runTask (http://localhost:9876/base/node_modules/zone.js/dis t/zone.js?11128be53f306ea156f04e90b0fb7f23fc2104a5:238:48) at XMLHttpRequest.ZoneTask.invoke (http://localhost:9876/base/node_modules/zone.js/dist/zone.js?11128be53f306ea156f04e90b0fb7f23fc2104a5:408:34)
Error loading http://localhost:9876/@angular/core/testing'

Following is my Karma.conf.js

// Karma configuration
// Generated on Thu May 12 2016 10:43:29 GMT+0530 (India Standard Time)

module.exports = function(config) {
  config.set({

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


    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher')
    ],

    // list of files / patterns to load in the browser
    files: [
      {pattern: 'dist/src/**/*.js', included:false, watched: true},
      // 'dist/src/**/*spec.js',
      'node_modules/es6-shim/es6-shim.js',
      'node_modules/zone.js/dist/zone.js',
      'node_modules/reflect-metadata/Reflect.js',
      'node_modules/systemjs/dist/system-polyfills.js',
      'node_modules/systemjs/dist/system.src.js',
      'karma-test-shim.js',
      'dist/systemjs.config.js',
      {pattern: 'node_modules/@angular/**/*.js', included: false, watched: true},
      {pattern: 'node_modules/@angular/**/*.js.map', included: false, watched: true},
    ],


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


    // 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'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],


    // 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'],


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

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}

And finally following is my karma-test-shim.js. This is where the issue is happening, as I have included @angular/core/testing, it complains:

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

jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;

__karma__.loaded = function () {
};

System.map = {
    '@angular/*':'node_modules/@angular/*'
}

// System.paths = {
//     'test/*': '/base/scripts/test/*.js',
//     'build/*': '/base/scripts/build/*.js',
//     'angular2/*': 'angular2/*',
//     'rx': 'rx'
// };

System.config({
  packages: {
    'base/dist/app': {
      defaultExtension: false,
      format: 'register',
      map: Object.keys(window.__karma__.files)
        .filter(onlyAppFiles)
        .reduce(function (pathsMapping, appPath) {
          var moduleName = appPath.replace(/^\/base\/dist\/app\//, './').replace(/\.js$/, '');
          pathsMapping[moduleName] = appPath + '?' + window.__karma__.files[appPath];
          return pathsMapping;
        }, {})
    }
  }
});

System.import('@angular/core/testing').then(function (testing) {
  return System.import('@angular/platform-browser-dynamic/testing').then(function (providers) {
    testing.setBaseTestProviders(providers.TEST_BROWSER_PLATFORM_PROVIDERS,
      providers.TEST_BROWSER_APPLICATION_PROVIDERS);
  });
}).then(function () {
  return Promise.all(
    Object.keys(window.__karma__.files)
      .filter(onlySpecFiles)
      .map(function (moduleName) {
        console.log('Spec file --- '+moduleName);
        return System.import(moduleName);
      }));
}).then(function () {
  __karma__.start();
}, function (error) {
    console.log("Karma Error----- \n"+error);
  __karma__.error(error.stack || error);
});

function onlyAppFiles(filePath) {
  return /^\/base\/dist\/app\/(?!.*\.spec\.js$)([a-z0-9-_\.\/]+)\.js$/.test(filePath);
}

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

1 Answer 1

3

Only defining @angular in the map block of your SystemJS configuration isn't enough. You need an entry in the packages block for each Angular2 module.

Here is the configuration I use for Karma (karma.conf.js):

module.exports = function(config) {
  config.set({
    basePath: '.',
    frameworks: ['jasmine'],

    files: [
      {pattern: 'node_modules/es6-shim/es6-shim.min.js', included: true, watched: true},
      {pattern: 'node_modules/reflect-metadata/Reflect.js', included: true, watched: true},
      {pattern: 'node_modules/zone.js/dist/zone.js', included: true, watched: true},
      {pattern: 'node_modules/systemjs/dist/system.src.js', included: true, watched: true},
      {pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false},
      {pattern: 'node_modules/@angular/**/*.js', included: false, watched: false},
      {pattern: 'karma-test-shim.js', included: true, watched: true},

      {pattern: 'app/**/*.js', included: false, watched: true},

      {pattern: 'app/**/*.ts', included: false, watched: false},
      {pattern: 'app/**/*.js.map', included: false, watched: false}
    ],
    (...)
});

And the content of my karma-test-shim.js file:

// Tun on full stack traces in errors to help debugging
Error.stackTraceLimit = Infinity;

jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;

__karma__.loaded = function() {};

var map = {
  'app': 'base/app',
  'rxjs': 'base/node_modules/rxjs',
  '@angular': 'base/node_modules/@angular'
};

var packages = {
  'app': { main: 'main.js',  defaultExtension: 'js' },
  'rxjs': { defaultExtension: 'js' }
};

var packageNames = [
  '@angular/common',
  '@angular/compiler',
  '@angular/core',
  '@angular/http',
  '@angular/platform-browser',
  '@angular/platform-browser-dynamic',
  '@angular/router',
  '@angular/router-deprecated',
  '@angular/testing',
  '@angular/upgrade',
];

packageNames.forEach(function(pkgName) {
  packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
});

packages['base/app'] = {
        defaultExtension: 'js',
        format: 'cjs',
        map: Object.keys(window.__karma__.files).filter(onlyAppFiles).reduce(createPathRecords, {})
    };

var config = {
  map: map,
  packages: packages
};

System.config(config);

System.import('@angular/platform-browser/src/browser/browser_adapter')
.then(function(browser_adapter) { browser_adapter.BrowserDomAdapter.makeCurrent(); })
.then(function() { return Promise.all(resolveTestFiles()); })
.then(function() { __karma__.start(); }, function(error) { __karma__.error(error.stack || error); });

function createPathRecords(pathsMapping, appPath) {
  var pathParts = appPath.split('/');
  var moduleName = './' + pathParts.slice(Math.max(pathParts.length - 2, 1)).join('/');
  moduleName = moduleName.replace(/\.js$/, '');
  pathsMapping[moduleName] = appPath + '?' + window.__karma__.files[appPath];
  return pathsMapping;
}

function onlyAppFiles(filePath) {
  return /\/base\/app\/(?!.*\.spec\.js$).*\.js$/.test(filePath);
}

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

function resolveTestFiles() {
  return Object.keys(window.__karma__.files)  // All files served by Karma.
    .filter(onlySpecFiles)
    .map(function(moduleName) {
        // loads all spec files via their global module names (e.g.
        // 'base/dist/vg-player/vg-player.spec')
        return System.import(moduleName);
    });
}
Sign up to request clarification or add additional context in comments.

9 Comments

Going off of this right now to try and get my setup going. Man this is much more painful than it should be >_>
Agreed with you that configuring Karma with Angular2 doesn't consist of defining paths (like in Angular1)...
Just an hint about AsyncTestZoneSpec. This made me a bit crazy ;-). See this issue: github.com/angular/angular/issues/8232. Don't forget to add node_modules/zone.js/dist/async-test.js in your karma configuration...
You use an RC version of Angular2?
I was able to fix this, this repo contains the code...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.