@dev-blinq/cucumber_client 1.0.1444-dev → 1.0.1444-stage

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 (50) hide show
  1. package/bin/assets/bundled_scripts/recorder.js +73 -73
  2. package/bin/assets/preload/css_gen.js +10 -10
  3. package/bin/assets/preload/toolbar.js +27 -29
  4. package/bin/assets/preload/unique_locators.js +1 -1
  5. package/bin/assets/preload/yaml.js +288 -275
  6. package/bin/assets/scripts/aria_snapshot.js +223 -220
  7. package/bin/assets/scripts/dom_attr.js +329 -329
  8. package/bin/assets/scripts/dom_parent.js +169 -174
  9. package/bin/assets/scripts/event_utils.js +94 -94
  10. package/bin/assets/scripts/pw.js +2050 -1949
  11. package/bin/assets/scripts/recorder.js +70 -45
  12. package/bin/assets/scripts/snapshot_capturer.js +147 -147
  13. package/bin/assets/scripts/unique_locators.js +170 -49
  14. package/bin/assets/scripts/yaml.js +796 -783
  15. package/bin/assets/templates/_hooks_template.txt +6 -2
  16. package/bin/assets/templates/utils_template.txt +16 -16
  17. package/bin/client/code_cleanup/find_step_definition_references.js +0 -1
  18. package/bin/client/code_cleanup/utils.js +16 -7
  19. package/bin/client/code_gen/api_codegen.js +2 -2
  20. package/bin/client/code_gen/code_inversion.js +119 -2
  21. package/bin/client/code_gen/duplication_analysis.js +2 -1
  22. package/bin/client/code_gen/function_signature.js +4 -0
  23. package/bin/client/code_gen/page_reflection.js +52 -11
  24. package/bin/client/code_gen/playwright_codeget.js +163 -75
  25. package/bin/client/cucumber/feature.js +4 -17
  26. package/bin/client/cucumber/feature_data.js +2 -2
  27. package/bin/client/cucumber/project_to_document.js +8 -2
  28. package/bin/client/cucumber/steps_definitions.js +19 -3
  29. package/bin/client/local_agent.js +1 -0
  30. package/bin/client/parse_feature_file.js +23 -26
  31. package/bin/client/playground/projects/env.json +2 -2
  32. package/bin/client/recorderv3/bvt_init.js +305 -0
  33. package/bin/client/recorderv3/bvt_recorder.js +1024 -58
  34. package/bin/client/recorderv3/implemented_steps.js +2 -0
  35. package/bin/client/recorderv3/index.js +3 -283
  36. package/bin/client/recorderv3/services.js +818 -142
  37. package/bin/client/recorderv3/step_runner.js +20 -6
  38. package/bin/client/recorderv3/step_utils.js +542 -73
  39. package/bin/client/recorderv3/update_feature.js +87 -39
  40. package/bin/client/recorderv3/wbr_entry.js +61 -0
  41. package/bin/client/recording.js +1 -0
  42. package/bin/client/upload-service.js +4 -2
  43. package/bin/client/utils/app_dir.js +21 -0
  44. package/bin/client/utils/socket_logger.js +87 -125
  45. package/bin/index.js +4 -1
  46. package/package.json +11 -5
  47. package/bin/client/recorderv3/app_dir.js +0 -23
  48. package/bin/client/recorderv3/network.js +0 -299
  49. package/bin/client/recorderv3/scriptTest.js +0 -5
  50. package/bin/client/recorderv3/ws_server.js +0 -72
@@ -5,6 +5,8 @@ import path from "path";
5
5
  import { CodePage } from "./page_reflection.js";
6
6
  import { convertToIdentifier, escapeNonPrintables } from "./utils.js";
7
7
  import socketLogger from "../utils/socket_logger.js";
8
+ import fs from "fs";
9
+
8
10
  const findElementIdentifier = (node, step, userData, elements) => {
9
11
  if (node.key) {
10
12
  // incase of rerunning implemented steps
@@ -47,6 +49,7 @@ const findElementIdentifier = (node, step, userData, elements) => {
47
49
  return elementIdentifier;
48
50
  };
49
51
  const _isCodeGenerationStep = (step) => {
52
+ return true;
50
53
  if (
51
54
  step.type === Types.CLICK ||
52
55
  step.type === Types.FILL ||
@@ -67,12 +70,44 @@ const _isCodeGenerationStep = (step) => {
67
70
  step.type === Types.VERIFY_PROPERTY ||
68
71
  step.type === Types.SET_INPUT_FILES ||
69
72
  step.type === Types.VERIFY_PAGE_SNAPSHOT ||
70
- step.type === Types.CONDITIONAL_WAIT
73
+ step.type === Types.CONDITIONAL_WAIT ||
74
+ step.type === Types.CLOSE_PAGE
71
75
  ) {
72
76
  return true;
73
77
  }
74
78
  return false;
75
79
  };
80
+
81
+ const _isLocatorStrategyStep = (step) => {
82
+ switch (step.type) {
83
+ case Types.VERIFY_PAGE_SNAPSHOT:
84
+ case Types.CLOSE_PAGE:
85
+ case Types.VERIFY_FILE_EXISTS:
86
+ case Types.VERIFY_PAGE_CONTAINS_NO_TEXT:
87
+ case Types.VERIFY_PAGE_CONTAINS_TEXT:
88
+ case Types.VERIFY_PAGE_PATH:
89
+ case Types.VERIFY_PAGE_TITLE:
90
+ case Types.VERIFY_TEXT_RELATED_TO_TEXT:
91
+ case Types.NAVIGATE:
92
+ case Types.RELOAD:
93
+ case Types.GO_BACK:
94
+ case Types.GO_FORWARD:
95
+ case Types.SLEEP:
96
+ case Types.SET_VIEWPORT:
97
+ case Types.VISUAL_VERIFICATION:
98
+ case Types.LOAD_DATA:
99
+ case Types.MAIL_GET_CODE_OR_URL:
100
+ case Types.ASK:
101
+ case Types.WAIT_FOR_USER_INPUT:
102
+ case Types.COMPLETE:
103
+ case Types.CLICK_SIMPLE:
104
+ case Types.FILL_SIMPLE:
105
+ case Types.API:
106
+ return false;
107
+ default:
108
+ return true;
109
+ }
110
+ };
76
111
  // Note: this function is used to exclude a key from an object
77
112
  // Please move it to utils and use it as a reusable function ...
78
113
  function excludeKey(obj, keyToRemove) {
@@ -97,6 +132,20 @@ const splitToLocatorsGroups = (locators) => {
97
132
  });
98
133
  return { basic, no_text, ignore_digit, context };
99
134
  };
135
+
136
+ const serializeOptions = (options, context) => {
137
+ if (!options) return "null";
138
+ if (typeof options !== 'object') return "null";
139
+ if (Array.isArray(options)) return "null";
140
+ let result = "{ ";
141
+ if (context) result += `"context": ${context}, `;
142
+ for (const key in options) {
143
+ result += `"${key}": ${JSON.stringify(options[key])}, `;
144
+ }
145
+ result += " }";
146
+ return result;
147
+ }
148
+
100
149
  const _generateCodeFromCommand = (step, elements, userData) => {
101
150
  let elementsChanged = false;
102
151
 
@@ -105,7 +154,12 @@ const _generateCodeFromCommand = (step, elements, userData) => {
105
154
  // handle element
106
155
  let element_name = null;
107
156
  let allStrategyLocators = null;
108
- if (_isCodeGenerationStep(step) && step.type !== Types.VERIFY_PAGE_SNAPSHOT) {
157
+ const codeLines = [];
158
+
159
+ if (_isCodeGenerationStep(step) === false)
160
+ return { codeLines, elements: elementsChanged ? elements : null, elementIdentifier, allStrategyLocators };
161
+
162
+ if (_isCodeGenerationStep(step) && _isLocatorStrategyStep(step)) {
109
163
  allStrategyLocators = step.allStrategyLocators ?? splitToLocatorsGroups(step.locators);
110
164
  let node = null;
111
165
 
@@ -167,8 +221,6 @@ const _generateCodeFromCommand = (step, elements, userData) => {
167
221
  }
168
222
  }
169
223
 
170
- const codeLines = [];
171
-
172
224
  let line = null;
173
225
  let comment = null;
174
226
  let input = null;
@@ -176,7 +228,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
176
228
  let attribute = null;
177
229
  let variable = null;
178
230
  let format = null;
179
- let options = null;
231
+ let options = step.options ?? null;
180
232
  let property = null;
181
233
  switch (step.type) {
182
234
  case Types.SET_INPUT:
@@ -186,7 +238,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
186
238
  //parameters.push(step.dataKey);
187
239
  input = "_" + step.dataKey;
188
240
  }
189
- line += `${input}, _params, null, this);`;
241
+ line += `${input}, _params, ${serializeOptions(options)}, this);`;
190
242
  if (element_name) {
191
243
  comment = `// Set ${element_name} to ${input}`;
192
244
  codeLines.push(escapeNonPrintables(comment));
@@ -199,7 +251,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
199
251
  comment = `// Check ${element_name}`;
200
252
  codeLines.push(escapeNonPrintables(comment));
201
253
  }
202
- line = `await context.web.setCheck(elements["${elementIdentifier}"], ${step.check}, _params, null, this);`;
254
+ line = `await context.web.setCheck(elements["${elementIdentifier}"], ${step.check}, _params, ${serializeOptions(options)}, this);`;
203
255
  codeLines.push(line);
204
256
  } else {
205
257
  switch (step.count) {
@@ -208,7 +260,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
208
260
  comment = `// Click on ${element_name}`;
209
261
  codeLines.push(escapeNonPrintables(comment));
210
262
  }
211
- line = `await context.web.click(elements["${elementIdentifier}"], _params, null, this);`;
263
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
212
264
  codeLines.push(line);
213
265
  break;
214
266
  case 2:
@@ -216,7 +268,9 @@ const _generateCodeFromCommand = (step, elements, userData) => {
216
268
  comment = `// Double click on ${element_name}`;
217
269
  codeLines.push(escapeNonPrintables(comment));
218
270
  }
219
- line = `await context.web.click(elements["${elementIdentifier}"], _params, {clickCount:2}, this);`;
271
+ options = options ?? {};
272
+ options.clickCount = 2;
273
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
220
274
  codeLines.push(line);
221
275
  break;
222
276
  default:
@@ -224,7 +278,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
224
278
  comment = `// Click on ${element_name}`;
225
279
  codeLines.push(escapeNonPrintables(comment));
226
280
  }
227
- line = `await context.web.click(elements["${elementIdentifier}"], _params, null, this);`;
281
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
228
282
  codeLines.push(line);
229
283
  break;
230
284
  }
@@ -235,17 +289,19 @@ const _generateCodeFromCommand = (step, elements, userData) => {
235
289
  case 1:
236
290
  comment = `// Parameterized click on ${step.value}`;
237
291
  codeLines.push(escapeNonPrintables(comment));
238
- line = `await context.web.click(elements["${elementIdentifier}"], _params, null, this);`;
292
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
239
293
  break;
240
294
  case 2:
241
295
  comment = `// Parameterized double click on ${step.value}`;
242
296
  codeLines.push(escapeNonPrintables(comment));
243
- line = `await context.web.click(elements["${elementIdentifier}"], _params, {clickCount:2}, this);`;
297
+ options = options ?? {};
298
+ options.clickCount = 2;
299
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
244
300
  break;
245
301
  default:
246
302
  comment = `// Parameterized click on ${step.value}`;
247
303
  codeLines.push(escapeNonPrintables(comment));
248
- line = `await context.web.click(elements["${elementIdentifier}"], _params, null, this);`;
304
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
249
305
  }
250
306
  codeLines.push(line);
251
307
  break;
@@ -264,7 +320,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
264
320
  } else {
265
321
  enter = '"' + step.parameters[2] + '"';
266
322
  }
267
- line += `${input}, "${format}", ${enter}, _params, null, this);`;
323
+ line += `${input}, "${format}", ${enter}, _params, ${serializeOptions(options)}, this);`;
268
324
  if (element_name) {
269
325
  comment = `// Set date time ${element_name} to "${input}" with format "${format}"`;
270
326
  codeLines.push(escapeNonPrintables(comment));
@@ -286,7 +342,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
286
342
  } else {
287
343
  enter = '"' + step.parameters[1] + '"';
288
344
  }
289
- line += `${input}, ${enter}, _params, null, this);`;
345
+ line += `${input}, ${enter}, _params, ${serializeOptions(options)}, this);`;
290
346
  if (element_name) {
291
347
  comment = `// Fill ${element_name} with "${input}"`;
292
348
  codeLines.push(escapeNonPrintables(comment));
@@ -308,7 +364,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
308
364
  } else {
309
365
  enter = '"' + step.parameters[1] + '"';
310
366
  }
311
- line += `${input}, ${enter}, _params, null, this);`;
367
+ line += `${input}, ${enter}, _params, ${serializeOptions(options)}, this);`;
312
368
  if (element_name) {
313
369
  comment = `// Fill ${element_name} with "${input}"`;
314
370
  codeLines.push(escapeNonPrintables(comment));
@@ -322,15 +378,25 @@ const _generateCodeFromCommand = (step, elements, userData) => {
322
378
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
323
379
  input = "_" + step.dataKey;
324
380
  }
325
- let options = "null";
381
+ // let options = "null";
326
382
  if (step.regex !== "") {
327
- options = `{regex: ${JSON.stringify(step.regex)},trimSpaces: ${step.trimSpaces}}`;
383
+ options = options ?? {}
384
+ options = {
385
+ ...options,
386
+ regex: step.regex,
387
+ trimSpaces: step.trimSpaces
388
+ } // `{regex: ${JSON.stringify(step.regex)},trimSpaces: ${step.trimSpaces}}`;
328
389
  } else if (step.trimSpaces) {
329
- options = `{trimSpaces: ${step.trimSpaces}}`;
390
+ options = options ?? {}
391
+ options = {
392
+ ...options,
393
+ trimSpaces: step.trimSpaces
394
+ }
395
+ // options = `{trimSpaces: ${step.trimSpaces}}`;
330
396
  } else {
331
- options = "null";
397
+ options = null//"null";
332
398
  }
333
- line = `await context.web.extractAttribute(elements["${elementIdentifier}"], "${attribute}", ${input}, _params,${options}, this);`;
399
+ line = `await context.web.extractAttribute(elements["${elementIdentifier}"], "${attribute}", ${input}, _params, ${serializeOptions(options)}, this);`;
334
400
 
335
401
  if (element_name) {
336
402
  comment = `// Extract attribute ${attribute} from ${element_name} to ${variable}`;
@@ -346,15 +412,24 @@ const _generateCodeFromCommand = (step, elements, userData) => {
346
412
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
347
413
  input = "_" + step.dataKey;
348
414
  }
349
- let options = "null";
350
415
  if (step.regex !== "") {
351
- options = `{regex: ${JSON.stringify(step.regex)},trimSpaces: ${step.trimSpaces}}`;
416
+ options = options ?? {}
417
+ options = {
418
+ ...options,
419
+ regex: step.regex,
420
+ trimSpaces: step.trimSpaces
421
+ } // `{regex: ${JSON.stringify(step.regex)},trimSpaces: ${step.trimSpaces}}`;
352
422
  } else if (step.trimSpaces) {
353
- options = `{trimSpaces: ${step.trimSpaces}}`;
423
+ options = options ?? {}
424
+ options = {
425
+ ...options,
426
+ trimSpaces: step.trimSpaces
427
+ }
428
+ // options = `{trimSpaces: ${step.trimSpaces}}`;
354
429
  } else {
355
- options = "null";
430
+ options = null//"null";
356
431
  }
357
- line = `await context.web.extractProperty(elements["${elementIdentifier}"], "${property}", ${input}, _params,${options}, this);`;
432
+ line = `await context.web.extractProperty(elements["${elementIdentifier}"], "${property}", ${input}, _params, ${serializeOptions(options)}, this);`;
358
433
 
359
434
  if (element_name) {
360
435
  comment = `// Extract property ${property} from ${element_name} to ${variable}`;
@@ -363,23 +438,40 @@ const _generateCodeFromCommand = (step, elements, userData) => {
363
438
  codeLines.push(line);
364
439
  break;
365
440
  }
366
- case Types.VERIFY_PAGE_SNAPSHOT:
441
+ case Types.VERIFY_PAGE_SNAPSHOT: {
367
442
  comment = step.nestFrmLoc
368
443
  ? `// Verify page snapshot ${step.parameters[0]} in the frame ${step.selectors.iframe_src}`
369
444
  : `// Verify page snapshot ${step.parameters[0]}`;
370
445
  codeLines.push(escapeNonPrintables(comment));
371
446
  line = `const frameLocator = ${JSON.stringify(step.selectors ?? null)}`;
372
447
  codeLines.push(line);
373
- line = `await context.web.snapshotValidation(frameLocator, _param_0 , _params, ${JSON.stringify(options)}, this);`;
448
+ line = `await context.web.snapshotValidation(frameLocator,${step.valueInStepText ? "_param_0" : `"${step.parameters[0]}"`}, _params, ${serializeOptions(options)}, this);`;
374
449
  codeLines.push(line);
450
+
451
+ const data = step.data;
452
+ if (data) {
453
+ try {
454
+ const { snapshot, fileName, filePath } = data;
455
+ const folderPath = process.env.BVT_TEMP_SNAPSHOTS_FOLDER ?? filePath;
456
+ const filePathWithName = path.join(folderPath, fileName);
457
+ if (!fs.existsSync(folderPath)) {
458
+ fs.mkdirSync(folderPath, { recursive: true });
459
+ }
460
+ fs.writeFileSync(filePathWithName, snapshot, "utf-8");
461
+ } catch (e) {
462
+ console.log(`Error saving snapshot file: ${e}`);
463
+ throw e;
464
+ }
465
+ }
375
466
  break;
467
+ }
376
468
  case Types.VERIFY_PAGE_CONTAINS_TEXT:
377
469
  line = "await context.web.verifyTextExistInPage( ";
378
470
  input = `${escapeNonPrintables(JSON.stringify(step.parameters[0]))}`;
379
471
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
380
472
  input = "_" + step.dataKey;
381
473
  }
382
- line += `${input}, null, this);`;
474
+ line += `${input}, ${serializeOptions(options)}, this);`;
383
475
  comment = `// Verify page contains text "${input}"`;
384
476
  codeLines.push(escapeNonPrintables(comment));
385
477
  codeLines.push(line);
@@ -393,7 +485,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
393
485
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
394
486
  input = "_" + step.dataKey;
395
487
  }
396
- line += `${input}, ${step.parameters[1]} ,_params, null, this);`;
488
+ line += `${input}, ${step.parameters[1]} , _params, ${serializeOptions(options)}, this);`;
397
489
  if (element_name) {
398
490
  comment = `// Verify ${element_name} contains text "${input}"`;
399
491
  codeLines.push(escapeNonPrintables(comment));
@@ -408,7 +500,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
408
500
  }
409
501
  line = `await context.web.analyzeTable(elements["${elementIdentifier}"], ${JSON.stringify(
410
502
  step.parameters[0]
411
- )}, "${step.parameters[1]}", ${input}, _params, null, this);`;
503
+ )}, "${step.parameters[1]}", ${input}, _params, ${serializeOptions(options)}, this);`;
412
504
  if (element_name) {
413
505
  comment = `// Analyze table ${element_name} query ${JSON.stringify(
414
506
  step.parameters[0]
@@ -428,27 +520,27 @@ const _generateCodeFromCommand = (step, elements, userData) => {
428
520
  } else if (step.dataSource === "environment") {
429
521
  input = `context.environment["_${step.dataKey}"]`;
430
522
  }
431
- line += `${input}, _params, null, this);`;
523
+ line += `${input}, _params, ${serializeOptions(options)}, this);`;
432
524
  if (element_name) {
433
525
  comment = `// Select "${input}" from ${element_name}`;
434
526
  codeLines.push(escapeNonPrintables(comment));
435
527
  }
436
528
  codeLines.push(line);
437
529
  } else if (step.selectMode === "click_combo") {
438
- line = `await context.web.click(elements["${elementIdentifier}"], _params, null, this);`;
530
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
439
531
  if (element_name) {
440
532
  comment = `// Open combobox ${element_name}`;
441
533
  codeLines.push(escapeNonPrintables(comment));
442
534
  }
443
535
  codeLines.push(line);
444
- line = `await context.web.click(elements["${optionIdentifier}"], _params, null, this);`;
536
+ line = `await context.web.click(elements["${optionIdentifier}"], _params, ${serializeOptions(options)}, this);`;
445
537
  if (element_name) {
446
538
  comment = `// Select "${optionIdentifier}" from ${element_name}`;
447
539
  codeLines.push(escapeNonPrintables(comment));
448
540
  }
449
541
  codeLines.push(line);
450
542
  } else if (step.selectMode === "click") {
451
- line = `await context.web.click(elements["${optionIdentifier}"], _params, null, this);`;
543
+ line = `await context.web.click(elements["${optionIdentifier}"], _params, ${serializeOptions(options)}, this);`;
452
544
  if (element_name) {
453
545
  comment = `// Select ${optionIdentifier} from ${element_name}`;
454
546
  codeLines.push(escapeNonPrintables(comment));
@@ -461,13 +553,13 @@ const _generateCodeFromCommand = (step, elements, userData) => {
461
553
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
462
554
  input = "_" + step.dataKey;
463
555
  }
464
- line += `${input}, false, _params, null, this);`;
556
+ line += `${input}, false, _params, ${serializeOptions(options)}, this);`;
465
557
  if (element_name) {
466
558
  comment = `// Fill ${element_name} with "${input}"`;
467
559
  codeLines.push(escapeNonPrintables(comment));
468
560
  }
469
561
  codeLines.push(line);
470
- line = `await context.web.click(elements["${optionIdentifier}"], _params, null, this);`;
562
+ line = `await context.web.click(elements["${optionIdentifier}"], _params, ${serializeOptions(options)}, this);`;
471
563
  codeLines.push(line);
472
564
  } else {
473
565
  throw new Error(`Unknown select mode ${step.selectMode}`);
@@ -479,13 +571,13 @@ const _generateCodeFromCommand = (step, elements, userData) => {
479
571
  case Types.RELOAD:
480
572
  comment = `// Reload page`;
481
573
  codeLines.push(escapeNonPrintables(comment));
482
- line = "await context.web.reloadPage({}, this);";
574
+ line = `await context.web.reloadPage(${serializeOptions(options)}, this);`;
483
575
  codeLines.push(line);
484
576
  break;
485
577
  case Types.CLOSE_PAGE:
486
578
  comment = `// Close page`;
487
579
  codeLines.push(escapeNonPrintables(comment));
488
- line = "await context.web.closePage({}, this);";
580
+ line = `await context.web.closePage(${serializeOptions(options)}, this);`;
489
581
  codeLines.push(line);
490
582
  break;
491
583
  case Types.NAVIGATE:
@@ -498,7 +590,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
498
590
  } else if (step.dataSource === "environment") {
499
591
  input = `context.environment["_${step.dataKey}"]`;
500
592
  }
501
- line = `await context.web.goto(${input}, this);`;
593
+ line = `await context.web.goto(${input}, this, ${serializeOptions(options)});`;
502
594
  codeLines.push(line);
503
595
  break;
504
596
  case Types.VERIFY_PAGE_PATH:
@@ -507,7 +599,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
507
599
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
508
600
  input = "_" + step.dataKey;
509
601
  }
510
- line += `${input}, null, this);`;
602
+ line += `${input}, ${serializeOptions(options)}, this);`;
511
603
  comment = `// Verify page path "${input}"`;
512
604
  codeLines.push(escapeNonPrintables(comment));
513
605
  codeLines.push(line);
@@ -518,7 +610,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
518
610
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
519
611
  input = "_" + step.dataKey;
520
612
  }
521
- line += `${input}, null, this);`;
613
+ line += `${input}, ${serializeOptions(options)}, this);`;
522
614
  comment = `// Verify page title "${input}"`;
523
615
  codeLines.push(escapeNonPrintables(comment));
524
616
  codeLines.push(line);
@@ -528,13 +620,13 @@ const _generateCodeFromCommand = (step, elements, userData) => {
528
620
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
529
621
  input = "_" + step.dataKey;
530
622
  }
531
- line = `await context.web.type(${input}, _params, null, this);`;
623
+ line = `await context.web.type(${input}, _params, ${serializeOptions(options)}, this);`;
532
624
  comment = `// Type "${input}"`;
533
625
  codeLines.push(escapeNonPrintables(comment));
534
626
  codeLines.push(line);
535
627
  break;
536
628
  case Types.HOVER:
537
- line = `await context.web.hover(elements["${elementIdentifier}"], _params, null, this);`;
629
+ line = `await context.web.hover(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
538
630
  if (element_name) {
539
631
  comment = `// Hover ${element_name}`;
540
632
  codeLines.push(escapeNonPrintables(comment));
@@ -575,13 +667,15 @@ const _generateCodeFromCommand = (step, elements, userData) => {
575
667
  case Types.CHECK:
576
668
  comment = `// Check ${element_name}`;
577
669
  codeLines.push(escapeNonPrintables(comment));
578
- line = `await context.web.setCheck(elements["${elementIdentifier}"], ${step.check}, _params, null, this);`;
670
+ line = `await context.web.setCheck(elements["${elementIdentifier}"], ${step.check}, _params, ${serializeOptions(options)}, this);`;
579
671
  codeLines.push(line);
580
672
  break;
581
673
  case Types.PRESS:
582
674
  comment = `// Press ${step.key}`;
583
675
  codeLines.push(escapeNonPrintables(comment));
584
- line = `await context.web.clickType( elements["${elementIdentifier}"] ,"${step.key}",null, _params, {"press":true}, this);`;
676
+ options = options ?? {};
677
+ options.press = true;
678
+ line = `await context.web.clickType( elements["${elementIdentifier}"] ,"${step.key}",null, _params, ${serializeOptions(options)}, this);`;
585
679
  codeLines.push(line);
586
680
  break;
587
681
  case Types.CONTEXT_CLICK:
@@ -593,7 +687,9 @@ const _generateCodeFromCommand = (step, elements, userData) => {
593
687
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
594
688
  input = "_" + step.dataKey;
595
689
  }
596
- line = `await context.web.click(elements["${elementIdentifier}"], _params, {"context": ${input}}, this);`;
690
+ // options = options ?? {};
691
+ // options.context = input;
692
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options, input)}, this);`;
597
693
  codeLines.push(line);
598
694
  break;
599
695
  case 2:
@@ -603,7 +699,10 @@ const _generateCodeFromCommand = (step, elements, userData) => {
603
699
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
604
700
  input = "_" + step.dataKey;
605
701
  }
606
- line = `await context.web.click(elements["${elementIdentifier}"], _params, {"context": ${input}, clickCount:2}, this);`;
702
+ options = options ?? {};
703
+ // options.context = input;
704
+ options.clickCount = 2;
705
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options, input)}, this);`;
607
706
  codeLines.push(line);
608
707
  break;
609
708
  default:
@@ -613,7 +712,9 @@ const _generateCodeFromCommand = (step, elements, userData) => {
613
712
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
614
713
  input = "_" + step.dataKey;
615
714
  }
616
- line = `await context.web.click(elements["${elementIdentifier}"], _params, {"context": ${input}}, this);`;
715
+ // options = options ?? {};
716
+ // options.context = input;
717
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options, input)}, this);`;
617
718
  codeLines.push(line);
618
719
  break;
619
720
  }
@@ -638,24 +739,24 @@ const _generateCodeFromCommand = (step, elements, userData) => {
638
739
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
639
740
  input = "_" + step.dataKey;
640
741
  }
641
- line += `"${step.parameters[0]}", ${input}, _params, null, this);`;
742
+ line += `"${step.parameters[0]}", ${input}, _params, ${serializeOptions(options)}, this);`;
642
743
  codeLines.push(line);
643
744
  break;
644
745
  }
645
746
  case Types.VERIFY_PROPERTY: {
646
747
  line = `await context.web.verifyProperty(elements["${elementIdentifier}"], `;
647
- input = "_param_0";
748
+ input = step.valueInStepText ? "_param_0" : `"${escapeNonPrintables(step.parameters[1].replaceAll('"', '\\"'))}"`;
648
749
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
649
750
  input = "_" + step.dataKey;
650
751
  }
651
- line += `"${step.parameters[0]}", ${input}, _params, null, this);`;
752
+ line += `"${step.parameters[0]}", ${input}, _params, ${serializeOptions(options)}, this);`;
652
753
  codeLines.push(line);
653
754
  break;
654
755
  }
655
756
  case Types.CONDITIONAL_WAIT: {
656
757
  line = `await context.web.conditionalWait(elements["${elementIdentifier}"], `;
657
- input = "_param_0";
658
- line += `"${step.parameters[1]}", ${input}, _params, null, this);`;
758
+ input = step.valueInStepText ? "_param_0" : `"${escapeNonPrintables(step.parameters[1].replaceAll('"', '\\"'))}"`;
759
+ line += `"${step.parameters[1]}", ${input}, _params, ${serializeOptions(options)}, this);`;
659
760
  codeLines.push(line);
660
761
  break;
661
762
  }
@@ -666,7 +767,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
666
767
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
667
768
  input = "_" + step.dataKey;
668
769
  }
669
- line += `${input}, _params, null, this);`;
770
+ line += `${input}, _params, ${serializeOptions(options)}, this);`;
670
771
  if (element_name) {
671
772
  comment = `// Set ${element_name} to ${input}`;
672
773
  codeLines.push(escapeNonPrintables(comment));
@@ -674,6 +775,8 @@ const _generateCodeFromCommand = (step, elements, userData) => {
674
775
  codeLines.push(line);
675
776
  break;
676
777
  }
778
+
779
+
677
780
  case Types.CLICK_SIMPLE:
678
781
  case Types.FILL_SIMPLE:
679
782
  // no code need to be added
@@ -684,22 +787,6 @@ const _generateCodeFromCommand = (step, elements, userData) => {
684
787
  return { codeLines, elements: elementsChanged ? elements : null, elementIdentifier, allStrategyLocators };
685
788
  };
686
789
 
687
- /**
688
- * Generates a report command based on the given position.
689
- * @param {"start"|"end"} position
690
- */
691
- const generateReportCommand = (position, cmdId) => {
692
- const codeLines = [];
693
- if (position === "start") {
694
- const line = `await context.web.addCommandToReport("${cmdId}", "PASSED", '{"status":"start","cmdId":"${cmdId}"}', {type:"cmdReport"},this);`;
695
- codeLines.push(line);
696
- } else if (position === "end") {
697
- const line = `await context.web.addCommandToReport("${cmdId}", "PASSED", '{"status":"end","cmdId":"${cmdId}"}', {type:"cmdReport"},this);`;
698
- codeLines.push(line);
699
- }
700
- return codeLines;
701
- };
702
-
703
790
  const generateCode = (recording, codePage, userData, projectDir, methodName) => {
704
791
  const stepsDefinitions = new StepsDefinitions(projectDir);
705
792
  stepsDefinitions.load(false);
@@ -722,12 +809,10 @@ const generateCode = (recording, codePage, userData, projectDir, methodName) =>
722
809
  codePage = new CodePage(mjsFullPath);
723
810
  codePage.generateModel();
724
811
  }
725
- //console.log("step found");
726
812
  }
727
813
  let elements = {};
728
814
  if (!codePage) {
729
- socketLogger.info("CodePage is null");
730
- console.log("codePage is null");
815
+ socketLogger.info("CodePage is null", undefined, "generateCode");
731
816
  } else {
732
817
  elements = codePage.getVariableDeclarationAsObject("elements");
733
818
  }
@@ -741,6 +826,7 @@ const generateCode = (recording, codePage, userData, projectDir, methodName) =>
741
826
  if (recordingStep.type === Types.COMPLETE) {
742
827
  return;
743
828
  }
829
+ socketLogger.info(`Generating code for step: ${recordingStep.type}`, undefined, "generateCode");
744
830
 
745
831
  // if (process.env.TEMP_RUN === "true") {
746
832
  // codeLines.push(...generateReportCommand("start", recordingStep.cmdId));
@@ -752,9 +838,11 @@ const generateCode = (recording, codePage, userData, projectDir, methodName) =>
752
838
  // codeLines.push(...generateReportCommand("end", recordingStep.cmdId));
753
839
  // }
754
840
  if (result.elements) {
841
+ socketLogger.info(`Updating elements with ${Object.keys(result.elements)}`, undefined, "generateCode");
755
842
  elements = result.elements;
756
843
  }
757
844
  if (result.elementIdentifier) {
845
+ socketLogger.info(`Adding locator metadata for ${result.elementIdentifier}`, undefined, "generateCode");
758
846
  locatorsMetadata[result.elementIdentifier] = result.allStrategyLocators;
759
847
  }
760
848
  });
@@ -791,7 +879,7 @@ const generatePageName = (url) => {
791
879
  }
792
880
  // join by _
793
881
  return lowerCaseParts.join("_");
794
- } catch (err) {
882
+ } catch {
795
883
  return "default";
796
884
  }
797
885
  };
@@ -6,7 +6,6 @@ import os from "os";
6
6
  import path from "path";
7
7
  import { parseStepTextParameters, toCucumberExpression, unEscapeNonPrintables } from "./utils.js";
8
8
  import stream from "stream";
9
- import { testStringForRegex } from "../recorderv3/update_feature.js";
10
9
  import { generateTestData } from "./feature_data.js";
11
10
  import socketLogger from "../utils/socket_logger.js";
12
11
  class DataTable {
@@ -490,8 +489,8 @@ const scenarioResolution = async (featureFilePath) => {
490
489
  let result = generateTestData(featureFilePath);
491
490
  if (result.changed) {
492
491
  fs.writeFileSync(tmpFeatureFilePath, result.newContent);
493
- console.log("Fake data was generated for this scenario");
494
- console.log("Variables:");
492
+ socketLogger.info("Generated fake data for feature", undefined, "scenarioResolution");
493
+ socketLogger.info("Variables generated:", result.variables, "scenarioResolution");
495
494
  for (let key in result.variables) {
496
495
  console.log(`${key}: ${result.variables[key].fake}`);
497
496
  }
@@ -503,8 +502,7 @@ const scenarioResolution = async (featureFilePath) => {
503
502
  fs.copyFileSync(featureFilePath, tmpFeatureFilePath);
504
503
  }
505
504
  const writable = new stream.Writable({
506
- write: function (chunk, encoding, next) {
507
- //console.log(chunk.toString());
505
+ write: (chunk, encoding, next) => {
508
506
  next();
509
507
  },
510
508
  });
@@ -521,23 +519,12 @@ const scenarioResolution = async (featureFilePath) => {
521
519
  // load the support code upfront
522
520
  const support = await loadSupport(runConfiguration, environment);
523
521
  // run cucumber, using the support code we loaded already
524
- await runCucumber({ ...runConfiguration, support }, environment, function (event) {
525
- // if (event.source) {
526
- // scenarioInfo.source = event.source.data;
527
- // }
528
- // if (event.pickle && event.pickle.name === scenarioName) {
529
- // scenarioInfo.pickle = event.pickle;
530
- // }
522
+ await runCucumber({ ...runConfiguration, support }, environment, (event) => {
531
523
  if (event.gherkinDocument) {
532
524
  gherkinDocument = event.gherkinDocument;
533
525
  }
534
- //console.log(event);
535
- //console.log(JSON.stringify(event, null, 2));
536
- // console.log("");
537
526
  });
538
527
  const feature = new Feature(gherkinDocument, featureFileContent);
539
- //const scenario = feature.getScenario(scenarioName);
540
- //return scenario;
541
528
  return feature;
542
529
  } finally {
543
530
  try {
@@ -41,10 +41,10 @@ const generateTestData = (featureFile) => {
41
41
  try {
42
42
  const fake = faker.helpers.fake(match[0]);
43
43
 
44
- if(fake === match[0]){
44
+ if (fake === match[0]) {
45
45
  continue;
46
46
  }
47
-
47
+
48
48
  otherFakeData.push({
49
49
  var: match[0],
50
50
  fake,