@testomatio/reporter 1.1.1-beta-codecept-logger → 1.1.1-beta.1.fix-logger

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/client.js CHANGED
@@ -130,9 +130,12 @@ class Client {
130
130
  steps,
131
131
  code = null,
132
132
  title,
133
+ file,
133
134
  suite_title,
134
135
  suite_id,
135
136
  test_id,
137
+ manuallyAttachedArtifacts,
138
+ meta,
136
139
  } = testData;
137
140
  let { message = '' } = testData;
138
141
 
@@ -146,18 +149,13 @@ class Client {
146
149
  // Attach logs
147
150
  const fullLogs = this.formatLogs({ error: errorFormatted, steps, logs: testData.logs });
148
151
 
149
- // GET ARTIFACTS from storage
150
- // const artifactFiles = artifactStorage.get(test_id);
151
- // if (artifactFiles) files.push(...artifactFiles);
152
+ // add artifacts
153
+ if (manuallyAttachedArtifacts?.length) files.push(...manuallyAttachedArtifacts);
152
154
 
153
- // // GET KEY-VALUEs from storage
154
- // const keyValueStorage = require('./storages/key-value-storage');
155
- // const keyValues = keyValueStorage.get(test_id);
156
-
157
155
  const uploadedFiles = [];
158
156
 
159
- for (const file of files) {
160
- uploadedFiles.push(upload.uploadFileByPath(file, this.uuid));
157
+ for (const f of files) {
158
+ uploadedFiles.push(upload.uploadFileByPath(f, this.uuid));
161
159
  }
162
160
 
163
161
  for (const [idx, buffer] of filesBuffers.entries()) {
@@ -177,6 +175,7 @@ class Client {
177
175
  status,
178
176
  stack: fullLogs,
179
177
  example,
178
+ file,
180
179
  code,
181
180
  title,
182
181
  suite_title,
@@ -185,7 +184,7 @@ class Client {
185
184
  message,
186
185
  run_time: parseFloat(time),
187
186
  artifacts,
188
- // meta: keyValues,
187
+ meta,
189
188
  };
190
189
 
191
190
  debug('Adding test run...', data);
@@ -251,9 +250,9 @@ class Client {
251
250
  logs = logs?.trim();
252
251
 
253
252
  let testLogs = '';
254
- if (steps) testLogs += `${chalk.bold.blue('################[ Steps ]################')}\n${steps}`;
255
- if (logs) testLogs += `\n\n${chalk.bold.gray('################[ Logs ]################')}\n${logs}`;
256
- if (error) testLogs += `\n\n${chalk.bold.red('################[ Failure ]################')}\n${error}`;
253
+ if (steps) testLogs += `${chalk.bold.blue('################[ Steps ]################')}\n${steps}\n\n`;
254
+ if (logs) testLogs += `${chalk.bold.gray('################[ Logs ]################')}\n${logs}\n\n`;
255
+ if (error) testLogs += `${chalk.bold.red('################[ Failure ]################')}\n${error}`;
257
256
  return testLogs;
258
257
  }
259
258
 
package/lib/config.js CHANGED
@@ -8,6 +8,10 @@ const debug = require('debug')('@testomatio/reporter:config');
8
8
  const dotenv = require('dotenv');
9
9
  const envFileVars = dotenv.config({ path: '.env' }).parsed; */
10
10
 
11
+ const TESTOMATIO = process.env.TESTOMATIO || process.env.TESTOMATIO_API_KEY || process.env.TESTOMATIO_TOKEN || '';
12
+ if (TESTOMATIO === 'undefined') console.error('TESTOMATIO is "undefined". Something went wrong. Contact dev team.');
13
+ process.env.TESTOMATIO = TESTOMATIO;
14
+
11
15
  // select only TESTOMATIO related variables (only to print them in debug)
12
16
  const testomatioEnvVars =
13
17
  Object.keys(process.env)
@@ -22,3 +26,4 @@ debug('TESTOMATIO variables:', testomatioEnvVars);
22
26
  const config = process.env;
23
27
 
24
28
  module.exports = config;
29
+ module.exports.TESTOMATIO = TESTOMATIO;
@@ -3,25 +3,38 @@ const fs = require('fs');
3
3
  const path = require('path');
4
4
  const os = require('os');
5
5
  const { join } = require('path');
6
- const { TESTOMAT_TMP_STORAGE_DIR } = require('../constants');
7
- const { fileSystem } = require('../utils/utils');
6
+ const { TESTOMAT_TMP_STORAGE_DIR } = require('./constants');
7
+ const { fileSystem, jestHelpers } = require('./utils/utils');
8
8
 
9
9
  class DataStorage {
10
+ static #instance;
11
+
12
+ context;
13
+
14
+ /**
15
+ *
16
+ * @returns {DataStorage}
17
+ */
18
+ static getInstance() {
19
+ if (!this.#instance) {
20
+ this.#instance = new DataStorage();
21
+ }
22
+ return this.#instance;
23
+ }
24
+
25
+ setContext(context) {
26
+ this.context = context;
27
+ }
28
+
10
29
  /**
11
- * Creates data storage instance for specific data type.
12
- * Stores data to global variable or to file depending on what is applicable for current test runner
30
+ * Creates data storage instance as singleton
31
+ * Stores data to global variable or to file depending on what is applicable for current test runner (adapter)
13
32
  * Recommend to use composition while using this class (instead of inheritance).
14
33
  * ! Also the class which will use data storage should be singleton (to avoid data loss).
15
- * But the data storage itself is not singleton. It will have an instance per data type.
16
- * @param {'log' | 'artifact' | 'keyvalue'} dataType – type of data to store
17
34
  */
18
- constructor(dataType) {
19
- this.dataType = dataType || 'data';
20
-
35
+ constructor() {
21
36
  // some frameworks use global variable to store data, some use file storage
22
37
  this.isFileStorage = true;
23
-
24
- this.dataDirPath = path.join(TESTOMAT_TMP_STORAGE_DIR, this.dataType);
25
38
  }
26
39
 
27
40
  #stringToFilename(str) {
@@ -37,23 +50,28 @@ class DataStorage {
37
50
  /**
38
51
  * Puts any data to storage (file or global variable).
39
52
  * If file: stores data as text, if global variable – stores as array of data.
53
+ * @param {'log' | 'artifact' | 'keyvalue'} dataType
40
54
  * @param {*} data anything you want to store (string, object, array, etc)
41
55
  * @param {*} context could be testId or any context (test name, suite name, including their IDs etc)
42
56
  * suite name + test name is used by default
43
57
  * @returns
44
58
  */
45
- putData(data, context = null) {
46
- fileSystem.createDir(this.dataDirPath);
59
+ putData(dataType, data, context = null) {
60
+ if (!dataType || !data) return;
61
+
62
+ context = context || this.context || global.testomatioTestTitle || jestHelpers.getIdOfCurrentlyRunningTest();
47
63
  if (!context) {
48
- debug(`No context provided for "${this.dataType}" data:`, data);
64
+ debug(`No context provided for "${dataType}" data:`, data);
49
65
  return;
50
66
  }
51
67
  context = this.#stringToFilename(context);
52
68
 
53
69
  if (this.isFileStorage) {
54
- this.#putDataToFile(data, context);
70
+ const dataDirPath = path.join(TESTOMAT_TMP_STORAGE_DIR, dataType);
71
+ fileSystem.createDir(dataDirPath);
72
+ this.#putDataToFile(dataType, data, context);
55
73
  } else {
56
- this.#putDataToGlobalVar(data, context);
74
+ this.#putDataToGlobalVar(dataType, data, context);
57
75
  }
58
76
  }
59
77
 
@@ -61,12 +79,16 @@ class DataStorage {
61
79
  * Returns data, stored for specific test/context (or data which was stored without test id specified).
62
80
  * This method will get data from global variable and/or from from file (previosly saved with put method).
63
81
  *
82
+ * @param {'log' | 'artifact' | 'keyvalue'} dataType
64
83
  * @param {string} context
65
- * @returns {any []} of data (any type), null (if no data found for test) or string (if data type is log)
84
+ * @returns {any []} array of data (any type), null (if no data found for context) or string (if data type is log)
66
85
  */
67
- getData(context) {
86
+ getData(dataType, context) {
87
+ // TODO: think if it could be useful
88
+ // context = context || this.context || global.testomatioTestTitle || jestHelpers.getIdOfCurrentlyRunningTest();
89
+
68
90
  if (!context) {
69
- debug(`No context passed`, context);
91
+ debug(`Trying to get "${dataType}" data without context`);
70
92
  return null;
71
93
  }
72
94
 
@@ -76,36 +98,37 @@ class DataStorage {
76
98
  let testDataFromGlobalVar = [];
77
99
 
78
100
  if (global?.testomatioDataStore) {
79
- testDataFromGlobalVar = this.#getDataFromGlobalVar(context);
101
+ testDataFromGlobalVar = this.#getDataFromGlobalVar(dataType, context);
80
102
  if (testDataFromGlobalVar) {
81
103
  if (testDataFromGlobalVar.length) return testDataFromGlobalVar;
82
104
  }
83
105
  // don't return nothing if no data in global variable
84
106
  }
85
107
 
86
- testDataFromFile = this.#getDataFromFile(context);
108
+ testDataFromFile = this.#getDataFromFile(dataType, context);
87
109
 
88
110
  if (testDataFromFile.length) {
89
111
  return testDataFromFile;
90
112
  }
91
- debug(`No "${this.dataType}" data for test id ${context} in both file and global variable`);
113
+ debug(`No "${dataType}" data for context "${context}" in both file and global variable`);
92
114
 
93
- // in case no data found for test
115
+ // in case no data found for context
94
116
  return null;
95
117
  }
96
118
 
97
119
  /**
120
+ * @param {'log' | 'artifact' | 'keyvalue'} dataType
98
121
  * @param {string} context
99
122
  * @returns aray of data (any type)
100
123
  */
101
- #getDataFromGlobalVar(context) {
124
+ #getDataFromGlobalVar(dataType, context) {
102
125
  try {
103
- if (global?.testomatioDataStore[this.dataType]) {
104
- const testData = global.testomatioDataStore[this.dataType][context];
105
- if (testData) debug(`"${this.dataType}" data for test id ${context}:`, testData.join(', '));
126
+ if (global?.testomatioDataStore[dataType]) {
127
+ const testData = global.testomatioDataStore[dataType][context];
128
+ if (testData) debug(`"${dataType}" data for constext "${context}":`, testData.join(', '));
106
129
  return testData || [];
107
130
  }
108
- // debug(`No ${this.dataType} data for test context ${context} in <global> storage`);
131
+ // debug(`No ${this.dataType} data for context ${context} in <global> storage`);
109
132
  return [];
110
133
  } catch (e) {
111
134
  // there could be no data, ignore
@@ -113,20 +136,21 @@ class DataStorage {
113
136
  }
114
137
 
115
138
  /**
116
- *
139
+ * @param {'log' | 'artifact' | 'keyvalue'} dataType
117
140
  * @param {*} context
118
141
  * @returns array of data (any type)
119
142
  */
120
- #getDataFromFile(context) {
143
+ #getDataFromFile(dataType, context) {
144
+ const dataDirPath = path.join(TESTOMAT_TMP_STORAGE_DIR, dataType);
121
145
  try {
122
- const filepath = join(this.dataDirPath, `${this.dataType}_${context}`);
146
+ const filepath = join(dataDirPath, `${dataType}_${context}`);
123
147
  if (fs.existsSync(filepath)) {
124
148
  const testDataAsText = fs.readFileSync(filepath, 'utf-8');
125
- if (testDataAsText) debug(`"${this.dataType}" data for test id ${context}:`, testDataAsText);
149
+ if (testDataAsText) debug(`"${dataType}" data for context "${context}":`, testDataAsText);
126
150
  const testDataArr = testDataAsText?.split(os.EOL) || [];
127
151
  return testDataArr;
128
152
  }
129
- // debug(`No ${this.dataType} data for test ${context} in <file> storage`);
153
+ // debug(`No ${this.dataType} data for ${context} in <file> storage`);
130
154
  return [];
131
155
  } catch (e) {
132
156
  // there could be no data, ignore
@@ -136,24 +160,33 @@ class DataStorage {
136
160
 
137
161
  /**
138
162
  * Puts data to global variable. Unlike the file storage, stores data in array (file storage just append as string).
163
+ * @param {'log' | 'artifact' | 'keyvalue'} dataType
139
164
  * @param {*} data
140
165
  * @param {*} context
141
166
  */
142
- #putDataToGlobalVar(data, context) {
167
+ #putDataToGlobalVar(dataType, data, context) {
143
168
  debug('Saving data to global variable for ', context, ':', data);
144
169
  if (!global.testomatioDataStore) global.testomatioDataStore = {};
145
- if (!global.testomatioDataStore?.[this.dataType]) global.testomatioDataStore[this.dataType] = {};
170
+ if (!global.testomatioDataStore?.[dataType]) global.testomatioDataStore[dataType] = {};
146
171
 
147
- if (!global.testomatioDataStore?.[this.dataType][context]) global.testomatioDataStore[this.dataType][context] = [];
148
- global.testomatioDataStore[this.dataType][context].push(data);
172
+ if (!global.testomatioDataStore?.[dataType][context]) global.testomatioDataStore[dataType][context] = [];
173
+ global.testomatioDataStore[dataType][context].push(data);
149
174
  }
150
175
 
151
- #putDataToFile(data, context) {
176
+ /**
177
+ * Puts data to file. Unlike the global variable storage, stores data as string
178
+ * @param {'log' | 'artifact' | 'keyvalue'} dataType
179
+ * @param {*} data
180
+ * @param {string} context
181
+ * @returns
182
+ */
183
+ #putDataToFile(dataType, data, context) {
184
+ const dataDirPath = path.join(TESTOMAT_TMP_STORAGE_DIR, dataType);
152
185
  if (typeof data !== 'string') data = JSON.stringify(data);
153
- const filename = `${this.dataType}_${context}`;
154
- const filepath = join(this.dataDirPath, filename);
155
- if (!fs.existsSync(this.dataDirPath)) fileSystem.createDir(this.dataDirPath);
156
- debug('Saving data to file for', context, 'to', filepath, ':\n', data, '\n');
186
+ const filename = `${dataType}_${context}`;
187
+ const filepath = join(dataDirPath, filename);
188
+ if (!fs.existsSync(dataDirPath)) fileSystem.createDir(dataDirPath);
189
+ debug(`Saving data to file for context "${context}" to ${filepath}. Data: ${JSON.stringify(data)}`);
157
190
 
158
191
  // append new line if file already exists (in this case its definitely includes some data)
159
192
  if (fs.existsSync(filepath)) {
@@ -164,7 +197,7 @@ class DataStorage {
164
197
  }
165
198
  }
166
199
 
167
- module.exports = DataStorage;
200
+ module.exports.dataStorage = DataStorage.getInstance();
168
201
 
169
202
  // TODO: consider using fs promises instead of writeSync/appendFileSync to
170
203
  // prevent blocking and improve performance (probably queue usage will be required)
@@ -6,8 +6,7 @@ const RubyAdapter = require('./ruby');
6
6
  const CSharpAdapter = require('./csharp');
7
7
 
8
8
  function AdapterFactory(lang, opts) {
9
- if (!lang) return new Adapter(opts);
10
-
9
+
11
10
  if (lang === 'java') {
12
11
  return new JavaAdapter(opts);
13
12
  }
@@ -23,6 +22,8 @@ function AdapterFactory(lang, opts) {
23
22
  if (lang === 'c#' || lang === 'csharp') {
24
23
  return new CSharpAdapter(opts);
25
24
  }
25
+
26
+ return new Adapter(opts);
26
27
  }
27
28
 
28
29
  module.exports = AdapterFactory;
@@ -5,6 +5,7 @@ const JsonCycle = require('json-cycle');
5
5
  const { APP_PREFIX, STATUS } = require('../constants');
6
6
  const { isValidUrl, foundedTestLog } = require('../utils/utils');
7
7
  const { parseFilterParams, generateFilterRequestParams, setS3Credentials, } = require('../utils/pipe_utils');
8
+ const { TESTOMATIO } = require('../config');
8
9
 
9
10
  if (process.env.TESTOMATIO_RUN) {
10
11
  process.env.runId = process.env.TESTOMATIO_RUN;
@@ -20,7 +21,7 @@ class TestomatioPipe {
20
21
  constructor(params, store) {
21
22
  this.isEnabled = false;
22
23
  this.url = params.testomatioUrl || process.env.TESTOMATIO_URL || 'https://app.testomat.io';
23
- this.apiKey = params.apiKey || process.env.TESTOMATIO;
24
+ this.apiKey = params.apiKey || TESTOMATIO;
24
25
  debug('Testomatio Pipe: ', this.apiKey ? 'API KEY' : '*no api key*');
25
26
  if (!this.apiKey) {
26
27
  return;
@@ -175,13 +176,14 @@ class TestomatioPipe {
175
176
  * @returns
176
177
  */
177
178
  addTest(data) {
178
- debug('Adding test...');
179
179
  if (!this.isEnabled) return;
180
180
  if (!this.runId) return;
181
181
  data.api_key = this.apiKey;
182
182
  data.create = this.createNewTests;
183
183
  const json = JsonCycle.stringify(data);
184
184
 
185
+ debug('Adding test', json);
186
+
185
187
  return this.axios.post(`/api/reporter/${this.runId}/testrun`, json, {
186
188
  maxContentLength: Infinity,
187
189
  maxBodyLength: Infinity,
@@ -1,6 +1,9 @@
1
- const { logger } = require('./storages/logger');
2
- const { artifactStorage } = require('./storages/artifact-storage');
3
- const { keyValueStorage } = require('./storages/key-value-storage');
1
+ const { services } = require('./services');
2
+ const { initPlaywrightForStorage } = require('./adapter/playwright');
3
+
4
+ if (process.env.PLAYWRIGHT_TEST_BASE_URL) {
5
+ initPlaywrightForStorage();
6
+ }
4
7
 
5
8
  /**
6
9
  * Stores path to file as artifact and uploads it to the S3 storage
@@ -8,7 +11,7 @@ const { keyValueStorage } = require('./storages/key-value-storage');
8
11
  */
9
12
  function saveArtifact(data, context = null) {
10
13
  if (!data) return;
11
- artifactStorage.put(data, context);
14
+ services.artifacts.put(data, context);
12
15
  }
13
16
 
14
17
  /**
@@ -16,7 +19,7 @@ function saveArtifact(data, context = null) {
16
19
  * @param {...any} args
17
20
  */
18
21
  function logMessage(...args) {
19
- logger.log(...args);
22
+ services.logger._templateLiteralLog(...args);
20
23
  }
21
24
 
22
25
  /**
@@ -24,7 +27,7 @@ function logMessage(...args) {
24
27
  * @param {*} message
25
28
  */
26
29
  function addStep(message) {
27
- logger.step(message);
30
+ services.logger.step(message);
28
31
  }
29
32
 
30
33
  /**
@@ -32,17 +35,7 @@ function addStep(message) {
32
35
  * @param {*} keyValue
33
36
  */
34
37
  function setKeyValue(keyValue) {
35
- keyValueStorage.put(keyValue);
36
- }
37
-
38
- /**
39
- *
40
- * @param {string} context – test id or test title or suite title + test title
41
- */
42
- function _setContext(context) {
43
- logger.setContext(context);
44
- keyValueStorage.setContext(context);
45
- artifactStorage.setContext(context);
38
+ services.keyValues.put(keyValue);
46
39
  }
47
40
 
48
41
  module.exports = {
@@ -50,5 +43,4 @@ module.exports = {
50
43
  log: logMessage,
51
44
  step: addStep,
52
45
  keyValue: setKeyValue,
53
- _setContext,
54
46
  };
package/lib/reporter.js CHANGED
@@ -1,24 +1,19 @@
1
- const { logger } = require('./storages/logger');
2
1
  const TestomatClient = require('./client');
3
2
  const TRConstants = require('./constants');
3
+ const { services } = require('./services');
4
4
 
5
- const log = logger.templateLiteralLog.bind(logger);
6
- const step = logger.step.bind(logger);
7
5
  const reporterFunctions = require('./reporter-functions');
8
6
 
9
7
  module.exports = {
10
- logger,
11
- testomatioLogger: logger,
12
- log,
13
- step,
14
- TestomatClient,
15
- TRConstants,
16
- };
8
+ // TODO: deprecate in future; use log or testomat.log
9
+ testomatioLogger: services.logger,
17
10
 
18
- module.exports.testomat = {
19
11
  artifact: reporterFunctions.artifact,
20
12
  log: reporterFunctions.log,
21
- step: reporterFunctions.step,
13
+ logger: services.logger,
22
14
  meta: reporterFunctions.keyValue,
23
- _setContext: reporterFunctions._setContext,
15
+ step: reporterFunctions.step,
16
+
17
+ TestomatClient,
18
+ TRConstants,
24
19
  };
@@ -1,5 +1,5 @@
1
- const debug = require('debug')('@testomatio/reporter:artifact-storage');
2
- const DataStorage = require('./data-storage');
1
+ const debug = require('debug')('@testomatio/reporter:services-artifacts');
2
+ const { dataStorage } = require('../data-storage');
3
3
 
4
4
  /**
5
5
  * Artifact storage is supposed to store file paths
@@ -7,18 +7,6 @@ const DataStorage = require('./data-storage');
7
7
  class ArtifactStorage {
8
8
  static #instance;
9
9
 
10
- #context;
11
-
12
- // there is autocompletion for the class methods if implemented singleton this way
13
- constructor() {
14
- this.dataStorage = new DataStorage('artifact');
15
-
16
- // singleton
17
- if (!ArtifactStorage.#instance) {
18
- ArtifactStorage.#instance = this;
19
- }
20
- }
21
-
22
10
  /**
23
11
  * Singleton
24
12
  * @returns {ArtifactStorage}
@@ -30,39 +18,28 @@ class ArtifactStorage {
30
18
  return this.#instance;
31
19
  }
32
20
 
33
- /**
34
- * @param {string} context - suite title + test title
35
- */
36
- setContext(context) {
37
- this.#context = context;
38
- }
39
-
40
21
  /**
41
22
  * Stores path to file as artifact and uploads it to the S3 storage
42
23
  * @param {string | {path: string, type: string, name: string}} data - path to file or object with path, type and name
43
24
  * @param {*} context testId or test title
44
25
  */
45
26
  put(data, context = null) {
46
- context = context || this.#context;
47
27
  if (!data) return;
48
28
  debug('Save artifact:', data);
49
- this.dataStorage.putData(data, context);
29
+ dataStorage.putData('artifact', data, context);
50
30
  }
51
31
 
52
32
  /**
53
33
  * Returns list of artifacts to upload
54
34
  * @param {*} context testId or test context from test runner
55
- * @returns {string | {path: string, type: string, name: string}[]}
35
+ * @returns {(string | {path: string, type: string, name: string})[]}
56
36
  */
57
37
  get(context) {
58
- if (!context) return null;
59
-
60
- // array of any data
61
- let artifacts = this.dataStorage.getData(context);
62
- if (!artifacts || !artifacts.length) return null;
38
+ let artifacts = dataStorage.getData('artifact', context);
39
+ if (!artifacts || !artifacts.length) return [];
63
40
 
64
41
  artifacts = artifacts.map(artifactData => {
65
- // artifact could be an object ({type, path, name} props) or string
42
+ // artifact could be an object ({type, path, name} props) or string (just path)
66
43
  let artifact;
67
44
  try {
68
45
  artifact = JSON.parse(artifactData);
@@ -72,7 +49,8 @@ class ArtifactStorage {
72
49
  return artifact;
73
50
  });
74
51
  artifacts = artifacts.filter(artifact => !!artifact);
75
- return artifacts.length ? artifacts : null;
52
+ debug(`Artifacts for test ${context}:`, artifacts);
53
+ return artifacts.length ? artifacts : [];
76
54
  }
77
55
  }
78
56
 
@@ -0,0 +1,13 @@
1
+ const { logger } = require('./logger');
2
+ const { artifactStorage } = require('./artifacts');
3
+ const { keyValueStorage } = require('./key-values');
4
+ const { dataStorage } = require('../data-storage');
5
+
6
+ module.exports.services = {
7
+ logger,
8
+ artifacts: artifactStorage,
9
+ keyValues: keyValueStorage,
10
+ setContext: context => {
11
+ dataStorage.setContext(context);
12
+ },
13
+ };
@@ -1,17 +1,11 @@
1
- const debug = require('debug')('@testomatio/reporter:key-value-storage');
2
- const DataStorage = require('./data-storage');
1
+ const debug = require('debug')('@testomatio/reporter:services-key-value');
2
+ const { dataStorage } = require('../data-storage');
3
3
 
4
4
  class KeyValueStorage {
5
5
  static #instance;
6
6
 
7
- #context;
8
-
9
- constructor() {
10
- this.dataStorage = new DataStorage('keyvalue');
11
- }
12
-
13
7
  /**
14
- *
8
+ *
15
9
  * @returns {KeyValueStorage}
16
10
  */
17
11
  static getInstance() {
@@ -21,20 +15,14 @@ class KeyValueStorage {
21
15
  return this.#instance;
22
16
  }
23
17
 
24
- /**
25
- * @param {string} context - suite title + test title
26
- */
27
- setContext(context) {
28
- this.#context = context;
29
- }
30
-
31
18
  /**
32
19
  * Stores key-value pair and passes it to reporter
33
20
  * @param {{key: string}} keyValue - key-value pair(s) as object
21
+ * @param {*} context - full test title
34
22
  */
35
- put(keyValue) {
23
+ put(keyValue, context = null) {
36
24
  if (!keyValue) return;
37
- this.dataStorage.putData(keyValue, this.#context);
25
+ dataStorage.putData('keyvalue', keyValue, context);
38
26
  }
39
27
 
40
28
  #isKeyValueObject(smth) {
@@ -44,14 +32,11 @@ class KeyValueStorage {
44
32
  /**
45
33
  * Returns key-values pairs for the test as object
46
34
  * @param {*} context testId or test context from test runner
47
- * @returns {Object} key-values pairs as object, e.g. {priority: 'high', browser: 'chrome'}
35
+ * @returns {{[key: string]: string} | {}} key-values pairs as object, e.g. {priority: 'high', browser: 'chrome'}
48
36
  */
49
37
  get(context = null) {
50
- context = context || this.#context;
51
- if (!context) return null;
52
-
53
- const keyValuesList = this.dataStorage.getData(context);
54
- if (!keyValuesList || !keyValuesList?.length) return null;
38
+ const keyValuesList = dataStorage.getData('keyvalue', context);
39
+ if (!keyValuesList || !keyValuesList?.length) return {};
55
40
 
56
41
  const keyValues = {};
57
42
  for (const keyValue of keyValuesList) {
@@ -66,7 +51,7 @@ class KeyValueStorage {
66
51
  }
67
52
  }
68
53
 
69
- return Object.keys(keyValues).length ? keyValues : null;
54
+ return keyValues;
70
55
  }
71
56
  }
72
57