Reputation: 504
I'm having an issue with Jasmine (+Karma + Webpack)
I narrowed the test down to the beforeEach
statement not waiting for the done()
callback to be executed before running the it
block.
EDIT: Navjot Ahuja pointed out that jasmine-node has an issue with setTimeout
in beforeEach
so I've changed it to use promises, slightly different to his suggestion (as his works, but this example doesn't)
Here's some things I've found which are odd:
spec
plugin (or `dots)
beforeAll
it works (but that's not an option)This is the test:
describe('Test', function () {
let flag = false;
describe('simple test -', function () {
beforeEach(function (done) {
console.log('SETTING TIMEOUT');
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
flag = true;
done();
}
};
xhttp.open('GET', 'https://api.github.com/zen', true);
xhttp.send();
});
it('should wait for done and set flag correctly', function () {
console.log('INSIDE IT STATEMENT');
expect(flag).toBe(true);
});
});
});
This is karma.conf.js
// Karma configuration
const webpackTestConfig = require('./build/tests.webpack.config.js');
module.exports = function (config) {
const webpackConfig = webpackTestConfig;
config.set({
client: {
args: [
`--ver=${config.ver}`,
`--region=${config.region}`,
`--env=${config.env}`
],
captureConsole: true
},
basePath: '',
frameworks: ['jasmine'],
files: [
'tests/integration/integrationTests.js'
],
reporters: ['spec', 'junit'],
junitReporter: {
useBrowserName: false,
outputFile: 'reports/js/unit-components/results/ITESTS-junit.xml'
},
coverageReporter: {
reporters: [
{type: 'text-summary', dir: 'reports/js/unit-components/coverage/text-summary/', subdir: '.'},
{type: 'lcov', dir: 'reports/js/unit-components/coverage/lcov/', subdir: '.'},
{type: 'html', dir: 'reports/js/unit-components/coverage/html', subdir: '.'},
{type: 'cobertura', dir: 'reports/js/unit-components/coverage/cobertura', subdir: '.'}
]
},
preprocessors: {
'tests/integration/integrationTests.js': ['webpack']
},
webpack: webpackConfig,
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
captureTimeout: 60000,
browserNoActivityTimeout: 600000,
singleRun: false
});
};
This is the test.webpack.config.js
/*global __dirname*/
const webpackConfigBase = require('./webpack.config.js');
const path = require('path');
const _ = require('underscore');
const rootDir = path.resolve(__dirname, '..');
module.exports = () => {
const config = webpackConfigBase();
_.extend(config.resolve.alias, {
'integrationTests': path.join(rootDir, 'tests/integration'),
'testUtils': path.join(rootDir, 'tests/util'),
'testFixtures': path.join(rootDir, 'tests/fixture')
});
return config;
};
And this is the referenced base webpack config:
/* globals __dirname */
const path = require('path');
const rootDir = path.resolve(__dirname, '..');
function matchModule(resource, moduleName) {
return resource && resource.indexOf(moduleName) >= 0;
}
module.exports = () => ({
context: path.join(rootDir, 'www/latest/'),
entry: './app/api.js',
resolve: {
modules: [
path.join(rootDir, 'www/latest/app'),
path.join(rootDir, 'node_modules')
],
alias: {
'vendor': path.join(rootDir, 'www/latest/vendor')
// other paths here but removed
}
},
output: {
path: path.join(rootDir, 'www/latest/dist/'),
publicPath: 'CENSOREDPATH',
filename: 'api.js',
devtoolModuleFilenameTemplate: 'applicationname://[resource-path]',
devtoolFallbackModuleFilenameTemplate: 'applicationname://[resource-path]?[hash]'
},
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
loader: 'eslint-loader'
},
{
test: /\.js$/,
exclude: function (resource) {
const es6Vendors = [
'vendor/censored/src',
'vendor/babel'
];
const isNodeModule = matchModule(resource, 'node_modules');
const isVendor = matchModule(resource, 'vendor');
const isEs6Vendor = (es6Vendors.filter(vendor => matchModule(resource, vendor)).length >= 1);
if (isNodeModule || (isVendor && !isEs6Vendor)) {
return true;
}
return false;
},
loader: 'babel-loader'
}
]
},
externals: {
'react/addons': true,
'react/lib/ExecutionEnvironment': true,
'react/lib/ReactContext': true
},
node: {
setImmediate: false,
clearImmediate: false
}
});
=========================================================================
This is the output from the console:
Version: webpack 3.6.0
Time: 39ms
webpack: Compiled successfully.
webpack: Compiling...
06 10 2017 07:30:01.789:WARN [karma]: No captured browser, open http://localhost:9876/
Hash: 020b93689ec1147a0c3b
Version: webpack 3.6.0
Time: 70ms
Asset Size Chunks Chunk Names
tests/integration/integrationTests.js 3.96 kB 0 [emitted] tests/integration/integrationTests.js
[0] ./tests/integration/integrationTests.js 238 bytes {0} [built]
[1] ./tests/integration models\/item.spec.js$ 192 bytes {0} [built]
[2] ./tests/integration/specs/models/item.spec.js 612 bytes {0} [optional] [built]
webpack: Compiled successfully.
06 10 2017 07:30:01.799:INFO [karma]: Karma v1.7.1 server started at http://0.0.0.0:9876/
06 10 2017 07:30:01.800:INFO [launcher]: Launching browser Chrome with unlimited concurrency
06 10 2017 07:30:01.812:INFO [launcher]: Starting browser Chrome
06 10 2017 07:30:02.238:INFO [Chrome 61.0.3163 (Linux 0.0.0)]: Connected on socket mL2CqoCdzxFggtuIAAAA with id 72267743
Chrome 61.0.3163 (Linux 0.0.0) LOG LOG: '=================', './specs/models/item.spec.js', '================='
LOG LOG: 'SETTING TIMEOUT'
LOG LOG: 'INSIDE IT STATEMENT'
Test
simple test -
Test
simple test -
✗ should wait for done and set flag correctly
Expected false to be true.
at UserContext.<anonymous> (tests/integration/integrationTests.js:121:30)
✗ should wait for done and set flag correctly
Expected false to be true.
at UserContext.<anonymous> (tests/integration/integrationTests.js:121:30)
Chrome 61.0.3163 (Linux 0.0.0): Executed 2 of 1 (2 FAILED) ERROR (0.007 secs / 0.003 secs)
The notable errors from the aforementioned console errors are:
Uncaught TypeError: Cannot read property 'spies' of undefined
Uncaught Error: Tried to complete the wrong suite
And the full output:
================= ./specs/models/item.spec.js =================
integrationTests.js:120 asdfasdf
debug.js:15 FAILED Test simple test - Test simple test - should wait for done and set flag correctly
debug.js:15 FAILED Test simple test - should wait for done and set flag correctly
2debug.js:6 Skipped 0 tests
integrationTests.js:120 asdfasdf
debug.js:21 Uncaught Expected false to be true.
at UserContext.<anonymous> (http://karma.vg.censored.com/base/tests/integration/integrationTests.js:121:26)
(anonymous) @ debug.js:21
setTimeout (async)
(anonymous) @ debug.js:20
window.__karma__.result @ debug.js:23
KarmaReporter.specDone @ adapter.js:243
dispatch @ jasmine.js:4366
(anonymous) @ jasmine.js:4337
specResultCallback @ jasmine.js:1175
complete @ jasmine.js:530
(anonymous) @ jasmine.js:4231
channel.port1.onmessage @ jasmine.js:1774
debug.js:21 Uncaught Expected false to be true.
at UserContext.<anonymous> (http://karma.vg.censored.com/base/tests/integration/integrationTests.js:121:26)
(anonymous) @ debug.js:21
setTimeout (async)
(anonymous) @ debug.js:20
window.__karma__.result @ debug.js:23
KarmaReporter.specDone @ adapter.js:243
dispatch @ jasmine.js:4366
(anonymous) @ jasmine.js:4337
specResultCallback @ jasmine.js:1175
complete @ jasmine.js:530
(anonymous) @ jasmine.js:4231
channel.port1.onmessage @ jasmine.js:1774
jasmine.js:1024 Uncaught TypeError: Cannot read property 'spies' of undefined
at currentSpies (jasmine.js:1024)
at SpyRegistry.clearSpies (jasmine.js:4848)
at clearResourcesForRunnable (jasmine.js:818)
at Spec.specResultCallback [as resultCallback] (jasmine.js:1173)
at QueueRunner.complete [as onComplete] (jasmine.js:530)
at jasmine.js:4231
at MessagePort.channel.port1.onmessage (jasmine.js:1774)
currentSpies @ jasmine.js:1024
SpyRegistry.clearSpies @ jasmine.js:4848
clearResourcesForRunnable @ jasmine.js:818
specResultCallback @ jasmine.js:1173
complete @ jasmine.js:530
(anonymous) @ jasmine.js:4231
channel.port1.onmessage @ jasmine.js:1774
jasmine.js:1024 Uncaught TypeError: Cannot read property 'spies' of undefined
at currentSpies (jasmine.js:1024)
at SpyRegistry.clearSpies (jasmine.js:4848)
at clearResourcesForRunnable (jasmine.js:818)
at nodeComplete (jasmine.js:955)
at QueueRunner.onComplete (jasmine.js:5327)
at jasmine.js:4231
at MessagePort.channel.port1.onmessage (jasmine.js:1774)
currentSpies @ jasmine.js:1024
SpyRegistry.clearSpies @ jasmine.js:4848
clearResourcesForRunnable @ jasmine.js:818
nodeComplete @ jasmine.js:955
onComplete @ jasmine.js:5327
(anonymous) @ jasmine.js:4231
channel.port1.onmessage @ jasmine.js:1774
jasmine.js:951 Uncaught Error: Tried to complete the wrong suite
at nodeComplete (jasmine.js:951)
at QueueRunner.onComplete (jasmine.js:5327)
at jasmine.js:4231
at MessagePort.channel.port1.onmessage (jasmine.js:1774)
nodeComplete @ jasmine.js:951
onComplete @ jasmine.js:5327
(anonymous) @ jasmine.js:4231
channel.port1.onmessage @ jasmine.js:1774
jasmine.js:1024 Uncaught TypeError: Cannot read property 'spies' of undefined
at currentSpies (jasmine.js:1024)
at SpyRegistry.clearSpies (jasmine.js:4848)
at clearResourcesForRunnable (jasmine.js:818)
at QueueRunner.onComplete (jasmine.js:984)
at jasmine.js:4231
at MessagePort.channel.port1.onmessage (jasmine.js:1774)
currentSpies @ jasmine.js:1024
SpyRegistry.clearSpies @ jasmine.js:4848
clearResourcesForRunnable @ jasmine.js:818
(anonymous) @ jasmine.js:984
(anonymous) @ jasmine.js:4231
channel.port1.onmessage @ jasmine.js:1774
jasmine.js:2373 Uncaught Uncaught TypeError: Cannot read property 'spies' of undefined
I have spent many hours on this now and have no clue, can anyone advise please?
Upvotes: 2
Views: 1807
Reputation: 1061
If you have found this question by searching for Uncaught Error: Tried to complete the wrong suite
:
See if there are any other errors in your code. Do this by setting singleRun: true
at the top level of karma configuration and take a look at the console in the browser.
See if maybe you have accidentally imported jasmine
twice. This may happen because:
jasmine
to frameworks
in karma config, you have added it to files
jasmine
, so you are needlessly specifying jasmine
under frameworks
. Example of such a plugin: @metahub/karma-jasmine-jquery
Upvotes: 1
Reputation: 1171
I guess timeouts are not supported right now in jasmine-node(Issue: https://github.com/mhevery/jasmine-node/issues/344)
You can use promises. Like this:
describe('Test', function() {
let flag = false;
let beforeEachPromise;
describe('simple test -', function() {
beforeEach(function(done) {
console.log('SETTING TIMEOUT');
beforeEachPromise = new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('TIMEOUT CALLBACK TRIGGERED');
flag = true;
done();
}, 2000);
})
});
it('should wait for done and set flag correctly', function() {
beforeEachPromise.then(function() {
expect(flag).toBe(true);
})
});
});
});
Upvotes: 1