-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathindex.js
134 lines (107 loc) · 4.68 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
const { Formatter, SummaryFormatter, formatterHelpers } = require('cucumber');
const { cross, tick } = require('figures');
const Table = require('cli-table3');
const colors = require('colors');
const { EOL: n } = require('os');
/**
* @typedef {Object} Options
* @property colorFns - a series of helper functions for outputting colors
* @property colorsEnabled
* @property cwd - the current working directory
* @property {EventEmitter} eventBroadcaster - an event emitter that emits the event protocol
* @property {EventDataCollector} eventDataCollector - an instance of EventDataCollector which handles the complexity of grouping the data for related events
* @property log - function which will write the passed string to the the designated stream
* @property snippetBuilder - an object with a build method that should be called with {keywordType, pickleStep}
* @property stream - the underlying stream the formatter is writing to
* @property supportCodeLibrary
* @see https://github.com/cucumber/cucumber-js/blob/master/docs/custom_formatters.md
*/
/** @see https://github.com/cucumber/cucumber-js/blob/master/src/formatter/helpers/issue_helpers.js */
const marks = {
ambiguous: cross,
failed: cross,
passed: tick,
pending: '?',
skipped: '-',
undefined: '?'
};
/** @see https://github.com/cli-table/cli-table3#custom-styles */
const table = {
chars: {
top: '', 'top-left': '', 'top-mid': '', 'top-right': '',
mid: '', 'left-mid': '', 'mid-mid': '', 'right-mid': '',
bottom: '', 'bottom-left': '', 'bottom-mid': '', 'bottom-right': ''
},
style: {
head: [],
border: []
}
};
class PrettyFormatter extends Formatter {
/** @param {Options} options */
constructor(options) {
super(options);
this.colorsEnabled = options.colorsEnabled;
this.descriptionEnabled = options.descriptionEnabled;
options.eventBroadcaster.on('test-case-started', (event) => {
const { gherkinDocument, pickle } = options.eventDataCollector.getTestCaseAttempt(event);
if (this.uri !== event.sourceLocation.uri) {
const { feature } = gherkinDocument;
if (this.uri) this.logn();
const tags = feature.tags.map((tag) => tag.name).join(' ');
if (tags) this.logn(options.colorFns.tag(tags));
this.logn(`${this.color(feature.keyword, 'magenta', 'bold')}: ${feature.name}`);
if (feature.description && this.descriptionEnabled) this.logn(`${n}${feature.description}`);
this.uri = event.sourceLocation.uri;
}
this.logn();
const tags = pickle.tags.map((tag) => tag.name).join(' ');
if (tags) this.logn(options.colorFns.tag(tags), 2);
const line = Math.min(...pickle.locations.map((location) => location.line));
const { keyword } = gherkinDocument.feature.children.find((child) => child.location.line === line);
this.logn(`${this.color(keyword, 'magenta', 'bold')}: ${pickle.name}`, 2);
});
options.eventBroadcaster.on('test-step-started', (event) => {
const testCaseAttempt = options.eventDataCollector.getTestCaseAttempt(event.testCase);
testCaseAttempt.stepResults = testCaseAttempt.testCase.steps.map(() => ({}));
const testStep = formatterHelpers.parseTestCaseAttempt({ testCaseAttempt }).testSteps[event.index];
if (!testStep.sourceLocation) return; // hook
this.logn(`${this.color(testStep.keyword.trim(), 'bold')} ${testStep.text}`, 4);
testStep.arguments.forEach((argument) => {
if (argument.content) {
this.logn(`"""${n}${argument.content}${n}"""`, 6);
}
if (argument.rows) {
const datatable = new Table(table);
datatable.push(...argument.rows);
this.logn(datatable, 6);
}
});
});
options.eventBroadcaster.on('test-step-finished', (event) => {
const { result: { status, exception } } = event;
if (status !== 'passed') {
this.logn(options.colorFns[status](`${marks[status]} ${status}`), 4);
}
if (exception) {
const error = formatterHelpers.formatError(exception, options.colorFns);
this.logn(error, 6);
}
});
options.eventBroadcaster.on('test-run-finished', (event) => {
const noptions = Object.create(options, { eventBroadcaster: { value: { on: () => { } } } });
const formatter = new SummaryFormatter(noptions);
if (this.uri) this.logn();
formatter.logSummary(event);
});
}
color(value, ...color) {
return this.colorsEnabled ? color.reduce((v, c) => v[c], colors)(value) : value;
}
logn(value = '', indent = 0) {
let text = value.toString();
if (indent > 0) text = text.replace(/^/gm, ' '.repeat(indent));
this.log(`${text}${n}`);
}
}
module.exports = PrettyFormatter;