Use of reserved word 'class' with karma and webpack - angularjs

I'm building a project with angularJS in ES6.
I'm trying to config karma test runner and coverage with istanbul.
When I try to lauch unit test with Karma, I've following error :
Use of reserved word 'class'
This is my karma config file :
var path = require('path');
module.exports = function (config) {
config.set({
basePath: '',
plugins: [
'karma-coverage',
'karma-jasmine',
'karma-phantomjs-launcher',
'karma-webpack',
'karma-coverage-istanbul-reporter'
],
frameworks: ['jasmine'],
files: [
'tests/index.js'
],
preprocessors: {
'tests/index.js': 'webpack'
},
webpack: {
module: {
rules: [{
test : /\.js$/,
use : {
loader: 'istanbul-instrumenter-loader',
query : {
esModules: true
}
},
include: path.resolve('src/')
}, {
test: /\.html$/, loaders: ["html-loader"]
}, {
test: /\.less$/,
use : [{
loader: "style-loader"
}, {
loader: "css-loader"
}, {
loader: "less-loader"
}]
}, {
test : /\.woff($|\?)|\.woff2($|\?)|\.ttf($|\?)|\.eot($|\?)|\.svg($|\?)/,
loader: 'url-loader'
}]
}
},
reporters: ['progress', 'coverage-istanbul'],
coverageIstanbulReporter: {
reports : ['text-summary'],
fixWebpackSourcePaths: true
},
port : 9876,
colors : true,
logLevel : config.LOG_INFO,
autoWatch : true,
browsers : ['PhantomJS'],
singleRun : true,
concurrency: Infinity,
})
};
And this is my tests/index.js file
// requires all tests in `project/test/src/components/**/index.js`
const tests = require.context('./specs/', true, /index\.js$/);
tests.keys().forEach(tests);
// requires all components in `project/src/components/**/index.js`
const components = require.context('../src/', true, /\.js$/);
components.keys().forEach(components);
Did I miss something ?
Thanks.

PhantomJS currently doesn't support es2015+.
So you either need a transpiler loader like babel-loader,
or you need to install PhantomJS beta which supports new syntax.

Related

Slow Karma Unit Tests

I wrote unit tests for a small reach application using Jasmine and Karma.And Karma is running slow for these tests.
This is my karma config:
var unitTestReportOutputDir = 'unit-test-report';
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
reporters: ['dots'],
port: 9876,
colors: false,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
autoWatchBatchDelay: 300,
exclude: ['./test/data/*.js'],
files: [
'tests.webpack.js'],
preprocessors: {
'tests.webpack.js': ['webpack']
},
webpack: require('./webpack.config.js'),
webpackMiddleware: {
noInfo: true
},
htmlReporter: {
outputDir: unitTestReportOutputDir, // where to put the reports
focusOnFailures: true, // reports show failures on start
namedFiles: true, // name files instead of creating sub-directories
pageTitle: 'Unit Test Report', // page title for reports; browser info by default
urlFriendlyName: false, // simply replaces spaces with _ for files/dirs
reportName: 'test-summary', // report summary filename; browser info by default
// experimental
preserveDescribeNesting: false, // folded suites stay folded
foldAll: false, // reports start folded (only with preserveDescribeNesting)
}
});
}
This is my webpack.config.js:
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var webpack = require('webpack');
var UglifyJsPlugin = require('uglify-js-plugin');
const path = require('path');
module.exports = {
devtool: 'inline-source-map',
entry: ['./src/index.js'],
output: {path: path.resolve(__dirname, "builds"), filename: 'bundle.js'},
module: {
rules: [
{
test: /\.jsx?$/,
use: [
{
loader: 'babel-loader'
}
]
},
{
test: /\.sass$/,
exclude: '/node_modules/',
use: ExtractTextPlugin.extract({
fallback: "style-loader",
loader: "css-loader!sass-loader"
})
}
]
},
resolve: {
extensions: ['.js', '.jsx', '.sass']
},
plugins: [
new ExtractTextPlugin({
filename: "stylesheets/style.css",
disable: false,
allChunks: true
}),
new webpack.ProvidePlugin({
"$": "jquery",
"jQuery": "jquery",
"window.jQuery": "jquery"
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production')
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
})
]
};
What do you guys usually do to speed up Karma in running unit tests ?
I put the code at: https://github.com/zainulfranciscus/karma-test
karma took 1 min 15 sec to start and 33 seconds to ran the tests, whenever I updated a test. There are 35 unit tests
Thank you.
Check out the karma-parallel plugin here:
https://www.npmjs.com/package/karma-parallel
More popular and karma-webpack compatible compared to the karma-sharding plugin.
Have you looked at karma-sharding? This plugin addresses some memory usage problems with some browsers, and numerous or memory intensive specs.
It will not run your tests all in parallel, but as of version 4.0.0, it supports parallel browser execution(i.e. will shard tests across browsers listed in your karma.conf.js)

babel webpack configuration ignored in karma.conf.js?

I am trying to make my first JS unit test with Karma and Jasmin. I am testing a react app.
I generated the karma config with "karma init" and modified it, see below for the karma.config.js
The webpack.config is required in the karma.config.js, but the babel loader is completely ignored, why?
I noticed it's ignored as it resulted in errors of undefined variable, etc...
When adding parts of the webpack.config.js directly in the karma.config.js (copy/paste), it works, but that is not what I want as I am duplicating code like my loaders and aliases, etc... How to solve this? See below also the webpack.config.js
The karma.config.js:
module.exports = function (config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: 'src/js/',
frameworks: ['jasmine'],
files: [
'tests/*.test.js',
],
preprocessors: {
'**/tests/*.test.js': ['webpack', 'sourcemap'],
},
webpack: require("../webpack.conf.js"),
webpackMiddleware: {
stats: "errors-only"
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['PhantomJS'],
phantomJsLauncher: {exitOnResourceError: true},
singleRun: false,
concurrency: Infinity
})
};
The webpack.config.js:
module.exports = function (env) {
if (env !== undefined) {
let analyse = !!env.analyse;
console.log("Analyse?: " + analyse);
if (analyse) {
plugins.push(new BundleAnalyzerPlugin({analyzerMode: 'static'}));
}
}
return {
entry: {
entry: ['./src/entry.js', './src/js/utils.js'],
},
devtool: devTool,
devServer: devServer,
output: {
path: __dirname + '/dist',
filename: '[name]-[hash].cache.js', // it contains the name ".cache", that is used in the webserver config.
sourceMapFilename: '[name]-[hash].cache.js.map',
},
module: {
rules: [
{ // The Babel loader:
test: /(\.jsx|\.js)$/,
exclude: /(node_modules|bower_components)/,
use: [{
loader: 'babel-loader',
options: {
presets: ['babel-preset-es2015', 'babel-preset-react'].map(require.resolve),
plugins: ['babel-plugin-transform-react-jsx-img-import'].map(require.resolve) // It will convert the used images to to "require" statements such that it's used by a loader below.
}
}]
},
{
test: /\.s?css$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(png|gif|jpe?g)$/,
use: [{
loader: 'file-loader',
options: {
name: 'resources/images/[name]-[hash]-cache.[ext]'
}
}]
},
{
test: /\.(otf|svg|eot|ttf|woff2?)(\?.*$|$)/,
use: [{
loader: 'file-loader',
options: {
name: 'resources/fonts/[name]-[hash]-cache.[ext]'
}
}]
},
]
},
plugins: plugins,
externals: ['axios'],
resolve: {
alias: {
// Ref: https://webpack.js.org/configuration/resolve/
Context: path.resolve(__dirname, 'src/js/context'),
Utils: path.resolve(__dirname, 'src/js/utils'),
....etc...
},
}
};
};
in karma.config.js:
webpack: require("../webpack.conf.js")
you're giving "webpack" a function instead of an object. you should immediately invoke it (with or without an env param) require("../webpack.conf.js")()

Karma Coverage for React JSX Files is Corrupted

I'm running test coverage over my .js and .jsx files using karma, mocha, and isparta for ES6 code coverage.
For some reason the coverage report over .jsx files is corrupted.
See the following image:
The report looks the same for all of the .jsx files, i.e. from the line the JSX syntax appears - the coverage is corrupted, even though we can see the function has been visited once.
Here is my karma.conf.js file:
var path = require('path');
var isparta = require('isparta');
const babelOptions = {
presets: ['stage-0', 'react'],
plugins: [
'transform-es2015-modules-commonjs',
'transform-es2015-destructuring',
'transform-es2015-spread',
'transform-object-rest-spread',
'transform-class-properties'
]
};
module.exports = function (config) {
config.set({
browsers: [process.env.JENKINS_HOME ? 'Firefox' : 'Chrome'],
singleRun: true,
frameworks: ['mocha'],
files: [
'tests.webpack.js'
],
preprocessors: {
'tests.webpack.js': ['webpack', 'sourcemap'],
'src/**/*.jsx': ['coverage']
},
reporters: ['progress', 'coverage'],
coverageReporter: {
dir: 'dist/coverage/',
reporters: [
{type: 'html'},
{type: 'text-summary'}
],
includeAllSources: true,
instrumenters: {isparta: isparta},
instrumenter: {
'**/*.js': 'isparta',
'**/*.jsx': 'isparta'
},
instrumenterOptions: {
isparta: {
babel: babelOptions,
embedSource: true,
noAutoWrap: true,
}
}
},
webpack: {
babel: babelOptions,
devtool: 'inline-source-map',
resolve: {
root: [path.resolve('.')],
alias: {
i18nJson: 'nfvo-utils/i18n/locale.json',
'nfvo-utils/RestAPIUtil.js': 'test-utils/mocks/RestAPIUtil.js',
'nfvo-utils': 'src/nfvo-utils',
'nfvo-components': 'src/nfvo-components',
'sdc-app': 'src/sdc-app'
}
},
module: {
preLoaders: [
{test: /\.js$/, exclude: /(src|node_modules)/, loader: 'eslint-loader'},
{test: /\.(js|jsx)$/, exclude: /(test|test\.js|node_modules)/, loader: 'isparta'}
],
loaders: [
{test: /\.(js|jsx)$/, exclude: /node_modules/, loader: 'babel-loader'},
{test: /\.json$/, loaders: ['json']},
{test: /\.(css|scss|png|jpg|svg|ttf|eot|otf|woff|woff2)(\?.*)?$/, loader: 'ignore-loader'},
]
},
eslint: {
configFile: './.eslintrc',
emitError: true,
emitWarning: true
},
},
webpackServer: {
noInfo: true
}
});
};
Please let me know if any further information is required, and I'll edit.

Can't find nodes with enzyme and css-modules when using karma-webpack

I've been using css-modules with mocha, enzyme and css-modules-require-hook without any problems.
Foo.js
import React from 'react';
import styles from './Foo.css';
const Foo = () => <div className={ styles.foo }>Foo component</div>;
export default Foo;
Foo.css
.foo {
color: rebeccapurple;
}
Foo.test.js
import Foo from './Foo';
describe('<Foo />', () => {
it('should render proper markup', () => {
const wrapper = shallow(<Foo />);
expect(wrapper.find('.foo')).to.have.length(1);
});
});
I started using Karma with karma-webpack-with-fast-source-maps and now the test fails because the styles in Foo.js is an array and it's not using keys to keep original class name.
[[376, '.Foo__foo___3QT3e {
color: rebeccapurple;
}
', '']]
I've tried importing the css-modules-require-hook in test-bundler.js for karma-webpack but that throws a bunch of errors.
WARNING in ./~/css-modules-require-hook/preset.js
Critical dependencies:
13:7-22 the request of a dependency is an expression
# ./~/css-modules-require-hook/preset.js 13:7-22
// many more warnings
ERROR in ./~/css-modules-require-hook/lib/index.js
Module not found: Error: Cannot resolve module 'fs' in /Users/qmmr/code/streetlife/composer/code/site/node_modules/css-modules-require-hook/lib
# ./~/css-modules-require-hook/lib/index.js 14:19-32
// more errors
PhantomJS 2.1.1 (Mac OS X 0.0.0) ERROR
SyntaxError: Unexpected token ')'
webpack.config.test.js
/* eslint-disable */
var path = require('path');
const CSS_MODULES_LOADER = [
'modules',
'importLoaders=1',
'localIdentName=[name]__[local]___[hash:base64:5]'
].join('&');
module.exports = {
resolve: {
extensions: [ '', '.js' ],
},
devtool: 'inline-source-map',
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel',
query: {
cacheDirectory: true,
plugins: [ 'transform-runtime', 'transform-class-properties', 'transform-export-extensions' ],
presets: [ 'es2015', 'react', 'stage-2' ],
}
},
{
test: /\.css$/,
loader: `css?${ CSS_MODULES_LOADER }`,
include: path.join(__dirname, '/css/modules'),
},
{ test: /\.json$/, loader: 'json' },
],
},
externals: {
'cheerio': 'window',
'react/addons': true,
'react/lib/ExecutionEnvironment': true,
'react/lib/ReactContext': true
},
};
karma.conf.js
// Karma configuration
var webpackConfig = require('./webpack.config.test');
module.exports = function(config) {
config.set({
basePath: '',
frameworks: [ 'mocha' ],
plugins: [
'karma-mocha',
'karma-phantomjs-launcher',
'karma-webpack-with-fast-source-maps'
],
files: [
{
pattern: './testBundler.js',
watched: false,
served: true,
included: true,
},
],
exclude: [],
preprocessors: {
[ './test-bundler.js' ]: [ 'webpack' ]
},
webpack: webpackConfig,
webpackMiddleware: {
noInfo: true,
stats: 'errors-only',
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: [ 'PhantomJS' ],
singleRun: true,
concurrency: Infinity,
})
}
test-bundler.js
// ---------------------------------------
// Test Environment Setup
// ---------------------------------------
import React from 'react';
import chai from 'chai';
import sinon from 'sinon';
import { shallow, mount } from 'enzyme';
// require('css-modules-require-hook/preset'); // Fix css-modules not rendering in tests
global.React = React;
global.expect = chai.expect;
global.sinon = sinon;
global.shallow = shallow;
global.mount = mount;
// ---------------------------------------
// Require Tests
// ---------------------------------------
// for use with karma-webpack-with-fast-source-maps
const __karmaWebpackManifest__ = new Array(); // eslint-disable-line
const inManifest = (path) => ~__karmaWebpackManifest__.indexOf(path);
const testsContext = require.context('../react', true, /\.test\.js$/);
// only run tests that have changed after the first pass.
const testsToRun = testsContext.keys().filter(inManifest);
(testsToRun.length ? testsToRun : testsContext.keys()).forEach(testsContext);
How can I use css-modules-require-hook in my setup (karma + webpack)?
EDIT: I've created a repository https://github.com/qmmr/yab to show the issue. When running npm run test:mocha the test passes. When running npm run test it fails (this is the karma-webpack integration).

Webpack error while loading module DomUtils after import enzyme

I have a project with TypeScript and React 0.14.
And I set-up test enviroment with karma/mocha/chai. And its work. But when I import and use function from enzyme I got error in browser (Human-readable error from Chrome):
Uncaught TypeError: ext[key].bind is not a function
As I understood modules 227...232 (internal DomUtils files) not loaded before using.
Maybe I forgot something? Or does anyone know workaround?
Sorry for huge configs:
Webpack config:
var webpack = require("webpack"),
path = require("path"),
ExtractTextPlugin = require("extract-text-webpack-plugin"),
precss = require('precss'),
autoprefixer = require('autoprefixer');
module.exports = {
entry: [
path.resolve(__dirname, "app/app.tsx")
],
output: {
filename: "bundle.js",
publicPath: "/build/",
path: path.resolve(__dirname, "build")
},
module: {
loaders: [
{test: /\.json$/, loader: 'json'},
{test: /\.tsx$/, exclude: /node_modules/, loader: 'es3ify!ts'},
{test: /\.s?css$/, loader: ExtractTextPlugin.extract('style', 'css!postcss')},
{test: /\.svg|eot|ttf|woff|woff2|ico|png|gif|jpg($|\?)/, loader: 'file'}
]
},
postcss: function () {
return [precss, autoprefixer];
},
resolve: {
root: path.resolve(__dirname, "app"),
extensions: ["", ".js", ".ts", ".tsx", ".json"]
},
plugins: [
new ExtractTextPlugin("bundle.css")
]
};
Karma config:
var webpack = require('webpack');
var webpackConfig = require('./webpack.config');
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['mocha', 'chai', 'sinon'],
files: [
'app/**/*-test.tsx'
],
exclude: [],
preprocessors: {
'app/**/*.tsx': ['webpack']
},
webpack: {
resolve: webpackConfig.resolve,
module: webpackConfig.module,
externals: {
'cheereo': 'window',
'react/addons': true,
'react/lib/ExecutionEnvironment': true,
'react/lib/ReactContext': true
}
},
reporters: ['progress', 'spec'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['PhantomJS'],
singleRun: true,
concurrency: Infinity
})
}
Test file:
import * as React from 'react';
import { shallow } from 'enzyme';
describe('Dashboard', () => {
it('should be OK', () => {
const instance = shallow(<div />);
expect(true).to.equal(true, 'true === true');
});
});
Webpack import chain: enzyme -> ... -> cheerio -> ... -> DomUtils
StackOverflow my last chance to solve the problem, Google don't know answer.
I've faced with same issue, for me it helps to put domutils as extrenal in webpack configuration. Based on your config try this:
webpack: {
resolve: webpackConfig.resolve,
module: webpackConfig.module,
externals: {
'domutils': 'true',
'cheereo': 'window',
'react/addons': true,
'react/lib/ExecutionEnvironment': true,
'react/lib/ReactContext': true
}
}

Resources