@dev-blinq/cucumber_client 1.0.1472-dev → 1.0.1472-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 (45) hide show
  1. package/bin/assets/bundled_scripts/recorder.js +73 -73
  2. package/bin/assets/scripts/recorder.js +87 -49
  3. package/bin/assets/scripts/snapshot_capturer.js +10 -17
  4. package/bin/assets/scripts/unique_locators.js +168 -40
  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/utils.js +16 -7
  8. package/bin/client/code_gen/code_inversion.js +125 -1
  9. package/bin/client/code_gen/duplication_analysis.js +2 -1
  10. package/bin/client/code_gen/function_signature.js +8 -0
  11. package/bin/client/code_gen/index.js +4 -0
  12. package/bin/client/code_gen/page_reflection.js +90 -9
  13. package/bin/client/code_gen/playwright_codeget.js +173 -77
  14. package/bin/client/codemod/find_harcoded_locators.js +173 -0
  15. package/bin/client/codemod/fix_hardcoded_locators.js +247 -0
  16. package/bin/client/codemod/index.js +8 -0
  17. package/bin/client/codemod/locators_array/find_misstructured_elements.js +148 -0
  18. package/bin/client/codemod/locators_array/fix_misstructured_elements.js +144 -0
  19. package/bin/client/codemod/locators_array/index.js +114 -0
  20. package/bin/client/codemod/types.js +1 -0
  21. package/bin/client/cucumber/feature.js +4 -17
  22. package/bin/client/cucumber/steps_definitions.js +17 -12
  23. package/bin/client/recorderv3/bvt_init.js +310 -0
  24. package/bin/client/recorderv3/bvt_recorder.js +1560 -1183
  25. package/bin/client/recorderv3/constants.js +45 -0
  26. package/bin/client/recorderv3/implemented_steps.js +2 -0
  27. package/bin/client/recorderv3/index.js +3 -293
  28. package/bin/client/recorderv3/mixpanel.js +41 -0
  29. package/bin/client/recorderv3/services.js +839 -142
  30. package/bin/client/recorderv3/step_runner.js +36 -7
  31. package/bin/client/recorderv3/step_utils.js +300 -98
  32. package/bin/client/recorderv3/update_feature.js +87 -39
  33. package/bin/client/recorderv3/utils.js +74 -0
  34. package/bin/client/recorderv3/wbr_entry.js +61 -0
  35. package/bin/client/recording.js +1 -0
  36. package/bin/client/types/locators.js +2 -0
  37. package/bin/client/upload-service.js +2 -0
  38. package/bin/client/utils/app_dir.js +21 -0
  39. package/bin/client/utils/socket_logger.js +100 -125
  40. package/bin/index.js +5 -0
  41. package/package.json +21 -6
  42. package/bin/client/recorderv3/app_dir.js +0 -23
  43. package/bin/client/recorderv3/network.js +0 -299
  44. package/bin/client/recorderv3/scriptTest.js +0 -5
  45. package/bin/client/recorderv3/ws_server.js +0 -72
@@ -170,7 +170,7 @@ export class CodePage {
170
170
  this.generateModel(fileContentNew);
171
171
  }
172
172
  catch (e) {
173
- logger.info("failed to format the code");
173
+ logger.error("failed to format the code");
174
174
  logger.debug(e);
175
175
  }
176
176
  if (!existsSync(this.sourceFileName)) {
@@ -288,6 +288,11 @@ export class CodePage {
288
288
  codePart.name = node.id.name;
289
289
  }
290
290
  }
291
+ findKey(funcString, key) {
292
+ const sourceRegex = new RegExp(`${key}:\\s*(.*)`);
293
+ const match = funcString.match(sourceRegex);
294
+ return match ? match[1] : null;
295
+ }
291
296
  collectAllTemplates() {
292
297
  const templates = [];
293
298
  if (this.cucumberCalls.length > 0) {
@@ -300,10 +305,12 @@ export class CodePage {
300
305
  const stepType = cucumberCall["stepType"];
301
306
  let firstFind = true;
302
307
  const stepPaths = [];
308
+ let source = null;
303
309
  for (let j = 0; j < this.methods.length; j++) {
304
310
  const method = this.methods[j];
305
311
  if (method.name === methodName) {
306
312
  if (firstFind) {
313
+ source = this.findKey(method.codePart, "source");
307
314
  foundMethod = true;
308
315
  const paramsObj = (method.node?.params ?? []);
309
316
  if (paramsObj && paramsObj.length > 0) {
@@ -315,7 +322,7 @@ export class CodePage {
315
322
  }
316
323
  }
317
324
  if (foundMethod) {
318
- templates.push({ pattern, methodName, params, stepType, paths: stepPaths });
325
+ templates.push({ pattern, methodName, params, stepType, paths: stepPaths, source });
319
326
  }
320
327
  }
321
328
  }
@@ -363,6 +370,39 @@ export class CodePage {
363
370
  return result;
364
371
  }
365
372
  }
373
+ addInfraCommandUtil(methodName, description, stepVariables, stepCodeLines, renamedText, previousText, parametersMap, protectStep = false, source = null, codePath = "") {
374
+ let code = "\n";
375
+ code += "/**\n";
376
+ code += ` * ${description}\n`;
377
+ const tags = [];
378
+ if (protectStep)
379
+ tags.push("@protect");
380
+ if (source)
381
+ tags.push(`@${source}`);
382
+ if (tags.length > 0)
383
+ code += ` * ${tags.join(" ")}\n`;
384
+ if (codePath !== null)
385
+ code += ` * @path=${escapeForComment(codePath)}\n`;
386
+ const matches = previousText.match(/"[^"]*"/g);
387
+ const countInMethodName = matches ? matches.length : 0;
388
+ code += " */\n";
389
+ code += `async function ${methodName} (${new Array(countInMethodName)
390
+ .fill(0)
391
+ .map((v, index) => `param${index}`)
392
+ .join(", ")}){\n`;
393
+ code += `// source: ${source}\n`;
394
+ code += `// implemented_at: ${new Date().toISOString()}\n`;
395
+ stepCodeLines.forEach((line) => (code += ` ${line}\n`));
396
+ if (renamedText === "verify_page_title" || renamedText === "verify_page_url") {
397
+ const parameters = stepVariables.map((v) => parametersMap[v.text.replace(/[<>]/g, "")]);
398
+ code += `await ${renamedText}(${parameters.map((v) => (isNaN(Number(v)) ? `"${v}"` : Number(v))).join(", ")});\n`;
399
+ }
400
+ else {
401
+ code += `await ${renamedText}(${stepVariables.map((v) => (isNaN(Number(v.text)) ? `"${v.text}"` : Number(v.text))).join(", ")});\n`;
402
+ }
403
+ code += "}\n";
404
+ return this._injectMethod(methodName, code);
405
+ }
366
406
  addInfraCommand(methodName, description, stepVarables, stepCodeLines, protectStep = false, source = null, codePath = "") {
367
407
  let code = "\n";
368
408
  code += "/**\n";
@@ -415,6 +455,46 @@ export class CodePage {
415
455
  code += "}\n";
416
456
  return this._injectMethod(methodName, code);
417
457
  }
458
+ _replaceSelectedCode(code, injectIndexEnd) {
459
+ const newFileContent = this.fileContent.substring(0, injectIndexEnd - 2) +
460
+ "\n " +
461
+ code +
462
+ "\n}\n" +
463
+ this.fileContent.substring(injectIndexEnd);
464
+ this._init();
465
+ this.generateModel(newFileContent);
466
+ }
467
+ _injectOneCommand(methodName, code) {
468
+ const result = { methodName };
469
+ code = code.trim();
470
+ const existMethod = this.methods.find((m) => m.name === methodName);
471
+ if (!existMethod) {
472
+ throw new Error(`method ${methodName} not found for injection`);
473
+ }
474
+ const oldCode = existMethod.codePart.trim();
475
+ this._replaceSelectedCode(code, existMethod.end);
476
+ result.status = CodeStatus.UPDATED;
477
+ result.oldCode = oldCode;
478
+ result.newCode = code;
479
+ return result;
480
+ }
481
+ _removeSelectedCode(commands, injectIndexStart, injectIndexEnd) {
482
+ let newFileContent = this.fileContent.substring(injectIndexStart, injectIndexEnd);
483
+ commands.forEach((cmd) => {
484
+ newFileContent = newFileContent.replace(cmd, "");
485
+ });
486
+ newFileContent =
487
+ this.fileContent.substring(0, injectIndexStart) + newFileContent + this.fileContent.substring(injectIndexEnd);
488
+ this._init();
489
+ this.generateModel(newFileContent);
490
+ }
491
+ _removeCommands(methodName, commands) {
492
+ const existMethod = this.methods.find((m) => m.name === methodName);
493
+ if (!existMethod) {
494
+ throw new Error(`method ${methodName} not found for removal`);
495
+ }
496
+ this._removeSelectedCode(commands, existMethod.start, existMethod.end);
497
+ }
418
498
  _injectMethod(methodName, code) {
419
499
  const result = { methodName };
420
500
  code = code.trim();
@@ -487,11 +567,12 @@ export class CodePage {
487
567
  if (!element || !element.locators)
488
568
  return element;
489
569
  const clone = JSON.parse(JSON.stringify(element));
490
- for (let i = 0; i < (clone.locators?.length ?? 0); i++) {
491
- const locator = clone.locators[i];
492
- if (locator.score)
493
- delete locator.score;
570
+ const locatorsArray = Array.isArray(clone.locators) ? clone.locators : [];
571
+ for (let i = 0; i < locatorsArray.length; i++) {
572
+ if (locatorsArray[i].score)
573
+ delete locatorsArray[i].score;
494
574
  }
575
+ clone.locators = Array.isArray(clone.locators) ? locatorsArray : [];
495
576
  return clone;
496
577
  }
497
578
  insertElements(elements) {
@@ -621,7 +702,7 @@ export class CodePage {
621
702
  let locatorsMetadataFileName = this.sourceFileName.replace(".mjs", ".json");
622
703
  const config = getAiConfig();
623
704
  if (config && config.locatorsMetadataDir) {
624
- locatorsMetadataFileName = path.join(config.locatorsMetadataDir, path.basename(locatorsMetadataFileName));
705
+ locatorsMetadataFileName = locatorsMetadataFileName.replace(path.join("features", "step_definitions"), path.join(config.locatorsMetadataDir));
625
706
  if (!existsSync(path.dirname(locatorsMetadataFileName))) {
626
707
  mkdirSync(path.dirname(locatorsMetadataFileName), { recursive: true });
627
708
  }
@@ -633,7 +714,7 @@ export class CodePage {
633
714
  }
634
715
  }
635
716
  catch {
636
- logger.info("failed to read locators metadata file", locatorsMetadataFileName);
717
+ logger.error("failed to read locators metadata file", locatorsMetadataFileName);
637
718
  }
638
719
  const keys = Object.keys(locatorsMetadata);
639
720
  keys.forEach((key) => {
@@ -643,7 +724,7 @@ export class CodePage {
643
724
  writeFileSync(locatorsMetadataFileName, JSON.stringify(metadata, null, 2), "utf8");
644
725
  }
645
726
  catch {
646
- logger.info("failed to write locators metadata file", locatorsMetadataFileName);
727
+ logger.error("failed to write locators metadata file", locatorsMetadataFileName);
647
728
  }
648
729
  }
649
730
  _getVariableStartEnd(variableName) {