Skip to content

Commit

Permalink
Merge pull request #6 from sullenor/sullenor/parallel-usage
Browse files Browse the repository at this point in the history
Sullenor/parallel usage
  • Loading branch information
sullenor committed May 6, 2016
2 parents 4d6f979 + 4943c15 commit 83da913
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 122 deletions.
31 changes: 31 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"env": {
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"rules": {
"comma-dangle": [
"error",
"always-multiline"
],
"indent": [
"error",
2
],
"linebreak-style": [
"error",
"unix"
],
"no-console": "off",
"no-control-regex": "off",
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}
}
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.babelrc
.editorconfig
.eslintrc.json
.gitignore
.npmignore
.travis.yml
Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ notifications:

language: node_js
node_js:
- "6"
- "4"
- "0.12"
172 changes: 64 additions & 108 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const inherits = require('util').inherits;
const EventEmitter = require('events').EventEmitter;
const EOL = require('os').EOL;
'use strict';

const { inherits } = require('util');
const { EventEmitter } = require('events');

const o = msg => console.log(msg);

Expand All @@ -11,105 +12,60 @@ const o = msg => console.log(msg);
function WdioTeamcityReporter() {
EventEmitter.call(this);

/**
* @param {object} suite
* @param {string} suite.type
* @param {string} suite.title
* @param {string} suite.parent
* @param {boolean} suite.pending
* @param {string} suite.file
* @param {string[]} suite.specs
* @param {string} suite.event
* @param {object} suite.runner
*/
this.on('suite:start', suite => {
o(`##teamcity[testSuiteStarted name='${escape(suite.title)}']`);
});

/**
* @param {object} test
* @param {string} test.type
* @param {string} test.title
* @param {string} test.parent
* @param {boolean} test.pending
* @param {string} test.file
* @param {string[]} test.specs
* @param {string} test.event
* @param {object} test.runner
* @param {string} test.specHash
*/
this.on('test:start', test => {
o(`##teamcity[testStarted name='${escape(test.title)}' captureStandardOutput='true']"`);
});

/**
* @param {object} test
* @param {string} test.type
* @param {string} test.title
* @param {string} test.parent
* @param {boolean} test.pending
* @param {string} test.file
* @param {string[]} test.specs
* @param {string} test.event
* @param {object} test.runner
* @param {string} test.specHash
*/
this.on('test:end', test => {
o(`##teamcity[testFinished name='${escape(test.title)}']`);
});

/**
* @param {object} test
* @param {string} test.type
* @param {object} test.err
* @param {string} test.title
* @param {string} test.parent
* @param {boolean} test.pending
* @param {string} test.file
* @param {string[]} test.specs
* @param {string} test.event
* @param {object} test.runner
* @param {string} test.specHash
*/
this.on('test:fail', test => {
o(`##teamcity[testFailed name='${escape(test.title)}' message='${escape(test.err.message)}' details='${escape(test.err.stack)}']`);
});

/**
* @param {object} test
* @param {string} test.type
* @param {string} test.title
* @param {string} test.parent
* @param {boolean} test.pending
* @param {string} test.file
* @param {string[]} test.specs
* @param {string} test.event
* @param {object} test.runner
* @param {string} test.specHash
*/
this.on('test:pending', test => {
o(`##teamcity[testIgnored name='${escape(test.title)}' message='pending']`);
});

/**
* @param {object} suite
* @param {string} suite.type
* @param {string} suite.title
* @param {string} suite.parent
* @param {boolean} suite.pending
* @param {string} suite.file
* @param {string[]} suite.specs
* @param {string} suite.event
* @param {object} suite.runner
* @param {string} suite.specHash
*/
this.on('suite:end', suite => {
o(`##teamcity[testSuiteFinished name='${escape(suite.title)}']`);
});
this.enableRealTimeOutput();
}

inherits(WdioTeamcityReporter, EventEmitter);

/**
* Makes it possible to display test results in real-time.
*
* Suite event handler accepts:
* * @param {object} suite
* * @param {string} suite.type
* * @param {string} suite.title
* * @param {string} suite.parent
* * @param {boolean} suite.pending
* * @param {string} suite.file
* * @param {string[]} suite.specs
* * @param {string} suite.event
* * @param {object} suite.runner
* * @param {string} [suite.specHash] is available for the suite:end event
*
* Each test event handler accepts:
* * @param {object} test
* * @param {string} test.type
* * @param {object} [test.err] is available for the test:fail event
* * @param {string} test.title
* * @param {string} test.parent
* * @param {boolean} test.pending
* * @param {string} test.file
* * @param {string[]} test.specs
* * @param {string} test.event
* * @param {object} test.runner
* * @param {string} test.specHash
*
* In order to distinguish separate processes running in parallel,
* each message should be signed with the unique identifier,
* which should be provided through the flowId attribute.
* So I use specHash for this.
*
* @see https://github.com/webdriverio/webdriverio/blob/16c9dcc7334e1015c48e07f113f00a6b63d31d7f/lib/utils/ReporterStats.js#L119-L127
* @see https://confluence.jetbrains.com/display/TCD65/Build+Script+Interaction+with+TeamCity
*/
WdioTeamcityReporter.prototype.enableRealTimeOutput = function () {
const handlers = {
'suite:start': suite => o(`##teamcity[testSuiteStarted name='${escape(suite.title)}' flowId='${escape(suite.specHash)}']`),
'test:start': test => o(`##teamcity[testStarted name='${escape(test.title)}' captureStandardOutput='true' flowId='${escape(test.specHash)}']"`),
'test:end': test => o(`##teamcity[testFinished name='${escape(test.title)}'] flowId='${escape(test.specHash)}'`),
'test:fail': test => o(`##teamcity[testFailed name='${escape(test.title)}' message='${escape(test.err.message)}' details='${escape(test.err.stack)}' flowId='${escape(test.specHash)}']`),
'test:pending': test => o(`##teamcity[testIgnored name='${escape(test.title)}' message='pending'] flowId='${escape(test.specHash)}'`),
'suite:end': suite => o(`##teamcity[testSuiteFinished name='${escape(suite.title)}'] flowId='${escape(suite.specHash)}'`),
};

Object.keys(handlers).forEach(event => this.on(event, handlers[event]));
};

module.exports = WdioTeamcityReporter;
module.exports.reporterName = 'teamcity';

Expand All @@ -126,14 +82,14 @@ function escape(str) {

return str
.toString()
.replace(/\x1B.*?m/g, "")
.replace(/\|/g, "||")
.replace(/\n/g, "|n")
.replace(/\r/g, "|r")
.replace(/\[/g, "|[")
.replace(/\]/g, "|]")
.replace(/\u0085/g, "|x")
.replace(/\u2028/g, "|l")
.replace(/\u2029/g, "|p")
.replace(/'/g, "|'");
.replace(/\x1B.*?m/g, '')
.replace(/\|/g, '||')
.replace(/\n/g, '|n')
.replace(/\r/g, '|r')
.replace(/\[/g, '|[')
.replace(/\]/g, '|]')
.replace(/\u0085/g, '|x')
.replace(/\u2028/g, '|l')
.replace(/\u2029/g, '|p')
.replace(/'/g, '|\'');
}
16 changes: 9 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "wdio-teamcity-reporter",
"version": "1.0.0",
"version": "1.0.1",
"description": "WebdriverIO Teamcity reporter",
"main": "index.js",
"engines": {
Expand All @@ -10,9 +10,9 @@
"build": "babel index.js --out-file index.js",
"cleanup": "git reset --hard",
"prepublish": "in-publish && npm run -s build || in-install",
"test": "ava --require babel-register test.js",
"test:n": "ava test.js",
"test:w": "ava --require babel-register --watch test.js"
"lint": "eslint *.js",
"test": "tape -r babel-register test.js",
"test:raw": "tape test.js"
},
"repository": {
"type": "git",
Expand All @@ -28,10 +28,12 @@
},
"homepage": "https://github.com/sullenor/wdio-teamcity-reporter#readme",
"devDependencies": {
"ava": "^0.14.0",
"babel-cli": "^6.7.5",
"babel-preset-es2015": "^6.6.0",
"babel-register": "^6.7.2",
"in-publish": "^2.0.0"
}
"eslint": "^2.9.0",
"in-publish": "^2.0.0",
"tape": "^4.5.1"
},
"dependencies": {}
}
12 changes: 5 additions & 7 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'ava';
import Reporter from './index';
const test = require('tape');
const Reporter = require('./index');

const events = [
'start',
Expand All @@ -15,11 +15,7 @@ const events = [
'end',
];

var reporter;

test.before(t => {
reporter = new Reporter();
});
var reporter = new Reporter();

events.forEach(event => test(event, t => {
const data = {
Expand All @@ -31,11 +27,13 @@ events.forEach(event => test(event, t => {
specs: [''],
event: event,
runner: {},
specHash: '98d5f98abe0e1d6b68d654ead0a9ce77',
};

if (event.indexOf('fail') > -1) {
data.err = new Error('artificial error');
}

reporter.emit(event, data);
t.end();
}));

0 comments on commit 83da913

Please sign in to comment.