Karma and Jasmine: Can't find variable: require - karma-runner

This is my first time attempting to unit test some code and I'm getting this error when using Karma and Jasmine:
PhantomJS 2.1.1 (Windows 8 0.0.0) ERROR
ReferenceError: Can't find variable: require
at unit/tests.js:1
I tried npm install karma-browserify --save-dev but that didn't solve the issue.
Any idea how to sort this?
My Karma conf file:
// Karma configuration
// Generated on Tue Nov 08 2016 03:14:50 GMT+0000 (GMT 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'],
// list of files / patterns to load in the browser
files: [
// '../shopping-basket.js',
'unit/*.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/**/*.js': ['browserify']
},
// 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'],
//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
})
}
tests.js
var myCode = require('./shopping-basket-functions');
describe('tests', function(){
describe('testFunction', function(){
it('should return 1', function(){
// Call the exported function from the module
myCode.testFunction().should.equal(1);
})
})
})
shopping-basket-functions.js
function testFunction () {
return 1;
}
// If we're running under Node,
if(typeof exports !== 'undefined') {
exports.testFunction = testFunction;
}

Have you tried using the template here: https://www.npmjs.com/package/grunt-template-jasmine-nml as specified in this answer?
Long story short, what it does is allow you to use the CommonJS syntax that NodeJS uses in order to reference and pull in other modules. See an example below of how you would reference it in your jasmine config file (again, per the other user's answer) :
jasmine: {
options: {
template: require('grunt-template-jasmine-nml'),
helpers: 'spec/helpers/**/*.js',
specs: 'spec/**/*.spec.js'
}
}

had same issue trying to build an app, phanotmjs kept on creeping the undefined variable require, solved it by:
npm install grunt-template-jasmine-nml --save-dev
this will update the right template and it works after.
trying:
grunt test -dd finished without error

Related

Troubles combining bundling Svelte Material UI with custom SCSS using Rollup

I have Svelte 3.x (with TS enabled) and a pretty standard Rollup config for bundling my SCSS files with this file structure:
| src
| styles.scss
| etc.
rollup.config.js:
export default {
input: 'src/main.ts',
output: {
sourcemap: true,
format: 'iife',
name: 'myapp',
file: 'public/build/bundle.js'
},
plugins: [
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file - better for performance
css: css => {
css.write('bundle.css');
},
preprocess: autoPreprocess(),
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({
browser: true,
dedupe: ['svelte']
}),
commonjs(),
typescript({ sourceMap: !production }),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};
This works fine. Now I'm struggling getting Svelte Material UI running.
After installing postcss, rollup-plugin-postcss, rollup-plugin-sass, svelte-material-uiand svelte-preprocess-sass and reading through here and there and there I added this to the plugins array in rollup.config.js:
postcss({
extract: true,
minimize: true,
use: [
['sass', {
includePaths: [
'./src/theme',
'./node_modules'
]
}]
]
})
When I test it in my app using a #smui/button the button (with a default styling and the default ripple effect) works, but none of my SCSS gets compiled (or get overwritten during bundling).
I'm searching the needle in the haystack and appreciate any hint.
Got it, I just missed adding emitCss: true in the Svelte plugin config. So my working rollup.config.js is this:
export default {
input: 'src/main.ts',
output: {
sourcemap: true,
format: 'iife',
name: 'myapp',
file: 'public/build/bundle.js'
},
plugins: [
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file - better for performance
css: css => {
css.write('bundle.css');
},
emitCss: true,
preprocess: autoPreprocess()
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({
browser: true,
dedupe: ['svelte']
}),
commonjs(),
typescript({ sourceMap: !production }),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};
This also has been answered here.

Using Karma + Jasmine, what is the best way to run only one test at a time?

Is the best way to do that, simply to use the .only flag?
However, if I used describe.only(, I get
Uncaught TypeError: describe.only is not a function
So how can I run/debug only one test at a time?
Here is my karma.conf.js file:
const path = require('path');
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'],
// list of files / patterns to load in the browser
files: [
'./node_modules/angular/angular.js',
'./node_modules/angular-ui-router/release/angular-ui-router.js',
'./node_modules/angular-mocks/angular-mocks.js',
// './public/pages/admin/specs/abc.js'
'./public/dist/app-production.js',
// './public/**/*.spec.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: ['spec', 'junit', /*progress*/],
junitReporter: {
outputDir: 'karma-results',
outputFile: 'karma-results.xml'
},
// 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_WARN'],
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: [/*Chrome*/ 'PhantomJS'],
// process.env.USER === dftjenkins
plugins: [
'karma-phantomjs-launcher',
'karma-chrome-launcher',
'karma-jasmine',
'karma-junit-reporter',
'karma-spec-reporter'
],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true,
// Concurrency level
// how many browser should be started simultaneous
concurrency: 5
})
};
The solution I have for the moment works quite well, all I do is change one line of our karma.conf.js file, like so:
before:
files: [
'./node_modules/angular/angular.js',
'./node_modules/angular-ui-router/release/angular-ui-router.js',
'./node_modules/angular-mocks/angular-mocks.js',
'./public/dist/app-production.js',
'./public/**/*.spec.js'
],
after:
files: [
'./node_modules/angular/angular.js',
'./node_modules/angular-ui-router/release/angular-ui-router.js',
'./node_modules/angular-mocks/angular-mocks.js',
'./public/dist/app-production.js',
process.env.KARMA_TEST_PATH || './public/**/*.spec.js'
],
now your just run karma like so:
KARMA_TEST_PATH=public/pages/x/specs/foo.spec.js karma start
and it will run that single test instead of all your specs.

SystemJS and KarmaJS: TypeError: System.import is not a function

I am trying to get my project working with Karma and SystemJS. I am using the karma-systemjs plugin with karma.
I keep getting the error below about System.import.
I believe it is because SystemJS is not being loaded by the time the karma-systemjs plugin runs. Please tell me what I am doing wrong.
Project structure
SystemJS configuration (system.conf.js)
System.config({
baseUrl: '',
defaultJSExtensions: true,
map: {
'jquery': 'vendor/kendo/js/jquery.min.js',
'angular': 'vendor/kendo/js/angular.js',
'kendo': 'vendor/kendo/js/kendo.all.min.js',
'angular-mocks': 'vendor/bower_components/angular-mocks/angular-mocks.js',
'angular-ui-router': 'vendor/bower_components/angular-ui-router/release/angular-ui-router.min.js',
'angular-toastr': 'vendor/bower_components/angular-toastr/dist/angular-toastr.tpls.min.js',
'angular-local-storage': 'vendor/bower_components/angular-local-storage/dist/angular-local-storage.min.js'
},
paths: {
'systemjs': 'vendor/bower_components/system.js/dist/system.js',
'system-polyfills': 'vendor/bower_components/system.js/dist/system-polyfills.js'
},
meta: {
'vendor/kendo/js/jquery.min.js': {
format: 'global',
exports: '$'
},
'vendor/kendo/js/angular.js': {
format: 'global',
deps: [
'vendor/kendo/js/jquery.min.js'
],
exports: 'angular'
},
'vendor/kendo/js/kendo.all.min.js': {
format: 'global',
deps: [
'vendor/kendo/js/angular.js'
],
exports: 'kendo'
},
'vendor/bower_components/angular-ui-router/release/angular-ui-router.min.js': {
format: 'global',
deps: [
'vendor/kendo/js/angular.js'
]
},
'vendor/bower_components/angular-mocks/angular-mocks.js': {
format: 'global',
deps: [
'vendor/kendo/js/angular.js'
],
exports: 'angular.mock'
},
'vendor/bower_components/angular-toastr/dist/angular-toastr.tpls.min.js': {
format: 'global',
deps: [
'vendor/kendo/js/angular.js'
]
},
'vendor/bower_components/angular-local-storage/dist/angular-local-storage.min': {
format: 'global',
deps: [
'vendor/kendo/js/angular.js'
]
}
}
});
Promise.all([
System.import('kendo'),
System.import('angular-mocks'),
System.import('angular-ui-router'),
System.import('angular-toastr'),
System.import('angular-local-storage')
]).then(function () {
System.import('angular')
.then(function (angular) {
System.import('ng/app/app.module')
.then(function (app) {
angular.bootstrap(document, ['s9.app']);
}, function (err) {
console.log(err);
});
}, function (err) {
console.log(err);
});
});
//# sourceMappingURL=system.conf.js.map
karma.conf.js
// Karma configuration
var configure = function (config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '.',
transpiler: null,
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['systemjs', 'jasmine'],
systemjs: {
// Path to your SystemJS configuration file
configFile: 'system.conf.js',
// Patterns for files that you want Karma to make available, but not loaded until a module
// requests them. eg. Third-party libraries.
serveFiles: [
'vendor/kendo/js/**/*.js',
'vendor/bower_components/**/*.js',
'ng/**/*.js',
'test/**/*Spec.js'
],
config: {
paths: {
'systemjs': 'vendor/bower_components/system.js/dist/system.js',
'system-polyfills': 'vendor/bower_components/system.js/dist/system-polyfills.js'
}
}
},
// list of files / patterns to load in the browser
files: [
{pattern: 'vendor/kendo/js/**/*.js', included: false},
{pattern: 'vendor/bower_components/**/*.js', included: false},
{pattern: 'ng/**/*.js', included: false},
{pattern: 'test/**/*Spec.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 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_DEBUG,
// 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
});
};
module.exports = configure;
//# sourceMappingURL=karma.conf.js.map
Error
I fixed this by moving the bootstrap code out of the config code. Apparently when using the karma-systemjs plugin System.import is not available yet when this is called (although it is at normal runtime).
What I did: I moved the bootstrap code (i.e. Promise.all([....) into into a separate file called bootstrap.js (name is not important) and then in my index.html I added them in this order:
Also from this link (the karma system js plugin author says): https://github.com/rolaveric/karma-systemjs/issues/71
I see the problem. It's because you've got your bootstrapping code
(eg. System.import() calls) inside your SystemJS config file -
system.conf.js karma-systemjs expects just a simple System.config()
call that it can then intercept to find out where your transpiler and
polyfills are. It does this by evaluating your config file with a fake
System object which simply records whatever is passed to
System.config(). This fake object has no System.import() method, which
causes your error.
I'd recommend moving your bootstrapping code into a separate file (I
personally put it in a script tag with my HTML). Otherwise you'll run
into similar problems if you try to use systemjs-builder, and you
probably don't want angular.bootstrap() to be called at the start of
your unit tests.

jspm + KarmaJS - exclude files from watch but not from serve

I can't figure out how to make karma to not watch for changes in folder jspm_packages/.
If I try to add 'jspm_packages' into exclude section then I get following errors:
DEBUG [web-server]: serving (cached): /Users/jm/dev/monka/node_modules/gulp-helpers/node_modules/karma-jspm/src/adapter.js
PhantomJS 1.9.8 (Mac OS X 0.0.0) ERROR
ReferenceError: Can't find variable: System
at /Users/jm/dev/monka/system.config.js:1
ERROR [PhantomJS 1.9.8 (Mac OS X 0.0.0)]: ReferenceError: Can't find variable: System
at http://localhost:9876/base/system.config.js?31f6cba38ed6c99ea3e9b4bc926e8ecfd6de8bd7:1
Here is my karma.conf.js
module.exports = function(config) {
config.set({
plugins: [
'karma-jspm',
'karma-jasmine',
'karma-beep-reporter',
'karma-verbose-reporter',
'karma-babel-preprocessor',
'karma-phantomjs-launcher'
],
basePath : '', // base path that will be used to resolve all patterns (eg. files, exclude)
frameworks : ['jspm', 'jasmine'], // frameworks to use available frameworks: https://npmjs.org/browse/keyword/karma-adapter
browsers : ['PhantomJS'], // start these browsers available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
reporters : ['progress', 'beep', 'verbose'/*, 'coverage'*/], // test results reporter to use possible values: 'dots', 'progress' available reporters: https://npmjs.org/browse/keyword/karma-reporter
singleRun : false, // Continuous Integration mode if true, Karma captures browsers, runs the tests and exits
autoWatch : true, // Enable / disable watching file and executing tests whenever any file changes
colors : true, // enable / disable colors in the output (reporters and logs)
files : [], // list of files / patterns to load in the browser
jspm: {
config : 'system.config.js',
loadFiles : ['test-unit/**/*.js'],
serveFiles : ['dist/**/**']
},
proxies: {
'/base/app' : '/base/dist/app',
'/base/common' : '/base/dist/common',
'/jspm_packages' : '/base/jspm_packages'
},
exclude: [
'coverage/**',
'typings/**',
'dist/**/*.js.map'
],
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_DEBUG,
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'src/**/*.js' : ['babel', 'coverage']
},
babelPreprocessor: {
options: { sourceMap:'inline', modules:'system' }
},
coverageReporter: { type:'html', dir:'coverage/' }
});
};
I'm think with Karma is not possible to exclude files from being watched that should also be served.
By excluding the jspm_packages Karma stops serving system.js which is located in the jspm_packages folder and therefore System is not defined.
If you want to get rid of serving the jspm_packages during the test run you could try to run the tests after creating a self-executing bundle and just serve that bundle.
See https://github.com/jspm/jspm-cli/blob/master/docs/production-workflows.md#creating-a-self-executing-bundle

browserify/karma/angular.js "TypeError: Cannot read property '$injector' of null" when second test uses "angular.mock.inject", "currentSpec" is null

I have an Angular.js app and am experimenting with using it with Browserify. The app works, but I want to run tests too, I have two jasmine tests that I run with karma. I user browserify to give me access to angular.js and angular-mocks.js and other test fixtures within the tests.
Versions are:-
"angular": "^1.4.0",
"angular-mocks": "^1.4.0",
"browserify": "^10.2.3",
"karma": "^0.12.32",
"karma-browserify": "^4.2.1",
"karma-chrome-launcher": "^0.1.12",
"karma-coffee-preprocessor": "^0.2.1",
"karma-jasmine": "^0.3.5",
"karma-phantomjs-launcher": "^0.1.4",
If I run the tests individually (by commenting one or the other from the karma.conf file) they both work OK. (yey!)
But if I run them both I get this error
TypeError: Cannot read property '$injector' of null
at Object.workFn (/tmp/3efdb16f2047e981872d82fd8db9c0a8.browserify:2272:22 <- node_modules/angular-mocks/angular-mocks.js:2271:0)
looking at line 2271 of the angular.mocks.js It reads
if (currentSpec.$injector) {
So clearly currentSpec is somehow now null.
I have isolated the problem to when I call "angular.mock.inject" in the second test.
beforeEach(angular.mock.inject(function (_GridUtilService_) {
gridUtilService = _GridUtilService_;
}));
If I comment this out it works, but obviously I can't then run a test n my gridUtilService.
Does anyone know how to run two (or more :-) angular-mock jasmine tests with karma and browserify?
below are my tests, karma.conf file. the Angular services work when deployed but for this purpose they can simply be dumb services that do nothing.
karma.conf:-
// Karma configuration
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: ['browserify', 'jasmine'],
// list of files / patterns to load in the browser
files: [
'src/main/assets/js/**/*.js',
// 'src/test/**/*.js'
'src/test/services/SettingUtil*.js',
'src/test/services/GridUtil*.js'
],
// list of files to exclude
exclude: [
'src/main/assets/js/**/app-config.js'
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'src/main/assets/js/**/*.js': ['browserify'],
'src/test/**/*.js': ['browserify']
},
browserify: {
debug: true,
extensions: ['.js', '.coffee', '.hbs']
},
// 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_DEBUG,
// 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: ['PhantomJS'],
browsers: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false
});
};
src/test/services/SettingUtilServiceTest.js:
'use strict';
describe("SettingUtilServiceTest.", function() {
it("contains spec with an expectation", function() {
expect(true).toBe(true);
});
require('angular');
require('angular-mocks');
// can't do below see error at https://github.com/xdissent/karma-browserify/issues/10
//beforeEach(module('dpServices'));
//so need todo this
beforeEach(angular.mock.module('dpServices'));
var fixtures = require('./serviceFixtures.js');
var sus = fixtures.settingUtilServiceTestFixtures;
var ts1 = sus.tablesetting1;
var ts2 = sus.tablesetting2;
var settingUtilService;
beforeEach(angular.mock.inject(function (_settingUtilService_) {
settingUtilService = _settingUtilService_;
}));
it('should return an object containing mins and maxs from function minMaxes()', function() {
expect(ts1).toBeDefined();
expect(ts2).toBeDefined();
var minMaxs = settingUtilService.minMaxs(ts1);
var mins = minMaxs.mins;
expect(mins).toBeDefined();
var maxs = minMaxs.maxs;
expect(maxs).toBeDefined();
});
});
src/test/services/GridUtilServiceTest.js:
'use strict';
describe("GridUtilServiceTest.", function() {
it("is a set of tests to test GridUtilService.", function() {
expect(true).toBe(true);
});
require('angular');
require('angular-mocks');
// can't do below see error at https://github.com/xdissent/karma-browserify/issues/10
// beforeEach(module('dpServices'));
//so need todo this
beforeEach(angular.mock.module('dpServices'));
var fixtures = require('./gridFixtures.js');
var gridFix = fixtures.gridUtilServiceTestFixtures;
var ts1 = gridFix.tablesetting1;
var ts2 = gridFix.tablesetting2;
var ts3 = gridFix.tablesetting3;
var gridUtilService;
beforeEach(angular.mock.inject(function (_GridUtilService_) {
gridUtilService = _GridUtilService_;
}));
it('should return an object containing mins and maxs from function minMaxes()', function() {
expect(ts1).toBeDefined();
expect(ts2).toBeDefined();
expect(ts3).toBeDefined();
});
});
If you need access to the angular setup I can provide it (split into multiple files using browserify's require() function and built with gulp... but as I say the app runs ok and the tests only fail when there are two tests, so I think the issue is with karma-jasmine and angular-mocks or overwriting the currentSpec variable.
If anyone knows how to split my angular tests into multiple tests (I don't want a monolithic angular test) without the error message all help is appreciated. thanks.
I had the same issue, the issue for me was because I was requiring angular and angular-mocks exactly as you were inside each describe block. I moved the two lines
require('angular');
require('angular-mocks');
above the describe blocks and made sure to only call them once.