Why is Karma not receiving a message from the browser after tests execution completes? - karma-runner

A test was failing with:
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
So I added this.timeout(0) to it, then I got:
Disconnected, because no message in 10000 ms.
I went on to add browserNoActivityTimeout: 0 to my config file.
When I try to run the tests, the browser opens and the console shows the passed test.
SUCCESS
Skipped 0 tests
Why is the browser not being closed? What is it waiting for?
browserNoActivityTimeout
How long will Karma wait for a message from a browser before disconnecting from it (in ms).
https://github.com/karma-runner/karma/blob/master/docs/config/01-configuration-file.md#browsernoactivitytimeout
Command:
karma start --single-run
Config:
webpackConfig.module.loaders.push({
test: /\.js$/,
include: /src/,
exclude: /node_modules/,
loader: 'isparta'
});
var karmaConfig = {
frameworks: ['mocha'],
browsers: ['Chrome'],
//browserNoActivityTimeout: 0,
logLevel: 'INFO',
//reporters: ['progress', 'coverage-allsources', 'coverage'],
reporters: ['progress', 'coverage'],
autoWatch: true,
files: [
'test/karma.js'
],
urlRoot: '/karma-runner/',
preprocessors: {
'test/karma.js': ['webpack', 'sourcemap']
},
webpackMiddleware: {
stats: 'minimal',
watchOptions: {
aggregateTimeout: 300
}
},
webpack: webpackConfig,
coverageReporter: {
dir: 'report/coverage',
include: 'src/**/*.js',
// Any .js files that are not imported/required need to be added to the
// exclude:, otherwise you will get a JS error for
// 'Unexpected token in esprima.js'.
// This appears to be a bug with the karma-coverage-allsources repo.
exclude: 'src/init.js',
reporters: [
{'type' : 'cobertura'},
{'type' : 'html'},
{'type': 'text-summary'}
]
}
};

Five minutes after typing the question, I find the answer.
The entry point "test/karma.js" has code that opens the debug tab and that is probably interrupting somehow Karma.
window.open('/karma-runner/debug.html', '_blank');

Related

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.

Testing async with karma

I am trying to set up some async tests using karma and jasmine. I am clearly making a very stupid mistake but I need it pointing out to me. After simplifying as much as possible I have the following:
package.json
{
"name": "newtest",
"version": "0.0.0",
"scripts": {
"test": "karma start karma.conf.js"
},
"devDependencies": {
"karma": "^0.12.28",
"karma-chrome-launcher": "^0.1.5",
"karma-jasmine": "^0.2"
}
}
karma.conf.js
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'tests/**/*.js'
],
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['Chrome'],
singleRun: true
});
};
tests/dummy.spec.js
describe("Testing async", function() {
it('should fail this test', function(done) {
setTimeout(function(){
expect(1).toBe(2);
done();
}, 1000);
});
it('should not fail this test', function(done) {
done();
});
});
and I am getting the following:
npm test
> newtest#0.0.0 test /home/mark/Projects/newtest
> karma start karma.conf.js
INFO [karma]: Karma v0.12.16 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
INFO [Chrome 39.0.2171 (Linux)]: Connected on socket T7j6LvNAwvS89wUdymCb with id 16891024
Chrome 39.0.2171 (Linux) Testing async should not fail this test FAILED
TypeError: undefined is not a function
at null.<anonymous> (/home/mark/Projects/newtest/tests/dummy.spec.js:12:5)
Chrome 39.0.2171 (Linux): Executed 2 of 2 (1 FAILED) (0.007 secs / 0.005 secs)
npm ERR! Test failed. See above for more details.
npm ERR! not ok code 0
So the test that I think should fail is passing fine, and vice-versa. Can someone point me to my error(s)?
I guess the first one fail because when the timeout is reach the test is allready finish, so both doesn't work.
It's has you'r not using jasmine 2.
The syntax seems good to me, what I can tell you is the difference with my configuration (wich is working) :
I have put karma-jasmine in dependencies with a ~ :
"dependencies": {
...
"karma-jasmine": "~0.2.0"
},
I'm using PhantomJS :
browsers:['PhantomJS'],
I don't know why I am having the problem, but I have tried on another machine and it works as expected.

karma coverage does not show any data

I have included the source files in the files & preprocessors section of my karma conf file. The tests run fine and the junit xml report shows the data. The html coverage just show 100% without any data. I have the similar structure for another project which is working fine but not this one. Not sure if i am missing something. Might be a very minor or silly thing i have missed.
karma.conf.js:
module.exports = function (config) {
config.set({
basePath: '../../',
frameworks: [
'jasmine'
],
// list of files / patterns to load in the browser
files: [
'app/js/**/*.js',
'test/spec/**/*.js'
],
preprocessors: {
'app/js/**/*.js': ['coverage']
},
exclude: [],
reporters: [ 'progress', 'junit', 'coverage' ],
coverageReporter: {
type: 'html',
dir: 'test/reports/unit/coverage'
},
junitReporter: {
outputFile: 'test/reports/unit/junit/junit.xml',
suite: 'unit'
},
port: 9876,
runnerPort: 9100,
colors: true,
logLevel: config.LOG_DEBUG,
autoWatch: false,
browsers: [ 'Chrome' ],
captureTimeout: 60000,
singleRun: true
});
};
my karma conf file is in test -> spec -> conf
and source files are in app -> js -> controllers/directives/services
the debug log shows its loading all the files in preprocessors but the report does not show any data "No data to display".
Use the following process:
Append the basepath to the preprocessor path:
../../app/js/**/*.js': ['coverage']
Restart karma
View the updated report

karma-runner error: Cannot call method 'invoke' of undefined

My karma runner is confusing me. Some tests run just fine but others, seemingly similar, don't.
This works:
it('should display an error when accessing /business-user without authentication', function() {
browser().navigateTo('../business-user');
expect(element('p#flash').text()).toBe('You must be logged in to access that page.');
});
This does not:
it('should take the user to the index lander upon logout', function() {
browser().navigateTo('../business-user/login');
input('username').enter('matt');
input('password').enter('letmein');
element('input:last').click();
element('a#logout').click();
expect(browser().window().path()).toBe('/');
});
Running the test as displayed gives me an error that a#logout cannot be found. I paused the runner to verify that a#logout was there, and it was. When I resume, I get the "TypeError: Cannot call method 'invoke' of undefined" error.
I would think the object that should be defined is the element, but why wouldn't it say that it can't find the element? And more importantly, why can't it find it in the first place?
Obligatory karma-e2e.conf.js dump:
// Karma configuration
// Generated on Tue Aug 20 2013 17:01:18 GMT-0600 (MDT)
module.exports = function(config) {
config.set({
basePath: '../..',
frameworks: ['ng-scenario'],
files: [
'test/e2e/*.js'
],
exclude: [
],
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['Chrome'],
captureTimeout: 60000,
singleRun: true,
proxies: {
'/': 'http://localhost:3000/'
},
urlRoot: '/_karma_/'
});
};
Any ideas?