@dev-blinq/cucumber_client 1.0.1475-dev → 1.0.1475-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 (47) hide show
  1. package/bin/assets/bundled_scripts/recorder.js +49 -49
  2. package/bin/assets/scripts/recorder.js +87 -34
  3. package/bin/assets/scripts/snapshot_capturer.js +10 -17
  4. package/bin/assets/scripts/unique_locators.js +78 -28
  5. package/bin/assets/templates/_hooks_template.txt +6 -2
  6. package/bin/assets/templates/utils_template.txt +16 -16
  7. package/bin/client/code_cleanup/codemod/find_harcoded_locators.js +173 -0
  8. package/bin/client/code_cleanup/codemod/fix_hardcoded_locators.js +247 -0
  9. package/bin/client/code_cleanup/utils.js +16 -7
  10. package/bin/client/code_gen/code_inversion.js +125 -1
  11. package/bin/client/code_gen/duplication_analysis.js +2 -1
  12. package/bin/client/code_gen/function_signature.js +8 -0
  13. package/bin/client/code_gen/index.js +4 -0
  14. package/bin/client/code_gen/page_reflection.js +90 -9
  15. package/bin/client/code_gen/playwright_codeget.js +173 -77
  16. package/bin/client/codemod/find_harcoded_locators.js +173 -0
  17. package/bin/client/codemod/fix_hardcoded_locators.js +247 -0
  18. package/bin/client/codemod/index.js +8 -0
  19. package/bin/client/codemod/locators_array/find_misstructured_elements.js +148 -0
  20. package/bin/client/codemod/locators_array/fix_misstructured_elements.js +144 -0
  21. package/bin/client/codemod/locators_array/index.js +114 -0
  22. package/bin/client/codemod/types.js +1 -0
  23. package/bin/client/cucumber/feature.js +4 -17
  24. package/bin/client/cucumber/steps_definitions.js +17 -12
  25. package/bin/client/recorderv3/bvt_init.js +310 -0
  26. package/bin/client/recorderv3/bvt_recorder.js +1560 -1183
  27. package/bin/client/recorderv3/constants.js +45 -0
  28. package/bin/client/recorderv3/implemented_steps.js +2 -0
  29. package/bin/client/recorderv3/index.js +3 -293
  30. package/bin/client/recorderv3/mixpanel.js +39 -0
  31. package/bin/client/recorderv3/services.js +839 -142
  32. package/bin/client/recorderv3/step_runner.js +36 -7
  33. package/bin/client/recorderv3/step_utils.js +316 -98
  34. package/bin/client/recorderv3/update_feature.js +85 -37
  35. package/bin/client/recorderv3/utils.js +80 -0
  36. package/bin/client/recorderv3/wbr_entry.js +61 -0
  37. package/bin/client/recording.js +1 -0
  38. package/bin/client/types/locators.js +2 -0
  39. package/bin/client/upload-service.js +2 -0
  40. package/bin/client/utils/app_dir.js +21 -0
  41. package/bin/client/utils/socket_logger.js +100 -125
  42. package/bin/index.js +5 -0
  43. package/package.json +21 -6
  44. package/bin/client/recorderv3/app_dir.js +0 -23
  45. package/bin/client/recorderv3/network.js +0 -299
  46. package/bin/client/recorderv3/scriptTest.js +0 -5
  47. 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,18 +70,54 @@ 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) {
79
114
  const { [keyToRemove]: _, ...rest } = obj;
80
115
  return rest;
81
116
  }
117
+ /**
118
+ * Split locators by strategy
119
+ * @param {import("../types/locators").LocatorBundle} locators
120
+ */
82
121
  const splitToLocatorsGroups = (locators) => {
83
122
  const no_text = locators.locators.filter((locator) => locator.mode === "NO_TEXT");
84
123
  const ignore_digit = locators.locators.filter((locator) => locator.mode === "IGNORE_DIGIT");
@@ -97,6 +136,20 @@ const splitToLocatorsGroups = (locators) => {
97
136
  });
98
137
  return { basic, no_text, ignore_digit, context };
99
138
  };
139
+
140
+ const serializeOptions = (options, context) => {
141
+ if (!options) return "null";
142
+ if (typeof options !== "object") return "null";
143
+ if (Array.isArray(options)) return "null";
144
+ let result = "{ ";
145
+ if (context) result += `"context": ${context}, `;
146
+ for (const key in options) {
147
+ result += `"${key}": ${JSON.stringify(options[key])}, `;
148
+ }
149
+ result += " }";
150
+ return result;
151
+ };
152
+
100
153
  const _generateCodeFromCommand = (step, elements, userData) => {
101
154
  let elementsChanged = false;
102
155
 
@@ -105,7 +158,12 @@ const _generateCodeFromCommand = (step, elements, userData) => {
105
158
  // handle element
106
159
  let element_name = null;
107
160
  let allStrategyLocators = null;
108
- if (_isCodeGenerationStep(step) && step.type !== Types.VERIFY_PAGE_SNAPSHOT) {
161
+ const codeLines = [];
162
+
163
+ if (_isCodeGenerationStep(step) === false)
164
+ return { codeLines, elements: elementsChanged ? elements : null, elementIdentifier, allStrategyLocators };
165
+
166
+ if (_isCodeGenerationStep(step) && _isLocatorStrategyStep(step)) {
109
167
  allStrategyLocators = step.allStrategyLocators ?? splitToLocatorsGroups(step.locators);
110
168
  let node = null;
111
169
 
@@ -167,8 +225,6 @@ const _generateCodeFromCommand = (step, elements, userData) => {
167
225
  }
168
226
  }
169
227
 
170
- const codeLines = [];
171
-
172
228
  let line = null;
173
229
  let comment = null;
174
230
  let input = null;
@@ -176,7 +232,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
176
232
  let attribute = null;
177
233
  let variable = null;
178
234
  let format = null;
179
- let options = null;
235
+ let options = step.options ?? null;
180
236
  let property = null;
181
237
  switch (step.type) {
182
238
  case Types.SET_INPUT:
@@ -186,7 +242,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
186
242
  //parameters.push(step.dataKey);
187
243
  input = "_" + step.dataKey;
188
244
  }
189
- line += `${input}, _params, null, this);`;
245
+ line += `${input}, _params, ${serializeOptions(options)}, this);`;
190
246
  if (element_name) {
191
247
  comment = `// Set ${element_name} to ${input}`;
192
248
  codeLines.push(escapeNonPrintables(comment));
@@ -199,7 +255,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
199
255
  comment = `// Check ${element_name}`;
200
256
  codeLines.push(escapeNonPrintables(comment));
201
257
  }
202
- line = `await context.web.setCheck(elements["${elementIdentifier}"], ${step.check}, _params, null, this);`;
258
+ line = `await context.web.setCheck(elements["${elementIdentifier}"], ${step.check}, _params, ${serializeOptions(options)}, this);`;
203
259
  codeLines.push(line);
204
260
  } else {
205
261
  switch (step.count) {
@@ -208,7 +264,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
208
264
  comment = `// Click on ${element_name}`;
209
265
  codeLines.push(escapeNonPrintables(comment));
210
266
  }
211
- line = `await context.web.click(elements["${elementIdentifier}"], _params, null, this);`;
267
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
212
268
  codeLines.push(line);
213
269
  break;
214
270
  case 2:
@@ -216,7 +272,9 @@ const _generateCodeFromCommand = (step, elements, userData) => {
216
272
  comment = `// Double click on ${element_name}`;
217
273
  codeLines.push(escapeNonPrintables(comment));
218
274
  }
219
- line = `await context.web.click(elements["${elementIdentifier}"], _params, {clickCount:2}, this);`;
275
+ options = options ?? {};
276
+ options.clickCount = 2;
277
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
220
278
  codeLines.push(line);
221
279
  break;
222
280
  default:
@@ -224,7 +282,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
224
282
  comment = `// Click on ${element_name}`;
225
283
  codeLines.push(escapeNonPrintables(comment));
226
284
  }
227
- line = `await context.web.click(elements["${elementIdentifier}"], _params, null, this);`;
285
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
228
286
  codeLines.push(line);
229
287
  break;
230
288
  }
@@ -235,17 +293,19 @@ const _generateCodeFromCommand = (step, elements, userData) => {
235
293
  case 1:
236
294
  comment = `// Parameterized click on ${step.value}`;
237
295
  codeLines.push(escapeNonPrintables(comment));
238
- line = `await context.web.click(elements["${elementIdentifier}"], _params, null, this);`;
296
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
239
297
  break;
240
298
  case 2:
241
299
  comment = `// Parameterized double click on ${step.value}`;
242
300
  codeLines.push(escapeNonPrintables(comment));
243
- line = `await context.web.click(elements["${elementIdentifier}"], _params, {clickCount:2}, this);`;
301
+ options = options ?? {};
302
+ options.clickCount = 2;
303
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
244
304
  break;
245
305
  default:
246
306
  comment = `// Parameterized click on ${step.value}`;
247
307
  codeLines.push(escapeNonPrintables(comment));
248
- line = `await context.web.click(elements["${elementIdentifier}"], _params, null, this);`;
308
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
249
309
  }
250
310
  codeLines.push(line);
251
311
  break;
@@ -264,7 +324,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
264
324
  } else {
265
325
  enter = '"' + step.parameters[2] + '"';
266
326
  }
267
- line += `${input}, "${format}", ${enter}, _params, null, this);`;
327
+ line += `${input}, "${format}", ${enter}, _params, ${serializeOptions(options)}, this);`;
268
328
  if (element_name) {
269
329
  comment = `// Set date time ${element_name} to "${input}" with format "${format}"`;
270
330
  codeLines.push(escapeNonPrintables(comment));
@@ -286,7 +346,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
286
346
  } else {
287
347
  enter = '"' + step.parameters[1] + '"';
288
348
  }
289
- line += `${input}, ${enter}, _params, null, this);`;
349
+ line += `${input}, ${enter}, _params, ${serializeOptions(options)}, this);`;
290
350
  if (element_name) {
291
351
  comment = `// Fill ${element_name} with "${input}"`;
292
352
  codeLines.push(escapeNonPrintables(comment));
@@ -308,7 +368,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
308
368
  } else {
309
369
  enter = '"' + step.parameters[1] + '"';
310
370
  }
311
- line += `${input}, ${enter}, _params, null, this);`;
371
+ line += `${input}, ${enter}, _params, ${serializeOptions(options)}, this);`;
312
372
  if (element_name) {
313
373
  comment = `// Fill ${element_name} with "${input}"`;
314
374
  codeLines.push(escapeNonPrintables(comment));
@@ -322,15 +382,25 @@ const _generateCodeFromCommand = (step, elements, userData) => {
322
382
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
323
383
  input = "_" + step.dataKey;
324
384
  }
325
- let options = "null";
385
+ // let options = "null";
326
386
  if (step.regex !== "") {
327
- options = `{regex: ${JSON.stringify(step.regex)},trimSpaces: ${step.trimSpaces}}`;
387
+ options = options ?? {};
388
+ options = {
389
+ ...options,
390
+ regex: step.regex,
391
+ trimSpaces: step.trimSpaces,
392
+ }; // `{regex: ${JSON.stringify(step.regex)},trimSpaces: ${step.trimSpaces}}`;
328
393
  } else if (step.trimSpaces) {
329
- options = `{trimSpaces: ${step.trimSpaces}}`;
394
+ options = options ?? {};
395
+ options = {
396
+ ...options,
397
+ trimSpaces: step.trimSpaces,
398
+ };
399
+ // options = `{trimSpaces: ${step.trimSpaces}}`;
330
400
  } else {
331
- options = "null";
401
+ options = null; //"null";
332
402
  }
333
- line = `await context.web.extractAttribute(elements["${elementIdentifier}"], "${attribute}", ${input}, _params,${options}, this);`;
403
+ line = `await context.web.extractAttribute(elements["${elementIdentifier}"], "${attribute}", ${input}, _params, ${serializeOptions(options)}, this);`;
334
404
 
335
405
  if (element_name) {
336
406
  comment = `// Extract attribute ${attribute} from ${element_name} to ${variable}`;
@@ -346,15 +416,24 @@ const _generateCodeFromCommand = (step, elements, userData) => {
346
416
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
347
417
  input = "_" + step.dataKey;
348
418
  }
349
- let options = "null";
350
419
  if (step.regex !== "") {
351
- options = `{regex: ${JSON.stringify(step.regex)},trimSpaces: ${step.trimSpaces}}`;
420
+ options = options ?? {};
421
+ options = {
422
+ ...options,
423
+ regex: step.regex,
424
+ trimSpaces: step.trimSpaces,
425
+ }; // `{regex: ${JSON.stringify(step.regex)},trimSpaces: ${step.trimSpaces}}`;
352
426
  } else if (step.trimSpaces) {
353
- options = `{trimSpaces: ${step.trimSpaces}}`;
427
+ options = options ?? {};
428
+ options = {
429
+ ...options,
430
+ trimSpaces: step.trimSpaces,
431
+ };
432
+ // options = `{trimSpaces: ${step.trimSpaces}}`;
354
433
  } else {
355
- options = "null";
434
+ options = null; //"null";
356
435
  }
357
- line = `await context.web.extractProperty(elements["${elementIdentifier}"], "${property}", ${input}, _params,${options}, this);`;
436
+ line = `await context.web.extractProperty(elements["${elementIdentifier}"], "${property}", ${input}, _params, ${serializeOptions(options)}, this);`;
358
437
 
359
438
  if (element_name) {
360
439
  comment = `// Extract property ${property} from ${element_name} to ${variable}`;
@@ -363,23 +442,40 @@ const _generateCodeFromCommand = (step, elements, userData) => {
363
442
  codeLines.push(line);
364
443
  break;
365
444
  }
366
- case Types.VERIFY_PAGE_SNAPSHOT:
445
+ case Types.VERIFY_PAGE_SNAPSHOT: {
367
446
  comment = step.nestFrmLoc
368
447
  ? `// Verify page snapshot ${step.parameters[0]} in the frame ${step.selectors.iframe_src}`
369
448
  : `// Verify page snapshot ${step.parameters[0]}`;
370
449
  codeLines.push(escapeNonPrintables(comment));
371
450
  line = `const frameLocator = ${JSON.stringify(step.selectors ?? null)}`;
372
451
  codeLines.push(line);
373
- line = `await context.web.snapshotValidation(frameLocator, _param_0 , _params, ${JSON.stringify(options)}, this);`;
452
+ line = `await context.web.snapshotValidation(frameLocator,${step.valueInStepText ? "_param_0" : `"${step.parameters[0]}"`}, _params, ${serializeOptions(options)}, this);`;
374
453
  codeLines.push(line);
454
+
455
+ const data = step.data;
456
+ if (data) {
457
+ try {
458
+ const { snapshot, fileName, filePath } = data;
459
+ const folderPath = process.env.BVT_TEMP_SNAPSHOTS_FOLDER ?? filePath;
460
+ const filePathWithName = path.join(folderPath, fileName);
461
+ if (!fs.existsSync(folderPath)) {
462
+ fs.mkdirSync(folderPath, { recursive: true });
463
+ }
464
+ fs.writeFileSync(filePathWithName, snapshot, "utf-8");
465
+ } catch (e) {
466
+ console.log(`Error saving snapshot file: ${e}`);
467
+ throw e;
468
+ }
469
+ }
375
470
  break;
471
+ }
376
472
  case Types.VERIFY_PAGE_CONTAINS_TEXT:
377
473
  line = "await context.web.verifyTextExistInPage( ";
378
474
  input = `${escapeNonPrintables(JSON.stringify(step.parameters[0]))}`;
379
475
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
380
476
  input = "_" + step.dataKey;
381
477
  }
382
- line += `${input}, null, this);`;
478
+ line += `${input}, ${serializeOptions(options)}, this);`;
383
479
  comment = `// Verify page contains text "${input}"`;
384
480
  codeLines.push(escapeNonPrintables(comment));
385
481
  codeLines.push(line);
@@ -393,7 +489,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
393
489
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
394
490
  input = "_" + step.dataKey;
395
491
  }
396
- line += `${input}, ${step.parameters[1]} ,_params, null, this);`;
492
+ line += `${input}, ${step.parameters[1]} , _params, ${serializeOptions(options)}, this);`;
397
493
  if (element_name) {
398
494
  comment = `// Verify ${element_name} contains text "${input}"`;
399
495
  codeLines.push(escapeNonPrintables(comment));
@@ -408,7 +504,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
408
504
  }
409
505
  line = `await context.web.analyzeTable(elements["${elementIdentifier}"], ${JSON.stringify(
410
506
  step.parameters[0]
411
- )}, "${step.parameters[1]}", ${input}, _params, null, this);`;
507
+ )}, "${step.parameters[1]}", ${input}, _params, ${serializeOptions(options)}, this);`;
412
508
  if (element_name) {
413
509
  comment = `// Analyze table ${element_name} query ${JSON.stringify(
414
510
  step.parameters[0]
@@ -428,27 +524,27 @@ const _generateCodeFromCommand = (step, elements, userData) => {
428
524
  } else if (step.dataSource === "environment") {
429
525
  input = `context.environment["_${step.dataKey}"]`;
430
526
  }
431
- line += `${input}, _params, null, this);`;
527
+ line += `${input}, _params, ${serializeOptions(options)}, this);`;
432
528
  if (element_name) {
433
529
  comment = `// Select "${input}" from ${element_name}`;
434
530
  codeLines.push(escapeNonPrintables(comment));
435
531
  }
436
532
  codeLines.push(line);
437
533
  } else if (step.selectMode === "click_combo") {
438
- line = `await context.web.click(elements["${elementIdentifier}"], _params, null, this);`;
534
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
439
535
  if (element_name) {
440
536
  comment = `// Open combobox ${element_name}`;
441
537
  codeLines.push(escapeNonPrintables(comment));
442
538
  }
443
539
  codeLines.push(line);
444
- line = `await context.web.click(elements["${optionIdentifier}"], _params, null, this);`;
540
+ line = `await context.web.click(elements["${optionIdentifier}"], _params, ${serializeOptions(options)}, this);`;
445
541
  if (element_name) {
446
542
  comment = `// Select "${optionIdentifier}" from ${element_name}`;
447
543
  codeLines.push(escapeNonPrintables(comment));
448
544
  }
449
545
  codeLines.push(line);
450
546
  } else if (step.selectMode === "click") {
451
- line = `await context.web.click(elements["${optionIdentifier}"], _params, null, this);`;
547
+ line = `await context.web.click(elements["${optionIdentifier}"], _params, ${serializeOptions(options)}, this);`;
452
548
  if (element_name) {
453
549
  comment = `// Select ${optionIdentifier} from ${element_name}`;
454
550
  codeLines.push(escapeNonPrintables(comment));
@@ -461,13 +557,13 @@ const _generateCodeFromCommand = (step, elements, userData) => {
461
557
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
462
558
  input = "_" + step.dataKey;
463
559
  }
464
- line += `${input}, false, _params, null, this);`;
560
+ line += `${input}, false, _params, ${serializeOptions(options)}, this);`;
465
561
  if (element_name) {
466
562
  comment = `// Fill ${element_name} with "${input}"`;
467
563
  codeLines.push(escapeNonPrintables(comment));
468
564
  }
469
565
  codeLines.push(line);
470
- line = `await context.web.click(elements["${optionIdentifier}"], _params, null, this);`;
566
+ line = `await context.web.click(elements["${optionIdentifier}"], _params, ${serializeOptions(options)}, this);`;
471
567
  codeLines.push(line);
472
568
  } else {
473
569
  throw new Error(`Unknown select mode ${step.selectMode}`);
@@ -479,13 +575,13 @@ const _generateCodeFromCommand = (step, elements, userData) => {
479
575
  case Types.RELOAD:
480
576
  comment = `// Reload page`;
481
577
  codeLines.push(escapeNonPrintables(comment));
482
- line = "await context.web.reloadPage({}, this);";
578
+ line = `await context.web.reloadPage(${serializeOptions(options)}, this);`;
483
579
  codeLines.push(line);
484
580
  break;
485
581
  case Types.CLOSE_PAGE:
486
582
  comment = `// Close page`;
487
583
  codeLines.push(escapeNonPrintables(comment));
488
- line = "await context.web.closePage({}, this);";
584
+ line = `await context.web.closePage(${serializeOptions(options)}, this);`;
489
585
  codeLines.push(line);
490
586
  break;
491
587
  case Types.NAVIGATE:
@@ -498,7 +594,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
498
594
  } else if (step.dataSource === "environment") {
499
595
  input = `context.environment["_${step.dataKey}"]`;
500
596
  }
501
- line = `await context.web.goto(${input}, this);`;
597
+ line = `await context.web.goto(${input}, this, ${serializeOptions(options)});`;
502
598
  codeLines.push(line);
503
599
  break;
504
600
  case Types.VERIFY_PAGE_PATH:
@@ -507,7 +603,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
507
603
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
508
604
  input = "_" + step.dataKey;
509
605
  }
510
- line += `${input}, null, this);`;
606
+ line += `${input}, ${serializeOptions(options)}, this);`;
511
607
  comment = `// Verify page path "${input}"`;
512
608
  codeLines.push(escapeNonPrintables(comment));
513
609
  codeLines.push(line);
@@ -518,7 +614,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
518
614
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
519
615
  input = "_" + step.dataKey;
520
616
  }
521
- line += `${input}, null, this);`;
617
+ line += `${input}, ${serializeOptions(options)}, this);`;
522
618
  comment = `// Verify page title "${input}"`;
523
619
  codeLines.push(escapeNonPrintables(comment));
524
620
  codeLines.push(line);
@@ -528,13 +624,13 @@ const _generateCodeFromCommand = (step, elements, userData) => {
528
624
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
529
625
  input = "_" + step.dataKey;
530
626
  }
531
- line = `await context.web.type(${input}, _params, null, this);`;
627
+ line = `await context.web.type(${input}, _params, ${serializeOptions(options)}, this);`;
532
628
  comment = `// Type "${input}"`;
533
629
  codeLines.push(escapeNonPrintables(comment));
534
630
  codeLines.push(line);
535
631
  break;
536
632
  case Types.HOVER:
537
- line = `await context.web.hover(elements["${elementIdentifier}"], _params, null, this);`;
633
+ line = `await context.web.hover(elements["${elementIdentifier}"], _params, ${serializeOptions(options)}, this);`;
538
634
  if (element_name) {
539
635
  comment = `// Hover ${element_name}`;
540
636
  codeLines.push(escapeNonPrintables(comment));
@@ -575,13 +671,15 @@ const _generateCodeFromCommand = (step, elements, userData) => {
575
671
  case Types.CHECK:
576
672
  comment = `// Check ${element_name}`;
577
673
  codeLines.push(escapeNonPrintables(comment));
578
- line = `await context.web.setCheck(elements["${elementIdentifier}"], ${step.check}, _params, null, this);`;
674
+ line = `await context.web.setCheck(elements["${elementIdentifier}"], ${step.check}, _params, ${serializeOptions(options)}, this);`;
579
675
  codeLines.push(line);
580
676
  break;
581
677
  case Types.PRESS:
582
678
  comment = `// Press ${step.key}`;
583
679
  codeLines.push(escapeNonPrintables(comment));
584
- line = `await context.web.clickType( elements["${elementIdentifier}"] ,"${step.key}",null, _params, {"press":true}, this);`;
680
+ options = options ?? {};
681
+ options.press = true;
682
+ line = `await context.web.clickType( elements["${elementIdentifier}"] ,"${step.key}",null, _params, ${serializeOptions(options)}, this);`;
585
683
  codeLines.push(line);
586
684
  break;
587
685
  case Types.CONTEXT_CLICK:
@@ -593,7 +691,9 @@ const _generateCodeFromCommand = (step, elements, userData) => {
593
691
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
594
692
  input = "_" + step.dataKey;
595
693
  }
596
- line = `await context.web.click(elements["${elementIdentifier}"], _params, {"context": ${input}}, this);`;
694
+ options = options ?? {};
695
+ // options.context = input;
696
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options, input)}, this);`;
597
697
  codeLines.push(line);
598
698
  break;
599
699
  case 2:
@@ -603,7 +703,10 @@ const _generateCodeFromCommand = (step, elements, userData) => {
603
703
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
604
704
  input = "_" + step.dataKey;
605
705
  }
606
- line = `await context.web.click(elements["${elementIdentifier}"], _params, {"context": ${input}, clickCount:2}, this);`;
706
+ options = options ?? {};
707
+ // options.context = input;
708
+ options.clickCount = 2;
709
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options, input)}, this);`;
607
710
  codeLines.push(line);
608
711
  break;
609
712
  default:
@@ -613,7 +716,9 @@ const _generateCodeFromCommand = (step, elements, userData) => {
613
716
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
614
717
  input = "_" + step.dataKey;
615
718
  }
616
- line = `await context.web.click(elements["${elementIdentifier}"], _params, {"context": ${input}}, this);`;
719
+ options = options ?? {};
720
+ // options.context = input;
721
+ line = `await context.web.click(elements["${elementIdentifier}"], _params, ${serializeOptions(options, input)}, this);`;
617
722
  codeLines.push(line);
618
723
  break;
619
724
  }
@@ -638,24 +743,25 @@ const _generateCodeFromCommand = (step, elements, userData) => {
638
743
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
639
744
  input = "_" + step.dataKey;
640
745
  }
641
- line += `"${step.parameters[0]}", ${input}, _params, null, this);`;
746
+ line += `"${step.parameters[0]}", ${input}, _params, ${serializeOptions(options)}, this);`;
642
747
  codeLines.push(line);
643
748
  break;
644
749
  }
645
750
  case Types.VERIFY_PROPERTY: {
646
751
  line = `await context.web.verifyProperty(elements["${elementIdentifier}"], `;
647
- input = "_param_0";
752
+ input = step.valueInStepText ? "_param_0" : `"${escapeNonPrintables(step.parameters[1].replaceAll('"', '\\"'))}"`;
648
753
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
649
754
  input = "_" + step.dataKey;
650
755
  }
651
- line += `"${step.parameters[0]}", ${input}, _params, null, this);`;
756
+ line += `"${step.parameters[0]}", ${input}, _params, ${serializeOptions(options)}, this);`;
652
757
  codeLines.push(line);
653
758
  break;
654
759
  }
655
760
  case Types.CONDITIONAL_WAIT: {
656
761
  line = `await context.web.conditionalWait(elements["${elementIdentifier}"], `;
657
- input = "_param_0";
658
- line += `"${step.parameters[1]}", ${input}, _params, null, this);`;
762
+ const timeout = Number(step.parameters[0]) / 1000;
763
+ input = step.valueInStepText ? "_param_0" : `"${escapeNonPrintables(String(timeout))}"`;
764
+ line += `"${step.parameters[1]}", ${input}, _params, ${serializeOptions(options)}, this);`;
659
765
  codeLines.push(line);
660
766
  break;
661
767
  }
@@ -666,7 +772,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
666
772
  if (step.dataSource === "userData" || step.dataSource === "parameters") {
667
773
  input = "_" + step.dataKey;
668
774
  }
669
- line += `${input}, _params, null, this);`;
775
+ line += `${input}, _params, ${serializeOptions(options)}, this);`;
670
776
  if (element_name) {
671
777
  comment = `// Set ${element_name} to ${input}`;
672
778
  codeLines.push(escapeNonPrintables(comment));
@@ -674,6 +780,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
674
780
  codeLines.push(line);
675
781
  break;
676
782
  }
783
+
677
784
  case Types.CLICK_SIMPLE:
678
785
  case Types.FILL_SIMPLE:
679
786
  // no code need to be added
@@ -684,22 +791,6 @@ const _generateCodeFromCommand = (step, elements, userData) => {
684
791
  return { codeLines, elements: elementsChanged ? elements : null, elementIdentifier, allStrategyLocators };
685
792
  };
686
793
 
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
794
  const generateCode = (recording, codePage, userData, projectDir, methodName) => {
704
795
  const stepsDefinitions = new StepsDefinitions(projectDir);
705
796
  stepsDefinitions.load(false);
@@ -722,12 +813,10 @@ const generateCode = (recording, codePage, userData, projectDir, methodName) =>
722
813
  codePage = new CodePage(mjsFullPath);
723
814
  codePage.generateModel();
724
815
  }
725
- //console.log("step found");
726
816
  }
727
817
  let elements = {};
728
818
  if (!codePage) {
729
- socketLogger.info("CodePage is null");
730
- console.log("codePage is null");
819
+ socketLogger.info("CodePage is null", undefined, "generateCode");
731
820
  } else {
732
821
  elements = codePage.getVariableDeclarationAsObject("elements");
733
822
  }
@@ -741,6 +830,7 @@ const generateCode = (recording, codePage, userData, projectDir, methodName) =>
741
830
  if (recordingStep.type === Types.COMPLETE) {
742
831
  return;
743
832
  }
833
+ socketLogger.info(`Generating code for step: ${recordingStep.type}`, undefined, "generateCode");
744
834
 
745
835
  // if (process.env.TEMP_RUN === "true") {
746
836
  // codeLines.push(...generateReportCommand("start", recordingStep.cmdId));
@@ -752,9 +842,11 @@ const generateCode = (recording, codePage, userData, projectDir, methodName) =>
752
842
  // codeLines.push(...generateReportCommand("end", recordingStep.cmdId));
753
843
  // }
754
844
  if (result.elements) {
845
+ socketLogger.info(`Updating elements with ${Object.keys(result.elements)}`, undefined, "generateCode");
755
846
  elements = result.elements;
756
847
  }
757
848
  if (result.elementIdentifier) {
849
+ socketLogger.info(`Adding locator metadata for ${result.elementIdentifier}`, undefined, "generateCode");
758
850
  locatorsMetadata[result.elementIdentifier] = result.allStrategyLocators;
759
851
  }
760
852
  });
@@ -768,7 +860,11 @@ const generateCode = (recording, codePage, userData, projectDir, methodName) =>
768
860
  locatorsMetadata,
769
861
  };
770
862
  };
771
- const generatePageName = (url) => {
863
+ const generatePageName = (url, isUtilStep) => {
864
+ if (isUtilStep) {
865
+ return "renamed_util";
866
+ }
867
+
772
868
  try {
773
869
  let pathname = url;
774
870
  try {
@@ -791,8 +887,8 @@ const generatePageName = (url) => {
791
887
  }
792
888
  // join by _
793
889
  return lowerCaseParts.join("_");
794
- } catch (err) {
890
+ } catch {
795
891
  return "default";
796
892
  }
797
893
  };
798
- export { generateCode, generatePageName };
894
+ export { generateCode, generatePageName, _generateCodeFromCommand };