@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.
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
@@ -0,0 +1 @@
1
+ export const config: NodeJS.ProcessEnv;
package/lib/config.js CHANGED
@@ -1,34 +1,29 @@
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.config = void 0;
1
7
  // This file is used to read environment variables from .env file
2
-
3
- // require('dotenv').config({ path: process.env.TESTOMATIO_ENV_FILE_PATH });
4
-
5
- const debug = require('debug')('@testomatio/reporter:config');
6
-
8
+ const debug_1 = __importDefault(require("debug"));
9
+ const debug = (0, debug_1.default)('@testomatio/reporter:config');
7
10
  /* for possibility to use multiple env files (reading different paths)
8
- const dotenv = require('dotenv');
9
11
  const envFileVars = dotenv.config({ path: '.env' }).parsed; */
10
-
11
- if (process.env.TESTOMATIO_API_KEY) {
12
- process.env.TESTOMATIO = process.env.TESTOMATIO_API_KEY;
12
+ if (process.env.TESTOMATIO_API_KEY && !process.env.TESTOMATIO) {
13
+ process.env.TESTOMATIO = process.env.TESTOMATIO_API_KEY;
13
14
  }
14
- if (process.env.TESTOMATIO_TOKEN) {
15
- process.env.TESTOMATIO = process.env.TESTOMATIO_TOKEN;
15
+ if (process.env.TESTOMATIO_TOKEN && !process.env.TESTOMATIO) {
16
+ process.env.TESTOMATIO = process.env.TESTOMATIO_TOKEN;
16
17
  }
17
-
18
18
  if (process.env.TESTOMATIO === 'undefined')
19
- console.error('TESTOMATIO is "undefined". Something went wrong. Contact dev team.');
20
-
19
+ console.error('TESTOMATIO is "undefined". Something went wrong. Contact dev team.');
21
20
  // select only TESTOMATIO related variables (only to print them in debug)
22
- const testomatioEnvVars =
23
- Object.keys(process.env)
21
+ const testomatioEnvVars = Object.keys(process.env)
24
22
  .filter(key => key.startsWith('TESTOMATIO') || key.startsWith('S3_'))
25
23
  .reduce((obj, key) => {
26
- obj[key] = process.env[key];
27
- return obj;
28
- }, {}) || {};
24
+ obj[key] = process.env[key];
25
+ return obj;
26
+ }, {}) || {};
29
27
  debug('TESTOMATIO variables:', testomatioEnvVars);
30
-
31
28
  // includes variables from .env file and process.env
32
- const config = process.env;
33
-
34
- module.exports = config;
29
+ exports.config = process.env;
@@ -0,0 +1,25 @@
1
+ export const APP_PREFIX: string;
2
+ export const TESTOMAT_TMP_STORAGE_DIR: string;
3
+ export const CSV_HEADERS: {
4
+ id: string;
5
+ title: string;
6
+ }[];
7
+ export namespace STATUS {
8
+ let PASSED: string;
9
+ let FAILED: string;
10
+ let SKIPPED: string;
11
+ let FINISHED: string;
12
+ }
13
+ export namespace HTML_REPORT {
14
+ let FOLDER: string;
15
+ let REPORT_DEFAULT_NAME: string;
16
+ let TEMPLATE_NAME: string;
17
+ }
18
+ export const AXIOS_TIMEOUT: number;
19
+ export const testomatLogoURL: "https://avatars.githubusercontent.com/u/59105116?s=36&v=4";
20
+ export namespace REPORTER_REQUEST_RETRIES {
21
+ let retryTimeout: number;
22
+ let retriesPerRequest: number;
23
+ let maxTotalRetries: number;
24
+ let withinTimeSeconds: number;
25
+ }
package/lib/constants.js CHANGED
@@ -1,60 +1,66 @@
1
- const chalk = require('chalk');
2
- const os = require('os');
3
- const path = require('path');
4
-
5
- const APP_PREFIX = chalk.gray('[TESTOMATIO]');
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.REPORTER_REQUEST_RETRIES = exports.testomatLogoURL = exports.AXIOS_TIMEOUT = exports.HTML_REPORT = exports.STATUS = exports.CSV_HEADERS = exports.TESTOMAT_TMP_STORAGE_DIR = exports.APP_PREFIX = void 0;
7
+ const picocolors_1 = __importDefault(require("picocolors"));
8
+ const os_1 = __importDefault(require("os"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const APP_PREFIX = picocolors_1.default.gray('[TESTOMATIO]');
11
+ exports.APP_PREFIX = APP_PREFIX;
6
12
  const TESTOMATIO_REQUEST_TIMEOUT = parseInt(process.env.TESTOMATIO_REQUEST_TIMEOUT, 10);
7
13
  if (TESTOMATIO_REQUEST_TIMEOUT) {
8
- console.log(`${APP_PREFIX} Request timeout is set to ${TESTOMATIO_REQUEST_TIMEOUT / 1000}s`);
14
+ console.log(`${APP_PREFIX} Request timeout is set to ${TESTOMATIO_REQUEST_TIMEOUT / 1000}s`);
9
15
  }
10
16
  const AXIOS_TIMEOUT = TESTOMATIO_REQUEST_TIMEOUT || 20 * 1000;
11
-
12
- const TESTOMAT_TMP_STORAGE_DIR = path.join(os.tmpdir(), 'testomatio_tmp');
13
-
17
+ exports.AXIOS_TIMEOUT = AXIOS_TIMEOUT;
18
+ const TESTOMAT_TMP_STORAGE_DIR = path_1.default.join(os_1.default.tmpdir(), 'testomatio_tmp');
19
+ exports.TESTOMAT_TMP_STORAGE_DIR = TESTOMAT_TMP_STORAGE_DIR;
14
20
  const CSV_HEADERS = [
15
- { id: 'suite_title', title: 'Suite_title' },
16
- { id: 'title', title: 'Title' },
17
- { id: 'status', title: 'Status' },
18
- { id: 'message', title: 'Message' },
19
- { id: 'stack', title: 'Stack' },
21
+ { id: 'suite_title', title: 'Suite_title' },
22
+ { id: 'title', title: 'Title' },
23
+ { id: 'status', title: 'Status' },
24
+ { id: 'message', title: 'Message' },
25
+ { id: 'stack', title: 'Stack' },
20
26
  ];
21
-
27
+ exports.CSV_HEADERS = CSV_HEADERS;
22
28
  const STATUS = {
23
- PASSED: 'passed',
24
- FAILED: 'failed',
25
- SKIPPED: 'skipped',
26
- FINISHED: 'finished',
29
+ PASSED: 'passed',
30
+ FAILED: 'failed',
31
+ SKIPPED: 'skipped',
32
+ FINISHED: 'finished',
27
33
  };
34
+ exports.STATUS = STATUS;
28
35
  // html pipe var
29
36
  const HTML_REPORT = {
30
- FOLDER: 'html-report',
31
- REPORT_DEFAULT_NAME: 'testomatio-report.html',
32
- TEMPLATE_NAME: 'testomatio.hbs',
37
+ FOLDER: 'html-report',
38
+ REPORT_DEFAULT_NAME: 'testomatio-report.html',
39
+ TEMPLATE_NAME: 'testomatio.hbs',
33
40
  };
34
-
41
+ exports.HTML_REPORT = HTML_REPORT;
35
42
  const testomatLogoURL = 'https://avatars.githubusercontent.com/u/59105116?s=36&v=4';
36
-
43
+ exports.testomatLogoURL = testomatLogoURL;
37
44
  const REPORTER_REQUEST_RETRIES = {
38
- retryTimeout: 5 * 1000, // sum = 5sec
39
- retriesPerRequest: 2,
40
- maxTotalRetries: Number(process.env.TESTOMATIO_MAX_REQUEST_FAILURES_COUNT) || 10,
41
- withinTimeSeconds: Number(process.env.TESTOMATIO_MAX_REQUEST_RETRIES_WITHIN_TIME_SECONDS) || 60,
45
+ retryTimeout: 5 * 1000, // sum = 5sec
46
+ retriesPerRequest: 2,
47
+ maxTotalRetries: Number(process.env.TESTOMATIO_MAX_REQUEST_FAILURES_COUNT) || 10,
48
+ withinTimeSeconds: Number(process.env.TESTOMATIO_MAX_REQUEST_RETRIES_WITHIN_TIME_SECONDS) || 60,
42
49
  };
50
+ exports.REPORTER_REQUEST_RETRIES = REPORTER_REQUEST_RETRIES;
43
51
 
44
- const RunStatus = {
45
- Passed: 'passed',
46
- Failed: 'failed',
47
- Finished: 'finished',
48
- };
52
+ module.exports.APP_PREFIX = APP_PREFIX;
49
53
 
50
- module.exports = {
51
- APP_PREFIX,
52
- TESTOMAT_TMP_STORAGE_DIR,
53
- CSV_HEADERS,
54
- STATUS,
55
- HTML_REPORT,
56
- AXIOS_TIMEOUT,
57
- testomatLogoURL,
58
- REPORTER_REQUEST_RETRIES,
59
- RunStatus,
60
- };
54
+ module.exports.AXIOS_TIMEOUT = AXIOS_TIMEOUT;
55
+
56
+ module.exports.TESTOMAT_TMP_STORAGE_DIR = TESTOMAT_TMP_STORAGE_DIR;
57
+
58
+ module.exports.CSV_HEADERS = CSV_HEADERS;
59
+
60
+ module.exports.STATUS = STATUS;
61
+
62
+ module.exports.HTML_REPORT = HTML_REPORT;
63
+
64
+ module.exports.testomatLogoURL = testomatLogoURL;
65
+
66
+ module.exports.REPORTER_REQUEST_RETRIES = REPORTER_REQUEST_RETRIES;
@@ -0,0 +1,34 @@
1
+ export const dataStorage: DataStorage;
2
+ declare class DataStorage {
3
+ static "__#12@#instance": any;
4
+ /**
5
+ *
6
+ * @returns {DataStorage}
7
+ */
8
+ static getInstance(): DataStorage;
9
+ context: any;
10
+ setContext(context: any): void;
11
+ isFileStorage: boolean;
12
+ /**
13
+ * Puts any data to storage (file or global variable).
14
+ * If file: stores data as text, if global variable – stores as array of data.
15
+ * @param {'log' | 'artifact' | 'keyvalue'} dataType
16
+ * @param {*} data anything you want to store (string, object, array, etc)
17
+ * @param {*} context could be testId or any context (test name, suite name, including their IDs etc)
18
+ * suite name + test name is used by default
19
+ * @returns
20
+ */
21
+ putData(dataType: "log" | "artifact" | "keyvalue", data: any, context?: any): void;
22
+ /**
23
+ * Returns data, stored for specific test/context (or data which was stored without test id specified).
24
+ * This method will get data from global variable and/or from from file (previosly saved with put method).
25
+ *
26
+ * @param {'log' | 'artifact' | 'keyvalue'} dataType
27
+ * @param {string} context
28
+ * @returns {any []} array of data (any type), null (if no data found for context) or string (if data type is log)
29
+ */
30
+ getData(dataType: "log" | "artifact" | "keyvalue", context: string): any[];
31
+ #private;
32
+ }
33
+ export function stringToMD5Hash(str: any): string;
34
+ export {};
@@ -1,203 +1,231 @@
1
- const debug = require('debug')('@testomatio/reporter:storage');
2
- const fs = require('fs');
3
- const path = require('path');
4
- const os = require('os');
5
- const { join } = require('path');
6
- const { TESTOMAT_TMP_STORAGE_DIR } = require('./constants');
7
- const { fileSystem, testRunnerHelper } = require('./utils/utils');
8
- const crypto = require('crypto');
9
-
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]; } };
7
+ }
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
+ exports.dataStorage = void 0;
40
+ exports.stringToMD5Hash = stringToMD5Hash;
41
+ const debug_1 = __importDefault(require("debug"));
42
+ const fs_1 = __importDefault(require("fs"));
43
+ const path_1 = __importStar(require("path"));
44
+ const os_1 = __importDefault(require("os"));
45
+ const constants_js_1 = require("./constants.js");
46
+ const utils_js_1 = require("./utils/utils.js");
47
+ const crypto_1 = __importDefault(require("crypto"));
48
+ const debug = (0, debug_1.default)('@testomatio/reporter:storage');
10
49
  class DataStorage {
11
- static #instance;
12
-
13
- context;
14
-
15
- /**
16
- *
17
- * @returns {DataStorage}
18
- */
19
- static getInstance() {
20
- if (!this.#instance) {
21
- this.#instance = new DataStorage();
50
+ static #instance;
51
+ context;
52
+ /**
53
+ *
54
+ * @returns {DataStorage}
55
+ */
56
+ static getInstance() {
57
+ if (!this.#instance) {
58
+ this.#instance = new DataStorage();
59
+ }
60
+ return this.#instance;
22
61
  }
23
- return this.#instance;
24
- }
25
-
26
- setContext(context) {
27
- this.context = context;
28
- }
29
-
30
- /**
31
- * Creates data storage instance as singleton
32
- * Stores data to global variable or to file depending on what is applicable for current test runner (adapter)
33
- * Recommend to use composition while using this class (instead of inheritance).
34
- * ! Also the class which will use data storage should be singleton (to avoid data loss).
35
- */
36
- constructor() {
37
- // some frameworks use global variable to store data, some use file storage
38
- this.isFileStorage = true;
39
- }
40
-
41
- /**
42
- * Puts any data to storage (file or global variable).
43
- * If file: stores data as text, if global variable – stores as array of data.
44
- * @param {'log' | 'artifact' | 'keyvalue'} dataType
45
- * @param {*} data anything you want to store (string, object, array, etc)
46
- * @param {*} context could be testId or any context (test name, suite name, including their IDs etc)
47
- * suite name + test name is used by default
48
- * @returns
49
- */
50
- putData(dataType, data, context = null) {
51
- if (!dataType || !data) return;
52
-
53
- context = context || this.context || testRunnerHelper.getNameOfCurrentlyRunningTest();
54
- if (!context) {
55
- // debug(`No context provided for "${dataType}" data:`, data);
56
- return;
62
+ setContext(context) {
63
+ this.context = context;
57
64
  }
58
- const contextHash = stringToMD5Hash(context);
59
-
60
- if (this.isFileStorage) {
61
- const dataDirPath = path.join(TESTOMAT_TMP_STORAGE_DIR, dataType);
62
- fileSystem.createDir(dataDirPath);
63
- this.#putDataToFile(dataType, data, contextHash);
64
- } else {
65
- this.#putDataToGlobalVar(dataType, data, contextHash);
65
+ /**
66
+ * Creates data storage instance as singleton
67
+ * Stores data to global variable or to file depending on what is applicable for current test runner (adapter)
68
+ * Recommend to use composition while using this class (instead of inheritance).
69
+ * ! Also the class which will use data storage should be singleton (to avoid data loss).
70
+ */
71
+ constructor() {
72
+ // some frameworks use global variable to store data, some use file storage
73
+ this.isFileStorage = true;
66
74
  }
67
- }
68
-
69
- /**
70
- * Returns data, stored for specific test/context (or data which was stored without test id specified).
71
- * This method will get data from global variable and/or from from file (previosly saved with put method).
72
- *
73
- * @param {'log' | 'artifact' | 'keyvalue'} dataType
74
- * @param {string} context
75
- * @returns {any []} array of data (any type), null (if no data found for context) or string (if data type is log)
76
- */
77
- getData(dataType, context) {
78
- // TODO: think if it could be useful
79
- // context = context || this.context || testRunnerHelper.getNameOfCurrentlyRunningTest();
80
-
81
- if (!context) {
82
- debug(`Trying to get "${dataType}" data without context`);
83
- return null;
75
+ /**
76
+ * Puts any data to storage (file or global variable).
77
+ * If file: stores data as text, if global variable – stores as array of data.
78
+ * @param {'log' | 'artifact' | 'keyvalue'} dataType
79
+ * @param {*} data anything you want to store (string, object, array, etc)
80
+ * @param {*} context could be testId or any context (test name, suite name, including their IDs etc)
81
+ * suite name + test name is used by default
82
+ * @returns
83
+ */
84
+ putData(dataType, data, context = null) {
85
+ if (!dataType || !data)
86
+ return;
87
+ context = context || this.context || utils_js_1.testRunnerHelper.getNameOfCurrentlyRunningTest();
88
+ if (!context) {
89
+ // debug(`No context provided for "${dataType}" data:`, data);
90
+ return;
91
+ }
92
+ const contextHash = stringToMD5Hash(context);
93
+ if (this.isFileStorage) {
94
+ const dataDirPath = path_1.default.join(constants_js_1.TESTOMAT_TMP_STORAGE_DIR, dataType);
95
+ utils_js_1.fileSystem.createDir(dataDirPath);
96
+ this.#putDataToFile(dataType, data, contextHash);
97
+ }
98
+ else {
99
+ this.#putDataToGlobalVar(dataType, data, contextHash);
100
+ }
84
101
  }
85
-
86
- const contextHash = stringToMD5Hash(context);
87
-
88
- let testDataFromFile = [];
89
- let testDataFromGlobalVar = [];
90
-
91
- if (global?.testomatioDataStore) {
92
- testDataFromGlobalVar = this.#getDataFromGlobalVar(dataType, contextHash);
93
- if (testDataFromGlobalVar) {
94
- if (testDataFromGlobalVar.length) return testDataFromGlobalVar;
95
- }
96
- // don't return nothing if no data in global variable
102
+ /**
103
+ * Returns data, stored for specific test/context (or data which was stored without test id specified).
104
+ * This method will get data from global variable and/or from from file (previosly saved with put method).
105
+ *
106
+ * @param {'log' | 'artifact' | 'keyvalue'} dataType
107
+ * @param {string} context
108
+ * @returns {any []} array of data (any type), null (if no data found for context) or string (if data type is log)
109
+ */
110
+ getData(dataType, context) {
111
+ // TODO: think if it could be useful
112
+ // context = context || this.context || testRunnerHelper.getNameOfCurrentlyRunningTest();
113
+ if (!context) {
114
+ debug(`Trying to get "${dataType}" data without context`);
115
+ return null;
116
+ }
117
+ const contextHash = stringToMD5Hash(context);
118
+ let testDataFromFile = [];
119
+ let testDataFromGlobalVar = [];
120
+ if (global?.testomatioDataStore) {
121
+ testDataFromGlobalVar = this.#getDataFromGlobalVar(dataType, contextHash);
122
+ if (testDataFromGlobalVar) {
123
+ if (testDataFromGlobalVar.length)
124
+ return testDataFromGlobalVar;
125
+ }
126
+ // don't return nothing if no data in global variable
127
+ }
128
+ testDataFromFile = this.#getDataFromFile(dataType, contextHash);
129
+ if (testDataFromFile.length) {
130
+ return testDataFromFile;
131
+ }
132
+ // debug(`No "${dataType}" data for context "${contextHash}" in both file and global variable`);
133
+ // in case no data found for context
134
+ return null;
97
135
  }
98
-
99
- testDataFromFile = this.#getDataFromFile(dataType, contextHash);
100
-
101
- if (testDataFromFile.length) {
102
- return testDataFromFile;
136
+ /**
137
+ * @param {'log' | 'artifact' | 'keyvalue'} dataType
138
+ * @param {string} context
139
+ * @returns aray of data (any type)
140
+ */
141
+ #getDataFromGlobalVar(dataType, context) {
142
+ try {
143
+ if (global?.testomatioDataStore[dataType]) {
144
+ const testData = global.testomatioDataStore[dataType][context];
145
+ if (testData)
146
+ debug(`"${dataType}" data for constext "${context}":`, testData.join(', '));
147
+ return testData || [];
148
+ }
149
+ // debug(`No ${this.dataType} data for context ${context} in <global> storage`);
150
+ return [];
151
+ }
152
+ catch (e) {
153
+ // there could be no data, ignore
154
+ }
103
155
  }
104
- // debug(`No "${dataType}" data for context "${contextHash}" in both file and global variable`);
105
-
106
- // in case no data found for context
107
- return null;
108
- }
109
-
110
- /**
111
- * @param {'log' | 'artifact' | 'keyvalue'} dataType
112
- * @param {string} context
113
- * @returns aray of data (any type)
114
- */
115
- #getDataFromGlobalVar(dataType, context) {
116
- try {
117
- if (global?.testomatioDataStore[dataType]) {
118
- const testData = global.testomatioDataStore[dataType][context];
119
- if (testData) debug(`"${dataType}" data for constext "${context}":`, testData.join(', '));
120
- return testData || [];
121
- }
122
- // debug(`No ${this.dataType} data for context ${context} in <global> storage`);
123
- return [];
124
- } catch (e) {
125
- // there could be no data, ignore
156
+ /**
157
+ * @param {'log' | 'artifact' | 'keyvalue'} dataType
158
+ * @param {*} context
159
+ * @returns array of data (any type)
160
+ */
161
+ #getDataFromFile(dataType, context) {
162
+ const dataDirPath = path_1.default.join(constants_js_1.TESTOMAT_TMP_STORAGE_DIR, dataType);
163
+ try {
164
+ const filepath = (0, path_1.join)(dataDirPath, `${dataType}_${context}`);
165
+ if (fs_1.default.existsSync(filepath)) {
166
+ const testDataAsText = fs_1.default.readFileSync(filepath, 'utf-8');
167
+ if (testDataAsText)
168
+ debug(`"${dataType}" data for context "${context}":`, testDataAsText);
169
+ const testDataArr = testDataAsText?.split(os_1.default.EOL) || [];
170
+ return testDataArr;
171
+ }
172
+ // debug(`No ${this.dataType} data for ${context} in <file> storage`);
173
+ return [];
174
+ }
175
+ catch (e) {
176
+ // there could be no data, ignore
177
+ }
178
+ return [];
126
179
  }
127
- }
128
-
129
- /**
130
- * @param {'log' | 'artifact' | 'keyvalue'} dataType
131
- * @param {*} context
132
- * @returns array of data (any type)
133
- */
134
- #getDataFromFile(dataType, context) {
135
- const dataDirPath = path.join(TESTOMAT_TMP_STORAGE_DIR, dataType);
136
- try {
137
- const filepath = join(dataDirPath, `${dataType}_${context}`);
138
- if (fs.existsSync(filepath)) {
139
- const testDataAsText = fs.readFileSync(filepath, 'utf-8');
140
- if (testDataAsText) debug(`"${dataType}" data for context "${context}":`, testDataAsText);
141
- const testDataArr = testDataAsText?.split(os.EOL) || [];
142
- return testDataArr;
143
- }
144
- // debug(`No ${this.dataType} data for ${context} in <file> storage`);
145
- return [];
146
- } catch (e) {
147
- // there could be no data, ignore
180
+ /**
181
+ * Puts data to global variable. Unlike the file storage, stores data in array (file storage just append as string).
182
+ * @param {'log' | 'artifact' | 'keyvalue'} dataType
183
+ * @param {*} data
184
+ * @param {*} context
185
+ */
186
+ #putDataToGlobalVar(dataType, data, context) {
187
+ debug('Saving data to global variable for ', context, ':', data);
188
+ if (!global.testomatioDataStore)
189
+ global.testomatioDataStore = {};
190
+ if (!global.testomatioDataStore?.[dataType])
191
+ global.testomatioDataStore[dataType] = {};
192
+ if (!global.testomatioDataStore?.[dataType][context])
193
+ global.testomatioDataStore[dataType][context] = [];
194
+ global.testomatioDataStore[dataType][context].push(data);
148
195
  }
149
- return [];
150
- }
151
-
152
- /**
153
- * Puts data to global variable. Unlike the file storage, stores data in array (file storage just append as string).
154
- * @param {'log' | 'artifact' | 'keyvalue'} dataType
155
- * @param {*} data
156
- * @param {*} context
157
- */
158
- #putDataToGlobalVar(dataType, data, context) {
159
- debug('Saving data to global variable for ', context, ':', data);
160
- if (!global.testomatioDataStore) global.testomatioDataStore = {};
161
- if (!global.testomatioDataStore?.[dataType]) global.testomatioDataStore[dataType] = {};
162
-
163
- if (!global.testomatioDataStore?.[dataType][context]) global.testomatioDataStore[dataType][context] = [];
164
- global.testomatioDataStore[dataType][context].push(data);
165
- }
166
-
167
- /**
168
- * Puts data to file. Unlike the global variable storage, stores data as string
169
- * @param {'log' | 'artifact' | 'keyvalue'} dataType
170
- * @param {*} data
171
- * @param {string} context
172
- * @returns
173
- */
174
- #putDataToFile(dataType, data, context) {
175
- const dataDirPath = path.join(TESTOMAT_TMP_STORAGE_DIR, dataType);
176
- if (typeof data !== 'string') data = JSON.stringify(data);
177
- const filename = `${dataType}_${context}`;
178
- const filepath = join(dataDirPath, filename);
179
- if (!fs.existsSync(dataDirPath)) fileSystem.createDir(dataDirPath);
180
- debug(`Saving data to file for context "${context}" to ${filepath}. Data: ${JSON.stringify(data)}`);
181
-
182
- // append new line if file already exists (in this case its definitely includes some data)
183
- if (fs.existsSync(filepath)) {
184
- fs.appendFileSync(filepath, os.EOL + data, 'utf-8');
185
- } else {
186
- fs.writeFileSync(filepath, data, 'utf-8');
196
+ /**
197
+ * Puts data to file. Unlike the global variable storage, stores data as string
198
+ * @param {'log' | 'artifact' | 'keyvalue'} dataType
199
+ * @param {*} data
200
+ * @param {string} context
201
+ * @returns
202
+ */
203
+ #putDataToFile(dataType, data, context) {
204
+ const dataDirPath = path_1.default.join(constants_js_1.TESTOMAT_TMP_STORAGE_DIR, dataType);
205
+ if (typeof data !== 'string')
206
+ data = JSON.stringify(data);
207
+ const filename = `${dataType}_${context}`;
208
+ const filepath = (0, path_1.join)(dataDirPath, filename);
209
+ if (!fs_1.default.existsSync(dataDirPath))
210
+ utils_js_1.fileSystem.createDir(dataDirPath);
211
+ debug(`Saving data to file for context "${context}" to ${filepath}. Data: ${JSON.stringify(data)}`);
212
+ // append new line if file already exists (in this case its definitely includes some data)
213
+ if (fs_1.default.existsSync(filepath)) {
214
+ fs_1.default.appendFileSync(filepath, os_1.default.EOL + data, 'utf-8');
215
+ }
216
+ else {
217
+ fs_1.default.writeFileSync(filepath, data, 'utf-8');
218
+ }
187
219
  }
188
- }
189
220
  }
190
-
191
221
  function stringToMD5Hash(str) {
192
- const md5 = crypto.createHash('md5');
193
- md5.update(str);
194
- const hash = md5.digest('hex');
195
-
196
- return hash;
222
+ const md5 = crypto_1.default.createHash('md5');
223
+ md5.update(str);
224
+ const hash = md5.digest('hex');
225
+ return hash;
197
226
  }
198
-
199
- module.exports.dataStorage = DataStorage.getInstance();
200
- module.exports.stringToMD5Hash = stringToMD5Hash;
201
-
227
+ exports.dataStorage = DataStorage.getInstance();
202
228
  // TODO: consider using fs promises instead of writeSync/appendFileSync to
203
229
  // prevent blocking and improve performance (probably queue usage will be required)
230
+
231
+ module.exports.stringToMD5Hash = stringToMD5Hash;