@zohodesk/testinglibrary 0.0.53-n20-experimental → 0.0.57-n20-experimental

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.
@@ -26,10 +26,11 @@ export async function generateAndCacheTestData(executionContext, type, identifie
26
26
  }
27
27
  }
28
28
 
29
- const { response, generators } = await dataGenerator.generate(testInfo, actorInfo, type, identifier, scenarioName, dataTable ? dataTable.hashes() : []);
29
+ const { response, generators } = await dataGenerator.generate(testInfo, actorInfo, type, identifier, scenarioName, dataTable ? dataTable.hashes() : [], cacheLayer);
30
30
  if (cacheLayer._trackForCleanup) {
31
31
  cacheLayer._trackForCleanup(entityName, response.data, generators, actorInfo, response.logs, identifier);
32
32
  } else {
33
33
  cacheLayer.set(entityName, response.data);
34
+ cacheLayer.set(`${entityName}_logs`, response.logs);
34
35
  }
35
36
  }
@@ -27,7 +27,7 @@ class DataGenerator {
27
27
  _classPrivateMethodInitSpec(this, _DataGenerator_brand);
28
28
  _classPrivateFieldInitSpec(this, _generatorIndex, null);
29
29
  }
30
- async generate(testInfo, actorInfo, generatorType, generatorName, scenarioName, dataTable) {
30
+ async generate(testInfo, actorInfo, generatorType, generatorName, scenarioName, dataTable, cacheLayer) {
31
31
  const startMs = Date.now();
32
32
  const startLabel = (0, _timeFormat.formatTimestamp)(startMs);
33
33
  _logger.Logger.log(_logger.Logger.INFO_TYPE, `Data generation started | generator="${generatorName}" | scenario="${scenarioName}" | startTime=${startLabel}`);
@@ -38,13 +38,21 @@ class DataGenerator {
38
38
  } else {
39
39
  generators = await _assertClassBrand(_DataGenerator_brand, this, _getGenerator).call(this, generatorName);
40
40
  }
41
- const processedGenerators = await (0, _DataGeneratorHelper.processGenerator)(generators, dataTable);
41
+ const resolvedDataTable = await (0, _DataGeneratorHelper.resolveCacheReferences)(dataTable, cacheLayer);
42
+ const processedGenerators = await (0, _DataGeneratorHelper.processGenerator)(generators, resolvedDataTable);
42
43
  const apiPayload = await _assertClassBrand(_DataGenerator_brand, this, _constructApiPayload).call(this, scenarioName, processedGenerators, actorInfo);
43
- const response = await (0, _DataGeneratorHelper.makeRequest)(process.env.DG_SERVICE_DOMAIN + process.env.DG_SERVICE_API_PATH, apiPayload);
44
+ const featureFlags = process.env.featureflags ? process.env.featureflags : '';
45
+ const headers = {
46
+ 'Content-Type': 'application/json',
47
+ 'featureflags': featureFlags
48
+ };
49
+ _logger.Logger.log(_logger.Logger.INFO_TYPE, 'Making request headers:', headers);
50
+ _logger.Logger.log(_logger.Logger.INFO_TYPE, `Payload: ${JSON.stringify(apiPayload, null, 4)}`);
51
+ const response = await (0, _DataGeneratorHelper.makeRequest)(process.env.DG_SERVICE_DOMAIN + process.env.DG_SERVICE_API_PATH, apiPayload, headers);
44
52
  const endMs = Date.now();
45
53
  const endLabel = (0, _timeFormat.formatTimestamp)(endMs);
46
54
  const totalLabel = (0, _timeFormat.formatDuration)(endMs - startMs);
47
- _logger.Logger.log(_logger.Logger.INFO_TYPE, `Generated response for the generator: ${generatorName} for scenario: ${scenarioName}, Response: ${JSON.stringify(response)}`);
55
+ _logger.Logger.log(_logger.Logger.INFO_TYPE, `Generated response for the generator: ${generatorName} for scenario: ${scenarioName}, Response: ${JSON.stringify(response, null, 4)}`);
48
56
  _logger.Logger.log(_logger.Logger.INFO_TYPE, `Data generation completed | generator="${generatorName}" | scenario="${scenarioName}" | startTime=${startLabel} | endTime=${endLabel} | totalTime=${totalLabel}`);
49
57
  return {
50
58
  response,
@@ -56,16 +64,16 @@ class DataGenerator {
56
64
  const totalLabel = (0, _timeFormat.formatDuration)(endMs - startMs);
57
65
  _logger.Logger.log(_logger.Logger.FAILURE_TYPE, `Data generation failed | generator="${generatorName}" | scenario="${scenarioName}" | startTime=${startLabel} | endTime=${endLabel} | totalTime=${totalLabel}`);
58
66
  if (error instanceof _DataGeneratorError.DataGeneratorError) {
59
- console.error(error.getMessage());
60
- console.error("Stack trace:", error.stack);
67
+ _logger.Logger.log(_logger.Logger.FAILURE_TYPE, error.getMessage());
68
+ _logger.Logger.log(_logger.Logger.FAILURE_TYPE, "Stack trace:", error.stack);
61
69
  _logger.Logger.log(_logger.Logger.FAILURE_TYPE, error.getMessage());
62
70
  } else {
63
- console.error("Error Type:", error.constructor.name);
64
- console.error("Error Message:", error.message);
65
- console.error("Stack trace:", error.stack);
71
+ _logger.Logger.log(_logger.Logger.FAILURE_TYPE, "Error Type:", error.constructor.name);
72
+ _logger.Logger.log(_logger.Logger.FAILURE_TYPE, "Error Message:", error.message);
73
+ _logger.Logger.log(_logger.Logger.FAILURE_TYPE, "Stack trace:", error.stack);
66
74
  _logger.Logger.log(_logger.Logger.FAILURE_TYPE, `${error.constructor.name} - Message: ${error.message}`);
67
75
  }
68
- console.error('Data Generation failed for the generator: ', generatorName, "\n\nError response :", error);
76
+ _logger.Logger.log(_logger.Logger.FAILURE_TYPE, `Data Generation failed for the generator: ${generatorName}\n\nError response: ${error}`);
69
77
  throw error;
70
78
  }
71
79
  }
@@ -6,6 +6,54 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.getGeneratorFilePath = getGeneratorFilePath;
7
7
  exports.makeRequest = makeRequest;
8
8
  exports.processGenerator = processGenerator;
9
+ exports.resolveCacheReferences = resolveCacheReferences;
10
+ // Matches a single ${EntityName} or ${EntityName.field.path} cell value.
11
+ // Anchored — values like "foo ${E1.id} bar" are left as-is on purpose.
12
+ const CACHE_REF = /^\$\{([A-Za-z_][\w-]*)(?:\.([A-Za-z_][\w.-]*))?\}$/;
13
+
14
+ // Resolve ${EntityName} / ${EntityName.field.path} references in a dataTable
15
+ // against the cacheLayer. Lets a later `generate ...` step reference an entity
16
+ // that an earlier step cached (e.g. ${E1.id} for an event created in a prior
17
+ // generator invocation).
18
+ async function resolveCacheReferences(rows, cacheLayer) {
19
+ if (!rows || !rows.length || !cacheLayer || typeof cacheLayer.get !== 'function') {
20
+ return rows || [];
21
+ }
22
+ const out = [];
23
+ for (const row of rows) {
24
+ const resolved = {};
25
+ for (const [key, value] of Object.entries(row)) {
26
+ const match = typeof value === 'string' ? value.match(CACHE_REF) : null;
27
+ if (!match) {
28
+ resolved[key] = value;
29
+ continue;
30
+ }
31
+ const [, entityName, fieldPath] = match;
32
+ const entity = await cacheLayer.get(entityName);
33
+ if (entity === undefined || entity === null) {
34
+ throw new Error(`DataGenerator: ${value} references entity "${entityName}" which is not in the cache.`);
35
+ }
36
+ if (!fieldPath) {
37
+ resolved[key] = entity;
38
+ continue;
39
+ }
40
+ let acc = entity;
41
+ for (const part of fieldPath.split('.')) {
42
+ if (acc === undefined || acc === null) {
43
+ break;
44
+ }
45
+ acc = acc[part];
46
+ }
47
+ if (acc === undefined) {
48
+ throw new Error(`DataGenerator: ${value} resolved to undefined (entity "${entityName}" has no path "${fieldPath}").`);
49
+ }
50
+ resolved[key] = acc;
51
+ }
52
+ out.push(resolved);
53
+ }
54
+ return out;
55
+ }
56
+
9
57
  //Create payload for the generators
10
58
  async function processGenerator(generators, dataTable) {
11
59
  if (!dataTable) {
@@ -29,12 +77,12 @@ async function processGenerator(generators, dataTable) {
29
77
  return generator;
30
78
  });
31
79
  }
32
- async function makeRequest(url, payload) {
80
+ async function makeRequest(url, payload, headers = {
81
+ 'Content-Type': 'application/json'
82
+ }) {
33
83
  const response = await fetch(url, {
34
84
  method: 'POST',
35
- headers: {
36
- 'Content-Type': 'application/json'
37
- },
85
+ headers: headers,
38
86
  body: JSON.stringify(payload)
39
87
  });
40
88
  if (!response.ok) {
@@ -125,6 +125,7 @@ var _default = exports.default = {
125
125
  const cleanupEntries = [];
126
126
  cache._trackForCleanup = (entityName, data, generators, actorInfo, logs, generatorName) => {
127
127
  cache.set(entityName, data);
128
+ cache.set(`${entityName}_logs`, logs);
128
129
  cleanupEntries.push({
129
130
  entityName,
130
131
  data,
@@ -183,7 +184,7 @@ var _default = exports.default = {
183
184
  const stepEndMs = Date.now();
184
185
  const stepEndLabel = (0, _timeFormat.formatTimestamp)(stepEndMs);
185
186
  const stepTotalLabel = (0, _timeFormat.formatDuration)(stepEndMs - stepStartMs);
186
- _logger.Logger.log(_logger.Logger.SUCCESS_TYPE, `Cleanup step success | ${actionDesc} (id: ${entityId}) | response=${JSON.stringify(cleanupResponse)} | startTime=${stepStartLabel} | endTime=${stepEndLabel} | totalTime=${stepTotalLabel}`);
187
+ _logger.Logger.log(_logger.Logger.SUCCESS_TYPE, `Cleanup step success | ${actionDesc} (id: ${entityId}) | response=${JSON.stringify(cleanupResponse, null, 4)} | startTime=${stepStartLabel} | endTime=${stepEndLabel} | totalTime=${stepTotalLabel}`);
187
188
  } catch (err) {
188
189
  failed++;
189
190
  const stepEndMs = Date.now();
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.Logger = void 0;
7
+ var _util = require("util");
7
8
  class LoggerImpl {
8
9
  constructor() {
9
10
  this.SUCCESS_TYPE = 'success';
@@ -20,8 +21,9 @@ class LoggerImpl {
20
21
  this.consoleLogger.error(err);
21
22
  }
22
23
  info() {}
23
- log(type, message) {
24
+ log(type, ...messageParts) {
24
25
  const color = this.colors[type];
26
+ const message = (0, _util.format)(...messageParts);
25
27
  this.consoleLogger.log(`${color[0]}${message}${color[1]}\n`);
26
28
  }
27
29
  }