@dev-blinq/cucumber_client 1.0.1417-dev → 1.0.1418-dev

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.
@@ -7,10 +7,11 @@ const { default: traverse } = pkg;
7
7
  import pkg1 from "@babel/generator";
8
8
  const { default: generate } = pkg1;
9
9
  import * as t from "@babel/types";
10
-
11
10
  import { CucumberExpression, ParameterTypeRegistry } from "@cucumber/cucumber-expressions";
12
11
  import { existsSync, readFileSync, writeFileSync } from "fs";
13
12
  import { getAiConfig } from "../code_gen/page_reflection.js";
13
+ import socketLogger from "../utils/socket_logger.js";
14
+
14
15
  const STEP_KEYWORDS = new Set(["Given", "When", "Then"]);
15
16
 
16
17
  /**
@@ -307,14 +308,17 @@ export function getDefaultPrettierConfig() {
307
308
  const configContent = readFileSync(prettierConfigPath, "utf-8");
308
309
  prettierConfig = JSON.parse(configContent);
309
310
  } catch (error) {
311
+ socketLogger.error("Error parsing Prettier config file", error);
310
312
  console.error(`Error parsing Prettier config file: ${error}`);
311
313
  }
312
314
  } else {
313
315
  // save the default config to .prettierrc
314
316
  try {
315
317
  writeFileSync(prettierConfigPath, JSON.stringify(prettierConfig, null, 2), "utf-8");
318
+ socketLogger.info(`Created default Prettier config at ${prettierConfigPath}`);
316
319
  console.log(`Created default Prettier config at ${prettierConfigPath}`);
317
320
  } catch (error) {
321
+ socketLogger.error(`Error writing Prettier config file: ${error}`);
318
322
  console.error(`Error writing Prettier config file: ${error}`);
319
323
  }
320
324
  }
@@ -4,6 +4,7 @@ import { StepsDefinitions } from "../cucumber/steps_definitions.js";
4
4
  import path from "path";
5
5
  import { CodePage } from "./page_reflection.js";
6
6
  import { convertToIdentifier, escapeNonPrintables } from "./utils.js";
7
+ import socketLogger from "../utils/socket_logger.js";
7
8
  const findElementIdentifier = (node, step, userData, elements) => {
8
9
  if (node.key) {
9
10
  // incase of rerunning implemented steps
@@ -725,6 +726,7 @@ const generateCode = (recording, codePage, userData, projectDir, methodName) =>
725
726
  }
726
727
  let elements = {};
727
728
  if (!codePage) {
729
+ socketLogger.info("CodePage is null");
728
730
  console.log("codePage is null");
729
731
  } else {
730
732
  elements = codePage.getVariableDeclarationAsObject("elements");
@@ -8,6 +8,7 @@ import { parseStepTextParameters, toCucumberExpression, unEscapeNonPrintables }
8
8
  import stream from "stream";
9
9
  import { testStringForRegex } from "../recorderv3/update_feature.js";
10
10
  import { generateTestData } from "./feature_data.js";
11
+ import socketLogger from "../utils/socket_logger.js";
11
12
  class DataTable {
12
13
  constructor(dataTableDocument) {
13
14
  if (!dataTableDocument) {
@@ -544,6 +545,9 @@ const scenarioResolution = async (featureFilePath) => {
544
545
  fs.rmSync(tmpDir, { recursive: true });
545
546
  }
546
547
  } catch (e) {
548
+ socketLogger.error(
549
+ `An error has occurred while removing the temp folder at ${tmpDir}. Please remove it manually. Error: ${e}`
550
+ );
547
551
  console.error(
548
552
  `An error has occurred while removing the temp folder at ${tmpDir}. Please remove it manually. Error: ${e}`
549
553
  );
@@ -12,11 +12,9 @@ import { updateFeatureFile } from "./update_feature.js";
12
12
  import { parseStepTextParameters } from "../cucumber/utils.js";
13
13
  import { AstBuilder, GherkinClassicTokenMatcher, Parser } from "@cucumber/gherkin";
14
14
  import chokidar from "chokidar";
15
- import logger from "../../logger.js";
16
15
  import { unEscapeNonPrintables } from "../cucumber/utils.js";
17
16
  import { findAvailablePort } from "../utils/index.js";
18
- import { Step } from "../cucumber/feature.js";
19
-
17
+ import socketLogger from "../utils/socket_logger.js";
20
18
  const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
21
19
 
22
20
  const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
@@ -45,7 +43,6 @@ async function evaluate(frame, script) {
45
43
  async function findNestedFrameSelector(frame, obj) {
46
44
  try {
47
45
  const parent = frame.parentFrame();
48
- if (parent) console.log(`Parent frame: ${JSON.stringify(parent)}`);
49
46
  if (!parent) return { children: obj };
50
47
  const frameElement = await frame.frameElement();
51
48
  if (!frameElement) return;
@@ -54,6 +51,7 @@ async function findNestedFrameSelector(frame, obj) {
54
51
  }, frameElement);
55
52
  return findNestedFrameSelector(parent, { children: obj, selectors });
56
53
  } catch (e) {
54
+ socketLogger.error(`Error in findNestedFrameSelector: ${e}`);
57
55
  console.error(e);
58
56
  }
59
57
  }
@@ -150,6 +148,7 @@ const transformAction = (action, el, isVerify, isPopupCloseClick, isInHoverMode,
150
148
  };
151
149
  }
152
150
  default: {
151
+ socketLogger.error(`Action not supported: ${action.name}`);
153
152
  console.log("action not supported", action);
154
153
  throw new Error("action not supported");
155
154
  }
@@ -161,6 +160,7 @@ const transformAction = (action, el, isVerify, isPopupCloseClick, isInHoverMode,
161
160
  * @property {string} projectDir
162
161
  * @property {string} TOKEN
163
162
  * @property {(name:string, data:any)=> void} sendEvent
163
+ * @property {Object} logger
164
164
  */
165
165
  export class BVTRecorder {
166
166
  #currentURL = "";
@@ -174,7 +174,6 @@ export class BVTRecorder {
174
174
  */
175
175
  constructor(initialState) {
176
176
  Object.assign(this, initialState);
177
- this.logger = logger;
178
177
  this.screenshotMap = new Map();
179
178
  this.snapshotMap = new Map();
180
179
  this.scenariosStepsMap = new Map();
@@ -186,7 +185,6 @@ export class BVTRecorder {
186
185
  });
187
186
  this.pageSet = new Set();
188
187
  this.lastKnownUrlPath = "";
189
- // TODO: what is world?
190
188
  this.world = { attach: () => {} };
191
189
  this.shouldTakeScreenshot = true;
192
190
  this.watcher = null;
@@ -209,7 +207,7 @@ export class BVTRecorder {
209
207
  __bvt_recordCommand: async ({ frame, page, context }, event) => {
210
208
  this.#activeFrame = frame;
211
209
  const nestFrmLoc = await findNestedFrameSelector(frame);
212
- console.log(`Time taken for action: ${event.statistics.time}`);
210
+ this.logger.info(`Time taken for action: ${event.statistics.time}`);
213
211
  await this.onAction({ ...event, nestFrmLoc });
214
212
  },
215
213
  __bvt_getMode: async () => {
@@ -228,8 +226,7 @@ export class BVTRecorder {
228
226
  await this.onClosePopup();
229
227
  },
230
228
  __bvt_log: async (src, message) => {
231
- // this.logger.info(message);
232
- console.log(`Inside Browser: ${message}`);
229
+ this.logger.info(`Inside Browser: ${message}`);
233
230
  },
234
231
  __bvt_getObject: (_src, obj) => {
235
232
  this.processObject(obj);
@@ -303,7 +300,7 @@ export class BVTRecorder {
303
300
  try {
304
301
  ai_config = JSON.parse(readFileSync(ai_config_file, "utf8"));
305
302
  } catch (error) {
306
- console.error("Error reading ai_config.json", error);
303
+ this.logger.error("Error reading ai_config.json", error);
307
304
  }
308
305
  }
309
306
  this.config = ai_config;
@@ -315,10 +312,7 @@ export class BVTRecorder {
315
312
  ],
316
313
  };
317
314
 
318
- let startTime = Date.now();
319
315
  const bvtContext = await initContext(url, false, false, this.world, 450, initScripts, this.envName);
320
- let stopTime = Date.now();
321
- this.logger.info(`Browser launched in ${(stopTime - startTime) / 1000} s`);
322
316
  this.bvtContext = bvtContext;
323
317
  this.stepRunner = new BVTStepRunner({
324
318
  projectDir: this.projectDir,
@@ -326,23 +320,18 @@ export class BVTRecorder {
326
320
  if (data && data.type) {
327
321
  switch (data.type) {
328
322
  case "cmdExecutionStart":
329
- console.log("Sending cmdExecutionStart event for cmdId:", data);
330
323
  this.sendEvent(this.events.cmdExecutionStart, data);
331
324
  break;
332
325
  case "cmdExecutionSuccess":
333
- console.log("Sending cmdExecutionSuccess event for cmdId:", data);
334
326
  this.sendEvent(this.events.cmdExecutionSuccess, data);
335
327
  break;
336
328
  case "cmdExecutionError":
337
- console.log("Sending cmdExecutionError event for cmdId:", data);
338
329
  this.sendEvent(this.events.cmdExecutionError, data);
339
330
  break;
340
331
  case "interceptResults":
341
- console.log("Sending interceptResults event");
342
332
  this.sendEvent(this.events.interceptResults, data);
343
333
  break;
344
334
  default:
345
- console.warn("Unknown command execution status type:", data.type);
346
335
  break;
347
336
  }
348
337
  }
@@ -381,13 +370,15 @@ export class BVTRecorder {
381
370
  }
382
371
  return;
383
372
  } catch (error) {
384
- console.error("Error evaluting in context:", error);
373
+ // console.error("Error evaluting in context:", error);
374
+ this.logger.error("Error evaluating in context:", error);
385
375
  }
386
376
  }
387
377
  }
388
378
 
389
379
  getMode() {
390
- console.log("getMode", this.#mode);
380
+ // console.log("getMode", this.#mode);
381
+ this.logger.info("Current mode:", this.#mode);
391
382
  return this.#mode;
392
383
  }
393
384
 
@@ -429,6 +420,8 @@ export class BVTRecorder {
429
420
  this.sendEvent(this.events.onBrowserClose);
430
421
  }
431
422
  } catch (error) {
423
+ this.logger.error("Error in page close event");
424
+ this.logger.error(error);
432
425
  console.error("Error in page close event");
433
426
  console.error(error);
434
427
  }
@@ -439,8 +432,10 @@ export class BVTRecorder {
439
432
  if (frame !== page.mainFrame()) return;
440
433
  this.handlePageTransition();
441
434
  } catch (error) {
435
+ this.logger.error("Error in handlePageTransition event");
436
+ this.logger.error(error);
442
437
  console.error("Error in handlePageTransition event");
443
- // console.error(error);
438
+ console.error(error);
444
439
  }
445
440
  try {
446
441
  if (frame !== this.#activeFrame) return;
@@ -459,6 +454,8 @@ export class BVTRecorder {
459
454
  // await this._setRecordingMode(frame);
460
455
  // await this._initPage(page);
461
456
  } catch (error) {
457
+ this.logger.error("Error in frame navigate event");
458
+ this.logger.error(error);
462
459
  console.error("Error in frame navigate event");
463
460
  // console.error(error);
464
461
  }
@@ -541,13 +538,9 @@ export class BVTRecorder {
541
538
 
542
539
  try {
543
540
  const result = await client.send("Page.getNavigationHistory");
544
- // console.log("Navigation History:", result);
545
541
  const entries = result.entries;
546
542
  const currentIndex = result.currentIndex;
547
543
 
548
- // ignore if currentIndex is not the last entry
549
- // if (currentIndex !== entries.length - 1) return;
550
-
551
544
  const currentEntry = entries[currentIndex];
552
545
  const transitionInfo = this.analyzeTransitionType(entries, currentIndex, currentEntry);
553
546
  this.previousIndex = currentIndex;
@@ -560,6 +553,8 @@ export class BVTRecorder {
560
553
  navigationAction: transitionInfo.action,
561
554
  };
562
555
  } catch (error) {
556
+ this.logger.error("Error in getCurrentTransition event");
557
+ this.logger.error(error);
563
558
  console.error("Error in getTransistionType event", error);
564
559
  } finally {
565
560
  await client.detach();
@@ -628,6 +623,8 @@ export class BVTRecorder {
628
623
  // add listener for frame navigation on new tab
629
624
  this._addFrameNavigateListener(page);
630
625
  } catch (error) {
626
+ this.logger.error("Error in page event");
627
+ this.logger.error(error);
631
628
  console.error("Error in page event");
632
629
  console.error(error);
633
630
  }
@@ -669,6 +666,7 @@ export class BVTRecorder {
669
666
  const { data } = await client.send("Page.captureScreenshot", { format: "png" });
670
667
  return data;
671
668
  } catch (error) {
669
+ this.logger.error("Error in taking browser screenshot");
672
670
  console.error("Error in taking browser screenshot", error);
673
671
  } finally {
674
672
  await client.detach();
@@ -838,6 +836,7 @@ export class BVTRecorder {
838
836
  BLINQ_ENV: this.envName,
839
837
  STORE_DETAILED_NETWORK_DATA: listenNetwork ? "true" : "false",
840
838
  CURRENT_STEP_ID: step.id,
839
+ DEBUG: "blinq:route",
841
840
  };
842
841
 
843
842
  this.bvtContext.navigate = true;
@@ -966,10 +965,11 @@ export class BVTRecorder {
966
965
  if (existsSync(_getDataFile(this.world, this.bvtContext, this.web))) {
967
966
  try {
968
967
  const testData = JSON.parse(readFileSync(_getDataFile(this.world, this.bvtContext, this.web), "utf8"));
969
- this.logger.info("Test data", testData);
968
+ // this.logger.info("Test data", testData);
970
969
  this.sendEvent(this.events.getTestData, testData);
971
970
  } catch (e) {
972
- this.logger.error("Error reading test data file", e);
971
+ // this.logger.error("Error reading test data file", e);
972
+ console.log("Error reading test data file", e);
973
973
  }
974
974
  }
975
975
 
@@ -978,10 +978,12 @@ export class BVTRecorder {
978
978
  this.watcher.on("all", async (event, path) => {
979
979
  try {
980
980
  const testData = JSON.parse(await readFile(_getDataFile(this.world, this.bvtContext, this.web), "utf8"));
981
- this.logger.info("Test data", testData);
981
+ // this.logger.info("Test data", testData);
982
+ console.log("Test data changed", testData);
982
983
  this.sendEvent(this.events.getTestData, testData);
983
984
  } catch (e) {
984
- this.logger.error("Error reading test data file", e);
985
+ // this.logger.error("Error reading test data file", e);
986
+ console.log("Error reading test data file", e);
985
987
  }
986
988
  });
987
989
  }
@@ -1014,7 +1016,7 @@ export class BVTRecorder {
1014
1016
  .filter((file) => file.endsWith(".feature"))
1015
1017
  .map((file) => path.join(this.projectDir, "features", file));
1016
1018
  try {
1017
- const parsedFiles = featureFiles.map((file) => parseFeatureFile(file));
1019
+ const parsedFiles = featureFiles.map((file) => this.parseFeatureFile(file));
1018
1020
  const output = {};
1019
1021
  parsedFiles.forEach((file) => {
1020
1022
  if (!file.feature) return;
@@ -1042,7 +1044,7 @@ export class BVTRecorder {
1042
1044
  loadExistingScenario({ featureName, scenarioName }) {
1043
1045
  const step_definitions = loadStepDefinitions(this.projectDir);
1044
1046
  const featureFilePath = path.join(this.projectDir, "features", featureName);
1045
- const gherkinDoc = parseFeatureFile(featureFilePath);
1047
+ const gherkinDoc = this.parseFeatureFile(featureFilePath);
1046
1048
  const scenario = gherkinDoc.feature.children.find((child) => child.scenario.name === scenarioName)?.scenario;
1047
1049
 
1048
1050
  const steps = [];
@@ -1201,20 +1203,21 @@ export class BVTRecorder {
1201
1203
  await this.cleanupExecution({ tags });
1202
1204
  await this.initExecution({ tags });
1203
1205
  }
1204
- }
1205
1206
 
1206
- const parseFeatureFile = (featureFilePath) => {
1207
- try {
1208
- let id = 0;
1209
- const uuidFn = () => (++id).toString(16);
1210
- const builder = new AstBuilder(uuidFn);
1211
- const matcher = new GherkinClassicTokenMatcher();
1212
- const parser = new Parser(builder, matcher);
1213
- const source = readFileSync(featureFilePath, "utf8");
1214
- const gherkinDocument = parser.parse(source);
1215
- return gherkinDocument;
1216
- } catch (e) {
1217
- console.log(e);
1207
+ parseFeatureFile(featureFilePath) {
1208
+ try {
1209
+ let id = 0;
1210
+ const uuidFn = () => (++id).toString(16);
1211
+ const builder = new AstBuilder(uuidFn);
1212
+ const matcher = new GherkinClassicTokenMatcher();
1213
+ const parser = new Parser(builder, matcher);
1214
+ const source = readFileSync(featureFilePath, "utf8");
1215
+ const gherkinDocument = parser.parse(source);
1216
+ return gherkinDocument;
1217
+ } catch (e) {
1218
+ this.logger.error(`Error parsing feature file: ${featureFilePath}`);
1219
+ console.log(e);
1220
+ }
1221
+ return {};
1218
1222
  }
1219
- return {};
1220
- };
1223
+ }
@@ -4,6 +4,7 @@ import { BVTRecorder } from "./bvt_recorder.js";
4
4
  import { compareWithScenario } from "../code_gen/duplication_analysis.js";
5
5
  import { getAppDataDir } from "./app_dir.js";
6
6
  import { readdir } from "fs/promises";
7
+ import socketLogger from "../utils/socket_logger.js";
7
8
 
8
9
  let port = process.env.EDITOR_PORT || 3003;
9
10
  const WS_URL = "http://localhost:" + port;
@@ -16,7 +17,9 @@ class PromisifiedSocketServer {
16
17
  init() {
17
18
  this.socket.on("request", async (data) => {
18
19
  const { event, input, id, roomId, socketId } = data;
19
- console.log("request", { event, input, id, roomId, socketId });
20
+ if (event !== "recorderWindow.getCurrentChromiumPath") {
21
+ socketLogger.info("Received request", { event, input, id, roomId, socketId });
22
+ }
20
23
  try {
21
24
  const handler = this.routes[event];
22
25
  if (!handler) {
@@ -24,17 +27,12 @@ class PromisifiedSocketServer {
24
27
  return;
25
28
  }
26
29
  const response = await handler(input);
27
- // console.log("response", { id, value: response, roomId, socketId });
30
+ if (event !== "recorderWindow.getCurrentChromiumPath") {
31
+ socketLogger.info(`Sending response`, { event, id, value: response, roomId, socketId });
32
+ }
28
33
  this.socket.emit("response", { id, value: response, roomId, socketId });
29
34
  } catch (error) {
30
- console.log("request", JSON.stringify({ event, input, id, roomId, socketId }));
31
- console.error("response", { id, error, roomId, socketId });
32
- // console.error({
33
- // message: error?.message,
34
- // code: error?.code,
35
- // info: error?.info,
36
- // stack: error?.stack,
37
- // })
35
+ socketLogger.error("Error handling request", { event, input, id, roomId, socketId, error });
38
36
  this.socket.emit("response", {
39
37
  id,
40
38
  error: {
@@ -51,45 +49,17 @@ class PromisifiedSocketServer {
51
49
  }
52
50
  }
53
51
 
54
- function memorySizeOf(obj) {
55
- var bytes = 0;
56
-
57
- function sizeOf(obj) {
58
- if (obj !== null && obj !== undefined) {
59
- switch (typeof obj) {
60
- case "number":
61
- bytes += 8;
62
- break;
63
- case "string":
64
- bytes += obj.length * 2;
65
- break;
66
- case "boolean":
67
- bytes += 4;
68
- break;
69
- case "object":
70
- var objClass = Object.prototype.toString.call(obj).slice(8, -1);
71
- if (objClass === "Object" || objClass === "Array") {
72
- for (var key in obj) {
73
- if (!obj.hasOwnProperty(key)) continue;
74
- sizeOf(obj[key]);
75
- }
76
- } else bytes += obj.toString().length * 2;
77
- break;
78
- }
79
- }
80
- return bytes;
81
- }
82
- return sizeOf(obj);
83
- }
84
-
85
52
  const init = ({ envName, projectDir, roomId, TOKEN }) => {
86
- console.log("connecting to " + WS_URL);
53
+ console.log("Connecting to " + WS_URL);
87
54
  const socket = io(WS_URL);
55
+ socketLogger.init(socket, { context: "BVTRecorder", eventName: "BVTRecorder.log" });
88
56
  socket.on("connect", () => {
89
- console.log("connected to server");
57
+ socketLogger.info("Connected to BVTRecorder server");
58
+ console.log("Connected to BVTRecorder server");
90
59
  });
91
60
  socket.on("disconnect", () => {
92
- console.log("disconnected from server");
61
+ socketLogger.info("Disconnected from server");
62
+ console.log("Disconnected from server");
93
63
  });
94
64
  socket.emit("joinRoom", { id: roomId, window: "cucumber_client/bvt_recorder" });
95
65
  const recorder = new BVTRecorder({
@@ -97,20 +67,19 @@ const init = ({ envName, projectDir, roomId, TOKEN }) => {
97
67
  projectDir,
98
68
  TOKEN,
99
69
  sendEvent: (event, data) => {
100
- console.log("Size of data", memorySizeOf(data), "bytes");
101
- console.log("----", event, data, "roomId", roomId);
70
+ socketLogger.info("Sending event", { event, data, roomId });
102
71
  socket.emit(event, data, roomId);
103
- console.log("Successfully sent event", event, "to room", roomId);
104
72
  },
73
+ logger: socketLogger,
105
74
  });
106
75
  recorder
107
76
  .openBrowser()
108
77
  .then(() => {
109
- // console.log("BVTRecorder.browserOpened");
78
+ socketLogger.info("BVTRecorder.browserOpened");
110
79
  socket.emit("BVTRecorder.browserOpened", null, roomId);
111
80
  })
112
81
  .catch((e) => {
113
- console.error("BVTRecorder.browserLaunchFailed", e);
82
+ socketLogger.error("BVTRecorder.browserLaunchFailed", e);
114
83
  socket.emit("BVTRecorder.browserLaunchFailed", e, roomId);
115
84
  });
116
85
  const timeOutForFunction = async (promise, timeout = 5000) => {
@@ -121,6 +90,7 @@ const init = ({ envName, projectDir, roomId, TOKEN }) => {
121
90
  return res;
122
91
  } catch (error) {
123
92
  console.error(error);
93
+ socketLogger.error(error);
124
94
  throw error;
125
95
  }
126
96
  };
@@ -130,10 +100,13 @@ const init = ({ envName, projectDir, roomId, TOKEN }) => {
130
100
  return recorder
131
101
  .openBrowser(input)
132
102
  .then(() => {
103
+ socketLogger.info("BVTRecorder.browserOpened");
104
+ console.info("BVTRecorder.browserOpened");
133
105
  socket.emit("BVTRecorder.browserOpened", { roomId, window: "cucumber_client/bvt_recorder" });
134
106
  })
135
107
  .catch((e) => {
136
- console.error(e);
108
+ socketLogger.error("Error opening browser", e);
109
+ console.error("BVTRecorder.browserLaunchFailed", e);
137
110
  socket.emit("BVTRecorder.browserLaunchFailed", { roomId, window: "cucumber_client/bvt_recorder" });
138
111
  });
139
112
  },
@@ -144,10 +117,12 @@ const init = ({ envName, projectDir, roomId, TOKEN }) => {
144
117
  return recorder
145
118
  .reOpenBrowser(input)
146
119
  .then(() => {
147
- // console.log("BVTRecorder.browserOpened");
120
+ socketLogger.info("BVTRecorder.browserOpened");
121
+ console.log("BVTRecorder.browserOpened");
148
122
  socket.emit("BVTRecorder.browserOpened", null, roomId);
149
123
  })
150
124
  .catch((e) => {
125
+ socketLogger.info("BVTRecorder.browserLaunchFailed");
151
126
  console.error("BVTRecorder.browserLaunchFailed", e);
152
127
  socket.emit("BVTRecorder.browserLaunchFailed", null, roomId);
153
128
  });
@@ -247,9 +222,7 @@ const init = ({ envName, projectDir, roomId, TOKEN }) => {
247
222
  "recorderWindow.getSnapshotFiles": async (input) => {
248
223
  const snapshotFolder = recorder.getSnapshotFolder();
249
224
  if (snapshotFolder) {
250
- // Get the list of filenames in the snapshot folder
251
225
  const files = await readdir(snapshotFolder);
252
- // Filter the files to only include .png files
253
226
  const ymlFiles = files.filter((file) => file.endsWith(".yml") || file.endsWith(".yaml"));
254
227
  return { folder: snapshotFolder, files: ymlFiles };
255
228
  } else return { folder: null, files: [] };
@@ -318,7 +291,6 @@ try {
318
291
  showUsage(error, usage);
319
292
  }
320
293
  try {
321
- // console.log({ envName, projectDir, featureName, scenarioName, stepIndex, roomId })
322
294
  init({
323
295
  envName,
324
296
  projectDir,
@@ -15,20 +15,7 @@ export class NamesService {
15
15
  if (!screenshot && commands.length > 1) {
16
16
  screenshot = this.screenshotMap.get(commands[commands.length - 2].inputID);
17
17
  }
18
- this.logger.info(
19
- "data: " +
20
- JSON.stringify(
21
- {
22
- commands,
23
- stepsNames,
24
- parameters,
25
- map,
26
- },
27
- null,
28
- 2
29
- )
30
- );
31
- // get screenshot for the last command
18
+
32
19
  const url = `${getRunsServiceBaseURL()}/generate-step-information/generate`;
33
20
  const TIMEOUT = 120; // 2 minutes
34
21
  const { data } = await axiosClient({
@@ -65,6 +52,7 @@ export class NamesService {
65
52
  }
66
53
  } catch (error) {
67
54
  if (i === TIMEOUT - 1) {
55
+ this.logger.error("Timeout while generating step details: ", error);
68
56
  console.error("Timeout while generating step details: ", error);
69
57
  }
70
58
  }
@@ -96,7 +84,6 @@ export class NamesService {
96
84
  scenario: scenarioAsText,
97
85
  };
98
86
 
99
- this.logger.info("data: " + JSON.stringify(genObject, null, 2));
100
87
  // get screenshot for the last command
101
88
  const url = `${getRunsServiceBaseURL()}/generate-step-information/generate_scenario_feature`;
102
89
  const TIMEOUT = 120; // 2 minutes
@@ -140,6 +127,7 @@ export class NamesService {
140
127
  if (result.status !== 200) {
141
128
  return { success: false, message: "Error while generating step details" };
142
129
  }
130
+
143
131
  return result.data;
144
132
  }
145
133
 
@@ -0,0 +1,132 @@
1
+ /**
2
+ * @typedef {Object} SocketLoggerEventPayload
3
+ * @property {string} level Log level (e.g. "info", "warn", "error", "debug")
4
+ * @property {string} context Log context/subsystem (e.g. "BVTRecorder")
5
+ * @property {*} data The log message payload (string, object, etc)
6
+ * @property {string} timestamp ISO string when the log was emitted
7
+ * @property {number} dataSize Size of data in bytes (-1 if unknown)
8
+ */
9
+
10
+ /**
11
+ * @typedef {Object} SocketLoggerInitOptions
12
+ * @property {string=} context Default context for all logs (optional)
13
+ * @property {string=} eventName Default event name (default: "recorder.log")
14
+ */
15
+
16
+ /**
17
+ * SocketLogger - Singleton for structured socket-based logging.
18
+ *
19
+ * @namespace SocketLogger
20
+ * @property {function(import('socket.io-client').Socket|import('socket.io').Socket, SocketLoggerInitOptions=):void} init
21
+ * @property {function(string, (string|*), Object=, string=, string=):void} log
22
+ * @property {function((string|*), Object=):void} info
23
+ * @property {function((string|*), Object=):void} warn
24
+ * @property {function((string|*), Object=):void} debug
25
+ * @property {function((string|*), Object=):void} error
26
+ *
27
+ * @example
28
+ * import logger from "./socket_logger.js";
29
+ * logger.init(socket, { context: "BVTRecorder" });
30
+ * logger.info("Step started", { step: 2 });
31
+ * logger.error("Failed!", { error: "bad stuff" });
32
+ */
33
+ const SocketLogger = (function () {
34
+ /** @type {import('socket.io-client').Socket|import('socket.io').Socket|null} */
35
+ let socket = null;
36
+ /** @type {string} */
37
+ let defaultContext = "";
38
+ /** @type {string} */
39
+ let defaultEventName = "recorder.log";
40
+
41
+ /**
42
+ * Initialize the logger (call once).
43
+ * @param {import('socket.io-client').Socket|import('socket.io').Socket} sock
44
+ * @param {SocketLoggerInitOptions=} opts
45
+ */
46
+ function init(sock, opts) {
47
+ socket = sock;
48
+ defaultContext = (opts && opts.context) || "";
49
+ defaultEventName = (opts && opts.eventName) || "recorder.log";
50
+ }
51
+
52
+ /**
53
+ * Low-level log method (most users use info/warn/debug/error).
54
+ * @param {string} level Log level ("info", "warn", "debug", "error")
55
+ * @param {string|*} message The log message or object
56
+ * @param {Object=} extra Extra fields (will be merged into log payload)
57
+ * @param {string=} eventName Override event name for this log (default: "recorder.log")
58
+ * @param {string=} context Override log context for this log (default: set in init)
59
+ */
60
+ function log(level, message, extra, eventName, context) {
61
+ if (!socket || typeof socket.emit !== "function") return;
62
+ /** @type {*} */
63
+ var data = typeof message === "object" ? message : { message: message };
64
+ /** @type {number} */
65
+ var dataSize = 0;
66
+ try {
67
+ dataSize = Buffer.byteLength(JSON.stringify(data || ""), "utf8");
68
+ } catch (e) {
69
+ dataSize = -1;
70
+ }
71
+ /** @type {SocketLoggerEventPayload} */
72
+ var eventPayload = Object.assign(
73
+ {
74
+ level: level,
75
+ context: context || defaultContext,
76
+ data: data,
77
+ timestamp: new Date().toISOString(),
78
+ dataSize: dataSize,
79
+ },
80
+ extra || {}
81
+ );
82
+ // @ts-ignore
83
+ try {
84
+ if (socket) {
85
+ socket.emit(eventName || defaultEventName, eventPayload);
86
+ }
87
+ } catch (e) {
88
+ console.error("Socket logging error:", e);
89
+ console.log("Socket event payload:", eventPayload);
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Write an info-level log event.
95
+ * @param {string|*} msg The message or object
96
+ * @param {Object=} ext Any extra fields/metadata
97
+ */
98
+ function info(msg, ext) {
99
+ log("info", msg, ext);
100
+ }
101
+
102
+ /**
103
+ * Write a warn-level log event.
104
+ * @param {string|*} msg The message or object
105
+ * @param {Object=} ext Any extra fields/metadata
106
+ */
107
+ function warn(msg, ext) {
108
+ log("warn", msg, ext);
109
+ }
110
+
111
+ /**
112
+ * Write a debug-level log event.
113
+ * @param {string|*} msg The message or object
114
+ * @param {Object=} ext Any extra fields/metadata
115
+ */
116
+ function debug(msg, ext) {
117
+ log("debug", msg, ext);
118
+ }
119
+
120
+ /**
121
+ * Write an error-level log event.
122
+ * @param {string|*} msg The message or object
123
+ * @param {Object=} ext Any extra fields/metadata
124
+ */
125
+ function error(msg, ext) {
126
+ log("error", msg, ext);
127
+ }
128
+
129
+ return { init, log, info, warn, debug, error };
130
+ })();
131
+
132
+ export default SocketLogger;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dev-blinq/cucumber_client",
3
- "version": "1.0.1417-dev",
3
+ "version": "1.0.1418-dev",
4
4
  "description": " ",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",