monocart-reporter 2.9.6 → 2.9.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/common.js CHANGED
@@ -1,244 +1,244 @@
1
- const Util = require('./utils/util.js');
2
- const getDefaultSummary = require('./default/summary.js');
3
- const generatePieChart = require('./utils/pie.js');
4
-
5
- const caseHandler = (item, summary) => {
6
- summary.tests.value += 1;
7
- summary.retries.value += item.retry;
8
-
9
- if (item.errors) {
10
- summary.errors.value += item.errors.length;
11
- }
12
-
13
- if (item.logs) {
14
- summary.logs.value += item.logs.length;
15
- }
16
-
17
- if (item.attachments) {
18
- summary.attachments.value += item.attachments.length;
19
- }
20
-
21
- const type = summary[item.caseType];
22
- if (!type) {
23
- return;
24
- }
25
- type.value += 1;
26
- };
27
-
28
- const stepHandler = (item, summary) => {
29
- summary.steps.value += 1;
30
-
31
- if (item.errors) {
32
- summary.errors.value += item.errors.length;
33
- }
34
- };
35
-
36
- // ===========================================================================
37
-
38
- // all tags for global report
39
- const tagHandler = (item, tags, tagOptions) => {
40
-
41
- const addTag = (tag) => {
42
- let tagItem = tags[tag];
43
- if (!tagItem) {
44
- tagItem = {};
45
- const options = tagOptions[tag];
46
- if (options) {
47
- if (options.style) {
48
- Object.assign(tagItem, options);
49
- } else {
50
- tagItem.style = options;
51
- }
52
- }
53
- tagItem.value = 0;
54
- tags[tag] = tagItem;
55
- }
56
- tagItem.value += 1;
57
- };
58
-
59
- // new syntax in playwright v1.42
60
- if (item.tags) {
61
-
62
- // tag starts with @
63
- item.tags.forEach((t) => {
64
- const tag = `${t}`.slice(1);
65
- addTag(tag);
66
- });
67
-
68
- return;
69
- }
70
-
71
- // supports old title tag
72
- const matches = item.title.matchAll(Util.tagPattern);
73
- for (const match of matches) {
74
- // all, before, key, after
75
- const tag = match[2];
76
- addTag(tag);
77
- }
78
- };
79
-
80
- const calculateSummary = (data, options) => {
81
- const tags = {};
82
- const tagOptions = options.tags || {};
83
-
84
- const summary = getDefaultSummary();
85
- // init summary data
86
- Object.keys(summary).forEach((k) => {
87
- const item = summary[k];
88
- item.id = k;
89
- item.value = 0;
90
- });
91
-
92
- // ====================================================
93
-
94
- const suiteMap = {};
95
- data.suiteTypes.forEach((k) => {
96
- suiteMap[k] = `${k}s`;
97
- });
98
-
99
- // only counting case parent without duplicate
100
- const suiteSet = new Set();
101
- // Unique title
102
- const projectSet = new Set();
103
- const fileSet = new Set();
104
-
105
- const suiteHandler = (item) => {
106
- const suiteType = item.suiteType;
107
- if (suiteType === 'project') {
108
- projectSet.add(item.title);
109
- return;
110
- }
111
-
112
- if (suiteType === 'file') {
113
- fileSet.add(item.title);
114
- return;
115
- }
116
-
117
- // shards and describes
118
- const type = suiteMap[suiteType];
119
- if (!type) {
120
- return;
121
- }
122
- summary[type].value += 1;
123
- };
124
-
125
- // ====================================================
126
-
127
- Util.forEach(data.rows, (item, parent) => {
128
-
129
- // do NOT collect tags from step
130
- if (Util.isTagItem(item)) {
131
- tagHandler(item, tags, tagOptions);
132
- }
133
-
134
- if (item.type === 'case') {
135
- suiteSet.add(parent);
136
- caseHandler(item, summary);
137
- return;
138
- }
139
-
140
- if (item.type === 'step') {
141
- stepHandler(item, summary);
142
- return;
143
- }
144
-
145
- if (item.type === 'suite') {
146
- suiteHandler(item);
147
- }
148
- });
149
-
150
- // ====================================================
151
-
152
- summary.suites.value = suiteSet.size;
153
- suiteSet.clear();
154
-
155
- summary.projects.value = projectSet.size;
156
- projectSet.clear();
157
-
158
- summary.files.value = fileSet.size;
159
- fileSet.clear();
160
-
161
- // ====================================================
162
-
163
- data.tags = tags;
164
- data.summary = summary;
165
-
166
- // ====================================================
167
-
168
- const caseTypes = data.caseTypes;
169
-
170
- // percent and pie data list
171
- const pieDataList = [];
172
- caseTypes.forEach((k) => {
173
- const item = summary[k];
174
- item.percent = Util.PF(item.value, summary.tests.value);
175
- pieDataList.push({
176
- ... item
177
- });
178
- });
179
-
180
- data.pieChart = generatePieChart(pieDataList);
181
-
182
- };
183
-
184
- // ===========================================================================
185
-
186
- const isTrendData = (data) => {
187
- if (!data.date) {
188
- return false;
189
- }
190
- if (!data.duration) {
191
- return false;
192
- }
193
- if (!data.summary) {
194
- return false;
195
- }
196
- return true;
197
- };
198
-
199
- const getTrendData = async (input) => {
200
- if (typeof input === 'function') {
201
- input = await input();
202
- }
203
-
204
- // path
205
- if (typeof input === 'string') {
206
- const data = Util.readJSONSync(input);
207
- if (data) {
208
- return data;
209
- }
210
- }
211
-
212
- if (input && typeof input === 'object') {
213
- return input;
214
- }
215
- };
216
-
217
- const getTrends = async (input) => {
218
-
219
- if (!input) {
220
- return [];
221
- }
222
- const data = await getTrendData(input);
223
- if (!data) {
224
- Util.logError('failed to load trend data');
225
- return [];
226
- }
227
-
228
- if (!isTrendData(data)) {
229
- Util.logError('trend data requires properties: date, duration and summary');
230
- return [];
231
- }
232
-
233
- // copy previous trends
234
- const trends = [].concat(data.trends || []);
235
- trends.push(Util.getCurrentTrendInfo(data));
236
-
237
- return trends;
238
- };
239
-
240
-
241
- module.exports = {
242
- calculateSummary,
243
- getTrends
244
- };
1
+ const Util = require('./utils/util.js');
2
+ const getDefaultSummary = require('./default/summary.js');
3
+ const generatePieChart = require('./utils/pie.js');
4
+
5
+ const caseHandler = (item, summary) => {
6
+ summary.tests.value += 1;
7
+ summary.retries.value += item.retry;
8
+
9
+ if (item.errors) {
10
+ summary.errors.value += item.errors.length;
11
+ }
12
+
13
+ if (item.logs) {
14
+ summary.logs.value += item.logs.length;
15
+ }
16
+
17
+ if (item.attachments) {
18
+ summary.attachments.value += item.attachments.length;
19
+ }
20
+
21
+ const type = summary[item.caseType];
22
+ if (!type) {
23
+ return;
24
+ }
25
+ type.value += 1;
26
+ };
27
+
28
+ const stepHandler = (item, summary) => {
29
+ summary.steps.value += 1;
30
+
31
+ if (item.errors) {
32
+ summary.errors.value += item.errors.length;
33
+ }
34
+ };
35
+
36
+ // ===========================================================================
37
+
38
+ // all tags for global report
39
+ const tagHandler = (item, tags, tagOptions) => {
40
+
41
+ const addTag = (tag) => {
42
+ let tagItem = tags[tag];
43
+ if (!tagItem) {
44
+ tagItem = {};
45
+ const options = tagOptions[tag];
46
+ if (options) {
47
+ if (options.style) {
48
+ Object.assign(tagItem, options);
49
+ } else {
50
+ tagItem.style = options;
51
+ }
52
+ }
53
+ tagItem.value = 0;
54
+ tags[tag] = tagItem;
55
+ }
56
+ tagItem.value += 1;
57
+ };
58
+
59
+ // new syntax in playwright v1.42
60
+ if (item.tags) {
61
+
62
+ // tag starts with @
63
+ item.tags.forEach((t) => {
64
+ const tag = `${t}`.slice(1);
65
+ addTag(tag);
66
+ });
67
+
68
+ return;
69
+ }
70
+
71
+ // supports old title tag
72
+ const matches = item.title.matchAll(Util.tagPattern);
73
+ for (const match of matches) {
74
+ // all, before, key, after
75
+ const tag = match[2];
76
+ addTag(tag);
77
+ }
78
+ };
79
+
80
+ const calculateSummary = (data, options) => {
81
+ const tags = {};
82
+ const tagOptions = options.tags || {};
83
+
84
+ const summary = getDefaultSummary();
85
+ // init summary data
86
+ Object.keys(summary).forEach((k) => {
87
+ const item = summary[k];
88
+ item.id = k;
89
+ item.value = 0;
90
+ });
91
+
92
+ // ====================================================
93
+
94
+ const suiteMap = {};
95
+ data.suiteTypes.forEach((k) => {
96
+ suiteMap[k] = `${k}s`;
97
+ });
98
+
99
+ // only counting case parent without duplicate
100
+ const suiteSet = new Set();
101
+ // Unique title
102
+ const projectSet = new Set();
103
+ const fileSet = new Set();
104
+
105
+ const suiteHandler = (item) => {
106
+ const suiteType = item.suiteType;
107
+ if (suiteType === 'project') {
108
+ projectSet.add(item.title);
109
+ return;
110
+ }
111
+
112
+ if (suiteType === 'file') {
113
+ fileSet.add(item.title);
114
+ return;
115
+ }
116
+
117
+ // shards and describes
118
+ const type = suiteMap[suiteType];
119
+ if (!type) {
120
+ return;
121
+ }
122
+ summary[type].value += 1;
123
+ };
124
+
125
+ // ====================================================
126
+
127
+ Util.forEach(data.rows, (item, parent) => {
128
+
129
+ // do NOT collect tags from step
130
+ if (Util.isTagItem(item)) {
131
+ tagHandler(item, tags, tagOptions);
132
+ }
133
+
134
+ if (item.type === 'case') {
135
+ suiteSet.add(parent);
136
+ caseHandler(item, summary);
137
+ return;
138
+ }
139
+
140
+ if (item.type === 'step') {
141
+ stepHandler(item, summary);
142
+ return;
143
+ }
144
+
145
+ if (item.type === 'suite') {
146
+ suiteHandler(item);
147
+ }
148
+ });
149
+
150
+ // ====================================================
151
+
152
+ summary.suites.value = suiteSet.size;
153
+ suiteSet.clear();
154
+
155
+ summary.projects.value = projectSet.size;
156
+ projectSet.clear();
157
+
158
+ summary.files.value = fileSet.size;
159
+ fileSet.clear();
160
+
161
+ // ====================================================
162
+
163
+ data.tags = tags;
164
+ data.summary = summary;
165
+
166
+ // ====================================================
167
+
168
+ const caseTypes = data.caseTypes;
169
+
170
+ // percent and pie data list
171
+ const pieDataList = [];
172
+ caseTypes.forEach((k) => {
173
+ const item = summary[k];
174
+ item.percent = Util.PF(item.value, summary.tests.value);
175
+ pieDataList.push({
176
+ ... item
177
+ });
178
+ });
179
+
180
+ data.pieChart = generatePieChart(pieDataList);
181
+
182
+ };
183
+
184
+ // ===========================================================================
185
+
186
+ const isTrendData = (data) => {
187
+ if (!data.date) {
188
+ return false;
189
+ }
190
+ if (!data.duration) {
191
+ return false;
192
+ }
193
+ if (!data.summary) {
194
+ return false;
195
+ }
196
+ return true;
197
+ };
198
+
199
+ const getTrendData = async (input) => {
200
+ if (typeof input === 'function') {
201
+ input = await input();
202
+ }
203
+
204
+ // path
205
+ if (typeof input === 'string') {
206
+ const data = Util.readJSONSync(input);
207
+ if (data) {
208
+ return data;
209
+ }
210
+ }
211
+
212
+ if (input && typeof input === 'object') {
213
+ return input;
214
+ }
215
+ };
216
+
217
+ const getTrends = async (input) => {
218
+
219
+ if (!input) {
220
+ return [];
221
+ }
222
+ const data = await getTrendData(input);
223
+ if (!data) {
224
+ Util.logError('failed to load trend data');
225
+ return [];
226
+ }
227
+
228
+ if (!isTrendData(data)) {
229
+ Util.logError('trend data requires properties: date, duration and summary');
230
+ return [];
231
+ }
232
+
233
+ // copy previous trends
234
+ const trends = [].concat(data.trends || []);
235
+ trends.push(Util.getCurrentTrendInfo(data));
236
+
237
+ return trends;
238
+ };
239
+
240
+
241
+ module.exports = {
242
+ calculateSummary,
243
+ getTrends
244
+ };
@@ -1,79 +1,79 @@
1
- module.exports = () => [{
2
- id: 'caseType',
3
- name: '',
4
- width: 36,
5
- sortable: false,
6
- align: 'center',
7
- formatter: 'iconCaseType'
8
- }, {
9
- id: 'title',
10
- name: 'Title',
11
- searchable: true,
12
- width: 350,
13
- maxWidth: 1230
14
- }, {
15
- id: 'type',
16
- name: 'Type',
17
- width: 50,
18
- sortable: false,
19
- align: 'center',
20
- formatter: 'iconType'
21
- }, {
22
- id: 'duration',
23
- name: 'Duration',
24
- align: 'right',
25
- sortAsc: false,
26
- formatter: 'duration'
27
- }, {
28
- id: 'errors',
29
- name: 'Errors',
30
- width: 60,
31
- align: 'center',
32
- comparer: 'errors',
33
- formatter: 'errors'
34
- }, {
35
- id: 'logs',
36
- name: 'Logs',
37
- width: 60,
38
- align: 'center',
39
- comparer: 'logs',
40
- formatter: 'logs'
41
- }, {
42
- id: 'annotations',
43
- name: 'Annotations',
44
- width: 100,
45
- markdown: true,
46
- searchable: true,
47
- comparer: 'annotations',
48
- formatter: 'annotations'
49
- }, {
50
- id: 'attachments',
51
- name: 'Attachments',
52
- width: 100,
53
- align: 'center',
54
- formatter: 'attachments'
55
- }, {
56
- id: 'status',
57
- name: 'Status',
58
- align: 'center'
59
- }, {
60
- id: 'expectedStatus',
61
- name: 'Expected',
62
- align: 'center'
63
- }, {
64
- id: 'outcome',
65
- name: 'Outcome',
66
- align: 'center',
67
- width: 85
68
- }, {
69
- id: 'retry',
70
- name: 'Retry',
71
- align: 'center',
72
- width: 50
73
- }, {
74
- id: 'location',
75
- name: 'Location',
76
- classMap: 'mcr-location',
77
- width: 200,
78
- maxWidth: 1981
79
- }];
1
+ module.exports = () => [{
2
+ id: 'caseType',
3
+ name: '',
4
+ width: 36,
5
+ sortable: false,
6
+ align: 'center',
7
+ formatter: 'iconCaseType'
8
+ }, {
9
+ id: 'title',
10
+ name: 'Title',
11
+ searchable: true,
12
+ width: 350,
13
+ maxWidth: 1230
14
+ }, {
15
+ id: 'type',
16
+ name: 'Type',
17
+ width: 50,
18
+ sortable: false,
19
+ align: 'center',
20
+ formatter: 'iconType'
21
+ }, {
22
+ id: 'duration',
23
+ name: 'Duration',
24
+ align: 'right',
25
+ sortAsc: false,
26
+ formatter: 'duration'
27
+ }, {
28
+ id: 'errors',
29
+ name: 'Errors',
30
+ width: 60,
31
+ align: 'center',
32
+ comparer: 'errors',
33
+ formatter: 'errors'
34
+ }, {
35
+ id: 'logs',
36
+ name: 'Logs',
37
+ width: 60,
38
+ align: 'center',
39
+ comparer: 'logs',
40
+ formatter: 'logs'
41
+ }, {
42
+ id: 'annotations',
43
+ name: 'Annotations',
44
+ width: 100,
45
+ markdown: true,
46
+ searchable: true,
47
+ comparer: 'annotations',
48
+ formatter: 'annotations'
49
+ }, {
50
+ id: 'attachments',
51
+ name: 'Attachments',
52
+ width: 100,
53
+ align: 'center',
54
+ formatter: 'attachments'
55
+ }, {
56
+ id: 'status',
57
+ name: 'Status',
58
+ align: 'center'
59
+ }, {
60
+ id: 'expectedStatus',
61
+ name: 'Expected',
62
+ align: 'center'
63
+ }, {
64
+ id: 'outcome',
65
+ name: 'Outcome',
66
+ align: 'center',
67
+ width: 85
68
+ }, {
69
+ id: 'retry',
70
+ name: 'Retry',
71
+ align: 'center',
72
+ width: 50
73
+ }, {
74
+ id: 'location',
75
+ name: 'Location',
76
+ classMap: 'mcr-location',
77
+ width: 200,
78
+ maxWidth: 1981
79
+ }];