Karma: Imports of style 'import B = A.B' are not understood by Karma

Created on 28 Mar 2017  ·  7Comments  ·  Source: karma-runner/karma

Expected behaviour

Should be able to import a module without an error being thrown.

Actual behaviour

Karma runner reports an error: "TypeError: FailingModule_1.FailingModule is undefined"

Environment Details

  • Karma version (output of karma --version): 1.5.0
var path = require("path");
var webpackConfig = require("./webpack.config");

module.exports = function(config) {
    config.set({
        autoWatch: true,
        basePath: "",
        browsers: ["Firefox"],
        colors: true,
        files: ["tests/*.ts"],
        frameworks: ["mocha", "chai", "sinon"],
        logLevel: config.LOG_INFO,
        plugins: ["karma-*"],
        port: 9876,
        preprocessors: {
            "tests/*.ts": ["webpack"]
        },
        reporters: ["mocha"],
        singleRun: false,
        webpack: {
            module: webpackConfig.module,
            resolve: webpackConfig.resolve
        }
    });
};

Steps to reproduce the behaviour

  1. Create a module FailingModule.ts with inner classes:
// Note: changing the wording to "export namespace" made no difference to the error.
export module FailingModule {
    export class Clazz {
        public static dummy() : string { return "dummy"; }
    }
}
  1. Create a module WorkingModule.ts without inner classes, for comparison:
export class WorkingClazz {
    public static dummy() : string { return "dummy"; }
}
  1. Import both modules in a Karma test and see that importing WorkingModule throws no error, yet FailingModule does:
import {WorkingClazz} from "../src/WorkingModule"; // Karma can run this import.
import {FailingModule} from "../src/FailingModule"; // Karma throws error upon this import.
import Clazz = FailingModule.Clazz;

describe("Run WorkingClazz & FailingModule.Clazz", () => {
    it("Karma should run test suite without throwing an import error.", function(){
        WorkingClazz.dummy();
        Clazz.dummy();
    });
});

Karma can import my other classes (which are not nested inside a declared module), just fine, and such tests do pass; it's just this specific case. Am I declaring my module/imports incorrectly, or is my configuration wrong somewhere? Thanks for any help.

Note: other supporting files like webpack configuration all transcribed on this StackOverflow post.

support

Most helpful comment

I've found the root of the problem, and an undesirable workaround. I'll explain the situation more clearly this time. My detailed setup for tsconfig, webpack, and karma is described – as before – in this StackOverflow post if needed, but the main steps for reproduction are as follows:

Setup

ModuleWithInnerClass.ts

export module A {
    export class B {
        public static hello() : string { return "hello"; }
    }
}

FailureCase.ts

import {A} from "./ModuleWithInnerClass";
import B = A.B; // We create an alias for the inner class. Karma fails here.
B.hello();

Problem

If no test runner is involved, this TypeScript code compiles (via ts-loader) and bundles (via Webpack) to produce code that runs perfectly in a browser without error. ✅

However, when Karma is involved, it gives the error "TypeError: A_1.B is undefined". ❌

Here is my Karma invocation: /usr/local/bin/node /Applications/WebStorm.app/Contents/plugins/js-karma/js_reporter/karma-intellij/lib/intellijServer.js --karmaPackageDir=/Users/me/project/node_modules/karma --configFile=/Users/me/project/karma.conf.js .

This is a pre-test problem and is thus the same regardless of whether Jasmine or Mocha/Chai are used as the testing frameworks.

Workaround

Remove the import B = A.B; aliasing line and instead write the namespace in manually: A.B.hello().

This is undesirable because it requires a huge amount of refactoring and means that my code has to accommodate my test runner, rather than the other way around. What is causing Karma to be unable to import inner classes of modules, and can we fix this?

All 7 comments

@shirakaba looks like a problem not in karma itself.
I think the problem in misconfiguration of webpack + typescript.
Try pass full webpackConfig in karma.config:

webpack: webpackConfig

Thanks

@maksimr Thanks for coming to help out! Unfortunately, passing the full webpackConfig produces no change in the situation.

@shirakaba what browser(launcher) do you use?

P.S.
Oh, I see, Firefox?

Above is a simplified configuration, but to be exact, I use Firefox 49.0.2 (the latest version is Firefox 52 or something), with a custom launcher config to prevent it auto-updating (this is the browser I am forced to use for television-related development):

    browsers: ["FirefoxDev"],
    customLaunchers: {
        FirefoxDev: {
            base: 'Firefox', // I have named Firefox 49.0.2 to just 'Firefox'
            prefs: {
                'app.update.auto' : false,
                'app.update.enabled' : false,
                'app.update.silent' : false,
                'xpinstall.signatures.required' : false
            },
            extensions: []
        }
    }

In the past, I have tried to use Chrome, but it said "no tests in file", so I'm stuck using the browser that I do my development on.

I've found the root of the problem, and an undesirable workaround. I'll explain the situation more clearly this time. My detailed setup for tsconfig, webpack, and karma is described – as before – in this StackOverflow post if needed, but the main steps for reproduction are as follows:

Setup

ModuleWithInnerClass.ts

export module A {
    export class B {
        public static hello() : string { return "hello"; }
    }
}

FailureCase.ts

import {A} from "./ModuleWithInnerClass";
import B = A.B; // We create an alias for the inner class. Karma fails here.
B.hello();

Problem

If no test runner is involved, this TypeScript code compiles (via ts-loader) and bundles (via Webpack) to produce code that runs perfectly in a browser without error. ✅

However, when Karma is involved, it gives the error "TypeError: A_1.B is undefined". ❌

Here is my Karma invocation: /usr/local/bin/node /Applications/WebStorm.app/Contents/plugins/js-karma/js_reporter/karma-intellij/lib/intellijServer.js --karmaPackageDir=/Users/me/project/node_modules/karma --configFile=/Users/me/project/karma.conf.js .

This is a pre-test problem and is thus the same regardless of whether Jasmine or Mocha/Chai are used as the testing frameworks.

Workaround

Remove the import B = A.B; aliasing line and instead write the namespace in manually: A.B.hello().

This is undesirable because it requires a huge amount of refactoring and means that my code has to accommodate my test runner, rather than the other way around. What is causing Karma to be unable to import inner classes of modules, and can we fix this?

import {B} from 'C';
export default class A extends B {
  xxx
}
Cannot read property 'B' of undefined

I'm unable to reproduce this issue using the provided reproduction. I'm using latest WebStorm and latest Firefox though. As there were a lot of changes both to Karma and to other moving parts I would assume that the issue has been fixed in the meantime. Please open a new issue with the fresh reproduction if you still experience this problem.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jambonrose picture jambonrose  ·  5Comments

jhildenbiddle picture jhildenbiddle  ·  4Comments

danielsiwiec picture danielsiwiec  ·  5Comments

donaldpipowitch picture donaldpipowitch  ·  3Comments

ORESoftware picture ORESoftware  ·  4Comments