@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.
- package/bin/assets/bundled_scripts/recorder.js +73 -73
- package/bin/assets/scripts/recorder.js +87 -49
- package/bin/assets/scripts/snapshot_capturer.js +10 -17
- package/bin/assets/scripts/unique_locators.js +168 -40
- package/bin/assets/templates/_hooks_template.txt +6 -2
- package/bin/assets/templates/utils_template.txt +16 -16
- package/bin/client/code_cleanup/utils.js +16 -7
- package/bin/client/code_gen/code_inversion.js +125 -1
- package/bin/client/code_gen/duplication_analysis.js +2 -1
- package/bin/client/code_gen/function_signature.js +8 -0
- package/bin/client/code_gen/index.js +4 -0
- package/bin/client/code_gen/page_reflection.js +90 -9
- package/bin/client/code_gen/playwright_codeget.js +173 -77
- package/bin/client/codemod/find_harcoded_locators.js +173 -0
- package/bin/client/codemod/fix_hardcoded_locators.js +247 -0
- package/bin/client/codemod/index.js +8 -0
- package/bin/client/codemod/locators_array/find_misstructured_elements.js +148 -0
- package/bin/client/codemod/locators_array/fix_misstructured_elements.js +144 -0
- package/bin/client/codemod/locators_array/index.js +114 -0
- package/bin/client/codemod/types.js +1 -0
- package/bin/client/cucumber/feature.js +4 -17
- package/bin/client/cucumber/steps_definitions.js +17 -12
- package/bin/client/recorderv3/bvt_init.js +310 -0
- package/bin/client/recorderv3/bvt_recorder.js +1560 -1183
- package/bin/client/recorderv3/constants.js +45 -0
- package/bin/client/recorderv3/implemented_steps.js +2 -0
- package/bin/client/recorderv3/index.js +3 -293
- package/bin/client/recorderv3/mixpanel.js +41 -0
- package/bin/client/recorderv3/services.js +839 -142
- package/bin/client/recorderv3/step_runner.js +36 -7
- package/bin/client/recorderv3/step_utils.js +300 -98
- package/bin/client/recorderv3/update_feature.js +87 -39
- package/bin/client/recorderv3/utils.js +74 -0
- package/bin/client/recorderv3/wbr_entry.js +61 -0
- package/bin/client/recording.js +1 -0
- package/bin/client/types/locators.js +2 -0
- package/bin/client/upload-service.js +2 -0
- package/bin/client/utils/app_dir.js +21 -0
- package/bin/client/utils/socket_logger.js +100 -125
- package/bin/index.js +5 -0
- package/package.json +21 -6
- package/bin/client/recorderv3/app_dir.js +0 -23
- package/bin/client/recorderv3/network.js +0 -299
- package/bin/client/recorderv3/scriptTest.js +0 -5
- 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.
|
|
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
|
-
|
|
491
|
-
|
|
492
|
-
if (
|
|
493
|
-
delete
|
|
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(
|
|
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.
|
|
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.
|
|
727
|
+
logger.error("failed to write locators metadata file", locatorsMetadataFileName);
|
|
647
728
|
}
|
|
648
729
|
}
|
|
649
730
|
_getVariableStartEnd(variableName) {
|