Angular Unit tests failing, not able to inject servies - angularjs

this is my karma.conf.js
`use strict`;
var path = require('path');
var conf = require('./gulp/conf');
var _ = require('lodash');
var wiredep = require('wiredep');
var pathSrcHtml = [
path.join(conf.paths.src, '/**/*.html')
];
function listFiles() {
var wiredepOptions = wiredep({
directory: 'src/bower_components',
exclude: [],
dependencies: true,
devDependencies: true
});
return wiredep(wiredepOptions).js
.concat([
path.join(conf.paths.src, '/app/**/*.module.js'),
path.join(conf.paths.src, '/app/**/*.js'),
path.join(conf.paths.src, '/app/*.spec.js')
])
.concat(pathSrcHtml);
}
module.exports = function(config) {
var files=['https://maps.googleapis.com/maps/api/js?sensor=false'].concat(listFiles());
var configuration = {
files: files,
singleRun: true,
autoWatch: false,
ngHtml2JsPreprocessor: {
stripPrefix: conf.paths.src ,
moduleName: 'truelocal'
},
logLevel: 'WARN',
frameworks: ['jasmine', 'angular-filesort'],
angularFilesort: {
whitelist: [path.join(conf.paths.src, '/**/!(*.html|*.spec|*.mock).js')]
},
browsers : ['PhantomJS'],
plugins : [
'karma-phantomjs-launcher',
'karma-angular-filesort',
'karma-coverage',
'karma-jasmine',
'karma-ng-html2js-preprocessor'
],
coverageReporter: {
type : 'html',
dir : 'coverage/'
},
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_DEBUG,
captureConsole: true,
reporters: ['progress']
};
// This is the default preprocessors configuration for a usage with Karma cli
// The coverage preprocessor in added in gulp/unit-test.js only for single tests
// It was not possible to do it there because karma doesn't let us now if we are
// running a single test or not
configuration.preprocessors = {};
pathSrcHtml.forEach(function(path) {
configuration.preprocessors[path] = ['ng-html2js'];
});
// This block is needed to execute Chrome on Travis
// If you ever plan to use Chrome and Travis, you can keep it
// If not, you can safely remove it
// https://github.com/karma-runner/karma/issues/1144#issuecomment-53633076
if(configuration.browsers[0] === 'Chrome' && process.env.TRAVIS) {
configuration.customLaunchers = {
'chrome-travis-ci': {
base: 'Chrome',
flags: ['--no-sandbox']
}
};
configuration.browsers = ['chrome-travis-ci'];
}
config.set(configuration);
};
//Bower.json
{
"name": "truelocal",
"version": "0.0.0",
"dependencies": {
"angular": "~1.4.10",
"angular-animate": "~1.4.10",
"angular-aria": "~1.4.10",
"angular-bootstrap": "~0.13.4",
"angular-cookies": "~1.4.10",
"angular-local-storage": "~0.2.3",
"angular-messages": "~1.4.10",
"angular-resource": "~1.4.10",
"angular-sanitize": "~1.4.10",
"angular-toastr": "~1.5.0",
"angular-touch": "~1.4.10",
"animate.css": "~3.4.0",
"bootstrap": "~3.3.5",
"jquery": "~1.11.3",
"malarkey": "yuanqing/malarkey#~1.3.1",
"moment": "~2.10.6",
"moment-parseformat": "~1.1.3",
"ng-file-upload-shim": "~9.1.2",
"jQuery.dotdotdot": "~1.7.4",
"lodash": "3.10.1",
"angular-ui-router": "~0.2.18",
"markerclustererplus": "~2.1.4",
"ng-fastclick": "~1.0.2",
"angular-swipe": "~0.1.0",
"angular-bindonce": "~0.3.3",
"angular-loading-bar": "~0.9.0",
"jquery-placeholder": "~2.3.1",
"angular-shims-placeholder": "^0.4.7"
},
"devDependencies": {
"angular-mocks": "~1.4.10"
},
"overrides": {
"bootstrap": {
"main": [
"dist/css/bootstrap.css",
"dist/fonts/glyphicons-halflings-regular.eot",
"dist/fonts/glyphicons-halflings-regular.svg",
"dist/fonts/glyphicons-halflings-regular.ttf",
"dist/fonts/glyphicons-halflings-regular.woff",
"dist/fonts/glyphicons-halflings-regular.woff2"
]
}
},
"resolutions": {
"jquery": "~1.11.3",
"angular": "^1.5.7"
}
}
This is an existing project with more than 200 Unit tests written, the code might need a bit of update but i'm not able to execute any unit test with dependent services.
I'm guessing the angular-mocks is causing an issue, if i move it up in the dependencies i dont get the module missing error. but i still dont get the other dependencies in the unit tests.

The Karma.conf.js was missing one file from the project. once all the files are fed to the test conf. tests worked like a Charm!

Related

transpiled code (babel) seems not working in Browser

Hi I'm working on an existing app which needs enhancements. The app is built using angularJS, Babel, webpack. I struggled running the app locally and finally succeeded in running it after making changes to how we call a basedirective (like below) which was using babel next generation javascript notation to regular notation (a compiler is present on babel site to do this).
function filtersDirective() {
return {
...baseDirective(template, FiltersCtrl),
...{
bindToController: {
customers: '=',
regions: '=',
managers: '=',
projects: '=',
statuses: '=',
},
},
}
}
Now the issue is I'm able to run this app locally and also able to build the bundle files (app.bundle.js, vendor.bundle.js, manifest.bundle.js) but when I deploy these files to my test server, the console error is like below.
ReferenceError: production is not defined
at dispatchXhrRequest (vendor.bundle.js:24340)
at new Promise (<anonymous>)
at xhrAdapter (vendor.bundle.js:24325)
at dispatchRequest (vendor.bundle.js:92054)
at <anonymous>
vendor.bundle.js:65932
TypeError: Cannot read property 'map' of undefined
at https://#domain/cdn/3.2.1/vendor.bundle.js:5202:31
at https://#domain/cdn/3.2.1/vendor.bundle.js:5090:28
at f1 (https://#domain/cdn/3.2.1/vendor.bundle.js:5070:27)
at https://#domain/cdn/3.2.1/vendor.bundle.js:4920:35
at https://#domain/cdn/3.2.1/vendor.bundle.js:4920:35
at https://#domain/cdn/3.2.1/vendor.bundle.js:4920:35
at https://#domain/cdn/3.2.1/vendor.bundle.js:4672:27
at getAttributeFromProjects (https://#domain/cdn/3.2.1/app.bundle.js:117:10)
at MainController (https://#domain/cdn/3.2.1/app.bundle.js:127:21)
at invoke (https://#domain/cdn/3.2.1/vendor.bundle.js:58052:17) <div ui-view="" class="ng-scope">
My Traspiled app.bundle.js looks like below
webpackJsonp([1], {
/***/
101:
/***/
(function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */
var __WEBPACK_IMPORTED_MODULE_0_deepmerge__ = __webpack_require__(69);
/* harmony import */
var __WEBPACK_IMPORTED_MODULE_0_deepmerge___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_deepmerge__);
const baseConfig = {
title: 'Test Dashboard',
dashboard: {
title: 'Test Report',
subtitle: 'Weekly Highlights'
},
header: {
title: 'Company Confidential',
nav: 'Test'
}
}
let config = baseConfig
if (window.AppConfig) {
if (window.AppConfig.config) {
config = __WEBPACK_IMPORTED_MODULE_0_deepmerge___default.a(baseConfig, window.AppConfig.config)
}
}
const {
title,
dashboard,
header,
statusBar
} = config
/* harmony export (immutable) */
__webpack_exports__["c"] = title;
/* harmony export (immutable) */
__webpack_exports__["a"] = dashboard;
/* unused harmony export header */
/* unused harmony export statusBar */
/* harmony default export */
__webpack_exports__["b"] = (config);
/***/
}),
/***/
222:
/***/
(function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (binding) */
__webpack_require__.d(__webpack_exports__, "b", function() {
return resolve;
});
/* harmony import */
var __WEBPACK_IMPORTED_MODULE_0_ramda__ = __webpack_require__(36);
/* harmony import */
var __WEBPACK_IMPORTED_MODULE_0_ramda___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_ramda__);
/* harmony import */
var __WEBPACK_IMPORTED_MODULE_1_angular__ = __webpack_require__(7);
/* harmony import */
var __WEBPACK_IMPORTED_MODULE_1_angular___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_angular__);
/* harmony import */
var __WEBPACK_IMPORTED_MODULE_2__utils__ = __webpack_require__(4);
/* harmony import */
var __WEBPACK_IMPORTED_MODULE_3__services_api__ = __webpack_require__(99);
/* harmony import */
var __WEBPACK_IMPORTED_MODULE_4__appConfig_config__ = __webpack_require__(101);
/* harmony import */
var __WEBPACK_IMPORTED_MODULE_5__dashboard_html__ = __webpack_require__(479);
/* harmony import */
var __WEBPACK_IMPORTED_MODULE_5__dashboard_html___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5__dashboard_html__);
/* harmony reexport (default from non-hamory) */
__webpack_require__.d(__webpack_exports__, "c", function() {
return __WEBPACK_IMPORTED_MODULE_5__dashboard_html___default.a;
});
Which is very different from previous version of app.bundle.js which is on prod server which looks like below
webpackJsonp([1], {
/***/
10:
/***/
(function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getWebpartData = undefined;
var _keys = __webpack_require__(124);
var _keys2 = _interopRequireDefault(_keys);
var _deepmerge = __webpack_require__(76);
var _deepmerge2 = _interopRequireDefault(_deepmerge);
var _utils = __webpack_require__(4);
var _majorMilestones = __webpack_require__(501);
var _majorMilestones2 = _interopRequireDefault(_majorMilestones);
var _budget = __webpack_require__(502);
var _budget2 = _interopRequireDefault(_budget);
var _projectRisksAndIssues = __webpack_require__(503);
var _projectRisksAndIssues2 = _interopRequireDefault(_projectRisksAndIssues);
var _actionItems = __webpack_require__(504);
var _actionItems2 = _interopRequireDefault(_actionItems);
var _keyDates = __webpack_require__(505);
var _keyDates2 = _interopRequireDefault(_keyDates);
var _gantt = __webpack_require__(506);
var _gantt2 = _interopRequireDefault(_gantt);
var _statusBar = __webpack_require__(507);
var _statusBar2 = _interopRequireDefault(_statusBar);
var _angular = __webpack_require__(6);
var _angular2 = _interopRequireDefault(_angular);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
below is my package.json file for reference
{
"name": "pmrdashboard",
"version": "3.2.1",
"dependencies": {
"#cgross/angular-notify": "2.5.1",
"angular": "1.4.2",
"angular-bootstrap": "~0.12.2",
"angular-chart.js": "^1.0.1",
"angular-gantt": "^1.2.13",
"angular-google-chart": "^0.1.0",
"angular-messages": "~1.4.2",
"angular-moment": "1.0.1",
"angular-pubsub": "^0.2.0",
"angular-resource": "~1.4.2",
"angular-sanitize": "~1.4.2",
"angular-strap": "^2.3.9",
"angular-toastr": "~1.5.0",
"angular-ui-router": "~0.2.15",
"animate.css": "~3.4.0",
"axios": "^0.16.2",
"babel-cli": "^6.24.1",
"babel-core": "^6.24.1",
"babel-polyfill": "^6.23.0",
"babel-runtime": "^6.23.0",
"bootstrap-sass": "3.3.7",
"chart.js": "2.1.0",
"deepmerge": "^1.3.2",
"echo-loader": "0.0.1",
"jquery": "~2.1.4",
"lodash": "^4.13.1",
"moment": "2.10.6",
"ngsticky-puemos": "^0.0.4",
"node-sass": "4.5.3",
"ramda": "^0.22.1"
},
"scripts": {
"dev": "babel-node scripts/cli.js dev",
"serve": "babel-node scripts/cli.js serve",
"build": "babel-node scripts/cli.js build --upload=false --plugins dynamic-import-node",
"deploy": "babel-node scripts/cli.js build",
"serve:prod": "babel-node scripts/cli.js serve:prod",
"serve:optimize": "babel-node scripts/cli.js serve:prod --optimize=true",
"serve:cdn": "babel-node scripts/cli.js serve:prod --usecdn=true"
},
"devDependencies": {
"babel-eslint": "^7.2.3",
"babel-loader": "^7.0.0",
"babel-plugin-angularjs-annotate": "^0.7.0",
"babel-plugin-dynamic-import-node": "^1.0.2",
"babel-plugin-external-helpers": "^6.22.0",
"babel-plugin-transform-object-rest-spread": "^6.23.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.5.1",
"chalk": "^1.1.3",
"clean-webpack-plugin": "0.1.16",
"cross-env": "^5.1.3",
"css-loader": "0.28.1",
"eslint": "2.13.1",
"eslint-config-angular": "^0.5.0",
"eslint-plugin-angular": "^2.4.0",
"execa": "^0.6.3",
"exports-loader": "0.6.4",
"express": "^4.15.3",
"extract-text-webpack-plugin": "2.1.0",
"file-loader": "0.11.1",
"fs-extra": "^3.0.1",
"html-loader": "0.4.5",
"html-webpack-harddisk-plugin": "0.1.0",
"html-webpack-plugin": "2.28.0",
"http-proxy-middleware": "*",
"http-server": "^0.10.0",
"image-webpack-loader": "3.3.1",
"imports-loader": "0.7.1",
"jshint-loader": "^0.8.4",
"raw-loader": "0.5.1",
"resolve-url-loader": "2.0.2",
"rollup": "^0.43.0",
"rollup-plugin-babel": "^2.7.1",
"rollup-plugin-node-resolve": "^3.0.0",
"sass-loader": "6.0.5",
"shelljs": "^0.7.7",
"ssh-webpack-plugin": "^0.1.7",
"style-loader": "0.17.0",
"svg-loader": "0.0.2",
"url-loader": "0.5.8",
"webpack": "3.0.0",
"webpack-dev-server": "^2.5.0",
"yargs": "^8.0.1"
},
"engines": {
"node": ">=0.10.0"
}
}
webpack config files: it's a folder with .babelrc, dev.js, server.js, prod.js, share.js and below is share.js file
const path = require('path')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {
rm
} = require('shelljs')
const pkg = require('../package.json')
const webpack = require('webpack')
const baseChunks = ['config', 'app']
const basePlugins = (chunks, enableHtml) => {
const html = enableHtml ?
[
new HtmlWebpackPlugin({
title: 'PMR Client',
filename: './index.html',
template: './src/client/index.ejs',
chunksSortMode: (a, b) => chunks.indexOf(a.names[0]) - chunks.indexOf(b.names[0]),
alwaysWriteToDisk: true,
env: process.env.NODE_ENV || 'development',
}),
new HtmlWebpackHarddiskPlugin(),
] :
[]
return [
new ExtractTextPlugin('style.css'),
...html,
new webpack.ProvidePlugin({
'window.jQuery': 'jquery',
}),
new webpack.optimize.ModuleConcatenationPlugin(),
]
}
const baseEntries = {
app: './src/app/index.js',
config: `./clients/${process.env.CLIENT}/config.js`,
}
const baseOutput = () => {
const output = {
path: path.join(__dirname, `../dist/cdn/${pkg.version}`),
filename: '[name].bundle.js',
}
if (process.env.NODE_ENV === 'production' && process.env.UPLOAD === 'true') {
output['publicPath'] = `//streamlinedoffice.com/pmr/cdn/${pkg.version}/`
}
return output
}
const sourceMap = (process.env.NODE_ENV === 'production') ? '' : 'sourceMap'
const getBaseConfig = ({
plugins = [],
chunks = [],
entries = baseEntries,
enableHtml = false
} = {}) => {
rm('-rf', path.resolve(__dirname, '../dist'))
const ch = [...baseChunks, ...chunks]
return {
entry: entries,
output: baseOutput(),
target: 'web',
devtool: 'cheap-module-eval-source-map',
plugins: [...basePlugins(ch, enableHtml), ...plugins],
module: {
rules: [{
test: /\.html$/,
use: [{
loader: 'html-loader',
options: {
minimize: true,
root: '../src/assets/images',
},
}, ],
},
{
test: [/src\/app.*\.js$/, /client.*\.js$/],
exclude: /node_modules/,
use: {
loader: 'babel-loader',
// loader:'echo-loader',
},
},
{
test: [/\.css$/, /\.scss$/],
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', `sass-loader?${sourceMap}`],
}),
},
{
test: /bootstrap-sass\/assets\/javascripts\//,
use: 'imports-loader?jQuery=jquery'
},
// Font Definitions
{
test: /\.svg$/,
loader: 'url-loader?limit=65000&mimetype=image/svg+xml&name=public/fonts/[name].[ext]',
},
{
test: /\.woff$/,
loader: 'url-loader?limit=65000&mimetype=application/font-woff&name=public/fonts/[name].[ext]',
},
{
test: /\.woff2$/,
loader: 'url-loader?limit=65000&mimetype=application/font-woff2&name=public/fonts/[name].[ext]',
},
{
test: /\.[ot]tf$/,
loader: 'url-loader?limit=65000&mimetype=application/octet-stream&name=public/fonts/[name].[ext]',
},
{
test: /\.eot$/,
loader: 'url-loader?limit=65000&mimetype=application/vnd.ms-fontobject&name=public/fonts/[name].[ext]',
},
{
test: /\.png$/,
use: {
loader: 'url-loader?limit=8192',
},
},
{
test: /\.(jpe?g|gif)$/i,
use: [
'file-loader?hash=sha512&digest=hex&publicPath=../&name=./img/[hash].[ext]',
{
loader: 'image-webpack-loader',
query: {
gifsicle: {
interlaced: false,
},
progressive: true,
optipng: {
optimizationLevel: 7,
},
bypassOnDebug: true,
},
},
],
},
],
},
}
}
module.exports = getBaseConfig
Below is the script used to build the app.bundle.js, vendor.bundle.js an d manifest.bundle.js files (this file is on scripts/cmds/prod.js)
import {
echo,
head,
execStrict,
ls,
copy,
rmdir,
mkdir
} from '../utils'
import fs from 'fs-extra'
import path from 'path'
import {
rollup
} from 'rollup'
import resolve from 'rollup-plugin-node-resolve'
import babel from 'rollup-plugin-babel'
const compiler = client =>
rollup({
entry: `./clients/${client}/config.js`,
plugins: [
resolve(),
babel({
exclude: 'node_modules/**',
babelrc: false,
presets: [
['env',
{
modules: false,
targets: {
browsers: [
"last 3 versions",
"Explorer 9",
],
},
},
],
],
plugins: ['external-helpers'],
externalHelpers: true
}),
],
}).then(bundle =>
bundle.write({
format: 'cjs',
dest: path.join(__dirname, `../../.tmpClients/${client}/config.js`),
})
)
const getClients = () =>
fs
.readdirSync('./clients')
.filter(file => fs.lstatSync(path.join('./clients', file)).isDirectory())
const handleCommand = async ({
upload = true,
optimize = true
}) => {
echo(head('Building clients...'))
const clients = getClients()
mkdir('./.tmpClients')
const promises = clients.map(client => {
compiler(client)
})
await Promise.all(promises)
echo(head('Run production build'))
await execStrict(
`cross-env UPLOAD=${upload} OPTIMIZE=${optimize} NODE_ENV=production webpack --config webpack/prod.js --progress --colors --define process.env.NODE_ENV="'production'"`
)
echo(head('Copying config files to clients'))
ls('./.tmpClients').forEach(client => {
copy({
origin: `./.tmpClients/${client}/*.js`,
dest: `./dist/clients/${client}`,
})
copy({
origin: `./dist/clients/${client}/index.html`,
dest: `./dist/clients/${client}/default.aspx`,
})
copy({
origin: './src/client/favicon.ico',
dest: `./dist/clients/${client}/`,
})
})
rmdir('./.tmpClients')
}
exports.command = 'build'
exports.describe = 'Create a production build'
exports.handler = handleCommand
exports.builder = {
upload: {
describe: 'Upload the production files to the cdn',
type: 'boolean',
default: true,
},
optimize: {
describe: 'Toggle the production optimizations, useful to check the production build as development',
type: 'boolean',
default: true,
},
}
below is .babelrc in webpack folder:
{
"presets": ["env"],
"plugins": ["transform-object-rest-spread", "dynamic-import-node"]
}
below .babelrc is in global same level as webpack folder
{
"presets": [
["env", {
"targets": {
"browsers": ["last 3 versions","Explorer 9"]
}
}]
],
"plugins": ["transform-runtime", "transform-object-rest-spread",
["angularjs-annotate", {
"explicitOnly": true
}]]
}
if anyone ran into such similar issue are know how to resolve it do share your inputs. Any help is much appreciated. Thanks

grunt-karma cannot find templateCache templates using grunt-angular-templates in generator-cg-angular scaffolded project Gruntfile

I used (Yeoman) generator-cg-angular to scaffold my AngularJS web-app, and I'm trying to run unit tests without using the html2js preprocessor, but alas it looks like I'm missing something.
I changed the folders tree
As per customer request, I moved index.html, app.js and app.less within a folder named app, so now the folder structure is something like the following:
|--- Gruntfile.js //the Gruntfile.js is in the root folder, just like this generator does out-of-the-box
|___dist
|___unit-test-results
|___node_modules
|___bower_components
|___app
|____app.js
|____app.less
|____index.html
|____directives
|____test-directive
|____test-directive.js
|____test-directive.less
|____test-directive.html
|____test-directive-spec.js
My karma task
karma: {
options: {
frameworks: ['jasmine'],
files: [ //this files data is also updated in the watch handler, if updated change there too
'<%= dom_munger.data.appjs %>',
'bower_components/angular-mocks/angular-mocks.js',
'<%= ngtemplates.main.dest %>',
'directive/**/*.html',
createFolderGlobs('*-spec.js')
],
logLevel:'ERROR',
reporters:['mocha','html'],
autoWatch: false, //watching is handled by grunt-contrib-watch
singleRun: true,
htmlReporter: {
outputFile: 'unit-test-results/unit-tests'+ grunt.template.today('yyyymmdd') +'.html',
// Optional
pageTitle: 'Unit Tests',
groupSuites: true,
useCompactStyle: true
}
},
all_tests: {
browsers: ['Chrome','Firefox']
},
during_watch: {
browsers: ['PhantomJS']
},
},
The test-directive-spec.js
describe('testDirective', function() {
beforeEach(module('myApp'));
beforeEach(module('directive/test-directive/test-directive.html')); //manually written
var scope,compile;
beforeEach(inject(function($rootScope,$compile) {
scope = $rootScope.$new();
compile = $compile;
}));
it('should ...', function() {
var element = compile('<test-directive></test-directive>')(scope);
scope.$digest();
expect(element.text()).toBe('hello world');
});
});
grunt test fails
When I run grunt test configured like this
grunt.registerTask('test',['dom_munger:read','karma:all_tests']);
the html report file says he the tests failed because the templates were not found
Error: [$injector:modulerr] Failed to instantiate module directive/test-directive/test-directive.html due to:
Error: [$injector:nomod] Module 'directive/test-directive/test-directive.html' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
So I tried adding the ngtemplates task to grunt test like this
grunt.registerTask('test',['dom_munger:read','ngtemplates','karma:all_tests']);
configuring ngtemplates like this
ngtemplates: {
main: {
options: {
module: pkg.name,
htmlmin:'<%= htmlmin.main.options %>',
url: function(url){ return url.replace('app/','')}
},
src: [createFolderGlobs('*.html'),'!'+ indexHtmlPath +'index.html','!_SpecRunner.html'],
dest: 'temp/templates.js'
}
}
and produces the following templates.js in a temp folder
angular.module('myApp').run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('directive/test-directive/test-directive.html',
"<div>hello world</div>"
);
}]);
But the html reporter still says that the templates are not found.
What am I doing so wrong?
Here's my package.json
{
"name": "myApp",
"version": "0.0.0",
"devDependencies": {
"eslint": "^3.16.1",
"eslint-config-angular": "^0.5.0",
"eslint-plugin-angular": "^1.6.1",
"grunt": "~0.4",
"grunt-angular-templates": "~0.5",
"grunt-browser-output": "0.1.0",
"grunt-contrib-clean": "~0.5",
"grunt-contrib-concat": "~0.3",
"grunt-contrib-connect": "~0.6",
"grunt-contrib-copy": "~0.5",
"grunt-contrib-cssmin": "~0.7",
"grunt-contrib-htmlmin": "~0.1",
"grunt-contrib-jshint": "~0.9",
"grunt-contrib-less": "~0.8",
"grunt-contrib-uglify": "~0.2",
"grunt-contrib-watch": "~0.6",
"grunt-dom-munger": "~3.4",
"grunt-file-exists": "^0.1.4",
"grunt-karma": "~0.8.3",
"grunt-ng-annotate": "^1.0.1",
"grunt-replace": "^1.0.1",
"grunt-timer": "^0.6.0",
"karma": "~0.12.6",
"karma-chrome-launcher": "~0.1.3",
"karma-firefox-launcher": "~0.1.3",
"karma-htmlfile-reporter": "^0.3.5",
"karma-jasmine": "~0.1.5",
"karma-mocha-reporter": "^2.2.2",
"karma-ng-html2js-preprocessor": "^1.0.0",
"karma-phantomjs-launcher": "~0.1.4",
"load-grunt-tasks": "~0.2"
}
}
After a lot of keyboard facerolling, I've come to this solution:
remove that directive/**/*.html from karma.options.files task configuration, since a) it's not enforcing project "folders-by-feature" structure and b) instead getting the templates from '<%= ngtemplates.main.dest %>' it's solid enough, you just need to change the grunt test task into grunt.registerTask('test',['dom_munger:read','ngtemplates','karma:all_tests']);
remove beforeEach(module('directive/test-directive/test-directive.html')); from test-directive-spec.js, since it looks like it clashes with the previously described ngtemplates mechanism, making the template unavaiable;

How to split code coverage by separate files for Angular, Karma and Webpack?

How can I split the coverage by separate files? Right now everything is working fine with the bundle file. I am using Angular, Webpack for bundling and Karma/Mocha/Chai for testing.
I have the following webpack.config:
module.exports = {
entry: {
public: "./application/src/public.js",
office: "./application/src/office.js"
},
output: {
path: "./client/javascripts/",
filename: "[name].js",
sourceMapFilename: "[name].js.map"
}
};
and following karma.conf.js:
module.exports = function(config) {
config.set({
basePath: "",
frameworks: ["mocha", "chai"],
reporters: ["mocha", "coverage"],
files: [
"./client/libs/angular/angular.js",
"./client/libs/angular-route/angular-route.js",
"./client/libs/angular-animate/angular-animate.js",
"./client/libs/angular-cookies/angular-cookies.js",
"./client/libs/angular-mocks/angular-mocks.js",
"./client/libs/angular-messages/angular-messages.js",
"./client/javascripts/office.js", /* the bundle */
"./application/**/*_tests.js"
],
preprocessors: {
"./client/javascripts/office.js": ["coverage"]
},
coverageReporter: {
type: "html",
dir: "coverage/"
},
exclude: [],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ["PhantomJS"],
singleRun: false
});
};
sample test file:
describe("AccountLoginCtrl", function() {
beforeEach(angular.mock.module("stAccount"));
var $controller;
var AccountLoginCtrl;
var $scope;
beforeEach(angular.mock.inject(function(_$controller_) {
$controller = _$controller_;
$scope = {};
AccountLoginCtrl = $controller("AccountLoginCtrl", {
$scope: $scope
});
}));
it("should exist", function() {
expect(AccountLoginCtrl).to.exist;
});
});
Settup your folder structure:
karma.conf.js
./application
./src
./components
entry.js
./tests
index.js
./components
./coverage
Add index.js in the tests folder as an entry point for the tests.
// adds all test files to the bundle.
var testsContext = require.context("./components", true, /\.js$/);
testsContext.keys().forEach(testsContext);
// adds the application to the bundle.
var componentsContext = require("../src/entry");
karma.conf.js
var path = require("path");
module.exports = function(config) {
config.set({
basePath: "",
frameworks: ["mocha"],
reporters: ["mocha", "coverage"],
files: [
"./client/libs/angular/angular.js",
"./client/libs/angular-route/angular-route.js",
"./client/libs/angular-animate/angular-animate.js",
"./client/libs/angular-cookies/angular-cookies.js",
"./client/libs/angular-mocks/angular-mocks.js",
"./client/libs/angular-messages/angular-messages.js",
"./application/tests/index.js",
],
preprocessors: {
"./application/tests/index.js": ["webpack"]
},
webpack: {
module: {
preLoaders: [
{
test: /\.js$/,
include: path.resolve("./application/src/"),
loader: "isparta"
}
]
}
},
webpackMiddleware: {
noInfo: true
},
coverageReporter: {
type: "html",
dir: "./application/coverage/"
},
exclude: [],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ["PhantomJS"],
singleRun: false
});
};
package.json
{
"devDependencies": {
"chai": "^3.4.0",
"isparta-loader": "^1.0.0",
"karma": "^0.13.12",
"karma-coverage": "^0.5.3",
"karma-mocha": "^0.2.0",
"karma-mocha-reporter": "^1.1.1",
"karma-phantomjs-launcher": "^0.2.1",
"karma-webpack": "^1.7.0",
"mocha": "^2.3.3",
"phantomjs": "^1.9.18",
"webpack": "^1.12.2"
}
}

I am unable to make phantomjs click the signin button

I am able to have chrome click the sign in button. I am working with protractor and automating it so we can do e2e testing with phantomjs.
The html is:
<div class="form-input">
<input type="submit" id="login-button" class="btn" value="Sign in">
I have tried:
element(by.css('[class="form-input"]')).click();
element(by.css('[type="submit"]')).click();
element.all(by.id('login-button')).first().click();
element(by.id('login-button')).click();
element(by.css('[class="btn"]')).click();
element(by.css('[value="Sign in"]')).click();
element.all(by.className('form-input')).last().click();
This is my ads-e2econf.js
var fs = require('fs');
//retrieving current date
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1; //January is 0!
var yyyy = today.getFullYear();
//retrieving current time
var time = new Date();
var hour = time.getHours() + ":";
var minutes = time.getMinutes() + ":";
if(dd<10) {
dd='0'+dd
}
if(mm<10) {
mm='0'+mm
}
today = mm+'/'+dd+'/'+yyyy;
time = hour + minutes;
var results = '\nThe following Protractor tests have failed on '+ today + ' #' + time + '\n\n';
exports.config = {
capabilities: {
browserName: 'chrome',
version: '',
platform: 'ANY'
},
seleniumServerJar: 'node_modules/protractor/selenium/selenium-server-standalone-2.45.0.jar',
specs: [
'test/specs/manage/*.js',
'test/specs/manage/clone/*.js',
'test/specs/regression/*.js',
'test/specs/create/create-basicAd.js',
'test/specs/create/create-pagepost.js',
'test/specs/create/create-targeting.js'
],
onPrepare: function () {
require('jasmine-reporters');
jasmine.getEnv().addReporter(new jasmine.ConsoleReporter(console.log));
jasmine.getEnv().addReporter(new function() {
this.reportSpecResults = function(spec) {
if (!spec.results().passed()) {
results += spec.suite.description + ' ' + spec.description;
if(spec.suite.description.substring(0, 4) == 'ADS-') {
results += 'censored' + spec.suite.description;
results += 'censored';
}
results += '\n';
}
};
});
},
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 1000000,
isVerbose: true
},
allScriptsTimeout: 1000000,
onCleanUp: function() {
fs.writeFileSync('/tmp/results.txt', results);
}
}
This is my karma config file.
// Karma configuration
module.exports = function(config) {
'use strict';
config.set({
// base path, that will be used to resolve files and exclude
basePath: '',
// testing framework to use (jasmine/mocha/qunit/...)
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'app/bower_components/jquery/dist/jquery.js',
'app/bower_components/lodash/dist/lodash.js',
'app/bower_components/angular/angular.js',
'app/bower_components/angular-mocks/angular-mocks.js',
'app/bower_components/angular-resource/angular-resource.js',
'app/bower_components/angular-cookies/angular-cookies.js',
'app/bower_components/angular-sanitize/angular-sanitize.js',
'app/bower_components/angular-route/angular-route.js',
'app/bower_components/angular-lodash/angular-lodash.js',
'app/bower_components/angular-bootstrap/ui-bootstrap.js',
'app/bower_components/ui-utils/ui-utils.js',
'app/bower_components/angulartics/src/angulartics.js',
'app/bower_components/angulartics/src/angulartics-ga.js',
'app/bower_components/ng-csv/src/ng-csv/ng-csv.js',
'app/bower_components/angulartics/src/angulartics-ga.js',
'app/bower_components/moment/moment.js',
'app/bower_components/ng-bs-daterangepicker/src/ng-bs-daterangepicker.js',
'app/bower_components/select2/select2.js',
'app/bower_components/angular-ui-select/dist/select.js',
'app/bower_components/angular-ui-select2/src/select2.js',
'app/bower_components/bn-tokens-angular/dist/bn-tokens-angular.js',
'app/bower_components/bn-catm-angular/dist/bn-catm-angular.js',
'app/bower_components/bn-topnav/dist/js/bn-topnav.js',
'app/bower_components/angular-ui-router/release/angular-ui-router.js',
'app/bower_components/bn-expression-builder/dist/bn-expression-builder.js',
'app/bower_components/bn-appbar/dist/js/bn-appbar.js',
'app/bower_components/zeroclipboard/dist/ZeroClipboard.js',
'app/bower_components/ng-clip/dest/ng-clip.min.js',
'app/bower_components/bn.dayparting/dist/bn.dayparting.js',
'app/lib/ng-grid/build/ng-grid.js',
'app/lib/ns-popover/nsPopover.js',
'app/lib/ps-input-time.js',
'app/lib/angular-ui-scrollfix/scrollfix.js',
'app/scripts/services/facebookAPI/providers/fbcommon.js', // FML
'app/scripts/services/facebookAPI/providers/facebook.js', // FMLx2
'app/scripts/*.js',
// 'app/mock/api/api.mock.js',
// 'app/mock/api/*.mock.js',
'app/scripts/**/*.js',
'app/templates/**/*.html',
'test/unit/**/*.js'
],
// generate js files from html templates to expose them during testing.
preprocessors: {
'app/templates/**/*.html': 'html2js'
},
// list of files / patterns to exclude
exclude: [],
// web server port
port: 9010,
// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
//autoWatch: true,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
//browsers: ['Chrome'],
// Timeout for capturing a browser (in ms).
captureTimeout: 60 * 1e3,
// to avoid DISCONNECTED messages
browserDisconnectTimeout : 10000, // default 2000
browserDisconnectTolerance : 1, // default 0
browserNoActivityTimeout : 60 * 1e3, //default 10000
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: false
});
};
This is my package.json:
{
"name": "client",
"version": "0.0.0",
"dependencies": {},
"devDependencies": {
"grunt": "^0.4.5",
"grunt-angular-templates": "^0.5.4",
"grunt-autoprefixer": "~0.4.0",
"grunt-concurrent": "~0.4.1",
"grunt-contrib-clean": "~0.5.0",
"grunt-contrib-coffee": "~0.7.0",
"grunt-contrib-compass": "~0.6.0",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-connect": "~0.5.0",
"grunt-contrib-copy": "~0.4.1",
"grunt-contrib-cssmin": "~0.7.0",
"grunt-contrib-htmlmin": "~0.1.3",
"grunt-contrib-imagemin": "~0.3.0",
"grunt-contrib-jshint": "~0.7.1",
"grunt-contrib-uglify": "~0.2.0",
"grunt-contrib-watch": "~0.5.2",
"grunt-google-cdn": "~0.2.0",
"grunt-jscs": "^0.8.1",
"grunt-karma": "~0.6.2",
"grunt-newer": "~0.5.4",
"grunt-ng-constant": "^1.1.0",
"grunt-ngmin": "~0.0.2",
"grunt-protractor-runner": "~0.2.3",
"grunt-rev": "~0.1.0",
"grunt-svgmin": "~0.2.0",
"grunt-usemin": "~2.0.0",
"grunt-wiredep": "~2.0.0",
"jasmine-reporters": "~0.4.1",
"jshint-stylish": "~0.1.3",
"karma": "~0.10.9",
"karma-chrome-launcher": "~0.1.2",
"karma-coffee-preprocessor": "~0.1.2",
"karma-firefox-launcher": "~0.1.3",
"karma-html2js-preprocessor": "~0.1.0",
"karma-jasmine": "~0.1.5",
"karma-ng-html2js-preprocessor": "~0.1.0",
"karma-ng-scenario": "~0.1.0",
"karma-phantomjs-launcher": "~0.1.1",
"karma-requirejs": "~0.2.1",
"karma-script-launcher": "~0.1.0",
"load-grunt-tasks": "~0.2.0",
"phantomjs": "~1.9.7-1",
"protractor": "~2.0.0",
"requirejs": "~2.1.10",
"time-grunt": "~0.2.1"
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"start": "grunt serve",
"test": "grunt test"
}
}
PhantomJS is the worst choice for e2e testing with protractor.
Even protractor core developers recommend against it:
We recommend against using PhantomJS for tests with Protractor. There
are many reported issues with PhantomJS crashing and behaving
differently from real browsers.
If you still want to solve this with PhantomJS, here is the list of things to try:
trigger click via executeScript():
browser.executeScript("arguments[0].click();", button.getWebElement());
wait for element to become clickable before making a click:
var EC = protractor.ExpectedConditions;
browser.wait(EC.elementToBeClickable(button), 5000);
maximize browser window at the startup:
browser.manage().window().maximize();
where button is an element you've found, e.g.:
var button = element(by.id("login-button"));

Error while executing karma tests

I am trying to run karma unit tests for my application. The application is created using my company's custom angular yeoman generator. (The generator is very similar to the angular-yeoman generator).
I am trying to run karma jasmine test for my application. But I keep on getting the error message whenever I run grunt test
Chrome 35.0.1916 (Mac OS X 10.9.0) ERROR Uncaught object at
/Users//Dummy
Apps/karma1/app/bower_components/angular/angular.js:1611
Warning: Task "karma:unit" failed. Use --force to continue.
I have the following in my Gruntfile.js:
karma: {
unit: {
configFile: 'karma.conf.js',
singleRun: true
}
}
In karma.conf.js file I have :
module.exports = function(config) {
config.set({
// base path, that will be used to resolve files and exclude
basePath: '',
// testing framework to use (jasmine/mocha/qunit/...)
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'app/bower_components/angular*/angular.js',
'app/bower_components/angular-mocks/angular-mocks.js',
'app/bower_components/angular-resource/angular-resource.js',
'app/bower_components/angular-cookies/angular-cookies.js',
'app/bower_components/angular-sanitize/angular-sanitize.js',
'app/bower_components/angular-route/angular-route.js',
'app/bower_components/angular-bootstrap/ui-bootstrap.js',
'app/bower_components/angular-bootstrap/ui-bootstrap-tpls.js',
'app/bower_components/service-state/js/StateService.js',
'app/scripts/controllers/dashboard.js',
'../test/spec/**/*.js'
],
// list of files / patterns to exclude
exclude: [],
// web server port
port: 8080,
// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers: ['Chrome'],
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: false
});
};
My package.json file :
{
"name": "karma1",
"version": "0.0.0",
"dependencies": {},
"devDependencies": {
"grunt": "~0.4.1",
"grunt-css": "~0.5.4",
"grunt-contrib-copy": "~0.4.1",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-coffee": "~0.7.0",
"grunt-contrib-uglify": "~0.2.0",
"grunt-contrib-compass": "~0.5.0",
"grunt-contrib-jshint": "~0.6.0",
"grunt-contrib-less": "~0.9.0",
"grunt-contrib-cssmin": "~0.6.0",
"grunt-contrib-connect": "~0.5.0",
"grunt-contrib-clean": "~0.5.0",
"grunt-contrib-htmlmin": "~0.1.3",
"grunt-contrib-watch": "~0.5.2",
"grunt-autoprefixer": "~0.2.0",
"grunt-usemin": "~0.1.11",
"grunt-rev": "~0.1.0",
"grunt-shell": "~0.2.2",
"grunt-concurrent": "~0.3.0",
"load-grunt-tasks": "~0.1.0",
"grunt-google-cdn": "~0.2.0",
"grunt-ngmin": "~0.0.2",
"time-grunt": "~0.1.0",
"karma-ng-scenario": "^0.1.0",
"grunt-karma": "^0.8.3",
"karma": "^0.12.16",
"karma-ng-html2js-preprocessor": "^0.1.0",
"karma-jasmine": "^0.1.5",
"karma-chrome-launcher": "^0.1.4",
"karma-mocha": "latest",
"chai": "1.4.0",
"karma-script-launcher": "~0.1.0",
"karma-html2js-preprocessor": "~0.1.0",
"karma-requirejs": "~0.2.0",
"karma-coffee-preprocessor": "~0.1.0",
"karma-phantomjs-launcher": "~0.1.0",
"grunt-open": "~0.2.2",
"ng-midway-tester": "2.0.5"
},
"engines": {
"node": ">=0.8.0"
},
"scripts": {
"test": "grunt test"
}
}
My test controller is :
'use strict';
describe('Controller: DashboardCtrl', function () {
// load the controller's module
beforeEach(module('karma1App'));
var DashboardCtrl,
scope;
// Initialize the controller and a mock scope
beforeEach(inject(function ($controller,$rootScope) {
scope = $rootScope.$new();
DashboardCtrl = $controller('DashboardCtrl', {
$scope: scope
});
}));
it('should attach a list of awesomeThings to the scope', function () {
expect(scope.awesomeThings.length).toBe(3);
});
});
I use REQUIREJS to load the other dependencies, but REQUIRE is used only in the directives. As a kick start I want to test my controllers and services but I keep getting this error.
Any idea what is going wrong.
Thanks!
The point I was missing that I was not loading the angular app. I am loading the angular app through a config file config.js
/* global angular */
'use strict';
var karma1App = angular.module('karma1App', [
'pascalprecht.translate', 'ngResource', 'ngRoute',
'ui.bootstrap' ]);
karma1App.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/site', {
activeTabName: 'site',
templateUrl: 'views/site.html',
controller: 'SiteCtrl'
})
.when('/Cases', {
templateUrl: 'views/Cases.html',
controller: 'CasesCtrl'
})
.when('/Cases/:caseid', {
templateUrl: 'views/Case.html',
controller: 'CaseCtrl'
})
.when('/Alarms', {
templateUrl: 'views/Alarms.html',
controller: 'AlarmsCtrl'
})
.when('/Analysis', {
templateUrl: 'views/Analysis.html',
controller: 'AnalysisCtrl'
})
.when('/Reports', {
templateUrl: 'views/Reports.html',
controller: 'ReportsCtrl'
}) /*
.when('/dashboard', {
activeTabName: 'dashboard',
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
*/
.when('/admin', {
templateUrl: 'views/admin.html',
controller: 'AdminCtrl'
})
.otherwise({
redirectTo: '/site'
}); }]);
In the karma.conf.js I added this following script tag :
files: [
'app/bower_components/angular*/angular.js',
'app/bower_components/angular-mocks/angular-mocks.js',
'app/bower_components/angular-resource/angular-resource.js',
'app/bower_components/angular-cookies/angular-cookies.js',
'app/bower_components/angular-sanitize/angular-sanitize.js',
'app/bower_components/angular-route/angular-route.js',
'app/bower_components/angular-bootstrap/ui-bootstrap.js',
'app/bower_components/angular-bootstrap/ui-bootstrap-tpls.js',
'./test/test-main.js',
'app/scripts/controllers/dashboard.js',
'../test/spec/**/*.js'
]
The test-main.js has the following line of code ONLY:
/* global angular */
'use strict';
var karma1App = angular.module('karma1App', [
'ngResource',
'ngRoute', // Angular 1.2 requires separate ngRoute
'ui.bootstrap',
'StateService'
]);
After loading the test-main.js file in the karma.conf.js file I was able to unit test my application using karma.
Hope this helps.
Thanks,
Anirban

Resources