Grunt code coverage doesn't work - javascript

I've the following grunt file which runs the mocha tests OK (I get results of the test after running grunt.js)Now I want to add a code and I use the https://github.com/taichi/grunt-istanbul module. but when I run the grunt.js nothing happen,any idea?
What I want is simply after that mocha test are running it will run the code coverage with some reports? any new code coverage will be great
This is my project structure
myApp
-server.js
-app.js
-test
-test1.spec
-test2.spec
-test-reports
-grunt.js
-utils
-file1.js
-file2.js
-controller
-file1.js
-file2.js
This is the code inside the grunt for what I've tried
module.exports = function (grunt) {
var path = require('path');
process.env.RESOURCE_PATH_PREFIX = "../";
var d = new Date();
var datestring = d.getDate() + "-" + (d.getMonth() + 1) + "-" + d.getFullYear() + " " +
d.getHours() + ":" + d.getMinutes();
var npmCommand = path.dirname(process.execPath).concat('/npm');
var reportDir = "./test-reports/" + datestring;
grunt.initConfig({
jasmine_nodejs: {
// task specific (default) options
options: {
specNameSuffix: ["-spec.js"],
helperNameSuffix: "helper.js",
useHelpers: false,
stopOnFailure: false,
reporters: {
console: {
colors: true,
},
junit: {
savePath: "./test-reports",
filePrefix: "testresult",
}
}
},
test: {
specs: [
"test/*",
]
},
makeReport: {
src: './test-reports/coverage.json',//should I create this file?or its created automatically ?
options: {
type: ['lcov', 'html'],
dir: reportDir,
print: 'detail'
}
},
coverage: {
APP_DIR_FOR_CODE_COVERAGE: "./utils/*.js",//HERE IS THE PATH OF THE UTILS Folder which all the js login which I want to test there
clean: ['build'],
instrument: {
files: tasks,//WHAT IS TASKS????
options: {
lazy: true,
basePath: 'build/instrument/'//I DONT KNOW WHAT IT IS???
}
},
reloadTasks: {
rootPath: 'build/instrument/tasks'//SHOULD I USE IT????
},
storeCoverage: {
options: {
dir: reportDir
}
}
}
});
grunt.loadNpmTasks('grunt-jasmine-nodejs');
grunt.loadNpmTasks('grunt-istanbul');
grunt.registerTask('default', ['jasmine_nodejs']);
grunt.registerTask('cover', ['instrument', 'test',
'storeCoverage', 'makeReport']);
};
If there is mocha code coverage which can help it will be great either, I want that after I run the test I will able to see report with all the code coverage.
I want that the coverage will be done for folder utils and controller (all the files there) how should I config that?
UPDATE
This is what I use for jasmin and I think I should change to mocha
jasmine_nodejs: {
// task specific (default) options
options: {
specNameSuffix: ["-spec.js"], // also accepts an array
helperNameSuffix: "helper.js",
useHelpers: false,
stopOnFailure: false,
reporters: {
console: {
colors: true,
cleanStack: 1, // (0|false)|(1|true)|2|3
verbosity: 4, // (0|false)|1|2|3|(4|true)
listStyle: "indent", // "flat"|"indent"
activity: false
},
junit: {
savePath: "./test-reports",
filePrefix: "testresult",
consolidate: true,
useDotNotation: true
}
}
},
test: {
// target specific options
options: {
useHelpers: false
},
// spec files
specs: [
"test/*",
]
}
},
How should I change it?
The syntax of my test are similar(jasmine/mocha) and what I want is simply to run my test and after run the code coverage

I'll give you an indirect answer. I've gotten code coverage to work before, but with a different plugin (and with mocha). I'm not sure if you're open to swapping out jasmine for mocha but I will say that I struggled with various code coverage plugins before coming across this one. I think you'll agree the configuration is both concise and obvious.
The plugin you want is grunt-mocha-istbanbul, and here is a sample configuration for your Gruntfile:
module.exports = function(grunt) {
grunt.initConfig({
clean: ['coverage'],
mocha_istanbul: {
coverage: {
src: 'test',
options: {
timeout: 20000,
'report-formats': 'html',
print: 'summary',
check: {
lines: 90,
statements: 90,
functions: 100,
branches: 80
}
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-mocha-istanbul');
grunt.registerTask('default', ['clean', 'mocha_istanbul']);
}

Related

passing value fron conf.js to a grunt task or between grunt tasks

How do I pass information between grunt tasks? I would like to pass a value from a grunt task to another grunt task.
My situation is that after completing a protractor test, I would like to pass a value to a new grunt task. To achieve this, I went ahead and set the value in process.env and tried to use process.env in the new grunt task. But that doesn't seem to work
This is conf.js:
afterLaunch: function(exitCode) {
return new Promise(function(fulfill, reject) {
if (typeof jasmine.getEnv().testReportFilePath !== 'undefined' && jasmine.getEnv().testReportFilePath !== null) {
process.env.testReportFilePath = jasmine.getEnv().testReportFilePath;
console.log('Trying: ' + process.env.testReportFilePath);
fulfill('Success: Environment variable testReportFilePath is set in conf.js');
} else {
reject(new Error('Failed: Environment variable testReportFilePath not set in conf.js'));
}
});
And this is my Gruntfile:
grunt.loadNpmTasks('grunt-protractor-runner');
grunt.loadNpmTasks('grunt-protractor-webdriver');
grunt.loadNpmTasks('grunt-execute');
grunt.config('protractor', {
require: [ setTesting ],
options: {
configFile: 'conf.js', // common config file
keepAlive: true, // If false, the grunt process stops when the test fails.
noColor: false // If true, protractor will not use colors in its output.
},
run_specific_suite: {
options: {
args: {
baseUrl: '<%= grunt.option("testUrl") %>',
browser: '<%= grunt.option("testBrowser") %>',
params: {
environment: '<%= grunt.option("testEnv") %>'
},
suite: '<%= grunt.option("testSuite") %>'
}
}
},
});
grunt.config('execute', {
email_stakeholders: {
options: {
args: [
process.env.testReportFilePath,
'myemail#email.com'
]
},
src: ['toDelete.js']
}
});
But process.env.testReportFilePath appears to be undefined in the gruntjs file.
This answer is long overdue. I did follow #mparnisari suggestion to write the variable out to the file. So I did the following in my conf.js to write the value into a yaml file :
fs.writeFileSync(path.join(process.cwd(),'_testReportFilePath.yml'),
'testReportFilePath: ' + jasmine.getEnv().testReportFilePath);
and in the gruntfile, the yaml file read using the grunt api :
// --- grunt execute task --- //
grunt.config('execute', {
email_stakeholders: {
options: {
args:[
grunt.file.readYAML(path.join(process.cwd(),'_testReportFilePath.yml')).testReportFilePath, // html report
'myemail#email.com'//enter the recipient emails here
]
},
src: ['test/scripts/nightlyPostTasks.js']
}
});
and appears to do what I need. Only quirk is that a dummy yaml file with the name _testReportFilePath.yml must always be present in CWD to prevent any grunt error.

Grunt + Browser sync: no CSS injection or ghost mode

I'm encountering some confusing issues with getting the browser sync plugin for Grunt to work properly. I have thoroughly read the docs and followed examples but there are a couple of things that won't work:
1) I'm not getting any CSS injection. I know I am running the plugin alongside a watch task, but I have watchTask: true set and my terminal is showing that bS is identifying the change to my CSS, it's just not reloading the browser.
2) None of the ghost mode options seem to work for me. I have set them all to true but, much like the livereload feature, I'm not able to make it work.
Here is my current Gruntfile:
'use strict';
module.exports = function (grunt) {
grunt.initConfig({
watch: {
less : {
files: ['static/css/less/*.less'],
tasks: ['less']
},
html : {
files: ['*.html']
},
js : {
files: ['static/js/*.js']
}
},
less: {
development: {
options: {
paths: ["css"],
compress: true,
yuicompress: true,
optimization: 2
},
files: {
"static/css/styles.css": "static/css/less/styles.less"
}
}
},
browserSync: {
default_options: {
bsFiles: {
src: [
"static/css/*.css",
"*.html"
]
},
options: {
watchTask: true,
server: {
baseDir: "./"
},
ghostMode: {
clicks: true,
forms: true,
scroll: true
}
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-browser-sync');
// Launch BrowserSync + watch task
grunt.registerTask('default', ['browserSync', 'watch']);
};
Any help would be really appreciated

Implement const in grunt from terminal

I want to get const name from the terminal using grunt, and use it in uglify. This is what i want to happen:
uglify: {
options: {
sourceMap: true,
compress: {
global_defs: {
<myConst>: false
}
}
},
ugly: {
src: 'beautiful.js',
dest: 'ugly.js'
}
}
I use:
grunt --target=blabla
to pass the parameter, so myConst should be the input from the terminal (in this case blabla). I can't seem to find a way to put it instead of myConst (in code). Is it possible and how can i do it?
Since running grunt gives you the following command-line arguments in process.argv:
node
path_to_grunt_script
Couldn't you simply do something like:
module.exports = function(grunt) {
var compress_defs={},
args=process.argv.slice(2); // take all command line arguments skipping first two
// scan command line arguments for "--target=SOMETHING"
args.forEach(function(arg){
if(arg.match(/--target=(\S+)/)) { // found our --target argument
compress_defs[RegExp.$1]=false;
}
});
grunt.initConfig({
uglify: {
options: {
sourceMap: true,
compress: {
global_defs: compress_defs
}
},
ugly: {
src: 'beautiful.js',
dest: 'ugly.js'
}
});
};
Or better yet, rather than rolling-your-own, use a command-line processing library like minimist.

issue in testing with gruntjs and phantomjs

I want to create a Gruntfile.js to run bunch of phantomjs tests, when I execute > grunt run-test from commandline, it runs a bunch of tests. I created a Gruntfile.js and package.json which works ok and it reads bunch of tests from a directory. Now my problem is that when I write a phantomjs test and run the "grunt", it gives me this error:
Error: Cannot find module 'system'
Error: Cannot find module 'phantom'
However phantomjs is installed before by using npm install phantomjs
Example of phantomtest which gives me the above error:
var system = require('system');
if (system.args.length === 1) {
console.log('Try to pass some args when invoking this script!');
} else {
system.args.forEach(function (arg, i) {
console.log(i + ': ' + arg);
});
}
phantom.exit();
When I run phantomjs test1 (name of the test file) it runs the test so I think maybe I should append "phantomjs" somewhere in the Gruntfile. Any idea?
Gruntfile.js
'use strict';
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
jshint: {
all: [
'Gruntfile.js',
'tests/*.js',
'<%= nodeunit.tests %>',
],
options: {
jshintrc: '.jshintrc',
},
},
// Before generating any new files, remove any previously-created files.
clean: {
tests: ['tmp'],
},
// Configuration to be run (and then tested).
testArgs: {
configFile:"test/testConf.js",
options: {
args: {
params: {
number: 1,
bool: true,
str: "string",
nil: null, // Null is not supported.
obj: {
array: [1, 2, 3],
undef: undefined
}
},
capabilities: {
'browserName': 'chrome'
},
rootElement:"body",
specs:["test/argsTest.js"],
verbose:true
}
}
},
testDebug: {
configFile:"test/testConf.js",
options: {
debug:true,
args: {
specs:["test/debugTest.js"],
}
}
},
// Unit tests.
nodeunit: {
tests: ['tests/*_test.js'],
},
});
// Actually load this plugin's task(s).
grunt.loadTasks('tests');
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-nodeunit');
// Whenever the "test" task is run, first clean the "tmp" dir, then run this
// plugin's task(s), then test the result.
grunt.registerTask('test', ['clean']);
// By default, lint and run all tests.
grunt.registerTask('default', ['jshint', 'test']);
};

How to output two files using grunt durandal

I am having a go at grunt for optimizing my Durandal SPA. It seems to work great but now I would like to output a second file called libs.js which is the merged uglified version of all my required libraries but my first dist is getting ignored and still the only file I get is main-built.js
I only get one file so app/libs.js never gets created. I also have no grunt errors.
Here is my Gruntfile:
module.exports = function (grunt) {
grunt.initConfig({
durandal: {
libs: {
src: [
"../scripts/jquery-1.9.1.js",
"../scripts/typeahead.js",
"../scripts/jquery-ui-1.10.3.js",
"../scripts/knockout-3.0.0rc.js",
"../scripts/toastr.js",
"../scripts/q.js",
"../scripts/breeze.min.js",
"../scripts/bootstrap.js",
"../scripts/moment.js",
"../scripts/lodash.js",
"../scripts/respond.js",
"../scripts/knockout-sortable.js",
"../scripts/knockout-bootstrap.js",
"../scripts/knockout.validation.js",
],
dest: 'scripts/libs.js',
options: {
uglify2: {
compress: {
global_defs: {
DEBUG: false
}
}
}
}
},
dist: {
src: [
"app/**/*.*",
"scripts/durandal/**/*.*"
],
options: {
baseUrl: "app/",
mainPath: "app/main.js",
out: "app/main-built.js",
uglify2: {
compress: {
global_defs: {
DEBUG: false
}
}
}
}
}
}
});
grunt.loadTasks('tasks');
grunt.registerTask('default', ['durandal']);
};
This is JavaScript. If you create an object like { a: 'a', a: 'b' }, the first key will be overwritten by the second by the VM.
Instead of configuring it like this:
dist: {
// config goes here
},
dist: {
// config goes here
}
Try
libs: {
// config goes here
},
main: {
// config goes here
}

Categories