Currently I'm trying to write some tests for a Vue component. However when I try to run the tests it errors out with the following message:
[BABEL] Note: The code generator has deoptimised the styling of /home/bono/dev/git_repos/hypernode-control-panel/hncp/vue/common/tests/unit/UpdateElementRadio.spec.es5.js as it exceeds the max of 500KB.
13 12 2018 15:52:18.339:INFO [karma-server]: Karma v3.1.3 server started at http://0.0.0.0:9876/
13 12 2018 15:52:18.341:INFO [launcher]: Launching browsers PhantomJS with concurrency unlimited
13 12 2018 15:52:18.344:INFO [launcher]: Starting browser PhantomJS
13 12 2018 15:52:18.594:INFO [PhantomJS 2.1.1 (Linux 0.0.0)]: Connected on socket fBfbs8v8mD1WMsLOAAAA with id 26571362
ERROR LOG: '[Vue warn]: Error in config.errorHandler: "ReferenceError: Can't find variable: Set"'
ERROR LOG: ReferenceError: Can't find variable: Set
patchRenderMixin
callHook
_init
VueComponent
createComponentInstanceForVnode
init
createComponent
createElm
patch
_update
updateComponent
get
Watcher
mountComponent
$mount
mount
shallowMount
callFn@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4550:25
run@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4542:13
runTest@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:5078:13
http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:5196:19
next@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4992:16
http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:5002:11
next@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4926:16
http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4970:9
timeslice@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:82:27
ERROR LOG: '[Vue warn]: Error in beforeCreate hook: "ReferenceError: Can't find variable: Set"
found in
---> <UpdateElementRadio> at hncp/vue/common/src/components/UpdateElementRadio.vue
<Root>'
ERROR LOG: ReferenceError: Can't find variable: Set
patchRenderMixin
callHook
_init
VueComponent
createComponentInstanceForVnode
init
createComponent
createElm
patch
_update
updateComponent
get
Watcher
mountComponent
$mount
mount
shallowMount
callFn@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4550:25
run@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4542:13
runTest@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:5078:13
http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:5196:19
next@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4992:16
http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:5002:11
next@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4926:16
http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:4970:9
timeslice@http://localhost:9876/base/node_modules/mocha/mocha.js?840d4fbbcc65a16cec39f9e25af2ea6d2cff68ea:82:27
UpdateElementRadio
✗ accepts label_text prop
Can't find variable: Set
patchRenderMixin
callHook
_init
VueComponent
createComponentInstanceForVnode
init
createComponent
createElm
patch
_update
updateComponent
get
Watcher
mountComponent
$mount
mount
shallowMount
PhantomJS 2.1.1 (Linux 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.041 secs / 0.01 secs)
npm ERR! Test failed. See above for more details.
This is the test I'm trying to run (note that it might be a bit of a non-sense test, I'm just trying to get things to work first):
import Vue from 'vue'
import { expect } from 'chai';
import { shallowMount } from '@vue/test-utils';
import UpdateElementRadio from '../../src/components/UpdateElementRadio.vue';
describe('UpdateElementRadio', () => {
it('accepts label_text prop', () => {
shallowMount(UpdateElementRadio);
const vm = new Vue(UpdateElementRadio).$mount();
console.log(vm.props);
expect(vm.props.label_text).to.equal(String);
});
});
I'm not too experienced with setting this stuff up, but everything works fine when I don't try to use any mount
function from vue-test-utils
. I have a feeling there's something wrong with my babel setup or something, since it's a es2015 reference (at least I found it was trying to get it from a lib.es2015
file). I tried using different babel presets, none really worked (or came up with more errors). I also checked the docs for @babel/preset-env
and I think it's the correct preset to use.
I'll share my karma config, webpack config and package.json
as well:
karma.conf.js:
// Karma configuration
// Generated on Thu Dec 13 2018 11:28:18 GMT+0100 (Central European Standard Time)
let webpackConfig = 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: ['mocha'],
// list of files / patterns to load in the browser
files: [
'hncp/vue/**/tests/unit/*.spec.js'
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'hncp/vue/**/tests/unit/*.spec.js': ['webpack', 'sourcemap', 'babel']
},
babelPreprocessor: {
options: {
presets: ['@babel/preset-env'],
sourceMap: 'inline',
},
filename: function (file) {
return file.originalPath.replace(/\.js$/, '.es5.js')
},
sourceFileName: function (file) {
return file.originalPath;
},
},
webpack: webpackConfig,
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['spec'],
plugins: [
'karma-phantomjs-launcher',
'karma-webpack',
'karma-sourcemap-loader',
'karma-mocha',
'karma-spec-reporter',
'karma-babel-preprocessor',
'karma-chai',
],
// 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: true,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity,
})
};
webpack.config.js:
var path = require('path'); var webpack = require('webpack'); var BundleTracker = require('webpack-bundle-tracker'); const VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
context: __dirname,
mode: 'development',
entry: {
'hncp/order': ['./hncp/vue/order/src/main'],
},
output: {
path: path.resolve('./hncp/static/webpack_bundles/'),
filename: "[name].js"
},
module: {
rules: [
{ // Needed for loading Vue stuff
test: /\.vue$/,
loader: 'vue-loader'
},
{ // Needed for loading things like <style> tags (used inside Vue stuff)
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{ // Needed for loading things like png files (used inside Vue templates)
test: /\.(eot|svg|png|ttf|woff|woff2)(\?\S*)?$/,
loader: 'file-loader'
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
},
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
new VueLoaderPlugin()
],
};
package.json:
{
"scripts": {
"test": "karma start --single-run"
},
"dependencies": {
"babel-preset-es2015": "^6.24.1",
"karma-cli": "^2.0.0",
"karma-phantomjs-launcher": "^1.0.4",
"vue-template-compiler": "^2.5.21"
},
"devDependencies": {
"@babel/core": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"@vue/test-utils": "^1.0.0-beta.27",
"babel-loader": "^8.0.4",
"chai": "^4.2.0",
"css-loader": "^2.0.0",
"file-loader": "^2.0.0",
"karma": "^3.1.3",
"karma-babel-preprocessor": "^8.0.0-beta.0",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^2.2.0",
"karma-mocha": "^1.3.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.32",
"karma-webpack": "^3.0.5",
"mocha": "^5.2.0",
"style-loader": "^0.23.1",
"vue": "^2.5.21",
"vue-loader": "^15.4.2",
"vue-test-utils": "^1.0.0-beta.11",
"webpack": "^4.27.1",
"webpack-bundle-tracker": "^0.4.2-beta",
"webpack-cli": "^3.1.2"
}
}
If try using $mount
from Vue
that works fine. I.e.:
import Vue from 'vue'
import { expect } from 'chai';
import { mount } from '@vue/test-utils';
import UpdateElementRadio from '../../src/components/UpdateElementRadio.vue';
describe('UpdateElementRadio', () => {
it('accepts label_text prop', () => {
const vm = new Vue(UpdateElementRadio).$mount();
console.log(vm);
expect(vm.props.label_text).to.equal(String);
});
});
I know it's a bit much to look at, but running out of ideas on how to fix this.
This is the UpdateElementRadio
:
<template>
<div class="float-label">
<label>{{ label_text }}</label>
<input type="radio" :name="name" v-on:change="$emit('update-value', value)"/>
<slot></slot>
<div class="update-element-radio-content" style="float:right">
{{ value }}
</div>
</div>
</template>
<script>
export default {
name: 'UpdateElementRadio',
props: {
label_text: String,
name: String,
value: Number
},
};
</script>
So I figured out why this was happening when, it turns out the culprit was PhantomJS. Since it's no longer being actively developed it also means it does not support ES6. See this issue on Github for the same problem I was experiencing.
So instead I decided to use Chrome for my tests instead, I made the following changes:
In karma.conf.js:
//Other config...
plugins: [
'karma-chrome-launcher',
...
]
//Other config...
browsers: ['ChromeHeadless'],
//Other config
In package.json make sure the karma-chrome-launcher
is set:
{
//other
"devDependencies": {
// Other...
"karma-chrome-launcher": "^2.2.0",
// Other...
}
}