@testomatio/reporter 2.0.1-beta.4 → 2.0.1-beta.5-timestamp
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/lib/adapter/codecept.js +335 -293
- package/lib/adapter/cucumber/current.js +203 -195
- package/lib/adapter/cucumber/legacy.js +155 -130
- package/lib/adapter/cucumber.js +16 -5
- package/lib/adapter/cypress-plugin/index.js +105 -91
- package/lib/adapter/jasmine.js +53 -54
- package/lib/adapter/jest.js +99 -97
- package/lib/adapter/mocha.js +141 -112
- package/lib/adapter/playwright.js +231 -199
- package/lib/adapter/vitest.js +149 -150
- package/lib/adapter/webdriver.js +121 -144
- package/lib/bin/cli.js +211 -229
- package/lib/bin/reportXml.js +52 -51
- package/lib/bin/startTest.js +95 -83
- package/lib/bin/uploadArtifacts.js +61 -56
- package/lib/client.js +465 -424
- package/lib/config.js +23 -18
- package/lib/constants.js +44 -50
- package/lib/data-storage.js +188 -216
- package/lib/junit-adapter/adapter.js +20 -17
- package/lib/junit-adapter/csharp.js +14 -28
- package/lib/junit-adapter/index.js +25 -27
- package/lib/junit-adapter/java.js +53 -41
- package/lib/junit-adapter/javascript.js +27 -30
- package/lib/junit-adapter/python.js +37 -38
- package/lib/junit-adapter/ruby.js +8 -11
- package/lib/output.js +52 -44
- package/lib/pipe/bitbucket.js +230 -223
- package/lib/pipe/csv.js +126 -113
- package/lib/pipe/debug.js +99 -118
- package/lib/pipe/github.js +213 -218
- package/lib/pipe/gitlab.js +206 -183
- package/lib/pipe/html.js +321 -258
- package/lib/pipe/index.js +66 -94
- package/lib/pipe/testomatio.js +474 -429
- package/lib/reporter-functions.js +26 -28
- package/lib/reporter.js +29 -34
- package/lib/services/artifacts.js +51 -55
- package/lib/services/index.js +12 -14
- package/lib/services/key-values.js +53 -56
- package/lib/services/logger.js +245 -226
- package/lib/template/testomatio.hbs +1366 -1026
- package/lib/uploader.js +364 -295
- package/lib/utils/pipe_utils.js +85 -89
- package/lib/utils/utils.js +307 -398
- package/lib/xmlReader.js +532 -525
- package/package.json +21 -64
- package/lib/adapter/codecept.d.ts +0 -2
- package/lib/adapter/cucumber/current.d.ts +0 -14
- package/lib/adapter/cucumber/legacy.d.ts +0 -0
- package/lib/adapter/cucumber.d.ts +0 -2
- package/lib/adapter/cypress-plugin/index.d.ts +0 -2
- package/lib/adapter/jasmine.d.ts +0 -11
- package/lib/adapter/jest.d.ts +0 -13
- package/lib/adapter/mocha.d.ts +0 -2
- package/lib/adapter/nightwatch.d.ts +0 -4
- package/lib/adapter/nightwatch.js +0 -80
- package/lib/adapter/playwright.d.ts +0 -14
- package/lib/adapter/vitest.d.ts +0 -35
- package/lib/adapter/webdriver.d.ts +0 -24
- package/lib/bin/cli.d.ts +0 -2
- package/lib/bin/reportXml.d.ts +0 -2
- package/lib/bin/startTest.d.ts +0 -2
- package/lib/bin/uploadArtifacts.d.ts +0 -2
- package/lib/client.d.ts +0 -76
- package/lib/config.d.ts +0 -1
- package/lib/constants.d.ts +0 -25
- package/lib/data-storage.d.ts +0 -34
- package/lib/junit-adapter/adapter.d.ts +0 -9
- package/lib/junit-adapter/csharp.d.ts +0 -5
- package/lib/junit-adapter/index.d.ts +0 -3
- package/lib/junit-adapter/java.d.ts +0 -5
- package/lib/junit-adapter/javascript.d.ts +0 -4
- package/lib/junit-adapter/python.d.ts +0 -5
- package/lib/junit-adapter/ruby.d.ts +0 -4
- package/lib/output.d.ts +0 -11
- package/lib/package.json +0 -3
- package/lib/pipe/bitbucket.d.ts +0 -25
- package/lib/pipe/csv.d.ts +0 -47
- package/lib/pipe/debug.d.ts +0 -29
- package/lib/pipe/github.d.ts +0 -30
- package/lib/pipe/gitlab.d.ts +0 -25
- package/lib/pipe/html.d.ts +0 -35
- package/lib/pipe/index.d.ts +0 -1
- package/lib/pipe/testomatio.d.ts +0 -71
- package/lib/replay.d.ts +0 -31
- package/lib/replay.js +0 -237
- package/lib/reporter-functions.d.ts +0 -34
- package/lib/reporter.d.ts +0 -232
- package/lib/services/artifacts.d.ts +0 -33
- package/lib/services/index.d.ts +0 -9
- package/lib/services/key-values.d.ts +0 -27
- package/lib/services/logger.d.ts +0 -64
- package/lib/uploader.d.ts +0 -60
- package/lib/utils/pipe_utils.d.ts +0 -41
- package/lib/utils/utils.d.ts +0 -54
- package/lib/xmlReader.d.ts +0 -92
- package/src/adapter/codecept.js +0 -373
- package/src/adapter/cucumber/current.js +0 -228
- package/src/adapter/cucumber/legacy.js +0 -158
- package/src/adapter/cucumber.js +0 -4
- package/src/adapter/cypress-plugin/index.js +0 -110
- package/src/adapter/jasmine.js +0 -60
- package/src/adapter/jest.js +0 -107
- package/src/adapter/mocha.cjs +0 -2
- package/src/adapter/mocha.js +0 -156
- package/src/adapter/nightwatch.js +0 -88
- package/src/adapter/playwright.js +0 -254
- package/src/adapter/vitest.js +0 -183
- package/src/adapter/webdriver.js +0 -142
- package/src/bin/cli.js +0 -348
- package/src/bin/reportXml.js +0 -77
- package/src/bin/startTest.js +0 -124
- package/src/bin/uploadArtifacts.js +0 -91
- package/src/client.js +0 -508
- package/src/config.js +0 -30
- package/src/constants.js +0 -53
- package/src/data-storage.js +0 -204
- package/src/junit-adapter/adapter.js +0 -23
- package/src/junit-adapter/csharp.js +0 -28
- package/src/junit-adapter/index.js +0 -28
- package/src/junit-adapter/java.js +0 -58
- package/src/junit-adapter/javascript.js +0 -31
- package/src/junit-adapter/python.js +0 -42
- package/src/junit-adapter/ruby.js +0 -10
- package/src/output.js +0 -57
- package/src/pipe/bitbucket.js +0 -252
- package/src/pipe/csv.js +0 -140
- package/src/pipe/debug.js +0 -119
- package/src/pipe/github.js +0 -232
- package/src/pipe/gitlab.js +0 -247
- package/src/pipe/html.js +0 -373
- package/src/pipe/index.js +0 -71
- package/src/pipe/testomatio.js +0 -504
- package/src/replay.js +0 -245
- package/src/reporter-functions.js +0 -55
- package/src/reporter.cjs_decprecated +0 -21
- package/src/reporter.js +0 -33
- package/src/services/artifacts.js +0 -59
- package/src/services/index.js +0 -13
- package/src/services/key-values.js +0 -59
- package/src/services/logger.js +0 -315
- package/src/template/emptyData.svg +0 -23
- package/src/template/testomatio.hbs +0 -1081
- package/src/uploader.js +0 -376
- package/src/utils/pipe_utils.js +0 -119
- package/src/utils/utils.js +0 -416
- package/src/xmlReader.js +0 -614
package/lib/config.js
CHANGED
|
@@ -1,29 +1,34 @@
|
|
|
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;
|
|
7
1
|
// This file is used to read environment variables from .env file
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
|
|
3
|
+
// require('dotenv').config({ path: process.env.TESTOMATIO_ENV_FILE_PATH });
|
|
4
|
+
|
|
5
|
+
const debug = require('debug')('@testomatio/reporter:config');
|
|
6
|
+
|
|
10
7
|
/* for possibility to use multiple env files (reading different paths)
|
|
8
|
+
const dotenv = require('dotenv');
|
|
11
9
|
const envFileVars = dotenv.config({ path: '.env' }).parsed; */
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
|
|
11
|
+
if (process.env.TESTOMATIO_API_KEY) {
|
|
12
|
+
process.env.TESTOMATIO = process.env.TESTOMATIO_API_KEY;
|
|
14
13
|
}
|
|
15
|
-
if (process.env.TESTOMATIO_TOKEN
|
|
16
|
-
|
|
14
|
+
if (process.env.TESTOMATIO_TOKEN) {
|
|
15
|
+
process.env.TESTOMATIO = process.env.TESTOMATIO_TOKEN;
|
|
17
16
|
}
|
|
17
|
+
|
|
18
18
|
if (process.env.TESTOMATIO === 'undefined')
|
|
19
|
-
|
|
19
|
+
console.error('TESTOMATIO is "undefined". Something went wrong. Contact dev team.');
|
|
20
|
+
|
|
20
21
|
// select only TESTOMATIO related variables (only to print them in debug)
|
|
21
|
-
const testomatioEnvVars =
|
|
22
|
+
const testomatioEnvVars =
|
|
23
|
+
Object.keys(process.env)
|
|
22
24
|
.filter(key => key.startsWith('TESTOMATIO') || key.startsWith('S3_'))
|
|
23
25
|
.reduce((obj, key) => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}, {}) || {};
|
|
26
|
+
obj[key] = process.env[key];
|
|
27
|
+
return obj;
|
|
28
|
+
}, {}) || {};
|
|
27
29
|
debug('TESTOMATIO variables:', testomatioEnvVars);
|
|
30
|
+
|
|
28
31
|
// includes variables from .env file and process.env
|
|
29
|
-
|
|
32
|
+
const config = process.env;
|
|
33
|
+
|
|
34
|
+
module.exports = config;
|
package/lib/constants.js
CHANGED
|
@@ -1,66 +1,60 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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;
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const os = require('os');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const APP_PREFIX = chalk.gray('[TESTOMATIO]');
|
|
12
6
|
const TESTOMATIO_REQUEST_TIMEOUT = parseInt(process.env.TESTOMATIO_REQUEST_TIMEOUT, 10);
|
|
13
7
|
if (TESTOMATIO_REQUEST_TIMEOUT) {
|
|
14
|
-
|
|
8
|
+
console.log(`${APP_PREFIX} Request timeout is set to ${TESTOMATIO_REQUEST_TIMEOUT / 1000}s`);
|
|
15
9
|
}
|
|
16
10
|
const AXIOS_TIMEOUT = TESTOMATIO_REQUEST_TIMEOUT || 20 * 1000;
|
|
17
|
-
|
|
18
|
-
const TESTOMAT_TMP_STORAGE_DIR =
|
|
19
|
-
|
|
11
|
+
|
|
12
|
+
const TESTOMAT_TMP_STORAGE_DIR = path.join(os.tmpdir(), 'testomatio_tmp');
|
|
13
|
+
|
|
20
14
|
const CSV_HEADERS = [
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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' },
|
|
26
20
|
];
|
|
27
|
-
|
|
21
|
+
|
|
28
22
|
const STATUS = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
PASSED: 'passed',
|
|
24
|
+
FAILED: 'failed',
|
|
25
|
+
SKIPPED: 'skipped',
|
|
26
|
+
FINISHED: 'finished',
|
|
33
27
|
};
|
|
34
|
-
exports.STATUS = STATUS;
|
|
35
28
|
// html pipe var
|
|
36
29
|
const HTML_REPORT = {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
30
|
+
FOLDER: 'html-report',
|
|
31
|
+
REPORT_DEFAULT_NAME: 'testomatio-report.html',
|
|
32
|
+
TEMPLATE_NAME: 'testomatio.hbs',
|
|
40
33
|
};
|
|
41
|
-
|
|
34
|
+
|
|
42
35
|
const testomatLogoURL = 'https://avatars.githubusercontent.com/u/59105116?s=36&v=4';
|
|
43
|
-
|
|
36
|
+
|
|
44
37
|
const REPORTER_REQUEST_RETRIES = {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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,
|
|
49
42
|
};
|
|
50
|
-
exports.REPORTER_REQUEST_RETRIES = REPORTER_REQUEST_RETRIES;
|
|
51
|
-
|
|
52
|
-
module.exports.APP_PREFIX = APP_PREFIX;
|
|
53
43
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
module.exports.STATUS = STATUS;
|
|
61
|
-
|
|
62
|
-
module.exports.HTML_REPORT = HTML_REPORT;
|
|
63
|
-
|
|
64
|
-
module.exports.testomatLogoURL = testomatLogoURL;
|
|
44
|
+
const RunStatus = {
|
|
45
|
+
Passed: 'passed',
|
|
46
|
+
Failed: 'failed',
|
|
47
|
+
Finished: 'finished',
|
|
48
|
+
};
|
|
65
49
|
|
|
66
|
-
module.exports
|
|
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
|
+
};
|
package/lib/data-storage.js
CHANGED
|
@@ -1,231 +1,203 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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');
|
|
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
|
+
|
|
49
10
|
class DataStorage {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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();
|
|
61
22
|
}
|
|
62
|
-
|
|
63
|
-
|
|
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;
|
|
64
57
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
this.isFileStorage = true;
|
|
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);
|
|
74
66
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
}
|
|
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;
|
|
101
84
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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;
|
|
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
|
|
135
97
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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
|
-
}
|
|
98
|
+
|
|
99
|
+
testDataFromFile = this.#getDataFromFile(dataType, contextHash);
|
|
100
|
+
|
|
101
|
+
if (testDataFromFile.length) {
|
|
102
|
+
return testDataFromFile;
|
|
155
103
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
return [];
|
|
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
|
|
179
126
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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
|
|
195
148
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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');
|
|
219
187
|
}
|
|
188
|
+
}
|
|
220
189
|
}
|
|
190
|
+
|
|
221
191
|
function stringToMD5Hash(str) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
192
|
+
const md5 = crypto.createHash('md5');
|
|
193
|
+
md5.update(str);
|
|
194
|
+
const hash = md5.digest('hex');
|
|
195
|
+
|
|
196
|
+
return hash;
|
|
226
197
|
}
|
|
227
|
-
exports.dataStorage = DataStorage.getInstance();
|
|
228
|
-
// TODO: consider using fs promises instead of writeSync/appendFileSync to
|
|
229
|
-
// prevent blocking and improve performance (probably queue usage will be required)
|
|
230
198
|
|
|
199
|
+
module.exports.dataStorage = DataStorage.getInstance();
|
|
231
200
|
module.exports.stringToMD5Hash = stringToMD5Hash;
|
|
201
|
+
|
|
202
|
+
// TODO: consider using fs promises instead of writeSync/appendFileSync to
|
|
203
|
+
// prevent blocking and improve performance (probably queue usage will be required)
|
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
1
|
class Adapter {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
2
|
+
constructor(opts) {
|
|
3
|
+
this.opts = opts;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
getFilePath(t) {
|
|
7
|
+
return t.file;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
formatTest(t) {
|
|
11
|
+
return t;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
formatStack(t) {
|
|
15
|
+
return t.stack || '';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
formatMessage(t) {
|
|
19
|
+
return t.message;
|
|
20
|
+
}
|
|
19
21
|
}
|
|
22
|
+
|
|
20
23
|
module.exports = Adapter;
|