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']);
};
Related
Configuring grunt to make automated JS tests with jenkins and qunit, I am actually blocking on this issue.
When I run grunt:
Running "qunit_junit" task
XML reports will be written to _build/test-reports
No "qunit" targets found.
Warning: Task "qunit" failed. Use --force to continue.
Aborted due to warnings.
My Gruntfile:
'use strict';
module.exports = function(grunt) {
var gruntConfig = {};
grunt.initConfig({
sync: {
target: {}
}
});
grunt.registerTask('default', ['qunit_junit', 'qunit']);
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-qunit-istanbul');
gruntConfig.qunit = {
src: ['static/test/index.html'],
options: {
coverage: {
src: ['static/js/**/*.js'],
instrumentedFiles: 'temp/',
htmlReport: 'report/coverage',
coberturaReport: 'report/',
linesThresholdPct: 20
}
}
};
grunt.loadNpmTasks('grunt-qunit-junit');
gruntConfig.qunit_junit = {
options: {
dest: 'report/'
}
};
};
I checked and console.log() in the node_modules, the grunt-contrib-qunit is installed and the task is in it so grunt finds the module and the task but seems not to load it.
Just at a glance - you are creating your config, but not doing anything with it.
Change this line
grunt.initConfig({
sync: {
target: {}
}
});
to this:
grunt.initConfig(gruntConfig);
You might also want to move that down below all the other stuff you add to gruntConfig.
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']);
}
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.
I want to avoid duplicate code, so i am trying to load grunt task from Grunt file "a" and use them in gruntfile "b".
that means: i want to see all task of "a" in file "b" (but without code), just setup like a reference or template to another gruntfile.
here is grunt file "b":
module.exports = function (grunt) {
'use strict';
var karmaGrunt = './../../grunt',
abortHandler = function () {
var errors = grunt.fail.errorcount,
warnings = grunt.fail.warncount;
if (errors > 0 || warnings > 0) {
//run rocketlauncher python script and then stop the grunt runner.
grunt.task.run(["shell:rocketlauncher", "fatal"]);
}
},
fatal = function () {
// this function stops grunt and make the jenkins build red.
grunt.fail.fatal('failed');
};
require("grunt-load-gruntfile")(grunt);
// load grunt task from another file and add it.
grunt.loadGruntfile(karmaGrunt);
//grunt needs to continue on error or warnings, that's why we have to set the force property true
grunt.option('force', true);
grunt.initConfig({
shell: {
options: {
execOptions: {
cwd: '../scripts'
}
},
'rocketlauncher': {
command: './runRocketLauncher.sh'
}
}
});
grunt.loadNpmTasks('grunt-karma');
grunt.loadNpmTasks('grunt-shell');
grunt.registerTask('build-process', ['karma', 'abortHandler']);
grunt.registerTask('abortHandler', abortHandler);
grunt.registerTask('fatal', fatal);
}
here is file "a":
module.exports = function (grunt) {
"use strict";
var eConfig = '../e-specs/karma.config.js',
dConfig = '../d-specs/karma.config.js',
cConfig = '../c-specs/karma.config.js';
grunt.initConfig({
karma: {
options: {
reporters: ['progress', 'coverage', 'threshold']
},
c: {
configFile: cConfig
},
d: {
configFile: dConfig
},
e: {
configFile: eConfig
}
}
});
grunt.loadNpmTasks('grunt-karma');
};
my file b load the task "Karma" but if i run only the grunt file of a i have 3 nested task ("e","c","d") but if i load them from another file, the only task i can see is "karma"
the error is:
No "karma" targets found.
Warning: Task "karma" failed. Used --force, continuing.
Done, but with warnings.
If i run the same task in file "a" directly the task is working like a charm.
There is a grunt plugin to load another Gruntfile: grunt-load-gruntfile
With this you can merge two Grunt configurations, including the defined tasks.
Here is an example:
./Gruntfile.js:
module.exports = function (grunt) {
require("grunt-load-gruntfile")(grunt);
grunt.loadGruntfile("web"); //loads the Gruntfile from the folder web/
grunt.registerTask('showConfig', "shows the current config", function(){
console.log(JSON.stringify(grunt.config(), null, 2));
});
};
and the second Gruntfile in ./web/Gruntfile.js.
module.exports = function (grunt) {
grunt.config("WebConfig", "Configuration from the Gruntfile in web/Gruntfile.js");
grunt.registerTask('server', "runs the server",function(){
console.log("just shows this message");
});
};
running grunt showConfig executes the task from the first Gruntfile and displays the configuration, including the parameter defined in ./web/Gruntfile.js.
running grunt server executes the task from ./web/Gruntfile.js.
I have recently discovered grunt as it is used within an opensource project I have started to work on. Having not worked with grunt before I am struggling to see how it works, or in my case doesn't.
The grunt file is supplied by the project and I assume it works for everyone else. I have installed grunt and the necessary grunt modules have all installed in the "Node_modules" directory.
When running the grunt file the first process performs a number of concatenations and this seems to work fine. The concatenated files are created.
All of the other steps do not seem to execute. The files they are intended to create are not created. There is no error message displayed on the console when grunt is executed.
I'm stumped - anyone have any clues what might be the problem.
The grunt file is :
/*global module:false*/
module.exports = function(grunt) {
// Project configuration...
grunt.initConfig({
manifest: grunt.file.readJSON('chrome/manifest.json'),
concat: {
dist: {
src: ['chrome/js/requester/**/*.js'],
dest: 'chrome/js/requester.js'
},
requester_html: {
src: [
'chrome/html/requester/header.html',
'chrome/html/requester/sidebar.html',
'chrome/html/requester/main.html',
'chrome/html/requester/loggers/*.html',
'chrome/html/requester/modals/*.html',
'chrome/html/requester/footer.html'
],
dest: 'chrome/requester.html'
},
requester_tester: {
src: [
'chrome/html/requester/header.html',
'chrome/html/requester/sidebar.html',
'chrome/html/requester/main.html',
'chrome/html/requester/modals/*.html',
'chrome/html/requester/loggers/*.html',
'chrome/html/requester/footer.html',
'chrome/html/requester/tester.html'
],
dest: 'chrome/tester.html'
}
},
mindirect: {
dist: {
src: ['chrome/js/requester.js'],
dest: 'chrome/js/requester.min.js'
}
},
watch: {
requester_templates: {
files: ['chrome/html/requester/templates/*'],
tasks: ['handlebars'],
options: {
livereload: true
}
},
requester_js: {
files: ['chrome/js/requester/**/*.js'],
tasks: ['concat:dist'],
options: {
livereload: true
}
},
requester_html: {
files: ['chrome/html/requester/*', 'chrome/html/requester/modals/*', 'chrome/html/requester/loggers/*'],
tasks: ['concat:requester_html', 'concat:requester_tester'],
options: {
livereload: true
}
},
requester_css: {
files: ['chrome/css/**/*.scss'],
tasks: ['sass'],
options: {
livereload: true
}
}
},
jshint: {
options: {
curly: true,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
undef: true,
boss: true,
eqnull: true,
browser: true
},
globals: {
jQuery: true
}
},
handlebars: {
compile: {
options: {
partialsUseNamespace: true,
namespace: 'Handlebars.templates',
processPartialName: function(filePath) {
var pieces = filePath.split("/");
var name = pieces[pieces.length - 1].split(".")[0];
return name;
},
processName: function(filePath) {
var pieces = filePath.split("/");
var name = pieces[pieces.length - 1].split(".")[0];
return name;
}
},
files: {
"chrome/html/requester/templates.js": "chrome/html/requester/templates/*"
}
}
},
sass: {
dist: {
files: {
'chrome/css/requester/styles.css': 'chrome/css/requester/styles.scss'
}
}
},
compress: {
main: {
options: {
archive: 'releases/v<%= manifest.version %>.zip'
},
files: [
{src: ['chrome/**', '!chrome/tests/**', '!chrome/manifest_key.json', '!chrome/tester.html'], dest: '/'}, // includes files in path and its subdirs
]
}
}
});
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-handlebars');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-mindirect');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-compress');
// Default task.
grunt.registerTask('default', ['jshint', 'concat']);
grunt.registerTask('package', ['concat', 'handlebars', 'sass', 'compress']);
};
The output from the console is as follows :
Running "jshint:globals" (jshint) task
>> 0 files lint free.
Running "concat:dist" (concat) task
File "chrome/js/requester.js" created.
Running "concat:requester_html" (concat) task
File "chrome/requester.html" created.
Running "concat:requester_tester" (concat) task
File "chrome/tester.html" created.
Done, without errors.
Given that the tasks are defined like this:
grunt.registerTask('default', ['jshint', 'concat']);
grunt.registerTask('package', ['concat', 'handlebars', 'sass', 'compress']);
the output you show is what you'd expect if you are running grunt without a task name. It runs the jshint and concat tasks.
If you want to run the tasks associated with package, then you have to run grunt package to run those tasks.
It looks like I did not understand "tasks" within grunt.
Instead of executing "grunt" which runs the "default" tasks, I had to execute "grunt package" which runs the tasks that I was interested in.
As Louis said, you have to specify the right task to run.
But you can also create or modify the tasks you have in order to make it simpler. In your example you may include package in the default task. Because concat task is already executed inside package, you may just replace it in the default task:
grunt.registerTask('default', ['jshint', 'package']);
grunt.registerTask('package', ['concat', 'handlebars', 'sass', 'compress']);
and, in order to build your site, just type
grunt
both jshint and package tasks will be executed