Unit tests with Karma outputs 404 on all the JS files

Hy guys,
I have an standart Aurelia setup for init test based on Karma in a pretty straight forward application.
When I run the test - the output is 404: for all the JS files. I banging my head with this and I can’t figure out what is wrong in the config. My config is as follows:

// aurelia-kara.js  in ./test

(function(global) {
  var karma = global.__karma__;
  var requirejs = global.requirejs
  var locationPathname = global.location.pathname;
  var root = 'src';
  karma.config.args.forEach(function(value, index) {
    if (value === 'aurelia-root') {
      root = karma.config.args[index + 1];
    }
  });

  if (!karma || !requirejs) {
    return;
  }

  function normalizePath(path) {
    var normalized = []
    var parts = path
      .split('?')[0] // cut off GET params, used by noext requirejs plugin
      .split('/')

    for (var i = 0; i < parts.length; i++) {
      if (parts[i] === '.') {
        continue
      }

      if (parts[i] === '..' && normalized.length && normalized[normalized.length - 1] !== '..') {
        normalized.pop()
        continue
      }

      normalized.push(parts[i])
    }

    // Use case of testing source code. RequireJS doesn't add .js extension to files asked via sibling selector
    // If normalized path doesn't include some type of extension, add the .js to it
    if (normalized.length > 0 && normalized[normalized.length - 1].indexOf('.') < 0) {
      normalized[normalized.length - 1] = normalized[normalized.length - 1] + '.js'
    }

    return normalized.join('/')
  }

  function patchRequireJS(files, originalLoadFn, locationPathname) {
    var IS_DEBUG = /debug\.html$/.test(locationPathname)

    requirejs.load = function (context, moduleName, url) {
      url = normalizePath(url)

      if (files.hasOwnProperty(url) && !IS_DEBUG) {
        url = url + '?' + files[url]
      }

      if (url.indexOf('/base') !== 0) {
        url = '/base/' + url;
      }

      return originalLoadFn.call(this, context, moduleName, url)
    }

    var originalDefine = global.define;
    global.define = function(name, deps, m) {
      if (typeof name === 'string') {
        originalDefine('/base/' + root + '/' + name, [name], function (result) { return result; });
      }

      return originalDefine(name, deps, m);
    }
  }

  function requireTests() {
    var TEST_REGEXP = /(spec)\.js$/i;
    var allTestFiles = ['/base/test/unit/setup.js'];

    Object.keys(window.__karma__.files).forEach(function(file) {
      if (TEST_REGEXP.test(file)) {
        allTestFiles.push(file);
      }
    });

    require(allTestFiles, window.__karma__.start);
  }

  karma.loaded = function() {}; // make it async
  patchRequireJS(karma.files, requirejs.load, locationPathname);
  requireTests();
})(window);

and my Karma.Conf.js is

const path = require('path');
const project = require('./aurelia_project/aurelia.json');
const karmaConfig = project.unitTestRunner;

let testSrc = [{ pattern: karmaConfig.source, included: false }, 'test/aurelia-karma.js'];

let output = project.platform.output;
let appSrc = project.build.bundles.map(x => path.join(output, x.name));
let entryIndex = appSrc.indexOf(path.join(output, project.build.loader.configTarget));
let entryBundle = appSrc.splice(entryIndex, 1)[0];
let sourceMaps = [{ pattern: 'scripts/**/*.js.map', included: false }];
let files = [entryBundle].concat(testSrc).concat(appSrc).concat(sourceMaps);

let transpilerOptions = project.transpiler.options;
transpilerOptions.sourceMap = 'inline';

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: [project.testFramework.id],
    files: files,
    exclude: [],
    preprocessors: {
      [karmaConfig.source]: [project.transpiler.id],
      [appSrc]: ['sourcemap', 'coverage']
    },
    babelPreprocessor: { options: transpilerOptions },
    reporters: ['progress', 'coverage'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    /*
     * start these browsers
     * available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
     */
    // browsers: [
    //   'Chrome',
    // ],
    /*
     * To run in non-headless mode:
     * 1. Comment the following lines
     * 2. Uncomment the above "browsers" setting
     */
    browsers: ['ChromeHeadless'],
    customLaunchers: {
      ChromeHeadless: {
        base: 'Chrome',
        flags: ['--no-sandbox', '--headless', '--disable-gpu', '--remote-debugging-port=9222']
      }
    },
    /** **************************************************************************** */

    /*
     * Continuous Integration mode
     * if true, Karma captures browsers, runs the tests and exits
     */
    singleRun: true,
    // client.args must be a array of string.
    // Leave 'aurelia-root', project.paths.root in this order so we can find
    // the root of the aurelia project.
    client: {
      args: ['aurelia-root', project.paths.root],
      jasmine: {
        random: false
      }
    },
    coverageReporter: {
      reporters: [{ type: 'html' }, { type: 'lcovonly' }, { type: 'text-summary' }],
      dir: path.resolve(__dirname, 'test/coverage-karma'),
      subdir: '.'
    }
  });
};

I can’t figure out what is wrong in this ?

Better start small: check if an ordinary non aurelia related file can be seen by in your tests or not first, then go further. Karma is often not very descriptive with loading errors.

1 Like

Indeed - Karma is so implicit in these errors!

I’ve added

describe('basic example', () => {
  it('should be true', () => {
    expect(true).toBe(true);
  });
});

in example folder example.spec.js

and I’ve changed the karma.conf to

....
files: [
      'test/aurelia-karma.js',
      { pattern: 'test/unit/example/*.js', watched: true, served: true, included: false }
    ],
....

The output thought is:

01 03 2024 14:15:50.672:INFO [filelist]: Changed file "C:/MyProject/common-plugin/test/unit/example/example.spec.js".
Chrome Headless 122.0.6261.95 (Windows 10): Executed 0 of 0 SUCCESS (0.002 secs / 0 secs)
TOTAL: 0 SUCCESS

=============================== Coverage summary ===============================
Statements   : Unknown% ( 0/0 )
Branches     : Unknown% ( 0/0 )
Functions    : Unknown% ( 0/0 )
Lines        : Unknown% ( 0/0 )
================================================================================

which is even more confusing. Why 0 of 0?

Also created this thread on SO. It’s really frustrating I have no tests loaded. And this project is another one, part of a mono-repo, where for the jade templates there is a task to compile them to HTML from there, Aurelia takes it’s own view-model pattern. But again, it’s giving a timeout.