Gulp + Babel + Webpack + Karma: Use sourcemaps for stacktrace - angularjs

In an AngularJS 1 project we use Gulp to compile the project with webpack and test it with Karma. We cannot get sourcemaps to work as expected.
I found the obvious plug-in (https://www.npmjs.com/package/karma-sourcemap-loader) but this seems to exist only to use sourcemaps while debugging karma tests, NOT to display a usable stacktrace.
I also found https://www.npmjs.com/package/karma-source-map-support which seems to be exclusive for browserify.
Am I missing something here? Has anyone gotten this to work?
Appended info:
This is the unusable output (note index.module.js, the webpack compiled file, which has inline sourcemaps):
PhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 629 of 629 (1 FAILED) (6.663 secs / 6.531 secs)
TOTAL: 1 FAILED, 628 SUCCESS
1) should A B not be A B
TrajectDetails Controller _aMethod()
Expected Object({ a: Object({ x: [ 'A', 'B' ] }) }) not to be Object({ materieel: Object({ x: [ 'A', 'B' ] }) }).
.tmp/serve/app/index.module.js:93820:42
[11:02:26] 'test' errored after 9.37 s
[11:02:26] Error: Failed 1 tests.
This is how my karma config looks:
var preprocessors = {};
pathSrcJs.forEach(function (path) {
preprocessors[path] = ['babel', 'sourcemap'];
});
pathSrcHtml.forEach(function (path) {
preprocessors[path] = ['ng-html2js'];
});
var configuration = {
files: listFiles(),
preprocessors: preprocessors,
singleRun: true,
colors: true,
autoWatch: false,
ngHtml2JsPreprocessor: {
stripPrefix: conf.paths.src + '/',
moduleName: 'xx-xx'
},
logLevel: 'INFO',
frameworks: ['source-map-support', 'jasmine'],
browsers: ['PhantomJS'],
plugins: [
'karma-phantomjs-launcher',
'karma-coverage',
'karma-jasmine',
'karma-ng-html2js-preprocessor',
'karma-spec-reporter',
'karma-babel-preprocessor',
'karma-sourcemap-loader',
'karma-source-map-support'
],
reporters: ['progress', 'spec'],
};
config.set(configuration);
Webpack config is like this:
var webpackOptions = {
watch: watch,
module: {
loaders: [{test: /\.js$/, exclude: /node_modules/, loaders: ['ng-annotate', 'babel-loader']}]
},
output: {filename: output},
devtool = 'inline-source-map'
};
var sources = [path.join(conf.paths.src, source)];
sources.push(path.join(conf.paths.src, '/app/**/*.spec.js'));
return gulp.src(sources)
.pipe(webpack(webpackOptions))
.pipe(gulp.dest(path.join(conf.paths.tmp, '/serve/app')));

Related

How to run tests in Angular & AngularJs hybrid app?

As I want to migrate my AngularJs application to Angular 7, I created a hybrid app using ngUpgrade. The old AngularJs app is now embedded in the new Angular one.
When I run ng test it fires my Angular tests which is fine. But I also want to run the old tests written in AngularJs.
At the moment my Karma config looks like:
'use strict';
const webpackConfig = require('./karma.webpack.config');
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '#angular-devkit/build-angular', 'es6-shim'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('#angular-devkit/build-angular/plugins/karma'),
require('karma-es6-shim'),
require('karma-junit-reporter'),
require('karma-webpack'),
],
client:{
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, 'coverage'),
reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true
},
mime: {
'text/x-typescript': ['ts','tsx']
},
exclude: [
'**/*.html'
],
preprocessors: {
'./karma.entrypoint.ts': ['webpack']
},
webpack: webpackConfig,
webpackMiddleware: {
noInfo: true,
stats: 'errors-only'
},
junitReporter : {
// results will be saved as $outputDir/$browserName.xml
outputDir : 'build/test-results/test/'
},
reporters: ['progress', 'kjhtml', 'junit'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
};
The ./karma.webpack.config file is:
const config = require('./webpack.config.js')();
const webpack = require('webpack');
const path = require('path');
const nibStylusPlugin = require('nib');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
module.exports = Object.assign({}, config, {
context: path.resolve(__dirname, '.'),
entry: {
test: './karma.entrypoint.ts'
},
mode: 'development',
devtool: 'cheap-module-inline-source-map',
optimization: {
splitChunks: false,
runtimeChunk: false
},
plugins: [
new ForkTsCheckerWebpackPlugin(),
new webpack.ProvidePlugin({
"window.jQuery": "jquery",
tv4: "tv4"
}),
new webpack.LoaderOptionsPlugin({
options: {
stylus: {
use: [nibStylusPlugin()],
import: ['~nib/lib/nib/index.styl'],
}
}
})
]
});
And last but not least the karma.entrypoint.ts:
import 'jquery';
import 'angular';
import 'angular-mocks';
import * as moment from 'moment';
import{appConfigMock} from './karma.app-mock.config';
window['__APP_CONFIG__'] = appConfigMock;
(<any>moment).suppressDeprecationWarnings = true;
const testsContext = (<any>require).context('./src/app/', true, /\.spec\.ts$/);
testsContext.keys().forEach(testsContext);
Before, when I had only the AngularJs app, I run the tests with a very similar structure by using karma command. It utilized my webpack config to create a new karma webpack config. Now, when I run it through the ng test command, I even cannot require the './karma.webpack.config' at the beginning on karma configuration (I get Invalid config file! TypeError: require(...) is not a function).
How should I approach this case to run all the tests?
I finally solved it by running the tests separately but with one npm command, npm run test:
"test-ng1": "cross-env APP_CONFIG=testing NODE_ENV=development karma start --single-run",
"test-ng2-apps": "ng test --watch=false --ts-config=./karma.tsconfig.json",
"test": "yarn test-ng2-apps && yarn test-ng1",

Jasmine test spec failing to pickup React import statement

I am trying to write unit tests for my reactjs code using Jasmine with the Karma test runner - automated with gulp. I am having an issue where my test spec includes import statements which are then not being picked up by the test body.
Here is my test spec:
import React from 'react';
import Utils from 'react-dom/test-utils';
import {MyClass} from "../Path/MyCodeFile.jsx";
describe('MyClass', function () {
it('can render without error', function () {
var component;
var element = React.createElement(
MyClass,
{}
);
expect(function () {
component = Utils.renderIntoDocument(element);
}).not.toThrow();
});
})
My Karma config file:
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'spec/*[Ss]pec.js',
'wwwroot/js/site.js'
],
exclude: [
],
preprocessors: {
'spec/*[Ss]pec.js': ['babel']
},
babelPreprocessor: {
options: {
presets: ['es2015', 'env'],
plugins: ["transform-es2015-modules-umd"]
}
},
reporters: ['progress', 'junit'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['Chrome'],
plugins: [
'karma-jasmine',
'karma-junit-reporter',
'karma-chrome-launcher',
'karma-babel-preprocessor'
],
singleRun: true,
concurrency: Infinity
});
}
My gulp task:
var gulp = require('gulp');
var Server = require('karma').Server;
gulp.task('unittest', function (done) {
new Server({
configFile: __dirname + '/karma.conf.js',
singleRun: true
}, function () {
done();
}).start();
});
And this is the message I get when running the task:
[21:17:11] Starting 'unittest'...
02 08 2018 21:17:13.030:INFO [karma]: Karma v2.0.5 server started at http://0.0.0.0:9876/
02 08 2018 21:17:13.030:INFO [launcher]: Launching browser Chrome with unlimited concurrency
02 08 2018 21:17:13.046:INFO [launcher]: Starting browser Chrome
02 08 2018 21:17:14.969:INFO [Chrome 67.0.3396 (Windows 10 0.0.0)]: Connected on socket peUBczU20NB36DSvAAAA with id 73989234
Chrome 67.0.3396 (Windows 10 0.0.0): Executed 0 of 1 SUCCESS (0 secs / 0 secs)
Chrome 67.0.3396 (Windows 10 0.0.0) MyClass can render without error FAILED
TypeError: Cannot read property 'createElement' of undefined
at <Jasmine>
at UserContext.<anonymous> (spec/applicationSpec.js:31:43)
at <Jasmine>
Chrome 67.0.3396 (Windows 10 0.0.0): Executed 1 of 1 (1 FAILED) (0 secs / 0.003 secs)
Chrome 67.0.3396 (Windows 10 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.02 secs / 0.003 secs)
[21:17:15] Finished 'unittest' after 3.6 s
It's as if the import statement isn't there.
After some pain, I have found an alternative approach which successfully runs the tests. My new test spec:
describe('MyClass', function () {
var React;
var Utils;
var MyClasses;
beforeAll(() => {
React = require("react");
Utils = require("react-dom/test-utils");
MyClasses = require("../Path/MyClass.jsx");
});
it('can render without error', function () {
var component;
var element = React.createElement(
MyClasses.MyClass,
{}
);
expect(function () {
component = Utils.renderIntoDocument(element);
}).not.toThrow();
});
})
and my updated Karma config:
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', 'browserify'],
files: [
'spec/*[Ss]pec.js',
'wwwroot/js/site.js'
],
exclude: [
],
preprocessors: {
'spec/*[Ss]pec.js': ['browserify']
},
browserify: {
debug: true,
transform: [
['babelify', {
presets: [
"#babel/preset-env",
"#babel/preset-react"
]
}]
],
extensions: ['.jsx']
},
reporters: ['progress', 'junit'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['Chrome'],
plugins: [
'karma-jasmine',
'karma-junit-reporter',
'karma-chrome-launcher',
'karma-babel-preprocessor',
'karma-browserify'
],
singleRun: true,
concurrency: Infinity
});
}

Karma skipping some test without error or xdescribe or xit

I have a bunch of tests that are totaly ignored.
I also looked for everywhere in the project for fdescribe, fit, xdescribe, xit, ddescribe or iit but there are none remainning. I just have a few xit but not much.
It seems to ignore all tests in a my /modules/ folder but it doesn't seem to be caused by misconfiguration because if I use fdescribe on some of them those are executed properly. Here is my karma.conf.js anyway in case you are intrested :
'use strict';
const stringify = require('stringify');
const babelify = require('babelify');
module.exports = (config) => {
config.set({
basePath: '',
frameworks: ['browserify', 'jasmine'],
files: [
'node_modules/jquery/dist/jquery.min.js',
'node_modules/angular/angular.js',
'node_modules/angular-route/angular-route.min.js',
'node_modules/angular-permission/dist/angular-permission.js',
'node_modules/angular-permission/dist/angular-permission-ng.js',
'node_modules/angular-sanitize/angular-sanitize.min.js',
'node_modules/angular-messages/angular-messages.min.js',
'node_modules/angular-mocks/angular-mocks.js',
'src/apps/publiques/app-publiques.module.js',
'src/apps/publiques/bootstrap-test.js',
'src/**/*.spec.js'
],
// the only folder that is excluded is correctly excluded
exclude: [
'src/modules/data-table/**/*.spec.js'
],
preprocessors: {
'src/apps/publiques/app-publiques.module.js': 'browserify',
'src/apps/publiques/bootstrap-test.js': 'browserify',
'src/**/*.spec.js': 'browserify',
},
browsers: ['PhantomJS'],
plugins: [
'karma-phantomjs-launcher',
'karma-jasmine',
'karma-browserify',
'karma-coverage',
'karma-mocha-reporter',
'karma-narrow-reporter',
'karma-jasmine-diff-reporter',
'karma-spec-reporter',
],
browserify: {
debug: true,
transform: [
babelify,
stringify,
],
},
reporters: [
'jasmine-diff',
// 'progress',
// 'mocha',
'narrow',
// 'spec'
],
specReporter: {
maxLogLines: 5, // limit number of lines logged per test
suppressErrorSummary: false, // do not print error summary
suppressFailed: false, // do not print information about failed tests
suppressPassed: false, // do not print information about passed tests
suppressSkipped: true, // do not print information about skipped tests
showSpecTiming: true, // print the time elapsed for each spec
failFast: true // test would finish with error when a first fail occurs.
},
mochaReporter: {
colors: {
success: 'green',
info: 'blue',
warning: 'yellow',
error: 'bgRed',
},
symbols: {
success: '+',
info: '#',
warning: '!',
error: 'x',
},
output: 'full',
},
phantomjsLauncher: {
exitOnResourceError: true,
},
port: 9876,
logLevel: config.LOG_DEBUG,
singleRun: true,
colors: true,
autoWatch: false,
});
};
End of karma log is
PhantomJS 2.1.1 (Windows 7 0.0.0) LOG: 'WARNING: Tried to load angular more than once.'
PhantomJS 2.1.1 (Windows 7 0.0.0): Executed 177 of 637 (skipped 10) SUCCESS
(0.858 secs / 0.82 secs)
[17:51:39] Karma Run Complete: No Failures
It turned out I had to beforeEach nested somewher like follow
describe('publiques-demandes-modifier.controller', () => {
beforeEach(() => {
angular.mock.module(app);
// mock window pour le test submitRedirect
const windowObj = { location: { href: '' } };
beforeEach(angular.mock.module(($provide) => {
$provide.value('$window', windowObj);
}));
angular.mock.inject((
I found out by using mocha reporter and by skipping last executed tests one by one to find the one responsible.

Angular Unit testing : $location in HTML5 mode requires a </path/to/my/app> tag to be present

I am using Karma to write my test scripts and here is my karma.conf.js code
'use strict';
/**
* Module dependencies.
*/
var _ = require('lodash'),
karmaReporters = ['spec', 'coverage'];
//Karma configuration
module.exports = function (karmaConfig) {
karmaConfig.set({
preprocessors: {
'./index.html': ['ng-html2js'],
'./app/*/modules/*/views/**/*.html': ['ng-html2js'],
'./app/config.js': ['coverage'],
'./app/application.js': ['coverage'],
'./app/*/modules/*/client/*.js': ['coverage'],
'./app/*/modules/*/client/config/*.js': ['coverage'],
'./app/*/modules/*/client/controllers/*.js': ['coverage'],
'./app/*/modules/*/client/directives/*.js': ['coverage'],
'./app/*/modules/*/client/services/*.js': ['coverage']
},
ngHtml2JsPreprocessor: {
moduleName: 'myApp',
cacheIdFromPath: function (filepath) {
return filepath;
}
},
// List of files / patterns to load in the browser
files: [
'./public/libs/angular/angular.js',
'./public/libs/angular-mocks/angular-mocks.js',
'./public/libs/angular-animate/angular-animate.js',
'./public/libs/angular-cookies/angular-cookies.js',
'./public/libs/angular-resource/angular-resource.js',
'./public/libs/angular-route/angular-route.js',
'./public/libs/angular-sanitize/angular-sanitize.js',
'./public/libs/angular-ui-router/release/angular-ui-router.js',
'./public/constants/constants.js',
'./app/config.js',
'./app/application.js',
'./app/*/modules/*/client/*.js',
'./app/*/modules/*/client/**/*.js',
'./app/*/modules/*/tests/unit/*.js',
'./index.html',
'./app/*/modules/*/client/views/**/*.html'
],
basePath: './',
//frameworks to use
frameworks: ['jasmine'],
// Test results reporter to use
// Possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
reporters: karmaReporters,
// Configure the coverage reporter
coverageReporter: {
dir: './coverage/client',
reporters: [
// Reporters not supporting the `file` property
{type: 'html', subdir: 'report-html'},
{type: 'lcov', subdir: 'report-lcov'},
// Output coverage to console
{type: 'text'}
],
instrumenterOptions: {
istanbul: {noCompact: true}
}
},
// Level of logging
// Possible values: karmaConfig.LOG_DISABLE || karmaConfig.LOG_ERROR || karmaConfig.LOG_WARN ||
// karmaConfig.LOG_INFO || karmaConfig.LOG_DEBUG
logLevel: karmaConfig.LOG_INFO,
browsers: ['Chrome'],
autoWatch: true,
singleRun: true,
colors: true
});
};
As per I remember it was working fine for certain time and due to some changes I am getting this error suddenly and I couldn't figure out what could be the issue.
Uncaught Error: [$location:no/path/to/my/app] $location in HTML5 mode requires a </path/to/my/app> tag to be present!
I have base url defined in my index file but still I am getting this error while running test scripts

ES6 + React + Karma + Coverage, show inaccurate values for code coverage

I am trying to set up code coverage for an ES6 react project. I got karma with code coverage to work, but its showing inaccurate numbers for the code coverage. I currently don't have any unit test written and its showing coverage for files. Here is my karma config file
var istanbul = require('browserify-istanbul');
module.exports = function (config) {
config.set({
base: './',
browsers: ['Chrome'],
singleRun: false,
autoWatch: true,
frameworks : [ 'jasmine', 'browserify'],
files: [
'js/**/*.js'
],
exclude: [ 'js/app.js' ],
preprocessors: {
'js/**/*.js': [ 'browserify' ]
},
browserify: {
configure: function(bundle){
bundle.on('prebundle', function(){
bundle
.transform(istanbul)
})
},
transform: [
['babelify', { presets: ['es2015', 'react'] }]
],
debug: true, // make stack traces readable.
},
reporters: [ 'progress', 'dots', 'coverage' ],
coverageReporter: {
type : 'text',
dir : 'coverage/'
}
});
};
The output is this
All files | 72.72 | 40.35 | 48.72 | 71.28 |

Resources