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

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?

Related

Karma gives 404 for images (AureliaJS)

Using the Aurelia CLI I run my unit tests with au test. Karma logs to console (over and over again for multiple requests):
WARN [web-server]: 404: /src/assets/images/avatar-backup.png
I understand that including my image files with tests isn't necessary and I could change the log levels to ignore these warnings, but this seems like it should really be a non issue. If for nothing else I want to know why and how to fix this for my own curiosity.
I've tried a combination of different methods found here and here (and elsewhere), but I still cannot figure out what I'm doing wrong. I'm still somewhat new to Karma and Aurelia so maybe I'm missing some fundamental understanding... I don't know.
Currently my this is my karma.conf.js
'use strict';
const path = require('path');
const project = require('./aurelia_project/aurelia.json');
const tsconfig = require('./tsconfig.json');
let testSrc = [
{ pattern: project.unitTestRunner.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];
// Added the image file sources
let imgFiles = [
{pattern: 'src/assets/images/*', watched: false, included: false, served: true, nocache: false},
// Added an exact path in case my pattern was somehow wrong, still doesn't load
{pattern: 'src/assets/images/avatar-backup.png', watched: false, included: false, served: true, nocache: false}
];
// Concat imgFiles to file array
let files = [entryBundle].concat(imgFiles).concat(testSrc).concat(appSrc);
module.exports = function(config) {
config.set({
basePath: '',
frameworks: [project.testFramework.id],
files: files,
exclude: [],
preprocessors: {
[project.unitTestRunner.source]: [project.transpiler.id]
},
typescriptPreprocessor: {
typescript: require('typescript'),
options: tsconfig.compilerOptions
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
// client.args must be a array of string.
// Leave 'aurelia-root', projectName.paths.root in this order so we can find
// the root of the aurelia projectName.
client: {
args: ['aurelia-root', project.paths.root]
},
browserConsoleLogOptions: {
terminal: true,
level: ""
},
// Not sure how to use proxy in combination with my added file sources or if I even need to...
// proxies: {
// "/img/": "http://localhost:9876/base/src/assets/images/"
// },
});
};
My app file structure looks like:
app
- src
- assets
- images
- (..images)
- test
- unit
- (..tests)

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

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');

Karma and Jasmine: Can't find variable: require

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

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.

Karma: browser idle

I am trying Karma for the first time, and after several hours I still can't get it to work.
When I run the test by typing karma start karma.conf.js in the terminal, the browser window opens and displays the following (I have also tried with Chrome with the same result):
This is the terminal output:
29 07 2015 16:27:12.835:INFO [karma]: Karma v0.13.3 server started at http://localhost:9876/
29 07 2015 16:27:12.852:INFO [launcher]: Starting browser Firefox
29 07 2015 16:27:15.866:INFO [Firefox 33.0.0 (Windows 7 0.0.0)]: Connected on socket HA1RSN-QsWuAO7NIAAAA with id 26755366
My karma.conf.js file is located at the root of my Node.js project and looks like this:
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'tests/unit/test.js'
],
exclude: [],
preprocessors: {},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['Firefox'],
singleRun: false
})
}
My test.js file looks like this (example test from a book, my actual tests will the Angular.js tests):
describe("First Test", function () {
var counter;
beforeEach(function () {
counter = 0;
});
it("increments value", function () {
counter++;
expect(counter).toEqual(1);
});
it("decrements value", function () {
counter--;
expect(counter).toEqual(0);
});
});
I'm using Node.js version 0.12.05.
I appreciate any help as I feel really lost here.
You need to trigger a test run, if you want it to execute. There are two ways to do this
Run karma run karma.conf.js in a second terminal window in the same working directory
Change the option singleRun to true, this way it will start, execute the test and then exit.