@testomatio/reporter 2.0.1-beta.5-timestamp → 2.0.1-beta.6

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.
Files changed (149) hide show
  1. package/README.md +1 -0
  2. package/lib/adapter/codecept.d.ts +2 -0
  3. package/lib/adapter/codecept.js +293 -335
  4. package/lib/adapter/cucumber/current.d.ts +14 -0
  5. package/lib/adapter/cucumber/current.js +195 -203
  6. package/lib/adapter/cucumber/legacy.d.ts +0 -0
  7. package/lib/adapter/cucumber/legacy.js +130 -155
  8. package/lib/adapter/cucumber.d.ts +2 -0
  9. package/lib/adapter/cucumber.js +5 -16
  10. package/lib/adapter/cypress-plugin/index.d.ts +2 -0
  11. package/lib/adapter/cypress-plugin/index.js +91 -105
  12. package/lib/adapter/jasmine.d.ts +11 -0
  13. package/lib/adapter/jasmine.js +54 -53
  14. package/lib/adapter/jest.d.ts +13 -0
  15. package/lib/adapter/jest.js +97 -99
  16. package/lib/adapter/mocha.d.ts +2 -0
  17. package/lib/adapter/mocha.js +112 -141
  18. package/lib/adapter/nightwatch.d.ts +4 -0
  19. package/lib/adapter/nightwatch.js +80 -0
  20. package/lib/adapter/playwright.d.ts +14 -0
  21. package/lib/adapter/playwright.js +199 -231
  22. package/lib/adapter/vitest.d.ts +35 -0
  23. package/lib/adapter/vitest.js +150 -149
  24. package/lib/adapter/webdriver.d.ts +24 -0
  25. package/lib/adapter/webdriver.js +144 -121
  26. package/lib/bin/cli.d.ts +2 -0
  27. package/lib/bin/cli.js +229 -211
  28. package/lib/bin/reportXml.d.ts +2 -0
  29. package/lib/bin/reportXml.js +51 -52
  30. package/lib/bin/startTest.d.ts +2 -0
  31. package/lib/bin/startTest.js +83 -95
  32. package/lib/bin/uploadArtifacts.d.ts +2 -0
  33. package/lib/bin/uploadArtifacts.js +56 -61
  34. package/lib/client.d.ts +76 -0
  35. package/lib/client.js +429 -465
  36. package/lib/config.d.ts +1 -0
  37. package/lib/config.js +18 -23
  38. package/lib/constants.d.ts +25 -0
  39. package/lib/constants.js +50 -44
  40. package/lib/data-storage.d.ts +34 -0
  41. package/lib/data-storage.js +216 -188
  42. package/lib/junit-adapter/adapter.d.ts +9 -0
  43. package/lib/junit-adapter/adapter.js +17 -20
  44. package/lib/junit-adapter/csharp.d.ts +5 -0
  45. package/lib/junit-adapter/csharp.js +28 -14
  46. package/lib/junit-adapter/index.d.ts +3 -0
  47. package/lib/junit-adapter/index.js +27 -25
  48. package/lib/junit-adapter/java.d.ts +5 -0
  49. package/lib/junit-adapter/java.js +41 -53
  50. package/lib/junit-adapter/javascript.d.ts +4 -0
  51. package/lib/junit-adapter/javascript.js +30 -27
  52. package/lib/junit-adapter/python.d.ts +5 -0
  53. package/lib/junit-adapter/python.js +38 -37
  54. package/lib/junit-adapter/ruby.d.ts +4 -0
  55. package/lib/junit-adapter/ruby.js +11 -8
  56. package/lib/output.d.ts +11 -0
  57. package/lib/output.js +44 -52
  58. package/lib/package.json +3 -0
  59. package/lib/pipe/bitbucket.d.ts +25 -0
  60. package/lib/pipe/bitbucket.js +223 -230
  61. package/lib/pipe/csv.d.ts +47 -0
  62. package/lib/pipe/csv.js +113 -126
  63. package/lib/pipe/debug.d.ts +29 -0
  64. package/lib/pipe/debug.js +125 -99
  65. package/lib/pipe/github.d.ts +30 -0
  66. package/lib/pipe/github.js +218 -213
  67. package/lib/pipe/gitlab.d.ts +25 -0
  68. package/lib/pipe/gitlab.js +183 -206
  69. package/lib/pipe/html.d.ts +35 -0
  70. package/lib/pipe/html.js +258 -321
  71. package/lib/pipe/index.d.ts +1 -0
  72. package/lib/pipe/index.js +94 -66
  73. package/lib/pipe/testomatio.d.ts +71 -0
  74. package/lib/pipe/testomatio.js +429 -474
  75. package/lib/replay.d.ts +31 -0
  76. package/lib/replay.js +255 -0
  77. package/lib/reporter-functions.d.ts +34 -0
  78. package/lib/reporter-functions.js +28 -26
  79. package/lib/reporter.d.ts +232 -0
  80. package/lib/reporter.js +34 -29
  81. package/lib/services/artifacts.d.ts +33 -0
  82. package/lib/services/artifacts.js +55 -51
  83. package/lib/services/index.d.ts +9 -0
  84. package/lib/services/index.js +14 -12
  85. package/lib/services/key-values.d.ts +27 -0
  86. package/lib/services/key-values.js +56 -53
  87. package/lib/services/logger.d.ts +64 -0
  88. package/lib/services/logger.js +226 -245
  89. package/lib/template/testomatio.hbs +1026 -1366
  90. package/lib/uploader.d.ts +60 -0
  91. package/lib/uploader.js +295 -364
  92. package/lib/utils/pipe_utils.d.ts +41 -0
  93. package/lib/utils/pipe_utils.js +89 -85
  94. package/lib/utils/utils.d.ts +54 -0
  95. package/lib/utils/utils.js +398 -307
  96. package/lib/xmlReader.d.ts +92 -0
  97. package/lib/xmlReader.js +525 -532
  98. package/package.json +64 -21
  99. package/src/adapter/codecept.js +373 -0
  100. package/src/adapter/cucumber/current.js +228 -0
  101. package/src/adapter/cucumber/legacy.js +158 -0
  102. package/src/adapter/cucumber.js +4 -0
  103. package/src/adapter/cypress-plugin/index.js +110 -0
  104. package/src/adapter/jasmine.js +60 -0
  105. package/src/adapter/jest.js +107 -0
  106. package/src/adapter/mocha.cjs +2 -0
  107. package/src/adapter/mocha.js +156 -0
  108. package/src/adapter/nightwatch.js +88 -0
  109. package/src/adapter/playwright.js +254 -0
  110. package/src/adapter/vitest.js +183 -0
  111. package/src/adapter/webdriver.js +142 -0
  112. package/src/bin/cli.js +348 -0
  113. package/src/bin/reportXml.js +77 -0
  114. package/src/bin/startTest.js +124 -0
  115. package/src/bin/uploadArtifacts.js +91 -0
  116. package/src/client.js +515 -0
  117. package/src/config.js +30 -0
  118. package/src/constants.js +53 -0
  119. package/src/data-storage.js +204 -0
  120. package/src/junit-adapter/adapter.js +23 -0
  121. package/src/junit-adapter/csharp.js +28 -0
  122. package/src/junit-adapter/index.js +28 -0
  123. package/src/junit-adapter/java.js +58 -0
  124. package/src/junit-adapter/javascript.js +31 -0
  125. package/src/junit-adapter/python.js +42 -0
  126. package/src/junit-adapter/ruby.js +10 -0
  127. package/src/output.js +57 -0
  128. package/src/pipe/bitbucket.js +252 -0
  129. package/src/pipe/csv.js +140 -0
  130. package/src/pipe/debug.js +125 -0
  131. package/src/pipe/github.js +232 -0
  132. package/src/pipe/gitlab.js +247 -0
  133. package/src/pipe/html.js +373 -0
  134. package/src/pipe/index.js +71 -0
  135. package/src/pipe/testomatio.js +504 -0
  136. package/src/replay.js +262 -0
  137. package/src/reporter-functions.js +55 -0
  138. package/src/reporter.cjs_decprecated +21 -0
  139. package/src/reporter.js +33 -0
  140. package/src/services/artifacts.js +59 -0
  141. package/src/services/index.js +13 -0
  142. package/src/services/key-values.js +59 -0
  143. package/src/services/logger.js +315 -0
  144. package/src/template/emptyData.svg +23 -0
  145. package/src/template/testomatio.hbs +1081 -0
  146. package/src/uploader.js +376 -0
  147. package/src/utils/pipe_utils.js +119 -0
  148. package/src/utils/utils.js +416 -0
  149. package/src/xmlReader.js +614 -0
@@ -1,122 +1,123 @@
1
- const chalk = require('chalk');
2
- const { TestomatioClient } = require('../client');
3
- const { STATUS } = require('../constants');
4
- const { getTestomatIdFromTestTitle } = require('../utils/utils');
5
- const debug = require('debug')('@testomatio/reporter:adapter:vitest');
6
-
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.VitestReporter = void 0;
7
+ const picocolors_1 = __importDefault(require("picocolors"));
8
+ const client_js_1 = require("../client.js");
9
+ const constants_js_1 = require("../constants.js");
10
+ const utils_js_1 = require("../utils/utils.js");
11
+ const debug_1 = __importDefault(require("debug"));
12
+ const debug = (0, debug_1.default)('@testomatio/reporter:adapter-jest');
7
13
  /**
8
- * @typedef {import('../../types').VitestTest} VitestTest
9
- * @typedef {import('../../types').VitestTestFile} VitestTestFile
10
- * @typedef {import('../../types').VitestSuite} VitestSuite
11
- * @typedef {import('../../types').VitestTestLogs} VitestTestLogs
12
- * @typedef {import('../../vitest.types').ErrorWithDiff} ErrorWithDiff
13
- * @typedef {typeof import('../constants').STATUS} STATUS
14
- * @typedef {import('../../types').TestData} TestData
14
+ * @typedef {import('../../types/types.js').VitestTest} VitestTest
15
+ * @typedef {import('../../types/types.js').VitestTestFile} VitestTestFile
16
+ * @typedef {import('../../types/types.js').VitestSuite} VitestSuite
17
+ * @typedef {import('../../types/types.js').VitestTestLogs} VitestTestLogs
18
+ * @typedef {import('../../types/vitest.types.js').ErrorWithDiff} ErrorWithDiff
19
+ * @typedef {typeof import('../constants.js').STATUS} STATUS
20
+ * @typedef {import('../../types/types.js').TestData} TestData
15
21
  */
16
-
17
22
  class VitestReporter {
18
- constructor(config = {}) {
19
- this.client = new TestomatioClient({ apiKey: config?.apiKey });
23
+ constructor(config = {}) {
24
+ this.client = new client_js_1.Client({ apiKey: config?.apiKey });
25
+ /**
26
+ * @type {(TestData & {status: string})[]} tests
27
+ */
28
+ this.tests = [];
29
+ }
30
+ // on run start
31
+ onInit() {
32
+ this.client.createRun();
33
+ }
20
34
  /**
21
- * @type {(TestData & {status: string})[]} tests
35
+ * @param {VitestTestFile[] | undefined} files // array with results;
36
+ * @param {unknown[] | undefined} errors // errors does not contain errors from tests; probably its testrunner errors
22
37
  */
23
- this.tests = [];
24
- }
25
-
26
- // on run start
27
- onInit() {
28
- this.client.createRun();
29
- }
30
-
31
- /**
32
- * @param {VitestTestFile[] | undefined} files // array with results;
33
- * @param {unknown[] | undefined} errors // errors does not contain errors from tests; probably its testrunner errors
34
- */
35
- async onFinished(files, errors) {
36
- if (!files || !files.length) console.info('No tests executed');
37
-
38
- files.forEach(file => {
39
- // task could be test or suite
40
- file.tasks.forEach(taskOrSuite => {
41
- if (taskOrSuite.type === 'test') {
42
- const test = taskOrSuite;
43
- this.tests.push(this.#getDataFromTest(test));
44
- } else if (taskOrSuite.type === 'suite') {
45
- const suite = taskOrSuite;
46
- this.#processTasksOfSuite(suite);
47
- } else {
48
- throw new Error('Unprocessed case. Unknown task type');
38
+ async onFinished(files, errors) {
39
+ if (!files || !files.length)
40
+ console.info('No tests executed');
41
+ files.forEach(file => {
42
+ // task could be test or suite
43
+ file.tasks.forEach(taskOrSuite => {
44
+ if (taskOrSuite.type === 'test') {
45
+ const test = taskOrSuite;
46
+ this.tests.push(this.#getDataFromTest(test));
47
+ }
48
+ else if (taskOrSuite.type === 'suite') {
49
+ const suite = taskOrSuite;
50
+ this.#processTasksOfSuite(suite);
51
+ }
52
+ else {
53
+ throw new Error('Unprocessed case. Unknown task type');
54
+ }
55
+ });
56
+ });
57
+ debug(this.tests.length, 'tests collected');
58
+ // send tests to Testomat.io
59
+ for (const test of this.tests) {
60
+ await this.client.addTestRun(test.status, test);
49
61
  }
50
- });
51
- });
52
-
53
- debug(this.tests.length, 'tests collected');
54
-
55
- // send tests to Testomat.io
56
- for (const test of this.tests) {
57
- await this.client.addTestRun(test.status, test);
62
+ console.log('finished');
63
+ if (errors.length)
64
+ console.error('Vitest adapter errors:', errors);
65
+ await this.client.updateRunStatus(getRunStatusFromResults(files));
66
+ }
67
+ /* non-used listeners
68
+ onUserConsoleLog(log) {}
69
+ onPathsCollected(paths) {} // paths array to files with tests
70
+ onCollected(files) {} // files array with tests (but without results)
71
+ onTaskUpdate(packs) {} // some updates come here on afterAll block execution
72
+ onTestRemoved(trigger) {}
73
+ onWatcherStart(files, errors) {}
74
+ onWatcherRerun(files, trigger) {}
75
+ onServerRestart(reason) {}
76
+ onProcessTimeout() {}
77
+ */
78
+ /**
79
+ * Recursively gets all tasks from suite and pushes them to "tests" array
80
+ *
81
+ * @param {VitestSuite} suite
82
+ */
83
+ #processTasksOfSuite(suite) {
84
+ suite.tasks.forEach(taskOrSuite => {
85
+ if (taskOrSuite.type === 'test') {
86
+ const test = taskOrSuite;
87
+ this.tests.push(this.#getDataFromTest(test));
88
+ }
89
+ else if (taskOrSuite.type === 'suite') {
90
+ const theSuite = taskOrSuite;
91
+ this.#processTasksOfSuite(theSuite);
92
+ }
93
+ else {
94
+ throw new Error('Unprocessed case. Unknown task type');
95
+ }
96
+ });
97
+ }
98
+ /**
99
+ * Processes task and returns test data ready to be sent to Testomat.io
100
+ *
101
+ * @param {VitestTest} test
102
+ *
103
+ * @returns {TestData & {status: string}}
104
+ */
105
+ #getDataFromTest(test) {
106
+ return {
107
+ error: test.result?.errors ? test.result.errors[0] : undefined,
108
+ file: test.file.name,
109
+ logs: test.logs ? transformLogsToString(test.logs) : '',
110
+ meta: test.meta,
111
+ status: getTestStatus(test),
112
+ suite_title: test.suite.name || test.file?.name,
113
+ test_id: (0, utils_js_1.getTestomatIdFromTestTitle)(test.name),
114
+ time: test.result?.duration || 0,
115
+ title: test.name,
116
+ // testomatio functions (artifacts, logs, steps, meta) are not supported
117
+ };
58
118
  }
59
-
60
- console.log('finished');
61
- if (errors.length) console.error('Vitest adapter errors:', errors);
62
-
63
- await this.client.updateRunStatus(getRunStatusFromResults(files));
64
- }
65
-
66
- /* non-used listeners
67
- onUserConsoleLog(log) {}
68
- onPathsCollected(paths) {} // paths array to files with tests
69
- onCollected(files) {} // files array with tests (but without results)
70
- onTaskUpdate(packs) {} // some updates come here on afterAll block execution
71
- onTestRemoved(trigger) {}
72
- onWatcherStart(files, errors) {}
73
- onWatcherRerun(files, trigger) {}
74
- onServerRestart(reason) {}
75
- onProcessTimeout() {}
76
- */
77
-
78
- /**
79
- * Recursively gets all tasks from suite and pushes them to "tests" array
80
- *
81
- * @param {VitestSuite} suite
82
- */
83
- #processTasksOfSuite(suite) {
84
- suite.tasks.forEach(taskOrSuite => {
85
- if (taskOrSuite.type === 'test') {
86
- const test = taskOrSuite;
87
- this.tests.push(this.#getDataFromTest(test));
88
- } else if (taskOrSuite.type === 'suite') {
89
- const theSuite = taskOrSuite;
90
- this.#processTasksOfSuite(theSuite);
91
- } else {
92
- throw new Error('Unprocessed case. Unknown task type');
93
- }
94
- });
95
- }
96
-
97
- /**
98
- * Processes task and returns test data ready to be sent to Testomat.io
99
- *
100
- * @param {VitestTest} test
101
- *
102
- * @returns {TestData & {status: string}}
103
- */
104
- #getDataFromTest(test) {
105
- return {
106
- error: test.result?.errors ? test.result.errors[0] : undefined,
107
- file: test.file.name,
108
- logs: test.logs ? transformLogsToString(test.logs) : '',
109
- meta: test.meta,
110
- status: getTestStatus(test),
111
- suite_title: test.suite.name || test.file?.name,
112
- test_id: getTestomatIdFromTestTitle(test.name),
113
- time: test.result?.duration || 0,
114
- title: test.name,
115
- // testomatio functions (artifacts, logs, steps, meta) are not supported
116
- };
117
- }
118
119
  }
119
-
120
+ exports.VitestReporter = VitestReporter;
120
121
  /**
121
122
  * Returns run status based on test results
122
123
  *
@@ -124,32 +125,28 @@ class VitestReporter {
124
125
  * @returns {'passed' | 'failed' | 'finished'}
125
126
  */
126
127
  function getRunStatusFromResults(files) {
127
- /**
128
- * @type {'passed' | 'failed' | 'finished'}
129
- */
130
- let status = 'finished'; // default status (if no failed or passed tests)
131
-
132
- files.forEach(file => {
133
- // search for failed tests
134
- file.tasks.forEach(taskOrSuite => {
135
- if (taskOrSuite.result?.state === 'fail') {
136
- status = 'failed'; // set status to failed if any test failed
137
- }
138
- });
139
-
140
- // if there are no failed tests > search for passed tests
141
- if (status !== 'failed') {
142
- file.tasks.forEach(taskOrSuite => {
143
- if (taskOrSuite.result?.state === 'pass') {
144
- status = 'passed'; // set status to passed if any test passed (and there are no failed tests)
128
+ /**
129
+ * @type {'passed' | 'failed' | 'finished'}
130
+ */
131
+ let status = 'finished'; // default status (if no failed or passed tests)
132
+ files.forEach(file => {
133
+ // search for failed tests
134
+ file.tasks.forEach(taskOrSuite => {
135
+ if (taskOrSuite.result?.state === 'fail') {
136
+ status = 'failed'; // set status to failed if any test failed
137
+ }
138
+ });
139
+ // if there are no failed tests > search for passed tests
140
+ if (status !== 'failed') {
141
+ file.tasks.forEach(taskOrSuite => {
142
+ if (taskOrSuite.result?.state === 'pass') {
143
+ status = 'passed'; // set status to passed if any test passed (and there are no failed tests)
144
+ }
145
+ });
145
146
  }
146
- });
147
- }
148
- });
149
-
150
- return status;
147
+ });
148
+ return status;
151
149
  }
152
-
153
150
  /**
154
151
  * Returns test status in Testomat.io format
155
152
  *
@@ -157,26 +154,30 @@ function getRunStatusFromResults(files) {
157
154
  * @returns 'passed' | 'failed' | 'skipped'
158
155
  */
159
156
  function getTestStatus(test) {
160
- if (test.result?.state === 'fail') return STATUS.FAILED;
161
- if (test.result?.state === 'pass') return STATUS.PASSED;
162
- if (!test.result && test.mode === 'skip') return STATUS.SKIPPED;
163
- console.error(chalk.red('Unprocessed case for defining test status. Contact dev team. Test:'), test);
157
+ if (test.result?.state === 'fail')
158
+ return constants_js_1.STATUS.FAILED;
159
+ if (test.result?.state === 'pass')
160
+ return constants_js_1.STATUS.PASSED;
161
+ if (!test.result && test.mode === 'skip')
162
+ return constants_js_1.STATUS.SKIPPED;
163
+ console.error(picocolors_1.default.red('Unprocessed case for defining test status. Contact dev team. Test:'), test);
164
164
  }
165
-
166
165
  /**
167
166
  * @param {VitestTestLogs[]} logs
168
167
  * @returns string
169
168
  */
170
169
  function transformLogsToString(logs) {
171
- if (!logs) return '';
172
- let logsStr = '';
173
- logs.forEach(log => {
174
- if (log.type === 'stdout') logsStr += `${log.content}\n`;
175
- if (log.type === 'stderr') logsStr += `${chalk.red(log.content)}\n`;
176
- });
177
- return logsStr;
170
+ if (!logs)
171
+ return '';
172
+ let logsStr = '';
173
+ logs.forEach(log => {
174
+ if (log.type === 'stdout')
175
+ logsStr += `${log.content}\n`;
176
+ if (log.type === 'stderr')
177
+ logsStr += `${picocolors_1.default.red(log.content)}\n`;
178
+ });
179
+ return logsStr;
178
180
  }
181
+ module.exports = VitestReporter;
179
182
 
180
183
  module.exports.VitestReporter = VitestReporter;
181
- module.exports.default = VitestReporter;
182
- module.exports = VitestReporter;
@@ -0,0 +1,24 @@
1
+ export default WebdriverReporter;
2
+ declare class WebdriverReporter extends WDIOReporter {
3
+ constructor(options: any);
4
+ client: TestomatClient;
5
+ _addTestPromises: any[];
6
+ _isSynchronising: boolean;
7
+ /**
8
+ *
9
+ * @param {RunnerStats} runData
10
+ */
11
+ onRunnerEnd(runData: RunnerStats): Promise<void>;
12
+ onRunnerStart(): void;
13
+ onTestStart(test: any): void;
14
+ onTestEnd(test: any): void;
15
+ onSuiteEnd(scerario: any): void;
16
+ addTest(test: any): Promise<void>;
17
+ /**
18
+ * @param {import('../../types/types.js').WebdriverIOScenario} scenario
19
+ */
20
+ addBddScenario(scenario: import("../../types/types.js").WebdriverIOScenario): Promise<import("../../types/types.js").PipeResult[]>;
21
+ }
22
+ import { default as WDIOReporter } from '@wdio/reporter';
23
+ import TestomatClient from '../client.js';
24
+ import { RunnerStats } from '@wdio/reporter';
@@ -1,132 +1,155 @@
1
- // eslint-disable-next-line global-require, import/no-extraneous-dependencies
2
- const WDIOReporter = require('@wdio/reporter').default;
3
- const TestomatClient = require('../client');
4
- const { getTestomatIdFromTestTitle, fileSystem } = require('../utils/utils');
5
- const { services } = require('../services');
6
- const { TESTOMAT_TMP_STORAGE_DIR } = require('../constants');
7
-
8
- class WebdriverReporter extends WDIOReporter {
9
- constructor(options) {
10
- super(options);
11
-
12
- this.client = new TestomatClient({ apiKey: options?.apiKey });
13
- options = Object.assign(options, { stdout: true });
14
-
15
- this._addTestPromises = [];
16
-
17
- this._isSynchronising = false;
18
- }
19
-
20
- onRunnerStart() {
21
- // clear dir with artifacts/logs
22
- fileSystem.clearDir(TESTOMAT_TMP_STORAGE_DIR);
23
- }
24
-
25
- onTestStart(test) {
26
- services.setContext(test.fullTitle);
27
- }
28
-
29
- get isSynchronised() {
30
- return this._isSynchronising === false;
31
- }
32
-
33
- async onRunnerEnd() {
34
- this._isSynchronising = true;
35
-
36
- await Promise.all(this._addTestPromises);
37
-
38
- this._isSynchronising = false;
39
- }
40
-
41
- onTestEnd(test) {
42
- test.suite = test.parent;
43
- const logs = getTestLogs(test.fullTitle);
44
- // TODO: FIX: artifacts for some reason leads to empty report on Testomat.io
45
- // const artifacts = services.artifacts.get(test.fullTitle);
46
- // const keyValues = services.keyValues.get(test.fullTitle);
47
- test.logs = logs;
48
- // test.artifacts = artifacts;
49
- // test.meta = keyValues;
50
- this._addTestPromises.push(this.addTest(test));
51
- }
52
-
53
- // wdio-cucumber does not trigger onTestEnd hook, thus, using this one
54
- onSuiteEnd(scerario) {
55
- if (scerario.type === 'scenario') {
56
- this._addTestPromises.push(this.addBddScenario(scerario));
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
57
7
  }
58
- }
59
-
60
- async addTest(test) {
61
- if (!this.client) return;
62
-
63
- const { title, _duration: duration, state, error, output } = test;
64
-
65
- const testId = getTestomatIdFromTestTitle(title);
66
-
67
- const screenshotEndpoint = '/session/:sessionId/screenshot';
68
- const screenshotsBuffers = output
69
- .filter(el => el.endpoint === screenshotEndpoint && el.result && el.result.value)
70
- .map(el => Buffer.from(el.result.value, 'base64'));
71
-
72
- await this.client.addTestRun(state, {
73
- rid: test.uid,
74
- manuallyAttachedArtifacts: test.artifacts,
75
- error,
76
- logs: test.logs,
77
- meta: test.meta,
78
- title,
79
- test_id: testId,
80
- time: duration,
81
- filesBuffers: screenshotsBuffers,
82
- });
83
- }
84
-
85
- /**
86
- * @param {import('../../types').WebdriverIOScenario} scenario
87
- */
88
- addBddScenario(scenario) {
89
- if (!this.client) return;
90
-
91
- const { title, _duration: duration } = scenario;
92
-
93
- const testId = getTestomatIdFromTestTitle(title || scenario.tags.map(tag => tag.name).join(' '));
94
-
95
- let scenarioState = scenario.tests.every(test => test.state === 'passed') ? 'passed' : 'failed';
96
- if (scenario.tests.every(test => test.state === 'skipped')) {
97
- scenarioState = 'skipped';
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const reporter_1 = __importStar(require("@wdio/reporter"));
40
+ const client_js_1 = __importDefault(require("../client.js"));
41
+ const utils_js_1 = require("../utils/utils.js");
42
+ const index_js_1 = require("../services/index.js");
43
+ const constants_js_1 = require("../constants.js");
44
+ class WebdriverReporter extends reporter_1.default {
45
+ constructor(options) {
46
+ super(options);
47
+ this.client = new client_js_1.default({ apiKey: options?.apiKey });
48
+ options = Object.assign(options, { stdout: true });
49
+ this._addTestPromises = [];
50
+ this._isSynchronising = false;
51
+ // NOTE: new functionality; may break everything
52
+ this.client.createRun();
53
+ }
54
+ get isSynchronised() {
55
+ return this._isSynchronising === false;
56
+ }
57
+ /**
58
+ *
59
+ * @param {RunnerStats} runData
60
+ */
61
+ async onRunnerEnd(runData) {
62
+ this._isSynchronising = true;
63
+ await Promise.all(this._addTestPromises);
64
+ this._isSynchronising = false;
65
+ // NOTE: new functionality; may break everything
66
+ // also this may require additional status mapping
67
+ await this.client.updateRunStatus(runData.failures ? 'failed' : 'passed');
68
+ }
69
+ onRunnerStart() {
70
+ // clear dir with artifacts/logs
71
+ //
72
+ utils_js_1.fileSystem.clearDir(constants_js_1.TESTOMAT_TMP_STORAGE_DIR);
73
+ }
74
+ onTestStart(test) {
75
+ index_js_1.services.setContext(test.fullTitle);
76
+ }
77
+ onTestEnd(test) {
78
+ test.suite = test.parent;
79
+ const logs = getTestLogs(test.fullTitle);
80
+ // TODO: FIX: artifacts for some reason leads to empty report on Testomat.io
81
+ // const artifacts = services.artifacts.get(test.fullTitle);
82
+ // const keyValues = services.keyValues.get(test.fullTitle);
83
+ test.logs = logs;
84
+ // test.artifacts = artifacts;
85
+ // test.meta = keyValues;
86
+ this._addTestPromises.push(this.addTest(test));
87
+ }
88
+ // wdio-cucumber does not trigger onTestEnd hook, thus, using this one
89
+ onSuiteEnd(scerario) {
90
+ if (scerario.type === 'scenario') {
91
+ this._addTestPromises.push(this.addBddScenario(scerario));
92
+ }
93
+ }
94
+ async addTest(test) {
95
+ if (!this.client)
96
+ return;
97
+ const { title, _duration: duration, state, error, output } = test;
98
+ const testId = (0, utils_js_1.getTestomatIdFromTestTitle)(title);
99
+ const screenshotEndpoint = '/session/:sessionId/screenshot';
100
+ const screenshotsBuffers = output
101
+ .filter(el => el.endpoint === screenshotEndpoint && el.result && el.result.value)
102
+ .map(el => Buffer.from(el.result.value, 'base64'));
103
+ await this.client.addTestRun(state, {
104
+ rid: test.uid || '',
105
+ manuallyAttachedArtifacts: test.artifacts,
106
+ error,
107
+ logs: test.logs,
108
+ meta: test.meta,
109
+ title,
110
+ test_id: testId,
111
+ time: duration,
112
+ filesBuffers: screenshotsBuffers,
113
+ });
114
+ }
115
+ /**
116
+ * @param {import('../../types/types.js').WebdriverIOScenario} scenario
117
+ */
118
+ addBddScenario(scenario) {
119
+ if (!this.client)
120
+ return;
121
+ const { title, _duration: duration } = scenario;
122
+ const testId = (0, utils_js_1.getTestomatIdFromTestTitle)(title || scenario.tags.map(tag => tag.name).join(' '));
123
+ let scenarioState = scenario.tests.every(test => test.state === 'passed') ? 'passed' : 'failed';
124
+ if (scenario.tests.every(test => test.state === 'skipped')) {
125
+ scenarioState = 'skipped';
126
+ }
127
+ const errors = scenario.tests
128
+ .filter(test => test.state === 'failed')
129
+ .map(test => test.error?.stack)
130
+ .filter(Boolean);
131
+ const error = errors.join('\n');
132
+ const tags = scenario.tags.map(tag => tag.name);
133
+ return this.client.addTestRun(scenarioState, {
134
+ error: error ? Error(error) : null,
135
+ title,
136
+ test_id: testId,
137
+ time: duration,
138
+ tags,
139
+ file: scenario.file,
140
+ // filesBuffers: screenshotsBuffers,
141
+ });
98
142
  }
99
- const errors = scenario.tests
100
- .filter(test => test.state === 'failed')
101
- .map(test => test.error?.stack)
102
- .filter(Boolean);
103
- const error = errors.join('\n');
104
-
105
- const tags = scenario.tags.map(tag => tag.name);
106
-
107
- return this.client.addTestRun(scenarioState, {
108
- rid: scenario.uid,
109
- error: error ? Error(error) : null,
110
- title,
111
- test_id: testId,
112
- time: duration,
113
- tags,
114
- file: scenario.file,
115
- // filesBuffers: screenshotsBuffers,
116
- });
117
- }
118
143
  }
119
-
120
144
  /**
121
145
  *
122
146
  * @param {*} fullTestTitle
123
147
  * @returns string
124
148
  */
125
149
  function getTestLogs(fullTestTitle) {
126
- const logsArr = services.logger.getLogs(fullTestTitle);
127
- // remove duplicates (for some reason, logs are duplicated several times)
128
- const logs = logsArr ? Array.from(new Set(logsArr)).join('\n').trim() : '';
129
- return logs;
150
+ const logsArr = index_js_1.services.logger.getLogs(fullTestTitle);
151
+ // remove duplicates (for some reason, logs are duplicated several times)
152
+ const logs = logsArr ? Array.from(new Set(logsArr)).join('\n').trim() : '';
153
+ return logs;
130
154
  }
131
-
132
155
  module.exports = WebdriverReporter;
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};