mrooding / gulp-protractor-cucumber-html-report

Generate html report from JSON file returned by cucumber-js json formatter
MIT License
12 stars 11 forks source link

Support multiple browser execution in protractor #6

Open mrooding opened 9 years ago

mrooding commented 9 years ago

The report now probably does not work well for running protractor with multipleCapabilities. Verify current behaviour and possible add proper support for this

csojka commented 8 years ago

I can verify that sharded reports present some issues for parsing the json. Something would likely need to combine .json files in an intelligent manner. I played around with appending to the report file but didn't have much luck.

Bill77 commented 8 years ago

Hi @mrooding,

I think we're close on this feature, although I don't know gulp well enough to do this. But with protractor-cucumber-framework going to 0.4.0, we now can have cucumber produce json output, my problem is that html-report produces report.html by default and overwrites itself when the gulp stream has multiple .json files.

Perhaps if it can use the .json file name instead?

Here is my protractor.conf.js

config.multiCapabilities = [
{
        browserName: 'chrome',
        name: 'Chrome',
        logName: 'chome log',
        cucumberOpts: {
            format: 'json:./test_out/cucumber.chrome.json'
        }
    },
    {
        browserName: 'internet explorer',
        name: 'Internet Explorer',
        logName: 'Internet Explorer log',
        cucumberOpts: {
            format: 'json:./test_out/cucumber.ie.json'
        }
    }
];

Here is the relevant Gulp settings

gulp
.src(['./test_out/*.json', '!./test_out/e2e.json'])                
.pipe(gulpPlugins.protractorCucumberHtmlReport({
    dest: 'test_out/e2e-reports'
}));
danyc commented 8 years ago

@csojka Something would likely need to combine .json files in an intelligent manner. I played around with appending to the report file but didn't have much luck.

I've managed to combine the multiple json files from shardTestFiles. I capture the JSON output like this:

var Cucumber = require('cucumber');
var fs = require('fs');
var path = require('path');
var moment = require('moment');

var JsonFormatter = Cucumber.Listener.JsonFormatter();

var reportDirectory = 'target/testreport/';
var reportFileName = 'cucumber-test-results_partial_';

var reportDirectoryPath = path.join(__dirname, '../../' + reportDirectory);
var currentDateTime = moment().format('YYYYMMDD_HHmmss_SSSSSSSSS');
var reportFilePath = path.join(reportDirectoryPath + reportFileName + currentDateTime + '.json');

function mkdirp(path, root) {
  var dirs = path.split('/');
  var dir = dirs.shift();
  var root = (root || '') + dir + '/';

  try {
    fs.mkdirSync(root);
  } catch (e) {
    if (!fs.statSync(root).isDirectory()) { throw new Error(e); }
  }

  return !dirs.length || mkdirp(dirs.join('/'), root);
}

module.exports = function JsonOutputHook() {
  JsonFormatter.log = function (json) {
    fs.open(reportFilePath, 'w+', function (err, fd) {
      if (err) {
        mkdirp(reportDirectoryPath);
        fd = fs.openSync(reportFilePath, 'w+');
      }
      fs.writeSync(fd, json);

      console.log('json file location: ' + reportFilePath);
    });
  };

  this.registerListener(JsonFormatter);
};

And I have the following gulp tasks:

gulp.task('test:combine_json_reports', _ => {
  var jsonConcat = require('gulp-json-concat');
  return gulp.src('target/testreport/cucumber-test-results_partial_*.json')
      .pipe(jsonConcat('cucumber-test-results.json', function (data) {
        // in data, the keys of the dictionary are the names of the files
        var concatJson = [];
        var keys = Object.keys(data);
        keys.forEach(function (key, index) {
          data[key].forEach(function (item) {
            concatJson.push(item);
          });
        });
        function compareStrings(a, b) {
          a = a.toLowerCase();
          b = b.toLowerCase();
          return (a < b) ? -1 : (a > b) ? 1 : 0;
        }
        // sort by id and description
        function compareResults(a, b) {
          if (compareStrings(a.id, b.id) === 0) {
            return compareStrings(a.description, b.description);
          } else {
            return compareStrings(a.id, b.id);
          }
        }
        concatJson = concatJson.sort(function (a, b) {
          return compareResults(a, b);
        });
        return new Buffer(JSON.stringify(concatJson, null, '\t'));
      }))
      .pipe(gulp.dest('target/testreport'));
});

gulp.task('test:generate_report', ['test:combine_json_reports'], _ => {
  var protractorReport = require('gulp-protractor-cucumber-html-report');
  return gulp.src('target/testreport/cucumber-test-results.json')
      .pipe(protractorReport({
        dest: 'target/testreport/'
      }));
});