I wish to create JUnit style XML reports from Protractor - Cucumber tests so that they can be used by CI.
Is there any detailed step on how this can be achieved?
Got the protractor-cucumber-junit npm library from below link but the documentation is not elaborate.
https://www.npmjs.com/package/protractor-cucumber-junit
Also the page points to a better plugin called 'cucumberjs-junitxml'. The documentation for this is given at
https://github.com/sonyschan/cucumberjs-junitxml
This too is not very helpful.
Questions:
What are the elaborate steps to be followed after installing the plugins to get the final XML?
What changes need to be done in the protractor config file or any other place within the project?
In order to generate the cucumber junit xml, first you need to generate cucumber json report:
1) Create a separate js file you can give it any name it would be better if you put this in hooks.js with all your before & after hooks
var Cucumber = require('cucumber'); // npm install --save cucumber
var fs = require('fs');
var hooks = function () {
var outputDir = './Reports/';
var JsonFormatter = Cucumber.Listener.JsonFormatter();
JsonFormatter.log = function (string) {
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir);
}
var targetJson = outputDir + 'cucumber_report.json';
fs.writeFile(targetJson, string, function (err) {
if (err) {
console.log('Failed to save cucumber test results to json file.');
console.log(err);
}
});
};
this.registerListener(JsonFormatter);
}
module.exports = hooks;
This would create cucumber_report.json file in Reports folder in your current directory.
2) You can consume this json report with the cucumber-junit library https://www.npmjs.com/package/cucumber-junit or one of the libraries you mentioned above , all are similar & follow the simple instructions & then simply run the below command
$ cat ./Reports/cucumber_report.json | ./node_modules/.bin/cucumber-junit > cucumber_report.xml
It would generate the cucumber_report.xml file.
Related
I am working on webdriverio CucumberJS BDD framework. I want to execute some code in afterScenario of wdio.config.js file for scenarios marked with particular tag eg #setting. I already have below afterScenario setup in my wdio.config.js. How can I run afterScenario with set of code only for particular tags from feature file?
/**
* Runs after a Cucumber scenario
*/
afterScenario: function (uri, feature, scenario, result, sourceLocation, context) {
if (commonHelper.elements.userMenuLink.isDisplayed()) {
commonHelper.clickLogout();
}
browser.deleteAllCookies();
},
I tried to insert below code in above file but it doesnt work
let isLastTag;
scenario.pickle.tags.forEach(tag => { isLastTag = tag.equals("#settings");
});
if(isLastTag.contains('settings'))
{
console.log('Setting key worked');
}
I'm developing my first node webkit app. I'm confused about packing the files. Is the end product a single file that can be executed ?
The end result will not be a single executable, you must also include some DLLs in your zip-file.
These line in github made me more confused.
How is the packaging done ?
Do I need to include the webkit files also in the package or just the files I have created ?
I packaged my node-webkit app successfully for various platforms by using the below gulp script. Below is the script which is self explanatory.
Reference : https://github.com/nwjs/nwbuilder/blob/master/example/Gulpfile.js
var NwBuilder = require('nw-builder');
var gulp = require('gulp');
var gutil = require('gulp-util');
gulp.task('nw', function () {
var nw = new NwBuilder({
version: '0.12.3',
files: '../nodepoc/**',
platforms: ['osx64','win32','win64']
});
// Log stuff you want
nw.on('log', function (msg) {
gutil.log('nw-builder', msg);
});
// Build returns a promise, return it so the task isn't called in parallel
return nw.build().catch(function (err) {
gutil.log('nw-builder', err);
});
});
gulp.task('default', ['nw']);
Save the file as gulpFile.js. In terminal , simply run gulp command in the same location as that of the gulpFile.js and it will download the necessary node-webkit distributions for the platforms and build the package for you.
I want to have the following reports:
coverage
spec
xunit
all running in a single mocha execution from my grunt
Currently - I have to run the tests 3 times, each time to generate a different report(!).
So I use grunt-mocha-test with 2 configuration where only the reporter is different (once xunit-file and once spec).
And then I have grunt-mocha-istanbul that runs the tests yet again,and generates the coverage report.
I tried using
{
options: {
reporters : ['xunit-file', 'spec']
}
}
for grunt-mocha-test at least to bring it down to 2, but that doesn't work as well.
reading grunt-mocha-istanbul documentation, i can't seem to find any info about reporter configuration.
How can I resolve this?
Maybe this can help:
https://github.com/glenjamin/mocha-multi
AFAIK this is not supported in Mocha yet, but it is on its way:
https://github.com/mochajs/mocha/pull/1360
Hope this helps,
György
I ran into the same problem recently, and found nothing after looking around SO as well as GH issues. It seems that topic of officially supporting multiple reporters are getting postponed over and over.
Having said that having a custom solution is quite easy, assuming the reporters you want to combine already exist. What I did is to create a small and naive custom reporter, and used the reporter in .mocharc.js config.
// junit-spec-reporter.js
const mocha = require("mocha");
const JUnit = require("mocha-junit-reporter");
const Spec = mocha.reporters.Spec;
const Base = mocha.reporters.Base;
function JunitSpecReporter(runner, options) {
Base.call(this, runner, options);
this._junitReporter = new JUnit(runner, options);
this._specReporter = new Spec(runner, options);
return this;
}
JunitSpecReporter.prototype.__proto__ = Base.prototype;
module.exports = JunitSpecReporter;
// .mocharc.js
module.exports = {
reporter: './junit-spec-reporter.js',
reporterOptions: {
mochaFile: './tests-results/results.xml'
}
};
The example above shows how to use both spec and junit reporter.
More info on custom reporter: https://mochajs.org/api/tutorial-custom-reporter.html
Note that this is just a proof of concept and can be made prettier and more robust using more generic approach (and TypeScript).
Update 14.9.2021
I have created a utility package for this: https://www.npmjs.com/package/#netatwork/mocha-utils
For simultaneously reporting for spec and x-unit, there's also an NPM package called spec-xunit-file.
In grunt:
grunt.initConfig({
mochaTest: {
test: {
options: {
reporter: 'spec-xunit-file',
...
},
...
}
}
...
});
I want to use factor-bundle to find common dependencies for my browserify entry points and save them out into a single common bundle:
https://www.npmjs.org/package/factor-bundle
The factor-bundle documentation makes it seem very easy to do on the command line, but I want to do it programmatically and I'm struggling to get my head around it.
My current script is this (I'm using reactify to transform react's jsx files too):
var browserify = require('browserify');
var factor = require('factor-bundle')
var glob = require('glob');
glob('static/js/'/**/*.{js,jsx}', function (err, files) {
var bundle = browserify({
debug: true
});
files.forEach(function(f) {
bundle.add('./' + f);
});
bundle.transform(require('reactify'));
// factor-bundle code goes here?
var dest = fs.createWriteStream('./static/js/build/common.js');
var stream = bundle.bundle().pipe(dest);
});
I'm trying to figure out how to use factor-bundle as a plugin, and specify the desired output file for each of the input files (ie each entry in files)
This answer is pretty late, so it's likely you've either already found a solution or a work around for this question. I'm answering this as it's quite similar to my question.
I was able to get this working by using factor-bundle as a browserify plugin. I haven't tested your specific code, but the pattern should be the same:
var fs = require('fs'),
browserify = require('browserify'),
factor = require('factor-bundle');
var bundle = browserify({
entries: ['x.js', 'y.js', 'z.js'],
debug: true
});
// Group common dependencies
// -o outputs the entry files without the common dependencies
bundle.plugin('factor-bundle', {
o: ['./static/js/build/x.js',
'./static/js/build/y.js',
'./static/js/build/z.js']
});
// Create Write Stream
var dest = fs.createWriteStream('./static/js/build/common.js');
// Bundle
var stream = bundle.bundle().pipe(dest);
The factor-bundle plugin takes output options o which need to have the same indexes as the entry files.
Unfortunately, I haven't figured out how to do anything else with these files after this point because I can't seem to access factor-bundle's stream event. So for minification etc, it might need to be done also via a browserify plugin.
I have created grunt-reactify to allow you to have a bundle file for a JSX file, in order to make it easier to work with modular React components.
All what you have to do is to specify a parent destination folder and the source files:
grunt.initConfig({
reactify: {
'tmp': 'test/**/*.jsx'
},
})
I have the following folder structure to my nodeunit tests for a particular project:
/tests
/tests/basic-test.js
/tests/models/
/tests/models/model1-tests.js
/tests/models/model2-tests.js
My question is - how do I get nodeunit to automatically execute ALL of the tests in the tests folder, including the sub-directories contained within?
If I execute nodeunit tests it only executes basic-test.js and skips everything in the sub-folders by default.
Use make based magic (or shell based magic).
test:
nodeunit $(shell find ./tests -name \*.js)
Here your passing the result of running find ./tests -name \*.js to nodeunit which should run all javascript tests recursively
Nodeunit allows you to pass in a list of directories from which to run tests. I used a package called diveSync which synchronously and recursively loops over files and directories. I store all the directories in an array and pass it to nodeunit:
var diveSync = require("diveSync"),
fs = require("fs"),
nodeUnit = require('nodeunit'),
directoriesToTest = ['test'];
diveSync(directoriesToTest[0], {directories:true}, function(err, file) {
if (fs.lstatSync(file).isDirectory()) {
directoriesToTest.push(file);
}
})
nodeUnit.reporters.default.run(directoriesToTest);
While this is not an automatic solution as described above, I have created a collector file like this:
allTests.js:
exports.registryTests = require("./registryTests.js");
exports.message = require("./messageTests.js")
When I run nodeunit allTests.js, it does run all the tests, and indicates the hierarchical arrangement as well:
? registryTests - [Test 1]
? registryTests - [Test 2]
? messageTests - [Test 1]
etc...
While the creation of a new unit test file will require including it in the collector, that is an easy, one-time task, and I can still run each file individually. For a very large project, this would also allow collectors that run more than one, but not all tests.
I was looking for solutions for the same question. None of the presented answers fully suited my situation where:
I didn't want to have any additional dependencies.
I already had nodeunit installed globally.
I didn't want to maintain the test file.
So the final solution for me was to combine Ian's and mbmcavoy's ideas:
// nodeunit tests.js
const path = require('path');
const fs = require('fs');
// Add folders you don't want to process here.
const ignores = [path.basename(__filename), 'node_modules', '.git'];
const testPaths = [];
// Reads a dir, finding all the tests inside it.
const readDir = (path) => {
fs.readdirSync(path).forEach((item) => {
const thisPath = `${path}/${item}`;
if (
ignores.indexOf(item) === -1 &&
fs.lstatSync(thisPath).isDirectory()
) {
if (item === 'tests') {
// Tests dir found.
fs.readdirSync(thisPath).forEach((test) => {
testPaths.push(`${thisPath}/${test}`);
});
} else {
// Sub dir found.
readDir(thisPath);
}
}
});
}
readDir('.', true);
// Feed the tests to nodeunit.
testPaths.forEach((path) => {
exports[path] = require(path);
});
Now I can run all my tests, new and old, with a mere nodeunit tests.js command.
As you can see from the code, the test files should be inside tests folders and the folders should not have any other files.