testbeats 2.0.0
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/LICENSE +21 -0
- package/README.md +60 -0
- package/package.json +65 -0
- package/src/beats/index.js +74 -0
- package/src/cli.js +23 -0
- package/src/commands/publish.js +54 -0
- package/src/extensions/ci-info.js +134 -0
- package/src/extensions/custom.js +29 -0
- package/src/extensions/hyperlinks.js +60 -0
- package/src/extensions/index.js +63 -0
- package/src/extensions/mentions.js +112 -0
- package/src/extensions/metadata.js +89 -0
- package/src/extensions/percy-analysis.js +203 -0
- package/src/extensions/quick-chart-test-summary.js +82 -0
- package/src/extensions/report-portal-analysis.js +95 -0
- package/src/extensions/report-portal-history.js +105 -0
- package/src/helpers/ci.js +62 -0
- package/src/helpers/constants.js +45 -0
- package/src/helpers/extension.helper.js +107 -0
- package/src/helpers/helper.js +102 -0
- package/src/helpers/metadata.helper.js +115 -0
- package/src/helpers/percy.js +60 -0
- package/src/helpers/performance.js +141 -0
- package/src/helpers/report-portal.js +47 -0
- package/src/index.d.ts +243 -0
- package/src/index.js +14 -0
- package/src/targets/chat.js +242 -0
- package/src/targets/custom.js +28 -0
- package/src/targets/delay.js +19 -0
- package/src/targets/index.js +39 -0
- package/src/targets/influx.js +208 -0
- package/src/targets/slack.js +266 -0
- package/src/targets/teams.js +304 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
const influx = require('influxdb-lite');
|
|
2
|
+
const Metric = require('performance-results-parser/src/models/Metric');
|
|
3
|
+
const PerformanceTestResult = require('performance-results-parser/src/models/PerformanceTestResult');
|
|
4
|
+
const Transaction = require('performance-results-parser/src/models/Transaction');
|
|
5
|
+
const TestCase = require('test-results-parser/src/models/TestCase');
|
|
6
|
+
const TestResult = require('test-results-parser/src/models/TestResult');
|
|
7
|
+
const TestSuite = require('test-results-parser/src/models/TestSuite');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
const { STATUS } = require('../helpers/constants');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @param {object} param0
|
|
15
|
+
* @param {PerformanceTestResult | TestResult} param0.result
|
|
16
|
+
* @param {import('..').Target} param0.target
|
|
17
|
+
*/
|
|
18
|
+
async function run({ result, target }) {
|
|
19
|
+
target.inputs = Object.assign({}, default_inputs, target.inputs);
|
|
20
|
+
const metrics = getMetrics({ result, target });
|
|
21
|
+
await influx.write(
|
|
22
|
+
{
|
|
23
|
+
url: target.inputs.url,
|
|
24
|
+
version: target.inputs.version,
|
|
25
|
+
db: target.inputs.db,
|
|
26
|
+
username: target.inputs.username,
|
|
27
|
+
password: target.inputs.password,
|
|
28
|
+
org: target.inputs.org,
|
|
29
|
+
bucket: target.inputs.bucket,
|
|
30
|
+
token: target.inputs.token,
|
|
31
|
+
},
|
|
32
|
+
metrics
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
*
|
|
38
|
+
* @param {object} param0
|
|
39
|
+
* @param {PerformanceTestResult | TestResult} param0.result
|
|
40
|
+
* @param {import('..').Target} param0.target
|
|
41
|
+
*/
|
|
42
|
+
function getMetrics({ result, target }) {
|
|
43
|
+
const influx_metrics = [];
|
|
44
|
+
if (result instanceof PerformanceTestResult) {
|
|
45
|
+
influx_metrics.push(getPerfRunInfluxMetric({ result, target }));
|
|
46
|
+
|
|
47
|
+
for (const transaction of result.transactions) {
|
|
48
|
+
influx_metrics.push(getTransactionInfluxMetric(transaction, target));
|
|
49
|
+
}
|
|
50
|
+
} else if (result instanceof TestResult) {
|
|
51
|
+
influx_metrics.push(getTestInfluxMetric({ result, target }, target.inputs.measurement_test_run));
|
|
52
|
+
for (const suite of result.suites) {
|
|
53
|
+
influx_metrics.push(getTestInfluxMetric({ result: suite, target }, target.inputs.measurement_test_suite));
|
|
54
|
+
for (const test_case of suite.cases) {
|
|
55
|
+
influx_metrics.push(getTestCaseInfluxMetric({ result: test_case, target }));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return influx_metrics;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @param {object} param0
|
|
64
|
+
* @param {PerformanceTestResult} param0.result
|
|
65
|
+
* @param {import('..').Target} param0.target
|
|
66
|
+
* @returns
|
|
67
|
+
*/
|
|
68
|
+
function getPerfRunInfluxMetric({ result, target }) {
|
|
69
|
+
const tags = Object.assign({}, target.inputs.tags);
|
|
70
|
+
tags.Name = result.name;
|
|
71
|
+
tags.Status = result.status;
|
|
72
|
+
|
|
73
|
+
const fields = Object.assign({}, target.inputs.fields);
|
|
74
|
+
fields.status = result.status === 'PASS' ? 0 : 1;
|
|
75
|
+
fields.transactions = result.transactions.length;
|
|
76
|
+
fields.transactions_passed = result.transactions.filter(_transaction => _transaction.status === "PASS").length;
|
|
77
|
+
fields.transactions_failed = result.transactions.filter(_transaction => _transaction.status === "FAIL").length;
|
|
78
|
+
|
|
79
|
+
for (const metric of result.metrics) {
|
|
80
|
+
setPerfInfluxMetricFields(metric, fields);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
measurement: target.inputs.measurement_perf_run,
|
|
85
|
+
tags,
|
|
86
|
+
fields
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
*
|
|
92
|
+
* @param {Metric} metric
|
|
93
|
+
*/
|
|
94
|
+
function setPerfInfluxMetricFields(metric, fields) {
|
|
95
|
+
let name = metric.name;
|
|
96
|
+
name = name.toLowerCase();
|
|
97
|
+
name = name.replace(' ', '_');
|
|
98
|
+
if (metric.type === "COUNTER" || metric.type === "RATE") {
|
|
99
|
+
fields[`${name}_sum`] = metric.sum;
|
|
100
|
+
fields[`${name}_rate`] = metric.rate;
|
|
101
|
+
} else if (metric.type === "TREND") {
|
|
102
|
+
fields[`${name}_avg`] = metric.avg;
|
|
103
|
+
fields[`${name}_med`] = metric.med;
|
|
104
|
+
fields[`${name}_max`] = metric.max;
|
|
105
|
+
fields[`${name}_min`] = metric.min;
|
|
106
|
+
fields[`${name}_p90`] = metric.p90;
|
|
107
|
+
fields[`${name}_p95`] = metric.p95;
|
|
108
|
+
fields[`${name}_p99`] = metric.p99;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
*
|
|
114
|
+
* @param {Transaction} transaction
|
|
115
|
+
*/
|
|
116
|
+
function getTransactionInfluxMetric(transaction, target) {
|
|
117
|
+
const tags = Object.assign({}, target.inputs.tags);
|
|
118
|
+
tags.Name = transaction.name;
|
|
119
|
+
tags.Status = transaction.status;
|
|
120
|
+
|
|
121
|
+
const fields = Object.assign({}, target.inputs.fields);
|
|
122
|
+
fields.status = transaction.status === 'PASS' ? 0 : 1;
|
|
123
|
+
|
|
124
|
+
for (const metric of transaction.metrics) {
|
|
125
|
+
setPerfInfluxMetricFields(metric, fields);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
measurement: target.inputs.measurement_perf_transaction,
|
|
130
|
+
tags,
|
|
131
|
+
fields
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @param {object} param0
|
|
137
|
+
* @param {TestResult | TestSuite} param0.result
|
|
138
|
+
* @param {import('..').Target} param0.target
|
|
139
|
+
* @returns
|
|
140
|
+
*/
|
|
141
|
+
function getTestInfluxMetric({ result, target }, measurement) {
|
|
142
|
+
const tags = Object.assign({}, target.inputs.tags);
|
|
143
|
+
tags.Name = result.name;
|
|
144
|
+
tags.Status = result.status;
|
|
145
|
+
|
|
146
|
+
const fields = Object.assign({}, target.inputs.fields);
|
|
147
|
+
fields.status = result.status === 'PASS' ? 0 : 1;
|
|
148
|
+
fields.total = result.total;
|
|
149
|
+
fields.passed = result.passed;
|
|
150
|
+
fields.failed = result.failed;
|
|
151
|
+
fields.duration = result.duration;
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
measurement,
|
|
155
|
+
tags,
|
|
156
|
+
fields
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* @param {object} param0
|
|
162
|
+
* @param {TestCase} param0.result
|
|
163
|
+
* @param {import('..').Target} param0.target
|
|
164
|
+
* @returns
|
|
165
|
+
*/
|
|
166
|
+
function getTestCaseInfluxMetric({ result, target }) {
|
|
167
|
+
const tags = Object.assign({}, target.inputs.tags);
|
|
168
|
+
tags.Name = result.name;
|
|
169
|
+
tags.Status = result.status;
|
|
170
|
+
|
|
171
|
+
const fields = Object.assign({}, target.inputs.fields);
|
|
172
|
+
fields.status = result.status === 'PASS' ? 0 : 1;
|
|
173
|
+
fields.duration = result.duration;
|
|
174
|
+
|
|
175
|
+
return {
|
|
176
|
+
measurement: target.inputs.measurement_test_case,
|
|
177
|
+
tags,
|
|
178
|
+
fields
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
const default_inputs = {
|
|
184
|
+
url: '',
|
|
185
|
+
version: 'v1',
|
|
186
|
+
db: '',
|
|
187
|
+
username: '',
|
|
188
|
+
password: '',
|
|
189
|
+
org: '',
|
|
190
|
+
bucket: '',
|
|
191
|
+
token: '',
|
|
192
|
+
measurement_perf_run: 'PerfRun',
|
|
193
|
+
measurement_perf_transaction: 'PerfTransaction',
|
|
194
|
+
measurement_test_run: 'TestRun',
|
|
195
|
+
measurement_test_suite: 'TestSuite',
|
|
196
|
+
measurement_test_case: 'TestCase',
|
|
197
|
+
tags: {},
|
|
198
|
+
fields: {}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const default_options = {
|
|
202
|
+
condition: STATUS.PASS_OR_FAIL
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
module.exports = {
|
|
206
|
+
run,
|
|
207
|
+
default_options
|
|
208
|
+
}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
const request = require('phin-retry');
|
|
2
|
+
const { getPercentage, truncate, getPrettyDuration } = require('../helpers/helper');
|
|
3
|
+
const extension_manager = require('../extensions');
|
|
4
|
+
const { HOOK, STATUS } = require('../helpers/constants');
|
|
5
|
+
|
|
6
|
+
const PerformanceTestResult = require('performance-results-parser/src/models/PerformanceTestResult');
|
|
7
|
+
const { getValidMetrics, getMetricValuesText } = require('../helpers/performance');
|
|
8
|
+
const TestResult = require('test-results-parser/src/models/TestResult');
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const COLORS = {
|
|
12
|
+
GOOD: '#36A64F',
|
|
13
|
+
WARNING: '#ECB22E',
|
|
14
|
+
DANGER: '#DC143C'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function run({ result, target }) {
|
|
18
|
+
setTargetInputs(target);
|
|
19
|
+
const payload = getMainPayload();
|
|
20
|
+
if (result instanceof PerformanceTestResult) {
|
|
21
|
+
await setPerformancePayload({ result, target, payload });
|
|
22
|
+
} else {
|
|
23
|
+
await setFunctionalPayload({ result, target, payload });
|
|
24
|
+
}
|
|
25
|
+
const message = getRootPayload({ result, payload });
|
|
26
|
+
return request.post({
|
|
27
|
+
url: target.inputs.url,
|
|
28
|
+
body: message
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function setFunctionalPayload({ result, target, payload }) {
|
|
33
|
+
await extension_manager.run({ result, target, payload, hook: HOOK.START });
|
|
34
|
+
setMainBlock({ result, target, payload });
|
|
35
|
+
await extension_manager.run({ result, target, payload, hook: HOOK.AFTER_SUMMARY });
|
|
36
|
+
setSuiteBlock({ result, target, payload });
|
|
37
|
+
await extension_manager.run({ result, target, payload, hook: HOOK.END });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function setTargetInputs(target) {
|
|
41
|
+
target.inputs = Object.assign({}, default_inputs, target.inputs);
|
|
42
|
+
if (target.inputs.publish === 'test-summary-slim') {
|
|
43
|
+
target.inputs.include_suites = false;
|
|
44
|
+
}
|
|
45
|
+
if (target.inputs.publish === 'failure-details') {
|
|
46
|
+
target.inputs.include_failure_details = true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function getMainPayload() {
|
|
51
|
+
return {
|
|
52
|
+
"blocks": []
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function setMainBlock({ result, target, payload }) {
|
|
57
|
+
let text = `*${getTitleText(result, target)}*\n`;
|
|
58
|
+
text += `\n*Results*: ${getResultText(result)}`;
|
|
59
|
+
text += `\n*Duration*: ${getPrettyDuration(result.duration, target.inputs.duration)}`;
|
|
60
|
+
payload.blocks.push({
|
|
61
|
+
"type": "section",
|
|
62
|
+
"text": {
|
|
63
|
+
"type": "mrkdwn",
|
|
64
|
+
"text": text
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function getTitleText(result, target) {
|
|
70
|
+
let text = target.inputs.title ? target.inputs.title : result.name;
|
|
71
|
+
if (target.inputs.title_suffix) {
|
|
72
|
+
text = `${text} ${target.inputs.title_suffix}`;
|
|
73
|
+
}
|
|
74
|
+
if (target.inputs.title_link) {
|
|
75
|
+
text = `<${target.inputs.title_link}|${text}>`;
|
|
76
|
+
}
|
|
77
|
+
return text;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function getResultText(result) {
|
|
81
|
+
const percentage = getPercentage(result.passed, result.total);
|
|
82
|
+
return `${result.passed} / ${result.total} Passed (${percentage}%)`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function setSuiteBlock({ result, target, payload }) {
|
|
86
|
+
let suite_attachments_length = 0;
|
|
87
|
+
if (target.inputs.include_suites) {
|
|
88
|
+
for (let i = 0; i < result.suites.length && suite_attachments_length < target.inputs.max_suites; i++) {
|
|
89
|
+
const suite = result.suites[i];
|
|
90
|
+
if (target.inputs.only_failures && suite.status !== 'FAIL') {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
// if suites length eq to 1 then main block will include suite summary
|
|
94
|
+
if (result.suites.length > 1) {
|
|
95
|
+
payload.blocks.push(getSuiteSummary({ target, suite }));
|
|
96
|
+
suite_attachments_length += 1;
|
|
97
|
+
}
|
|
98
|
+
if (target.inputs.include_failure_details) {
|
|
99
|
+
// Only attach failure details block if there were failures
|
|
100
|
+
if (suite.failed > 0) {
|
|
101
|
+
payload.blocks.push(getFailureDetails(suite));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function getSuiteSummary({ target, suite }) {
|
|
109
|
+
let text = `*${getSuiteTitle(suite)}*\n`;
|
|
110
|
+
text += `\n*Results*: ${getResultText(suite)}`;
|
|
111
|
+
text += `\n*Duration*: ${getPrettyDuration(suite.duration, target.inputs.duration)}`;
|
|
112
|
+
return {
|
|
113
|
+
"type": "section",
|
|
114
|
+
"text": {
|
|
115
|
+
"type": "mrkdwn",
|
|
116
|
+
"text": text
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function getSuiteTitle(suite) {
|
|
122
|
+
const emoji = suite.status === 'PASS' ? '✅' : suite.total === suite.skipped ? '⏭️' : '❌';
|
|
123
|
+
return `${emoji} ${suite.name}`;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function getFailureDetails(suite) {
|
|
127
|
+
let text = '';
|
|
128
|
+
const cases = suite.cases;
|
|
129
|
+
for (let i = 0; i < cases.length; i++) {
|
|
130
|
+
const test_case = cases[i];
|
|
131
|
+
if (test_case.status === 'FAIL') {
|
|
132
|
+
text += `*Test*: ${test_case.name}\n*Error*: ${truncate(test_case.failure, 150)}\n\n`;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
"type": "section",
|
|
137
|
+
"text": {
|
|
138
|
+
"type": "mrkdwn",
|
|
139
|
+
"text": text
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
*
|
|
146
|
+
* @param {object} param0
|
|
147
|
+
* @param {PerformanceTestResult | TestResult} param0.result
|
|
148
|
+
* @returns
|
|
149
|
+
*/
|
|
150
|
+
function getRootPayload({ result, payload }) {
|
|
151
|
+
let color = COLORS.GOOD;
|
|
152
|
+
if (result.status !== 'PASS') {
|
|
153
|
+
let somePassed = true;
|
|
154
|
+
if (result instanceof PerformanceTestResult) {
|
|
155
|
+
somePassed = result.transactions.some(suite => suite.status === 'PASS');
|
|
156
|
+
} else {
|
|
157
|
+
somePassed = result.suites.some(suite => suite.status === 'PASS');
|
|
158
|
+
}
|
|
159
|
+
if (somePassed) {
|
|
160
|
+
color = COLORS.WARNING;
|
|
161
|
+
} else {
|
|
162
|
+
color = COLORS.DANGER;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
"attachments": [
|
|
167
|
+
{
|
|
168
|
+
"color": color,
|
|
169
|
+
"blocks": payload.blocks
|
|
170
|
+
}
|
|
171
|
+
]
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async function setPerformancePayload({ result, target, payload }) {
|
|
176
|
+
await extension_manager.run({ result, target, payload, hook: HOOK.START });
|
|
177
|
+
await setPerformanceMainBlock({ result, target, payload });
|
|
178
|
+
await extension_manager.run({ result, target, payload, hook: HOOK.AFTER_SUMMARY });
|
|
179
|
+
await setTransactionBlock({ result, target, payload });
|
|
180
|
+
await extension_manager.run({ result, target, payload, hook: HOOK.END });
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
*
|
|
185
|
+
* @param {object} param0
|
|
186
|
+
* @param {PerformanceTestResult} param0.result
|
|
187
|
+
*/
|
|
188
|
+
async function setPerformanceMainBlock({ result, target, payload }) {
|
|
189
|
+
let text = `*${getTitleText(result, target)}*\n`;
|
|
190
|
+
result.total = result.transactions.length;
|
|
191
|
+
result.passed = result.transactions.filter(_transaction => _transaction.status === 'PASS').length;
|
|
192
|
+
text += `\n*Results*: ${getResultText(result)}`;
|
|
193
|
+
const valid_metrics = await getValidMetrics({ metrics: result.metrics, target, result });
|
|
194
|
+
for (let i = 0; i < valid_metrics.length; i++) {
|
|
195
|
+
const metric = valid_metrics[i];
|
|
196
|
+
text += `\n*${metric.name}*: ${getMetricValuesText({ metric, target, result })}`;
|
|
197
|
+
}
|
|
198
|
+
payload.blocks.push({
|
|
199
|
+
"type": "section",
|
|
200
|
+
"text": {
|
|
201
|
+
"type": "mrkdwn",
|
|
202
|
+
"text": text
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
*
|
|
209
|
+
* @param {object} param0
|
|
210
|
+
* @param {PerformanceTestResult} param0.result
|
|
211
|
+
*/
|
|
212
|
+
async function setTransactionBlock({ result, target, payload }) {
|
|
213
|
+
if (target.inputs.include_suites) {
|
|
214
|
+
for (let i = 0; i < result.transactions.length; i++) {
|
|
215
|
+
const transaction = result.transactions[i];
|
|
216
|
+
if (target.inputs.only_failures && transaction.status !== 'FAIL') {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
// if transactions length eq to 1 then main block will include transaction summary
|
|
220
|
+
if (result.transactions.length > 1) {
|
|
221
|
+
let text = `*${getTitleText(transaction, target)}*\n`;
|
|
222
|
+
const valid_metrics = await getValidMetrics({ metrics: transaction.metrics, target, result });
|
|
223
|
+
for (let i = 0; i < valid_metrics.length; i++) {
|
|
224
|
+
const metric = valid_metrics[i];
|
|
225
|
+
text += `\n*${metric.name}*: ${getMetricValuesText({ metric, target, result })}`;
|
|
226
|
+
}
|
|
227
|
+
payload.blocks.push({
|
|
228
|
+
"type": "section",
|
|
229
|
+
"text": {
|
|
230
|
+
"type": "mrkdwn",
|
|
231
|
+
"text": text
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
const default_options = {
|
|
241
|
+
condition: STATUS.PASS_OR_FAIL
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const default_inputs = {
|
|
245
|
+
publish: 'test-summary',
|
|
246
|
+
include_suites: true,
|
|
247
|
+
max_suites: 10,
|
|
248
|
+
only_failures: false,
|
|
249
|
+
include_failure_details: false,
|
|
250
|
+
duration: '',
|
|
251
|
+
metrics: [
|
|
252
|
+
{
|
|
253
|
+
"name": "Samples",
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
"name": "Duration",
|
|
257
|
+
"condition": "always",
|
|
258
|
+
"fields": ["avg", "p95"]
|
|
259
|
+
}
|
|
260
|
+
]
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
module.exports = {
|
|
264
|
+
run,
|
|
265
|
+
default_options
|
|
266
|
+
}
|