@testomatio/reporter 2.0.1-beta.5-timestamp → 2.0.1
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/README.md +1 -0
- package/lib/adapter/codecept.d.ts +2 -0
- package/lib/adapter/codecept.js +293 -335
- package/lib/adapter/cucumber/current.d.ts +14 -0
- package/lib/adapter/cucumber/current.js +195 -203
- package/lib/adapter/cucumber/legacy.d.ts +0 -0
- package/lib/adapter/cucumber/legacy.js +130 -155
- package/lib/adapter/cucumber.d.ts +2 -0
- package/lib/adapter/cucumber.js +5 -16
- package/lib/adapter/cypress-plugin/index.d.ts +2 -0
- package/lib/adapter/cypress-plugin/index.js +91 -105
- package/lib/adapter/jasmine.d.ts +11 -0
- package/lib/adapter/jasmine.js +54 -53
- package/lib/adapter/jest.d.ts +13 -0
- package/lib/adapter/jest.js +97 -99
- package/lib/adapter/mocha.d.ts +2 -0
- package/lib/adapter/mocha.js +112 -141
- package/lib/adapter/nightwatch.d.ts +4 -0
- package/lib/adapter/nightwatch.js +80 -0
- package/lib/adapter/playwright.d.ts +14 -0
- package/lib/adapter/playwright.js +199 -231
- package/lib/adapter/vitest.d.ts +35 -0
- package/lib/adapter/vitest.js +150 -149
- package/lib/adapter/webdriver.d.ts +24 -0
- package/lib/adapter/webdriver.js +144 -121
- package/lib/bin/cli.d.ts +2 -0
- package/lib/bin/cli.js +229 -211
- package/lib/bin/reportXml.d.ts +2 -0
- package/lib/bin/reportXml.js +51 -52
- package/lib/bin/startTest.d.ts +2 -0
- package/lib/bin/startTest.js +83 -95
- package/lib/bin/uploadArtifacts.d.ts +2 -0
- package/lib/bin/uploadArtifacts.js +56 -61
- package/lib/client.d.ts +76 -0
- package/lib/client.js +429 -465
- package/lib/config.d.ts +1 -0
- package/lib/config.js +18 -23
- package/lib/constants.d.ts +25 -0
- package/lib/constants.js +50 -44
- package/lib/data-storage.d.ts +34 -0
- package/lib/data-storage.js +216 -188
- package/lib/junit-adapter/adapter.d.ts +9 -0
- package/lib/junit-adapter/adapter.js +17 -20
- package/lib/junit-adapter/csharp.d.ts +5 -0
- package/lib/junit-adapter/csharp.js +28 -14
- package/lib/junit-adapter/index.d.ts +3 -0
- package/lib/junit-adapter/index.js +27 -25
- package/lib/junit-adapter/java.d.ts +5 -0
- package/lib/junit-adapter/java.js +41 -53
- package/lib/junit-adapter/javascript.d.ts +4 -0
- package/lib/junit-adapter/javascript.js +30 -27
- package/lib/junit-adapter/python.d.ts +5 -0
- package/lib/junit-adapter/python.js +38 -37
- package/lib/junit-adapter/ruby.d.ts +4 -0
- package/lib/junit-adapter/ruby.js +11 -8
- package/lib/output.d.ts +11 -0
- package/lib/output.js +44 -52
- package/lib/package.json +3 -0
- package/lib/pipe/bitbucket.d.ts +25 -0
- package/lib/pipe/bitbucket.js +223 -230
- package/lib/pipe/csv.d.ts +47 -0
- package/lib/pipe/csv.js +113 -126
- package/lib/pipe/debug.d.ts +29 -0
- package/lib/pipe/debug.js +125 -99
- package/lib/pipe/github.d.ts +30 -0
- package/lib/pipe/github.js +218 -213
- package/lib/pipe/gitlab.d.ts +25 -0
- package/lib/pipe/gitlab.js +183 -206
- package/lib/pipe/html.d.ts +35 -0
- package/lib/pipe/html.js +258 -321
- package/lib/pipe/index.d.ts +1 -0
- package/lib/pipe/index.js +94 -66
- package/lib/pipe/testomatio.d.ts +71 -0
- package/lib/pipe/testomatio.js +429 -474
- package/lib/replay.d.ts +31 -0
- package/lib/replay.js +255 -0
- package/lib/reporter-functions.d.ts +34 -0
- package/lib/reporter-functions.js +28 -26
- package/lib/reporter.d.ts +232 -0
- package/lib/reporter.js +34 -29
- package/lib/services/artifacts.d.ts +33 -0
- package/lib/services/artifacts.js +55 -51
- package/lib/services/index.d.ts +9 -0
- package/lib/services/index.js +14 -12
- package/lib/services/key-values.d.ts +27 -0
- package/lib/services/key-values.js +56 -53
- package/lib/services/logger.d.ts +64 -0
- package/lib/services/logger.js +226 -245
- package/lib/template/testomatio.hbs +1026 -1366
- package/lib/uploader.d.ts +60 -0
- package/lib/uploader.js +295 -364
- package/lib/utils/pipe_utils.d.ts +41 -0
- package/lib/utils/pipe_utils.js +89 -85
- package/lib/utils/utils.d.ts +54 -0
- package/lib/utils/utils.js +398 -307
- package/lib/xmlReader.d.ts +92 -0
- package/lib/xmlReader.js +525 -532
- package/package.json +64 -21
- package/src/adapter/codecept.js +373 -0
- package/src/adapter/cucumber/current.js +228 -0
- package/src/adapter/cucumber/legacy.js +158 -0
- package/src/adapter/cucumber.js +4 -0
- package/src/adapter/cypress-plugin/index.js +110 -0
- package/src/adapter/jasmine.js +60 -0
- package/src/adapter/jest.js +107 -0
- package/src/adapter/mocha.cjs +2 -0
- package/src/adapter/mocha.js +156 -0
- package/src/adapter/nightwatch.js +88 -0
- package/src/adapter/playwright.js +254 -0
- package/src/adapter/vitest.js +183 -0
- package/src/adapter/webdriver.js +142 -0
- package/src/bin/cli.js +348 -0
- package/src/bin/reportXml.js +77 -0
- package/src/bin/startTest.js +124 -0
- package/src/bin/uploadArtifacts.js +91 -0
- package/src/client.js +515 -0
- package/src/config.js +30 -0
- package/src/constants.js +53 -0
- package/src/data-storage.js +204 -0
- package/src/junit-adapter/adapter.js +23 -0
- package/src/junit-adapter/csharp.js +28 -0
- package/src/junit-adapter/index.js +28 -0
- package/src/junit-adapter/java.js +58 -0
- package/src/junit-adapter/javascript.js +31 -0
- package/src/junit-adapter/python.js +42 -0
- package/src/junit-adapter/ruby.js +10 -0
- package/src/output.js +57 -0
- package/src/pipe/bitbucket.js +252 -0
- package/src/pipe/csv.js +140 -0
- package/src/pipe/debug.js +125 -0
- package/src/pipe/github.js +232 -0
- package/src/pipe/gitlab.js +247 -0
- package/src/pipe/html.js +373 -0
- package/src/pipe/index.js +71 -0
- package/src/pipe/testomatio.js +504 -0
- package/src/replay.js +262 -0
- package/src/reporter-functions.js +55 -0
- package/src/reporter.cjs_decprecated +21 -0
- package/src/reporter.js +33 -0
- package/src/services/artifacts.js +59 -0
- package/src/services/index.js +13 -0
- package/src/services/key-values.js +59 -0
- package/src/services/logger.js +315 -0
- package/src/template/emptyData.svg +23 -0
- package/src/template/testomatio.hbs +1081 -0
- package/src/uploader.js +376 -0
- package/src/utils/pipe_utils.js +119 -0
- package/src/utils/utils.js +416 -0
- package/src/xmlReader.js +614 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class JestReporter {
|
|
2
|
+
constructor(globalConfig: any, options: any);
|
|
3
|
+
_globalConfig: any;
|
|
4
|
+
_options: any;
|
|
5
|
+
client: TestomatClient;
|
|
6
|
+
onRunStart(): void;
|
|
7
|
+
onTestStart(testFile: any): void;
|
|
8
|
+
onTestCaseStart(test: any, testCase: any): void;
|
|
9
|
+
onTestResult(test: any, testResult: any): void;
|
|
10
|
+
onRunComplete(contexts: any, results: any): void;
|
|
11
|
+
}
|
|
12
|
+
export default JestReporter;
|
|
13
|
+
import TestomatClient from '../client.js';
|
package/lib/adapter/jest.js
CHANGED
|
@@ -1,105 +1,103 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.JestReporter = void 0;
|
|
7
|
+
const picocolors_1 = __importDefault(require("picocolors"));
|
|
8
|
+
const client_js_1 = __importDefault(require("../client.js"));
|
|
9
|
+
const constants_js_1 = require("../constants.js");
|
|
10
|
+
const utils_js_1 = require("../utils/utils.js");
|
|
11
|
+
const index_js_1 = require("../services/index.js");
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const debug_1 = __importDefault(require("debug"));
|
|
14
|
+
const debug = (0, debug_1.default)('@testomatio/reporter:adapter-jest');
|
|
9
15
|
class JestReporter {
|
|
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
|
-
|
|
16
|
+
constructor(globalConfig, options) {
|
|
17
|
+
this._globalConfig = globalConfig;
|
|
18
|
+
this._options = options;
|
|
19
|
+
this.client = new client_js_1.default({ apiKey: options?.apiKey });
|
|
20
|
+
this.client.createRun();
|
|
21
|
+
}
|
|
22
|
+
onRunStart() {
|
|
23
|
+
// clear tmp dir
|
|
24
|
+
utils_js_1.fileSystem.clearDir(constants_js_1.TESTOMAT_TMP_STORAGE_DIR);
|
|
25
|
+
}
|
|
26
|
+
// start of test file (including beforeAll)
|
|
27
|
+
onTestStart(testFile) {
|
|
28
|
+
debug('Start running test file:', testFile.path);
|
|
29
|
+
index_js_1.services.setContext(testFile.path);
|
|
30
|
+
}
|
|
31
|
+
// start of the test (including beforeEach)
|
|
32
|
+
onTestCaseStart(test, testCase) {
|
|
33
|
+
debug('Start running test:', testCase.fullName);
|
|
34
|
+
index_js_1.services.setContext(testCase.fullName);
|
|
35
|
+
}
|
|
36
|
+
// end of test file! (there is also onTestCaseResult listener)
|
|
37
|
+
onTestResult(test, testResult) {
|
|
38
|
+
if (!this.client)
|
|
39
|
+
return;
|
|
40
|
+
const { testResults } = testResult;
|
|
41
|
+
for (const result of testResults) {
|
|
42
|
+
let error;
|
|
43
|
+
let steps;
|
|
44
|
+
const { status, title, duration, failureMessages } = result;
|
|
45
|
+
if (failureMessages[0]) {
|
|
46
|
+
let errorMessage = failureMessages[0].replace((0, utils_js_1.ansiRegExp)(), '');
|
|
47
|
+
errorMessage = errorMessage.split('\n')[0];
|
|
48
|
+
error = new Error(errorMessage);
|
|
49
|
+
steps = failureMessages[0];
|
|
50
|
+
}
|
|
51
|
+
const testId = (0, utils_js_1.getTestomatIdFromTestTitle)(title);
|
|
52
|
+
// suite titles from most outer to most inner, separated by space
|
|
53
|
+
let fullSuiteTitle = testResult.ancestorTitles?.join(' ');
|
|
54
|
+
// if no suite titles, use file name
|
|
55
|
+
if (!fullSuiteTitle && testResult.testFilePath)
|
|
56
|
+
fullSuiteTitle = path_1.default.basename(testResult.testFilePath);
|
|
57
|
+
const logs = getTestLogs(result);
|
|
58
|
+
const artifacts = index_js_1.services.artifacts.get(result.fullName);
|
|
59
|
+
const keyValues = index_js_1.services.keyValues.get(result.fullName);
|
|
60
|
+
const deducedStatus = status === 'pending' ? 'skipped' : status;
|
|
61
|
+
// In jest if test is not matched with test name pattern it is considered as skipped.
|
|
62
|
+
// So adding a check if it is skipped for real or because of test pattern
|
|
63
|
+
if (!this._globalConfig.testNamePattern || deducedStatus !== 'skipped') {
|
|
64
|
+
this.client.addTestRun(deducedStatus, {
|
|
65
|
+
test_id: testId,
|
|
66
|
+
suite_title: fullSuiteTitle,
|
|
67
|
+
error,
|
|
68
|
+
steps,
|
|
69
|
+
title,
|
|
70
|
+
time: duration,
|
|
71
|
+
logs,
|
|
72
|
+
manuallyAttachedArtifacts: artifacts,
|
|
73
|
+
meta: keyValues,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
onRunComplete(contexts, results) {
|
|
79
|
+
if (!this.client)
|
|
80
|
+
return;
|
|
81
|
+
const { numFailedTests } = results;
|
|
82
|
+
const status = numFailedTests === 0 ? 'passed' : 'failed';
|
|
83
|
+
this.client.updateRunStatus(status);
|
|
77
84
|
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
onRunComplete(contexts, results) {
|
|
81
|
-
if (!this.client) return;
|
|
82
|
-
|
|
83
|
-
const { numFailedTests } = results;
|
|
84
|
-
const status = numFailedTests === 0 ? STATUS.PASSED : STATUS.FAILED;
|
|
85
|
-
this.client.updateRunStatus(status);
|
|
86
|
-
}
|
|
87
85
|
}
|
|
88
|
-
|
|
86
|
+
exports.JestReporter = JestReporter;
|
|
89
87
|
function getTestLogs(testResult) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return logs;
|
|
88
|
+
const suiteLogsArr = index_js_1.services.logger.getLogs(testResult.testFilePath);
|
|
89
|
+
const suiteLogs = suiteLogsArr ? suiteLogsArr.join('\n').trim() : '';
|
|
90
|
+
const testLogsArr = index_js_1.services.logger.getLogs(testResult.fullName);
|
|
91
|
+
const testLogs = testLogsArr ? testLogsArr.join('\n').trim() : '';
|
|
92
|
+
let logs = '';
|
|
93
|
+
if (suiteLogs) {
|
|
94
|
+
logs += `${picocolors_1.default.bold('\t--- Suite ---')}\n${suiteLogs}`;
|
|
95
|
+
}
|
|
96
|
+
if (testLogs) {
|
|
97
|
+
logs += `\n${picocolors_1.default.bold('\t--- Test ---')}\n${testLogs}`;
|
|
98
|
+
}
|
|
99
|
+
return logs;
|
|
103
100
|
}
|
|
104
|
-
|
|
105
101
|
module.exports = JestReporter;
|
|
102
|
+
|
|
103
|
+
module.exports.JestReporter = JestReporter;
|
package/lib/adapter/mocha.js
CHANGED
|
@@ -1,154 +1,125 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
EVENT_TEST_PASS,
|
|
15
|
-
EVENT_TEST_PENDING,
|
|
16
|
-
EVENT_SUITE_BEGIN,
|
|
17
|
-
EVENT_SUITE_END,
|
|
18
|
-
EVENT_TEST_BEGIN,
|
|
19
|
-
EVENT_TEST_END,
|
|
20
|
-
} = Mocha.Runner.constants;
|
|
21
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const mocha_1 = __importDefault(require("mocha"));
|
|
7
|
+
const client_js_1 = __importDefault(require("../client.js"));
|
|
8
|
+
const constants_js_1 = require("../constants.js");
|
|
9
|
+
const utils_js_1 = require("../utils/utils.js");
|
|
10
|
+
const config_js_1 = require("../config.js");
|
|
11
|
+
const index_js_1 = require("../services/index.js");
|
|
12
|
+
const picocolors_1 = __importDefault(require("picocolors"));
|
|
13
|
+
const { EVENT_RUN_BEGIN, EVENT_RUN_END, EVENT_TEST_FAIL, EVENT_TEST_PASS, EVENT_TEST_PENDING, EVENT_SUITE_BEGIN, EVENT_SUITE_END, EVENT_TEST_BEGIN, EVENT_TEST_END, } = mocha_1.default.Runner.constants;
|
|
22
14
|
function MochaReporter(runner, opts) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// clear dir with artifacts/logs
|
|
36
|
-
fileSystem.clearDir(TESTOMAT_TMP_STORAGE_DIR);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
runner.on(EVENT_SUITE_BEGIN, async suite => {
|
|
40
|
-
services.setContext(suite.fullTitle());
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
runner.on(EVENT_SUITE_END, async () => {
|
|
44
|
-
services.setContext(null);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
runner.on(EVENT_TEST_BEGIN, async test => {
|
|
48
|
-
services.setContext(test.fullTitle());
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
runner.on(EVENT_TEST_END, async () => {
|
|
52
|
-
services.setContext(null);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
runner.on(EVENT_TEST_PASS, async test => {
|
|
56
|
-
passes += 1;
|
|
57
|
-
|
|
58
|
-
console.log(chalk.bold.green('✔'), test.fullTitle());
|
|
59
|
-
const testId = getTestomatIdFromTestTitle(test.title);
|
|
60
|
-
|
|
61
|
-
const logs = getTestLogs(test);
|
|
62
|
-
const artifacts = services.artifacts.get(test.fullTitle());
|
|
63
|
-
const keyValues = services.keyValues.get(test.fullTitle());
|
|
64
|
-
|
|
65
|
-
client.addTestRun(STATUS.PASSED, {
|
|
66
|
-
test_id: testId,
|
|
67
|
-
suite_title: getSuiteTitle(test),
|
|
68
|
-
title: getTestName(test),
|
|
69
|
-
code: process.env.TESTOMATIO_UPDATE_CODE ? test.body.toString() : '',
|
|
70
|
-
file: getFile(test),
|
|
71
|
-
time: test.duration,
|
|
72
|
-
logs,
|
|
73
|
-
manuallyAttachedArtifacts: artifacts,
|
|
74
|
-
meta: keyValues,
|
|
15
|
+
mocha_1.default.reporters.Base.call(this, runner);
|
|
16
|
+
let passes = 0;
|
|
17
|
+
let failures = 0;
|
|
18
|
+
let skipped = 0;
|
|
19
|
+
// let artifactStore;
|
|
20
|
+
const apiKey = opts?.reporterOptions?.apiKey || config_js_1.config.TESTOMATIO;
|
|
21
|
+
const client = new client_js_1.default({ apiKey });
|
|
22
|
+
runner.on(EVENT_RUN_BEGIN, () => {
|
|
23
|
+
client.createRun();
|
|
24
|
+
// clear dir with artifacts/logs
|
|
25
|
+
utils_js_1.fileSystem.clearDir(constants_js_1.TESTOMAT_TMP_STORAGE_DIR);
|
|
75
26
|
});
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
runner.on(EVENT_TEST_PENDING, test => {
|
|
79
|
-
skipped += 1;
|
|
80
|
-
console.log('skip: %s', test.fullTitle());
|
|
81
|
-
const testId = getTestomatIdFromTestTitle(test.title);
|
|
82
|
-
client.addTestRun(STATUS.SKIPPED, {
|
|
83
|
-
title: getTestName(test),
|
|
84
|
-
suite_title: getSuiteTitle(test),
|
|
85
|
-
code: process.env.TESTOMATIO_UPDATE_CODE ? test.body.toString() : '',
|
|
86
|
-
file: getFile(test),
|
|
87
|
-
test_id: testId,
|
|
88
|
-
time: test.duration,
|
|
27
|
+
runner.on(EVENT_SUITE_BEGIN, async (suite) => {
|
|
28
|
+
index_js_1.services.setContext(suite.fullTitle());
|
|
89
29
|
});
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
30
|
+
runner.on(EVENT_SUITE_END, async () => {
|
|
31
|
+
index_js_1.services.setContext(null);
|
|
32
|
+
});
|
|
33
|
+
runner.on(EVENT_TEST_BEGIN, async (test) => {
|
|
34
|
+
index_js_1.services.setContext(test.fullTitle());
|
|
35
|
+
});
|
|
36
|
+
runner.on(EVENT_TEST_END, async () => {
|
|
37
|
+
index_js_1.services.setContext(null);
|
|
38
|
+
});
|
|
39
|
+
runner.on(EVENT_TEST_PASS, async (test) => {
|
|
40
|
+
passes += 1;
|
|
41
|
+
console.log(picocolors_1.default.bold(picocolors_1.default.green('✔')), test.fullTitle());
|
|
42
|
+
const testId = (0, utils_js_1.getTestomatIdFromTestTitle)(test.title);
|
|
43
|
+
const logs = getTestLogs(test);
|
|
44
|
+
const artifacts = index_js_1.services.artifacts.get(test.fullTitle());
|
|
45
|
+
const keyValues = index_js_1.services.keyValues.get(test.fullTitle());
|
|
46
|
+
client.addTestRun(constants_js_1.STATUS.PASSED, {
|
|
47
|
+
test_id: testId,
|
|
48
|
+
suite_title: getSuiteTitle(test),
|
|
49
|
+
title: getTestName(test),
|
|
50
|
+
code: process.env.TESTOMATIO_UPDATE_CODE ? test.body.toString() : '',
|
|
51
|
+
file: getFile(test),
|
|
52
|
+
time: test.duration,
|
|
53
|
+
logs,
|
|
54
|
+
manuallyAttachedArtifacts: artifacts,
|
|
55
|
+
meta: keyValues,
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
runner.on(EVENT_TEST_PENDING, test => {
|
|
59
|
+
skipped += 1;
|
|
60
|
+
console.log('skip: %s', test.fullTitle());
|
|
61
|
+
const testId = (0, utils_js_1.getTestomatIdFromTestTitle)(test.title);
|
|
62
|
+
client.addTestRun(constants_js_1.STATUS.SKIPPED, {
|
|
63
|
+
title: getTestName(test),
|
|
64
|
+
suite_title: getSuiteTitle(test),
|
|
65
|
+
code: process.env.TESTOMATIO_UPDATE_CODE ? test.body.toString() : '',
|
|
66
|
+
file: getFile(test),
|
|
67
|
+
test_id: testId,
|
|
68
|
+
time: test.duration,
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
runner.on(EVENT_TEST_FAIL, async (test, err) => {
|
|
72
|
+
failures += 1;
|
|
73
|
+
console.log(picocolors_1.default.bold(picocolors_1.default.red('✖')), test.fullTitle(), picocolors_1.default.gray(err.message));
|
|
74
|
+
const testId = (0, utils_js_1.getTestomatIdFromTestTitle)(test.title);
|
|
75
|
+
const logs = getTestLogs(test);
|
|
76
|
+
client.addTestRun(constants_js_1.STATUS.FAILED, {
|
|
77
|
+
error: err,
|
|
78
|
+
suite_title: getSuiteTitle(test),
|
|
79
|
+
file: getFile(test),
|
|
80
|
+
test_id: testId,
|
|
81
|
+
title: getTestName(test),
|
|
82
|
+
code: process.env.TESTOMATIO_UPDATE_CODE ? test.body.toString() : '',
|
|
83
|
+
time: test.duration,
|
|
84
|
+
logs,
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
runner.on(EVENT_RUN_END, () => {
|
|
88
|
+
const status = failures === 0 ? constants_js_1.STATUS.PASSED : constants_js_1.STATUS.FAILED;
|
|
89
|
+
console.log(picocolors_1.default.bold(status), `${passes} passed, ${failures} failed, ${skipped} skipped`);
|
|
90
|
+
// @ts-ignore
|
|
91
|
+
client.updateRunStatus(status);
|
|
108
92
|
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
runner.on(EVENT_RUN_END, () => {
|
|
112
|
-
const status = failures === 0 ? STATUS.PASSED : STATUS.FAILED;
|
|
113
|
-
console.log(chalk.bold(status), `${passes} passed, ${failures} failed, ${skipped} skipped`);
|
|
114
|
-
client.updateRunStatus(status);
|
|
115
|
-
});
|
|
116
93
|
}
|
|
117
|
-
|
|
118
94
|
function getTestLogs(test) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return logs;
|
|
95
|
+
const suiteLogsArr = index_js_1.services.logger.getLogs(test.parent.fullTitle());
|
|
96
|
+
const suiteLogs = suiteLogsArr ? suiteLogsArr.join('\n').trim() : '';
|
|
97
|
+
const testLogsArr = index_js_1.services.logger.getLogs(test.fullTitle());
|
|
98
|
+
const testLogs = testLogsArr ? testLogsArr.join('\n').trim() : '';
|
|
99
|
+
let logs = '';
|
|
100
|
+
if (suiteLogs) {
|
|
101
|
+
logs += `${picocolors_1.default.bold('\t--- BeforeSuite ---')}\n${suiteLogs}`;
|
|
102
|
+
}
|
|
103
|
+
if (testLogs) {
|
|
104
|
+
logs += `\n${picocolors_1.default.bold('\t--- Test ---')}\n${testLogs}`;
|
|
105
|
+
}
|
|
106
|
+
return logs;
|
|
132
107
|
}
|
|
133
|
-
|
|
134
|
-
// To have this reporter "extend" a built-in reporter uncomment the following line:
|
|
135
|
-
Mocha.utils.inherits(MochaReporter, Mocha.reporters.Spec);
|
|
136
|
-
|
|
137
|
-
module.exports = MochaReporter;
|
|
138
|
-
|
|
139
108
|
function getSuiteTitle(test, pathArr = []) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return pathArr.filter(t => !!t)[0];
|
|
109
|
+
if (test.parent.parent)
|
|
110
|
+
getSuiteTitle(test.parent, pathArr);
|
|
111
|
+
pathArr.push(test.parent.title);
|
|
112
|
+
return pathArr.filter(t => !!t)[0];
|
|
145
113
|
}
|
|
146
|
-
|
|
147
114
|
function getFile(test) {
|
|
148
|
-
|
|
115
|
+
return test.parent.file?.replace(process.cwd(), '');
|
|
149
116
|
}
|
|
150
|
-
|
|
151
117
|
function getTestName(test) {
|
|
152
|
-
|
|
153
|
-
|
|
118
|
+
if (process.env.TESTOMATIO_CREATE === 'fulltitle')
|
|
119
|
+
return test.fullTitle();
|
|
120
|
+
return test.title;
|
|
154
121
|
}
|
|
122
|
+
// To have this reporter "extend" a built-in reporter uncomment the following line:
|
|
123
|
+
// @ts-ignore
|
|
124
|
+
mocha_1.default.utils.inherits(MochaReporter, mocha_1.default.reporters.Spec);
|
|
125
|
+
module.exports = MochaReporter;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const client_js_1 = __importDefault(require("../client.js"));
|
|
7
|
+
const config_js_1 = require("../config.js");
|
|
8
|
+
const constants_js_1 = require("../constants.js");
|
|
9
|
+
const utils_js_1 = require("../utils/utils.js");
|
|
10
|
+
const apiKey = config_js_1.config.TESTOMATIO;
|
|
11
|
+
const client = new client_js_1.default({ apiKey });
|
|
12
|
+
module.exports = {
|
|
13
|
+
write: async (results, options, done) => {
|
|
14
|
+
await client.createRun();
|
|
15
|
+
const testFiles = results.modules;
|
|
16
|
+
for (const fileName in testFiles) {
|
|
17
|
+
// in nightwatch: object containing tests from a single file
|
|
18
|
+
const testModule = testFiles[fileName];
|
|
19
|
+
// passed and failed tests (tests with assertions)
|
|
20
|
+
const completedTests = testModule.completed;
|
|
21
|
+
// skipped tests (skipped by user or tests without assertions)
|
|
22
|
+
const skippedTests = testModule.skipped;
|
|
23
|
+
const tags = testModule.tags || [];
|
|
24
|
+
// if test file contains multiple suites, the last suite name is used as a name 🤷♂️
|
|
25
|
+
// no other places which contain suite name (even inside test object)
|
|
26
|
+
const suiteTitle = testModule.name;
|
|
27
|
+
for (const testTitle in completedTests) {
|
|
28
|
+
const test = completedTests[testTitle];
|
|
29
|
+
let status;
|
|
30
|
+
switch (test.status) {
|
|
31
|
+
case 'pass':
|
|
32
|
+
status = constants_js_1.STATUS.PASSED;
|
|
33
|
+
break;
|
|
34
|
+
case 'fail':
|
|
35
|
+
status = constants_js_1.STATUS.FAILED;
|
|
36
|
+
break;
|
|
37
|
+
// probably not required (because skipped tests are in separate array), but just in case
|
|
38
|
+
case 'skip':
|
|
39
|
+
status = constants_js_1.STATUS.SKIPPED;
|
|
40
|
+
console.info('Skipped test is in completed tests array:', test, 'Not expected behavior.');
|
|
41
|
+
break;
|
|
42
|
+
default:
|
|
43
|
+
console.error('Test status processing error:', test.status);
|
|
44
|
+
}
|
|
45
|
+
const testId = (0, utils_js_1.getTestomatIdFromTestTitle)(testTitle);
|
|
46
|
+
client.addTestRun(status, {
|
|
47
|
+
error: { name: test.assertions?.[0]?.name, message: test.assertions?.[0]?.message, stack: test.stackTrace },
|
|
48
|
+
file: testModule.modulePath?.replace(process.cwd(), ''),
|
|
49
|
+
message: test.assertions?.[0]?.message,
|
|
50
|
+
rid: `${testModule.uuid || ''}_${testTitle || ''}`,
|
|
51
|
+
stack: test.stackTrace,
|
|
52
|
+
suite_title: suiteTitle,
|
|
53
|
+
tags,
|
|
54
|
+
test_id: testId,
|
|
55
|
+
time: test.timeMs,
|
|
56
|
+
title: testTitle,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
// just array with skipped tests titles, no any other info
|
|
60
|
+
for (const testTitle of skippedTests) {
|
|
61
|
+
client.addTestRun(constants_js_1.STATUS.SKIPPED, {
|
|
62
|
+
suite_title: suiteTitle,
|
|
63
|
+
tags,
|
|
64
|
+
rid: `${testModule.uuid || ''}_${testTitle || ''}`,
|
|
65
|
+
title: testTitle,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* @type {'passed' | 'failed' | 'finished'}
|
|
71
|
+
*/
|
|
72
|
+
let runStatus = 'finished';
|
|
73
|
+
if (results.failed)
|
|
74
|
+
runStatus = 'failed';
|
|
75
|
+
else if (results.passed)
|
|
76
|
+
runStatus = 'passed';
|
|
77
|
+
await client.updateRunStatus(runStatus);
|
|
78
|
+
done();
|
|
79
|
+
},
|
|
80
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export default PlaywrightReporter;
|
|
2
|
+
declare class PlaywrightReporter {
|
|
3
|
+
constructor(config?: {});
|
|
4
|
+
client: TestomatioClient;
|
|
5
|
+
uploads: any[];
|
|
6
|
+
onBegin(config: any, suite: any): void;
|
|
7
|
+
suite: any;
|
|
8
|
+
config: any;
|
|
9
|
+
onTestBegin(testInfo: any): void;
|
|
10
|
+
onTestEnd(test: any, result: any): void;
|
|
11
|
+
onEnd(result: any): Promise<void>;
|
|
12
|
+
#private;
|
|
13
|
+
}
|
|
14
|
+
import TestomatioClient from '../client.js';
|