How do I use package aliases in Karma? (Example: $ for jquery) - javascript

My code depends on tons of other code, and is loaded last in the browser when running from the normal index.html-file. So of course when dependency 1 is jquery, and dependency 2 uses $.html(), and my code is loaded third, that works just fine in the browser.
But in Karma everything screeches to a halt since I'm loading 'jquery' from bower, not '$'.
To be clear: it's not my code that's creating errors, it's the dependencies. I don't get to test my code since everything errors out before then.
So how do I get the tests to work?
Note: I also run everything through webpack so I can use ES6-code, but webpack is loaded in Karma as well, so that should have no effect.
Chrome 45.0.2454 (Mac OS X 10.11.0) ERROR
Uncaught TypeError: Cannot set property '$' of undefined
at /Users/tom/dev/orm/bower_components/jointjs/dist/joint.js:37
Webpack.conf.js:
var webpack = require('webpack');
module.exports = {
devtool: 'source-map-loader',
externals: [
'jquery',
'joint',
'backbone',
'loadash'
],
// entry: './src/index.js',
// output: {
// path: './public',
// filename: 'designer.js'
// },
plugins: [
new webpack.ProvidePlugin({'$': 'jquery', 'jointjs': 'joint'})
],
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
}
};
Karma.conf.js:
// Karma configuration
// Generated on Thu Oct 08 2015 10:54:47 GMT+0200 (CEST)
var webconf = require('./webpack.config.js');
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',
'requirejs',
'bower'
],
// list of files / patterns to load in the browser
files: [
'test-main.js',
{
pattern: 'test/*.js',
included: false
}
],
bowerPackages: [
'jquery',
'jointjs',
'backbone',
'lodash'
],
// 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/*.js': [
'webpack',
'sourcemap'
],
'src/**/*.js': [
'webpack',
'sourcemap'
]
},
webpack: webconf,
// 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: [
'PhantomJS',
'Chrome'
],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false
});
};

I think you're either looking for webpack externals
Webpack Externals
{
externals: {
// require("jquery") is external and available
// on the global var jQuery
"jquery": "jQuery"
}
}
...or, provide plugins.
Provide Plugin vs. Externals
plugins: [
new webpack.ProvidePlugin({
"_": "underscore"
})
]
Most likely provide plugin, because you want to provide that global variable to all the webpacked bundles.

I have no idea what changed, but it now works fine. I include here the final Karma config-file. The webpack-file is identical to the one above.
Note that a couple of configuration changes are actually just normal configuration changes that I've changed since getting it to work.
// Karma configuration
// Generated on Thu Oct 08 2015 10:54:47 GMT+0200 (CEST)
var webconf = require('./webpack.config.js');
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: [
'requirejs',
'bower',
'jasmine',
],
bowerPackages: [
'jquery',
'lodash',
'backbone',
'jointjs'
],
// list of files / patterns to load in the browser
files: [
'test-main.js',
{
pattern: 'test/*.js',
included: false
}
],
// 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/*.js': [
'webpack',
'sourcemap'
],
'src/**/*.js': [
'webpack',
'sourcemap'
]
},
webpack: webconf,
// 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,
client: {
captureConsole: false
},
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: [
'PhantomJS',
'Chrome'
],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false
});
};

Related

Flow with Jasmine: Assign properties and methods to `this` creates 'Cannot set Property' Error

I am a newbie with "Flow" and I am trying to assign an arbitrary property, e.g. foo, to the keyword this. The purpose of this is to setup my test suite environments cleanly in a beforeEach statement. An example would be something like:
// #flow
describe('test', () => {
beforeEach(() => {
this.foo = 'Hello';
});
it('should bar', () => {
expect(this.foo).toBe('Hello');
});
});
Flow would complain about each this.foo with the following:
Flow: property `foo`. Property not found in global object.
I understand that it's bad practice to inject a property to this, but as mentioned previously, I need to assign to do this (sorry for the pun), to set the state of my tests.
Even though I have this error, I thought my karma test would run fine. When I run my an individual karma test, I would get the following error:
TypeError: Cannot set property 'foo' of undefined
I'm not sure what the problem is. This is my karma configuration setup.
module.exports = function configSettings(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'],
// list of files / patterns to load in the browser
files: [
{pattern: 'test/**/*.js', watched: false},
],
exclude: [],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'test/**/*.js': ['webpack', 'sourcemap'],
},
webpack: {
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env'],
plugins: ['transform-flow-strip-types']
},
},
},
],
},
devtool: 'inline-source-map',
},
webpackServer: {
noInfo: true,
},
// test results reporter to use
// possible values: 'dots', 'progress'
// Continuous Integration mode
// 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
logLevel: config.LOG_DEBUG,
// start these browsers
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['ChromeCanary'],
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity,
});
};

Angular 2 testing karma with webpack Can't find variable: Map

I am trying to test my directive with karma and webpack.
This is the karma config file
module.exports = function (config) {
config.set({
basePath: './',
frameworks: ["jasmine"],
files: [
{
pattern: 'directive.spec.ts',
watched: false
}],
exclude: [],
preprocessors: {
'directive.spec.ts': ['webpack', 'sourcemap']
},
webpackServer: {
noInfo: true
},
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: [
"PhantomJS"
],
singleRun: true,
reporters: ['mocha'],
webpack: {
resolve: {
extensions: ['', '.ts', '.js'],
modulesDirectories: ['node_modules', '.'],
},
module: {
loaders: [{
test: /\.ts$/,
loader: 'awesome-typescript-loader'
}]
},
stats: {
colors: true,
reasons: true
},
debug: true,
devtool: 'inline-source-map'
}
});
};
And the directive.spec.ts:
import { MyDirective } from './directive';
import {TestComponent} from './test';
import {
async,
inject,
TestBed,
} from '#angular/core/testing';
describe('TestComponent', () => {
let fixture: any;
beforeEach(() => {
fixture = TestBed.configureTestingModule({
declarations: [ TestComponent, MyDirective]
})
.createComponent(TestComponent);
fixture.detectChanges();
});
it('should work', () => {
expect(true).toBe(true);
});
But when I am trying to run my test I am getting this error:
PhantomJS 2.1.1 (Mac OS X 0.0.0) ERROR ReferenceError: Can't find
variable: Map at directive.spec.ts:1380
What am I missing here?
Please follow these steps. It worked for me:
1) Create a "karma-main.js" file with following code
require('core-js/es6');
require('core-js/es7/reflect');
require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/proxy');
require('zone.js/dist/sync-test');
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');
var appContext = require.context('<Source code root folder>', true, /\.spec\.ts/); // Assuming test case files ends with spec.ts
appContext.keys().forEach(appContext);
var testing = require('#angular/core/testing');
var browser = require('#angular/platform-browser-dynamic/testing');
testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting());
2) Your karma.conf.js file should look like
var webpackConfig = require('./webpack.config')
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
plugins: [
'karma-jasmine',
'karma-PhantomJS-launcher',
'karma-webpack'
],
webpack: webpackConfig,
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
{ pattern: '<relative path to karma-main.js>', watched: false }
],
// 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: {
'<relative path to karma-main.js>': ['webpack']
},
// 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: ['PhantomJS'],
// 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
})
}
Here is my guess: somewhere in the code you use a class Map which appeared in ES6. But PhantomJS doesn't know about this class yet since it's something too new.
So there are 3 choices:
Get rid of usage of Map and use only current JS features (like Object properties) - the cleanest approach.
Use transpiler for transforming your ES6 code into ES5 that's well understood by modern browser. This has huge disadvantages as it will mess with your line numbers and you may have to sacrifice the possibility to debug some of the code.
Use polyfills that implement ES6 features as functions in external libraries (as Sachin Gaur suggested)

TypeError: expect(...).to.be is not a function

I am configuring my Karma amd mocha framework with grunt in my project. When I am running karma start I am getting below-mentioned error.
I am getting this error in my console while running command : Karma start
TypeError: expect(...).to.be is not a function
My Karma.confjs
// Karma configuration
// Generated on Fri Nov 27 2015 11:48:47 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: ['mocha', 'chai'],
// list of files / patterns to load in the browser
files: [
'bower_components/angular/angular.js',
'bower_components/angular-mocks/angular-mocks.js',
'app/*.js',
// 'test/specs/*.js',
'test/specs/array.js',
// 'test/specs/myCtlr-spec.js',
//'test/*.js'
],
// 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','coverage'],
preprocessors: {
'src/app/**/*.js': ['coverage']
},
coverageReporter: {
type: 'lcov',
dir: 'coverage/'
},
// 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: ['PhantomJS', 'Chrome'],
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 simultanous
concurrency: Infinity
})
}
My array.js test
// var expect = require('chai').expect;
describe("Mocha: The 'toBe' matcher compares with ===", function() {
it("and has a positive case", function() {
expect(true).to.be(true);
});
it("and can have a negative case", function() {
expect(false).not.to.be(true);
});
});
Please suggest what I am missing.
You need to write expect(true).to.be.equal(true) the be is a chain (object) not a function. Or you could write:
expect(true).to.be.true;
expect(false).to.be.false;

Karma coverage fails to show correct results

I need some help regarding Karma with browserify coverage. I created a repo with the test I am running in here:
https://github.com/jotaoncode/web-istanbul
The results on my coverage are the following:
Results of coverage
The test only runs over the function index. But as you can see the results are a 100% and marks only the first row of the file with a green color.
I have seen cases where istanbul shows correctly the coverage values, I have changed the test and the source but nothing.
I also have this karma configuration:
module.exports = function(config) {
config.set({
//logLevel: 'LOG_DEBUG',
reporters: ['spec', 'coverage'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun : true,
autoWatch : false,
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
port: 9876,
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: [
'mocha',
'browserify'
],
files: [
'src/**/*.js',
'test/*.js'
],
// list of files to exclude
exclude: [],
preprocessors: {
'src/**/*.js': ['browserify', 'coverage'],
'test/**/*.js': ['browserify']
},
coverageReporter: {
reporters: [
{ type: 'html' },
{ type: 'text' },
{ type: 'lcovonly' }
],
instrumenterOptions: {
istanbul: {
noCompact: true
}
},
instrumenter: {
'test/**/*.js': 'istanbul'
},
includeAllSources: true
},
// enable / disable colors in the output (reporters and logs)
colors: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: [
'PhantomJS2'
]
});
};
If you ran the tests you will see that it actually works fine, but the coverage report is not correct.
After doing some research I found this is solved as commented in this issue:
https://github.com/karma-runner/karma-coverage/issues/16
I used browserify-istanbul and now coverage report is working fine :)

jquery-jasmine - fixture could not be loaded

I am trying to load some fixtures for testing purposes. So far I have prepared a json file.
I did set up my beforeEach function which should load particular file but I am getting an error:
Error: Fixture could not be loaded: tests/license_filter/license_test_data.json (status: error, message: undefined)
Part of test function:
beforeEach(function () {
jasmine.getFixtures().fixturesPath = 'tests/license_filter';
loadFixtures('license_test_data.json');
});
Karma config:
// Karma configuration
// Generated on Mon Nov 10 2014 21:12:33 GMT+0100 (Central European Standard Time)
module.exports = function (config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: 'license_tool/static',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'js/external/jquery.js',
'../../node_modules/jasmine-jquery/lib/jasmine-jquery.js',
'js/external/jquery.tmpl.js',
'js/external/jquery.validate.js',
'js/helpers.js',
'js/version_ninja.js',
'tests/**/*.html',
'tests/**/*.js'
],
// 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: {
'**/*.html': ['html2js']
},
// 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: ['PhantomJS'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false
});
};
I've found a solution for that.
This is my beforeeach
beforeEach(function () {
jasmine.getJSONFixtures().fixturesPath = 'base/tests/license_filter';
loadJSONFixtures('license_test_data.json');
});
I had to add this to files list in karma.conf.js:
{
pattern: 'tests/**/*.json',
watched: true,
served: true,
included: false
}

Categories