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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Anudeep
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
> !IMPORTANT - This npm package has been renamed from [test-results-reporter](https://www.npmjs.com/package/test-results-reporter) to [testbeats](https://www.npmjs.com/package/testbeats). test-results-reporter will soon be phased out, and users are encouraged to transition to testbeats.
|
|
2
|
+
|
|
3
|
+
<span align="center">
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
#### Publish test results to Microsoft Teams, Google Chat, Slack and many more.
|
|
9
|
+
|
|
10
|
+
<br />
|
|
11
|
+
|
|
12
|
+

|
|
13
|
+

|
|
14
|
+

|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
[](https://github.com/test-results-reporter/testbeats/stargazers)
|
|
18
|
+

|
|
19
|
+
|
|
20
|
+
<hr>
|
|
21
|
+
|
|
22
|
+
### Targets
|
|
23
|
+
|
|
24
|
+
<img height="48" style="margin: 6px;" src="./assets/slack.png" alt="slack" /> <img height="48" style="margin: 6px;" src="./assets/teams.png" alt="teams" /> <img height="48" style="margin: 6px;" src="./assets/chat.png" alt="chat" />
|
|
25
|
+
|
|
26
|
+
### Extensions
|
|
27
|
+
|
|
28
|
+
<img height="48" style="margin: 6px;" src="./assets/reportportal.jpeg" alt="reportportal" /> <img height="48" style="margin: 6px;" src="./assets/quickchart.png" alt="quickchart" /> <img height="48" style="margin: 6px;" src="./assets/hyperlink.png" alt="hyperlink" /> <img height="48" style="margin: 6px;" src="./assets/mentions.png" alt="mentions" />
|
|
29
|
+
|
|
30
|
+
### Test Results
|
|
31
|
+
|
|
32
|
+
<img height="48" style="margin: 6px;" src="./assets/testng.png" alt="testng" /> <img height="48" style="margin: 6px;" src="./assets/junit.png" alt="junit" /> <img height="48" style="margin: 6px;" src="./assets/cucumber.png" alt="cucumber" /> <img height="48" style="margin: 6px;" src="./assets/mocha.png" alt="mocha" /> <img height="48" style="margin: 6px;" src="./assets/xunit.png" alt="xunit" /> <img height="48" style="margin: 6px;" src="./assets/jmeter.png" alt="jmeter" />
|
|
33
|
+
|
|
34
|
+
<hr>
|
|
35
|
+
|
|
36
|
+
## Sample Reports
|
|
37
|
+
|
|
38
|
+
<br>
|
|
39
|
+
|
|
40
|
+

|
|
41
|
+
|
|
42
|
+

|
|
43
|
+
|
|
44
|
+
<br />
|
|
45
|
+
|
|
46
|
+
<hr >
|
|
47
|
+
|
|
48
|
+
# [Documentation](https://test-results-reporter.github.io/)
|
|
49
|
+
|
|
50
|
+
</span>
|
|
51
|
+
|
|
52
|
+
<br />
|
|
53
|
+
|
|
54
|
+
## Need Help
|
|
55
|
+
|
|
56
|
+
We use [Github Discussions](https://github.com/test-results-reporter/testbeats/discussions) to receive feedback, discuss ideas & answer questions. Head over to it and feel free to start a discussion. We are always happy to help 😊.
|
|
57
|
+
|
|
58
|
+
## Support Us
|
|
59
|
+
|
|
60
|
+
Like this project! Star it on [Github](https://github.com/test-results-reporter/testbeats) ⭐. Your support means a lot to us.
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "testbeats",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Publish test results to Microsoft Teams, Google Chat, Slack and InfluxDB",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"types": "./src/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"testbeats": "src/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"/src"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"test": "c8 mocha test",
|
|
15
|
+
"build": "pkg --out-path dist ."
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/test-results-reporter/testbeats.git"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"test",
|
|
23
|
+
"results",
|
|
24
|
+
"publish",
|
|
25
|
+
"report",
|
|
26
|
+
"microsoft teams",
|
|
27
|
+
"teams",
|
|
28
|
+
"slack",
|
|
29
|
+
"influx",
|
|
30
|
+
"influxdb",
|
|
31
|
+
"junit",
|
|
32
|
+
"mocha",
|
|
33
|
+
"cucumber",
|
|
34
|
+
"testng",
|
|
35
|
+
"xunit",
|
|
36
|
+
"reportportal",
|
|
37
|
+
"google chat",
|
|
38
|
+
"chat",
|
|
39
|
+
"percy",
|
|
40
|
+
"jmeter"
|
|
41
|
+
],
|
|
42
|
+
"author": "",
|
|
43
|
+
"license": "ISC",
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/test-results-reporter/testbeats/issues"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://test-results-reporter.github.io",
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"async-retry": "^1.3.3",
|
|
50
|
+
"dotenv": "^14.3.2",
|
|
51
|
+
"influxdb-lite": "^1.0.0",
|
|
52
|
+
"performance-results-parser": "latest",
|
|
53
|
+
"phin-retry": "^1.0.3",
|
|
54
|
+
"pretty-ms": "^7.0.1",
|
|
55
|
+
"rosters": "0.0.1",
|
|
56
|
+
"sade": "^1.8.1",
|
|
57
|
+
"test-results-parser": "latest"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"c8": "^7.12.0",
|
|
61
|
+
"mocha": "^10.1.0",
|
|
62
|
+
"pactum": "^3.2.3",
|
|
63
|
+
"pkg": "^5.8.0"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const request = require('phin-retry');
|
|
2
|
+
const TestResult = require('test-results-parser/src/models/TestResult');
|
|
3
|
+
const { getCIInformation } = require('../helpers/ci');
|
|
4
|
+
|
|
5
|
+
function get_base_url() {
|
|
6
|
+
return process.env.TEST_BEATS_URL || "https://app.testbeats.com";
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {import('../index').PublishReport} config
|
|
11
|
+
* @param {TestResult} result
|
|
12
|
+
*/
|
|
13
|
+
async function run(config, result) {
|
|
14
|
+
if (config.project && config.run && config.api_key) {
|
|
15
|
+
const run_id = await publishTestResults(config, result);
|
|
16
|
+
if (run_id) {
|
|
17
|
+
attachTestBeatsReportHyperLink(config, run_id);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param {import('../index').PublishReport} config
|
|
24
|
+
* @param {TestResult} result
|
|
25
|
+
*/
|
|
26
|
+
async function publishTestResults(config, result) {
|
|
27
|
+
try {
|
|
28
|
+
const payload = {
|
|
29
|
+
project: config.project,
|
|
30
|
+
run: config.run,
|
|
31
|
+
...result
|
|
32
|
+
}
|
|
33
|
+
const ci = getCIInformation();
|
|
34
|
+
if (ci) {
|
|
35
|
+
payload.ci_details = [ci];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const response = await request.post({
|
|
39
|
+
url: `${get_base_url()}/api/core/v1/test-runs`,
|
|
40
|
+
headers: {
|
|
41
|
+
'x-api-key': config.api_key
|
|
42
|
+
},
|
|
43
|
+
body: payload
|
|
44
|
+
});
|
|
45
|
+
return response.id;
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.log("Unable to publish results to TestBeats");
|
|
48
|
+
console.log(error);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @param {import('../index').PublishReport} config
|
|
54
|
+
* @param {string} run_id
|
|
55
|
+
*/
|
|
56
|
+
function attachTestBeatsReportHyperLink(config, run_id) {
|
|
57
|
+
const beats_link = get_test_beats_report_link(run_id);
|
|
58
|
+
if (config.targets) {
|
|
59
|
+
for (const target of config.targets) {
|
|
60
|
+
target.inputs.title_link = beats_link;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
*
|
|
67
|
+
* @param {string} run_id
|
|
68
|
+
* @returns
|
|
69
|
+
*/
|
|
70
|
+
function get_test_beats_report_link(run_id) {
|
|
71
|
+
return `${get_base_url()}/reports/${run_id}`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
module.exports = { run }
|
package/src/cli.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
require('dotenv').config();
|
|
3
|
+
|
|
4
|
+
const sade = require('sade');
|
|
5
|
+
|
|
6
|
+
const prog = sade('test-results-reporter');
|
|
7
|
+
const publish = require('./commands/publish');
|
|
8
|
+
|
|
9
|
+
prog
|
|
10
|
+
.version('0.0.7')
|
|
11
|
+
.option('-c, --config', 'Provide path to custom config', 'config.json');
|
|
12
|
+
|
|
13
|
+
prog.command('publish')
|
|
14
|
+
.action(async (opts) => {
|
|
15
|
+
try {
|
|
16
|
+
await publish.run(opts);
|
|
17
|
+
} catch (error) {
|
|
18
|
+
console.error(error);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
prog.parse(process.argv);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const trp = require('test-results-parser');
|
|
3
|
+
const prp = require('performance-results-parser');
|
|
4
|
+
|
|
5
|
+
const { processData } = require('../helpers/helper');
|
|
6
|
+
const beats = require('../beats');
|
|
7
|
+
const target_manager = require('../targets');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {import('../index').PublishOptions} opts
|
|
11
|
+
*/
|
|
12
|
+
async function run(opts) {
|
|
13
|
+
if (typeof opts.config === 'string') {
|
|
14
|
+
const cwd = process.cwd();
|
|
15
|
+
opts.config = require(path.join(cwd, opts.config));
|
|
16
|
+
}
|
|
17
|
+
const config = processData(opts.config);
|
|
18
|
+
if (config.reports) {
|
|
19
|
+
for (const report of config.reports) {
|
|
20
|
+
await processReport(report);
|
|
21
|
+
}
|
|
22
|
+
} else {
|
|
23
|
+
await processReport(config);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
*
|
|
29
|
+
* @param {import('../index').PublishReport} report
|
|
30
|
+
*/
|
|
31
|
+
async function processReport(report) {
|
|
32
|
+
const parsed_results = [];
|
|
33
|
+
for (const result_options of report.results) {
|
|
34
|
+
if (result_options.type === 'custom') {
|
|
35
|
+
parsed_results.push(result_options.result);
|
|
36
|
+
} else if (result_options.type === 'jmeter') {
|
|
37
|
+
parsed_results.push(prp.parse(result_options));
|
|
38
|
+
} else {
|
|
39
|
+
parsed_results.push(trp.parse(result_options));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
for (let i = 0; i < parsed_results.length; i++) {
|
|
44
|
+
const result = parsed_results[i];
|
|
45
|
+
await beats.run(report, result);
|
|
46
|
+
for (const target of report.targets) {
|
|
47
|
+
await target_manager.run(target, result);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = {
|
|
53
|
+
run
|
|
54
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
const { STATUS, HOOK } = require("../helpers/constants");
|
|
2
|
+
const { getCIInformation } = require('../helpers/ci');
|
|
3
|
+
const { addTeamsExtension, addSlackExtension, addChatExtension } = require('../helpers/extension.helper');
|
|
4
|
+
const { getTeamsMetaDataText, getSlackMetaDataText, getChatMetaDataText } = require('../helpers/metadata.helper');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @param {object} param0 - the payload object
|
|
9
|
+
* @param {import('..').Extension} param0.extension - The result object
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
async function run({ target, extension, payload, result }) {
|
|
13
|
+
extension.inputs = Object.assign({}, default_inputs, extension.inputs);
|
|
14
|
+
if (target.name === 'teams') {
|
|
15
|
+
extension.inputs = Object.assign({}, default_inputs_teams, extension.inputs);
|
|
16
|
+
const text = await get_text({ target, extension, result });
|
|
17
|
+
if (text) {
|
|
18
|
+
addTeamsExtension({ payload, extension, text });
|
|
19
|
+
}
|
|
20
|
+
} else if (target.name === 'slack') {
|
|
21
|
+
extension.inputs = Object.assign({}, default_inputs_slack, extension.inputs);
|
|
22
|
+
const text = await get_text({ target, extension, result });
|
|
23
|
+
if (text) {
|
|
24
|
+
addSlackExtension({ payload, extension, text });
|
|
25
|
+
}
|
|
26
|
+
} else if (target.name === 'chat') {
|
|
27
|
+
extension.inputs = Object.assign({}, default_inputs_chat, extension.inputs);
|
|
28
|
+
const text = await get_text({ target, extension, result });
|
|
29
|
+
if (text) {
|
|
30
|
+
addChatExtension({ payload, extension, text });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
*
|
|
37
|
+
* @param {import('..').CIInfoInputs} inputs
|
|
38
|
+
*/
|
|
39
|
+
function get_repository_elements(inputs) {
|
|
40
|
+
const elements = [];
|
|
41
|
+
const ci = getCIInformation();
|
|
42
|
+
if (inputs.show_repository && ci && ci.repository_url && ci.repository_name) {
|
|
43
|
+
elements.push({ label: 'Repository', key: ci.repository_name, value: ci.repository_url, type: 'hyperlink' });
|
|
44
|
+
}
|
|
45
|
+
if (inputs.show_repository_branch && ci && ci.repository_ref) {
|
|
46
|
+
if (ci.repository_ref.includes('refs/pull')) {
|
|
47
|
+
const pr_url = ci.repository_url + ci.repository_ref.replace('refs/pull/', '/pull/');
|
|
48
|
+
const pr_name = ci.repository_ref.replace('refs/pull/', '').replace('/merge', '');
|
|
49
|
+
elements.push({ label: 'Pull Request', key: pr_name, value: pr_url, type: 'hyperlink' });
|
|
50
|
+
} else {
|
|
51
|
+
const branch_url = ci.repository_url + ci.repository_ref.replace('refs/heads/', '/tree/');
|
|
52
|
+
const branch_name = ci.repository_ref.replace('refs/heads/', '');
|
|
53
|
+
elements.push({ label: 'Branch', key: branch_name, value: branch_url, type: 'hyperlink' });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return elements;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
*
|
|
61
|
+
* @param {import('..').CIInfoInputs} inputs
|
|
62
|
+
*/
|
|
63
|
+
function get_build_elements(inputs) {
|
|
64
|
+
let elements = [];
|
|
65
|
+
const ci = getCIInformation();
|
|
66
|
+
if (inputs.show_build && ci && ci.build_url) {
|
|
67
|
+
const name = (ci.build_name || 'Build') + (ci.build_number ? ` #${ci.build_number}` : '');
|
|
68
|
+
elements.push({ label: 'Build', key: name, value: ci.build_url, type: 'hyperlink' });
|
|
69
|
+
}
|
|
70
|
+
if (inputs.data) {
|
|
71
|
+
elements = elements.concat(inputs.data);
|
|
72
|
+
}
|
|
73
|
+
return elements;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function get_text({ target, extension, result }) {
|
|
77
|
+
const repository_elements = get_repository_elements(extension.inputs);
|
|
78
|
+
const build_elements = get_build_elements(extension.inputs);
|
|
79
|
+
if (target.name === 'teams') {
|
|
80
|
+
const repository_text = await getTeamsMetaDataText({ elements: repository_elements, target, extension, result, default_condition: default_options.condition });
|
|
81
|
+
const build_text = await getTeamsMetaDataText({ elements: build_elements, target, extension, result, default_condition: default_options.condition });
|
|
82
|
+
if (build_text) {
|
|
83
|
+
return `${repository_text ? `${repository_text}\n\n` : '' }${build_text}`;
|
|
84
|
+
} else {
|
|
85
|
+
return repository_text;
|
|
86
|
+
}
|
|
87
|
+
} else if (target.name === 'slack') {
|
|
88
|
+
const repository_text = await getSlackMetaDataText({ elements: repository_elements, target, extension, result, default_condition: default_options.condition });
|
|
89
|
+
const build_text = await getSlackMetaDataText({ elements: build_elements, target, extension, result, default_condition: default_options.condition });
|
|
90
|
+
if (build_text) {
|
|
91
|
+
return `${repository_text ? `${repository_text}\n` : '' }${build_text}`;
|
|
92
|
+
} else {
|
|
93
|
+
return repository_text;
|
|
94
|
+
}
|
|
95
|
+
} else if (target.name === 'chat') {
|
|
96
|
+
const repository_text = await getChatMetaDataText({ elements: repository_elements, target, extension, result, default_condition: default_options.condition });
|
|
97
|
+
const build_text = await getChatMetaDataText({ elements: build_elements, target, extension, result, default_condition: default_options.condition });
|
|
98
|
+
if (build_text) {
|
|
99
|
+
return `${repository_text ? `${repository_text}<br>` : '' }${build_text}`;
|
|
100
|
+
} else {
|
|
101
|
+
return repository_text;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const default_options = {
|
|
107
|
+
hook: HOOK.AFTER_SUMMARY,
|
|
108
|
+
condition: STATUS.PASS_OR_FAIL,
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const default_inputs = {
|
|
112
|
+
title: '',
|
|
113
|
+
show_repository: true,
|
|
114
|
+
show_repository_branch: true,
|
|
115
|
+
show_build: true,
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const default_inputs_teams = {
|
|
119
|
+
|
|
120
|
+
separator: true
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const default_inputs_slack = {
|
|
124
|
+
separator: false
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const default_inputs_chat = {
|
|
128
|
+
separator: true
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
module.exports = {
|
|
132
|
+
run,
|
|
133
|
+
default_options
|
|
134
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { HOOK, STATUS } = require('../helpers/constants');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {object} param0
|
|
7
|
+
* @param {import('../index').CustomExtension} param0.extension
|
|
8
|
+
*/
|
|
9
|
+
async function run({ target, extension, payload, root_payload, result }) {
|
|
10
|
+
if (typeof extension.inputs.load === 'string') {
|
|
11
|
+
const cwd = process.cwd();
|
|
12
|
+
const extension_runner = require(path.join(cwd, extension.inputs.load));
|
|
13
|
+
await extension_runner.run({ target, extension, payload, root_payload, result });
|
|
14
|
+
} else if (typeof extension.inputs.load === 'function') {
|
|
15
|
+
await extension.inputs.load({ target, extension, payload, root_payload, result });
|
|
16
|
+
} else {
|
|
17
|
+
throw `Invalid 'load' input in custom extension - ${extension.inputs.load}`;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const default_options = {
|
|
22
|
+
hook: HOOK.END,
|
|
23
|
+
condition: STATUS.PASS_OR_FAIL
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = {
|
|
27
|
+
run,
|
|
28
|
+
default_options
|
|
29
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const { STATUS, HOOK } = require("../helpers/constants");
|
|
2
|
+
const { addChatExtension, addSlackExtension, addTeamsExtension } = require('../helpers/extension.helper');
|
|
3
|
+
const { getTeamsMetaDataText, getSlackMetaDataText, getChatMetaDataText } = require("../helpers/metadata.helper");
|
|
4
|
+
|
|
5
|
+
async function run({ target, extension, payload, result }) {
|
|
6
|
+
const elements = get_elements(extension.inputs.links);
|
|
7
|
+
if (target.name === 'teams') {
|
|
8
|
+
extension.inputs = Object.assign({}, default_inputs_teams, extension.inputs);
|
|
9
|
+
const text = await getTeamsMetaDataText({ elements, target, extension, result, default_condition: default_options.condition });
|
|
10
|
+
if (text) {
|
|
11
|
+
addTeamsExtension({ payload, extension, text });
|
|
12
|
+
}
|
|
13
|
+
} else if (target.name === 'slack') {
|
|
14
|
+
extension.inputs = Object.assign({}, default_inputs_slack, extension.inputs);
|
|
15
|
+
extension.inputs.block_type = 'context';
|
|
16
|
+
const text = await getSlackMetaDataText({ elements, target, extension, result, default_condition: default_options.condition });
|
|
17
|
+
if (text) {
|
|
18
|
+
addSlackExtension({ payload, extension, text });
|
|
19
|
+
}
|
|
20
|
+
} else if (target.name === 'chat') {
|
|
21
|
+
extension.inputs = Object.assign({}, default_inputs_chat, extension.inputs);
|
|
22
|
+
const text = await getChatMetaDataText({ elements, target, extension, result, default_condition: default_options.condition });
|
|
23
|
+
if (text) {
|
|
24
|
+
addChatExtension({ payload, extension, text });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @param {import("..").Link[]} links
|
|
32
|
+
*/
|
|
33
|
+
function get_elements(links) {
|
|
34
|
+
return links.map(_ => { return { key: _.text, value: _.url, type: 'hyperlink', condition: _.condition } });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const default_options = {
|
|
38
|
+
hook: HOOK.END,
|
|
39
|
+
condition: STATUS.PASS_OR_FAIL,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const default_inputs_teams = {
|
|
43
|
+
title: '',
|
|
44
|
+
separator: true
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const default_inputs_slack = {
|
|
48
|
+
title: '',
|
|
49
|
+
separator: false
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const default_inputs_chat = {
|
|
53
|
+
title: '',
|
|
54
|
+
separator: true
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = {
|
|
58
|
+
run,
|
|
59
|
+
default_options
|
|
60
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const hyperlinks = require('./hyperlinks');
|
|
2
|
+
const mentions = require('./mentions');
|
|
3
|
+
const rp_analysis = require('./report-portal-analysis');
|
|
4
|
+
const rp_history = require('./report-portal-history');
|
|
5
|
+
const qc_test_summary = require('./quick-chart-test-summary');
|
|
6
|
+
const percy_analysis = require('./percy-analysis');
|
|
7
|
+
const custom = require('./custom');
|
|
8
|
+
const metadata = require('./metadata');
|
|
9
|
+
const ci_info = require('./ci-info');
|
|
10
|
+
const { EXTENSION } = require('../helpers/constants');
|
|
11
|
+
const { checkCondition } = require('../helpers/helper');
|
|
12
|
+
|
|
13
|
+
async function run(options) {
|
|
14
|
+
const { target, result, hook } = options;
|
|
15
|
+
const extensions = target.extensions || [];
|
|
16
|
+
for (let i = 0; i < extensions.length; i++) {
|
|
17
|
+
const extension = extensions[i];
|
|
18
|
+
const extension_runner = getExtensionRunner(extension);
|
|
19
|
+
const extension_options = Object.assign({}, extension_runner.default_options, extension);
|
|
20
|
+
if (extension_options.hook === hook) {
|
|
21
|
+
if (await checkCondition({ condition: extension_options.condition, result, target, extension })) {
|
|
22
|
+
extension.outputs = {};
|
|
23
|
+
options.extension = extension;
|
|
24
|
+
try {
|
|
25
|
+
await extension_runner.run(options);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
console.log('Failed to run extension');
|
|
28
|
+
console.log(extension);
|
|
29
|
+
console.log(error);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function getExtensionRunner(extension) {
|
|
37
|
+
switch (extension.name) {
|
|
38
|
+
case EXTENSION.HYPERLINKS:
|
|
39
|
+
return hyperlinks;
|
|
40
|
+
case EXTENSION.MENTIONS:
|
|
41
|
+
return mentions;
|
|
42
|
+
case EXTENSION.REPORT_PORTAL_ANALYSIS:
|
|
43
|
+
return rp_analysis;
|
|
44
|
+
case EXTENSION.REPORT_PORTAL_HISTORY:
|
|
45
|
+
return rp_history;
|
|
46
|
+
case EXTENSION.QUICK_CHART_TEST_SUMMARY:
|
|
47
|
+
return qc_test_summary;
|
|
48
|
+
case EXTENSION.PERCY_ANALYSIS:
|
|
49
|
+
return percy_analysis;
|
|
50
|
+
case EXTENSION.CUSTOM:
|
|
51
|
+
return custom;
|
|
52
|
+
case EXTENSION.METADATA:
|
|
53
|
+
return metadata;
|
|
54
|
+
case EXTENSION.CI_INFO:
|
|
55
|
+
return ci_info;
|
|
56
|
+
default:
|
|
57
|
+
return require(extension.name);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = {
|
|
62
|
+
run
|
|
63
|
+
}
|