I have a Gruntfile.js through which i'm invoking mochaTest using grunt-mocha-test module. I can pass an argument/parameter to the gruntTask from command line but i'm struggling to pass the same parameter into the spec file running via the above module. The code looks like below,
mochaTest: {
test: {
options: {
reporter: 'spec',
quiet: false,
clearRequireCache: false,
clearCacheFilter: (key) => true,
noFail: false
},
src: [
'test/createSpec.js'
]
}
}
Task is registered like below,
grunt.registerTask('e2etest', function(scope) {
console.log(scope); // logs user/session based on the parameter passed
grunt.task.run('mochaTest');
});
// Above task is invoked like,
grunt e2etest:user
(or)
grunt e2etest:session
I need to pass this value (user/session) into mochaTest so it can be accessed inside the spec file. Fundamentally the aim is to run the createSpec.js file both for user and session, this values is parametrized inside the spec file and based on the value passed the suite would run.
Is there a possibility to do this? Please advise.
You can utilize nodes process.argv
to read the argument (i.e. user
or session
) from within the file named createSpec.js
.
To better understand how, follow these steps:
At the top of createSpec.js
add the following line of code:
console.log(process.argv);
Then run grunt e2etest:user
via your CLI and you should see the following logged to your console:
[ 'node', '/usr/local/bin/grunt', 'e2etest:user' ]
Note: the information you want is positioned at index two of the array.
Now, delete the line we just added which reads console.log(process.argv);
from createSpec.js
.
createSpec.js
So, the steps above (1-3) illustrated that the arguments (user
or session
) can be accessed in createSpec.js
utilizing process.argv
. In which case you could do something like the following inside createSpec.js
.
const argument = process.argv[2].split(':').pop();
if (argument === 'user') {
// Run `user` specific tests here...
} else if (argument === 'session') {
// Run `session` specific tests here...
}
Note, we're using process.argv[2].split(/:/).pop();
to extract either user
or session
from the array item positioned at index two, whose initial value will be either e2etest:user
or e2etest:session
respectively.
Gruntfile
Your createSpec.js
file is now somewhat dependent on the grunt task named e2etest
being invoked correctly. For example, if a user were to run grunt e2etest
without providing the arguments then createSpec.js
is not going to do much.
To enforce the correct usage of the e2etest
task (i.e. it must be run using either grunt e2etest:user
or grunt e2etest:session
), you could change your task in your Gruntfile
as follows:
grunt.registerTask('e2etest', function(scope) {
if (!scope || !(scope === 'user' || scope === 'session')) {
grunt.warn(`Must be invoked with: ${this.name}:user or ${this.name}:session`);
}
grunt.task.run('mochaTest');
});
The gist above initially checks that an argument has been provided and is either user
or session
. If the argument is incorrect or missing then grunt.warn is utilized to warn the user.
If your version of nodejs does not support ES6 Template literals then use grunt.warn
as follows instead:
grunt.warn('Must be invoked with: ' + this.name + ':user or ' + this.name + ':session');
Additional comment
The code/gist shown in the createSpec.js section above will work if your use-case is exactly as you mention in your question. I.e. you invoke via the commandline using grunt e2etest:user
or grunt e2etest:session
. However, if that changes and you cannot guarantee that e2etest:user
or e2etest:session
will be exactly positioned at index two of the process.argv
array, then you may need to do the following at the top of createSpec.js
instead:
// Return the value in the array which starts with
// `e2etest` then extract the string after the colon `:`
const argument = process.argv.filter(arg => {
return arg.match(/^e2etest:.*/);
}).toString().split(':').pop();
if (argument === 'user') {
// Run `user` specific tests here...
} else if (argument === 'session') {
// Run `session` specific tests here...
}