@dev-blinq/cucumber_client 1.0.1173-dev → 1.0.1173-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 +220 -0
- package/bin/assets/preload/accessibility.js +1 -1
- package/bin/assets/preload/find_context.js +1 -1
- package/bin/assets/preload/generateSelector.js +24 -0
- package/bin/assets/preload/locators.js +18 -0
- package/bin/assets/preload/recorderv3.js +85 -11
- package/bin/assets/preload/unique_locators.js +24 -3
- package/bin/assets/scripts/aria_snapshot.js +235 -0
- package/bin/assets/scripts/dom_attr.js +372 -0
- package/bin/assets/scripts/dom_element.js +0 -0
- package/bin/assets/scripts/dom_parent.js +185 -0
- package/bin/assets/scripts/event_utils.js +105 -0
- package/bin/assets/scripts/pw.js +7886 -0
- package/bin/assets/scripts/recorder.js +1147 -0
- package/bin/assets/scripts/snapshot_capturer.js +155 -0
- package/bin/assets/scripts/unique_locators.js +844 -0
- package/bin/assets/scripts/yaml.js +4770 -0
- package/bin/assets/templates/page_template.txt +2 -16
- package/bin/assets/templates/utils_template.txt +65 -12
- package/bin/client/cli_helpers.js +0 -1
- package/bin/client/code_cleanup/utils.js +43 -14
- package/bin/client/code_gen/code_inversion.js +112 -18
- package/bin/client/code_gen/index.js +3 -0
- package/bin/client/code_gen/page_reflection.js +37 -20
- package/bin/client/code_gen/playwright_codeget.js +152 -48
- package/bin/client/cucumber/feature.js +96 -42
- package/bin/client/cucumber/project_to_document.js +8 -7
- package/bin/client/cucumber/steps_definitions.js +59 -16
- package/bin/client/local_agent.js +9 -7
- package/bin/client/operations/dump_tree.js +159 -8
- package/bin/client/playground/playground.js +1 -1
- package/bin/client/project.js +6 -2
- package/bin/client/recorderv3/bvt_recorder.js +236 -79
- package/bin/client/recorderv3/cli.js +1 -0
- package/bin/client/recorderv3/implemented_steps.js +111 -11
- package/bin/client/recorderv3/index.js +45 -4
- package/bin/client/recorderv3/network.js +299 -0
- package/bin/client/recorderv3/step_runner.js +179 -13
- package/bin/client/recorderv3/step_utils.js +159 -14
- package/bin/client/recorderv3/update_feature.js +55 -30
- package/bin/client/recording.js +8 -0
- package/bin/client/run_cucumber.js +116 -4
- package/bin/client/scenario_report.js +112 -50
- package/bin/client/test_scenario.js +0 -1
- package/bin/index.js +1 -0
- package/package.json +15 -8
- package/bin/client/code_gen/get_implemented_steps.js +0 -27
|
@@ -32,7 +32,6 @@ const MAX_SIZE_LIMIT = 1e7 * 3;
|
|
|
32
32
|
|
|
33
33
|
import { getJsonReport } from "./bvt_json_report.js";
|
|
34
34
|
import { profile } from "./profiler.js";
|
|
35
|
-
import { getDocumentAndPickel } from "./cucumber/feature.js";
|
|
36
35
|
winCA({});
|
|
37
36
|
|
|
38
37
|
class Client {
|
|
@@ -383,7 +382,7 @@ class LocalAgent {
|
|
|
383
382
|
error: command.data.errorMessage,
|
|
384
383
|
});
|
|
385
384
|
agent.stepFailResolve(command.data.errorMessage);
|
|
386
|
-
logger.
|
|
385
|
+
logger.error("Step fail, " + command.data.errorMessage);
|
|
387
386
|
} else {
|
|
388
387
|
agent.stepEndResolve();
|
|
389
388
|
logger.info("Step end");
|
|
@@ -655,6 +654,7 @@ class LocalAgent {
|
|
|
655
654
|
|
|
656
655
|
let page = agent.project.getPage(agent.pageName, true);
|
|
657
656
|
const generateCodeResult = generateCode(recording, page, userData, agent.project.rootFolder, methodName);
|
|
657
|
+
|
|
658
658
|
if (generateCodeResult.simple === true) {
|
|
659
659
|
agent.sendDone("generateStepCode", null);
|
|
660
660
|
break;
|
|
@@ -707,6 +707,9 @@ class LocalAgent {
|
|
|
707
707
|
cucumberStep: agent.cucumberStep,
|
|
708
708
|
},
|
|
709
709
|
});
|
|
710
|
+
if (generateCodeResult.locatorsMetadata) {
|
|
711
|
+
page.addLocatorsMetadata(generateCodeResult.locatorsMetadata);
|
|
712
|
+
}
|
|
710
713
|
await page.save();
|
|
711
714
|
agent.scenarioReport.updateLastStep({
|
|
712
715
|
recording: command.data.recording,
|
|
@@ -967,7 +970,7 @@ class LocalAgent {
|
|
|
967
970
|
async createNewStepLocal(
|
|
968
971
|
featureName,
|
|
969
972
|
cucumberStep,
|
|
970
|
-
|
|
973
|
+
comments,
|
|
971
974
|
userData,
|
|
972
975
|
firstStep,
|
|
973
976
|
previousTasks,
|
|
@@ -1056,9 +1059,8 @@ class LocalAgent {
|
|
|
1056
1059
|
//stepText = _replaceWithLocalData(stepText, testData);
|
|
1057
1060
|
|
|
1058
1061
|
logger.info("\x1b[38;5;208mCreate new step:\x1b[0m " + stepText);
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
await this.context.web.beforeStep(null, stepObject);
|
|
1062
|
+
if (this.context && this.context.stable) {
|
|
1063
|
+
await this.context.stable.beforeStep(null, cucumberStep);
|
|
1062
1064
|
}
|
|
1063
1065
|
//this.pageName = pageName;
|
|
1064
1066
|
this.cucumberStep = cucumberStep;
|
|
@@ -1083,7 +1085,7 @@ class LocalAgent {
|
|
|
1083
1085
|
previousTasks,
|
|
1084
1086
|
scenarioDocument,
|
|
1085
1087
|
scenarioStepIndex,
|
|
1086
|
-
comments
|
|
1088
|
+
comments,
|
|
1087
1089
|
featureFileText,
|
|
1088
1090
|
recover,
|
|
1089
1091
|
dumpConfig: this.dumpConfig,
|
|
@@ -48,18 +48,13 @@ const _openCDP = async (context) => {
|
|
|
48
48
|
// let result = await cdp.send("DOM.getDocument", { depth: -1, pierce: true });
|
|
49
49
|
// console.log("result", JSON.stringify(result, null, 2));
|
|
50
50
|
};
|
|
51
|
+
|
|
51
52
|
const getAccessibilityTree = async (context, dumpConfig) => {
|
|
52
53
|
for (let i = 0; i < 3; i++) {
|
|
53
54
|
await _closeCDP();
|
|
54
55
|
try {
|
|
55
56
|
await _openCDP(context);
|
|
56
|
-
if (dumpConfig && dumpConfig.supress_errors === true) {
|
|
57
|
-
process.env.SUPRESS_ERRORS = "true";
|
|
58
|
-
}
|
|
59
57
|
//wait for 2 seconds
|
|
60
|
-
// if (dumpConfig && dumpConfig.independentThought === true) {
|
|
61
|
-
// context.INDEPENDENT_THOUGHT = "true";
|
|
62
|
-
// }
|
|
63
58
|
if (dumpConfig && dumpConfig.load_all_lazy === true) {
|
|
64
59
|
await context.page.evaluate(() => {
|
|
65
60
|
// document.addEventListener("load", () => {
|
|
@@ -86,6 +81,7 @@ const getAccessibilityTree = async (context, dumpConfig) => {
|
|
|
86
81
|
break;
|
|
87
82
|
}
|
|
88
83
|
}
|
|
84
|
+
|
|
89
85
|
await context.page.evaluate(() => {
|
|
90
86
|
const { top, left } = window.originalScroll || { top: 0, left: 0 };
|
|
91
87
|
window.scrollTo(left, top);
|
|
@@ -381,6 +377,81 @@ const findLocatorByText = async (context, texts, backendNodeId) => {
|
|
|
381
377
|
await _closeCDP();
|
|
382
378
|
}
|
|
383
379
|
};
|
|
380
|
+
function classifyLocatorsByStrategy(locators) {
|
|
381
|
+
const locs = [];
|
|
382
|
+
|
|
383
|
+
const allStrategyLocators = {
|
|
384
|
+
basic: [],
|
|
385
|
+
no_text: [],
|
|
386
|
+
ignore_digit: [],
|
|
387
|
+
context: [],
|
|
388
|
+
strategy: "basic",
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
const regexRegex = /\/.*\\[d][+].*\//;
|
|
392
|
+
for (const locator of locators) {
|
|
393
|
+
if (locator.mode) {
|
|
394
|
+
const { mode, ...rest } = locator;
|
|
395
|
+
locs.push(rest);
|
|
396
|
+
allStrategyLocators[locator.mode.toLowerCase()].push(rest);
|
|
397
|
+
} else if (locator.text && locator.text.length > 0) {
|
|
398
|
+
locs.push({
|
|
399
|
+
...locator,
|
|
400
|
+
mode: "CONTEXT",
|
|
401
|
+
});
|
|
402
|
+
allStrategyLocators["context"].push(locator);
|
|
403
|
+
} else if (regexRegex.test(locator.css)) {
|
|
404
|
+
locs.push({
|
|
405
|
+
...locator,
|
|
406
|
+
mode: "IGNORE_DIGIT",
|
|
407
|
+
});
|
|
408
|
+
allStrategyLocators["ignore_digit"].push(locator);
|
|
409
|
+
} else if (locator.css.includes("text=") || locator.css.includes("[name=") || locator.css.includes("label=")) {
|
|
410
|
+
locs.push(locator);
|
|
411
|
+
allStrategyLocators["basic"].push(locator);
|
|
412
|
+
} else {
|
|
413
|
+
locs.push({
|
|
414
|
+
...locator,
|
|
415
|
+
mode: "NO_TEXT",
|
|
416
|
+
});
|
|
417
|
+
allStrategyLocators["no_text"].push(locator);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
if (allStrategyLocators["context"].length > 0) {
|
|
421
|
+
allStrategyLocators["strategy"] = "context";
|
|
422
|
+
} else if (allStrategyLocators["basic"].length === 0 && allStrategyLocators["no_text"].length > 0) {
|
|
423
|
+
allStrategyLocators["strategy"] = "no_text";
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
return {
|
|
427
|
+
locators: locs,
|
|
428
|
+
allStrategyLocators,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
async function filterLocators(cssLocators, elObjectId) {
|
|
433
|
+
const kept = [];
|
|
434
|
+
for (const selector of cssLocators) {
|
|
435
|
+
// call window.findElement(selector) === el
|
|
436
|
+
const { result } = await cdp.send("Runtime.callFunctionOn", {
|
|
437
|
+
functionDeclaration: `
|
|
438
|
+
function(element,selector) {
|
|
439
|
+
console.log("filterLocators in progress");
|
|
440
|
+
console.log(element,selector);
|
|
441
|
+
return window.findElement(selector) === element;
|
|
442
|
+
}
|
|
443
|
+
`,
|
|
444
|
+
objectId: elObjectId,
|
|
445
|
+
arguments: [{ objectId: elObjectId }, { value: selector }],
|
|
446
|
+
returnByValue: true,
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
if (result.value) {
|
|
450
|
+
kept.push(selector);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return kept;
|
|
454
|
+
}
|
|
384
455
|
|
|
385
456
|
async function getRecorderLocators(context, backendNodeId) {
|
|
386
457
|
if (!cdp) {
|
|
@@ -391,7 +462,8 @@ async function getRecorderLocators(context, backendNodeId) {
|
|
|
391
462
|
backendNodeId: backendNodeId,
|
|
392
463
|
});
|
|
393
464
|
const objectId = domNode.object.objectId;
|
|
394
|
-
let
|
|
465
|
+
let locators = [];
|
|
466
|
+
locators = await cdp.send("Runtime.callFunctionOn", {
|
|
395
467
|
functionDeclaration:
|
|
396
468
|
"function(element,options) { console.log(element,options); return window.getPWLocators(element,options); }",
|
|
397
469
|
objectId: objectId,
|
|
@@ -408,8 +480,87 @@ async function getRecorderLocators(context, backendNodeId) {
|
|
|
408
480
|
],
|
|
409
481
|
returnByValue: true,
|
|
410
482
|
});
|
|
483
|
+
if (!locators || !locators.result || !locators.result.value) {
|
|
484
|
+
locators = [];
|
|
485
|
+
} else {
|
|
486
|
+
locators = locators.result?.value;
|
|
487
|
+
}
|
|
488
|
+
let cssLocators = [];
|
|
489
|
+
try {
|
|
490
|
+
let origenCss = await cdp.send("Runtime.callFunctionOn", {
|
|
491
|
+
functionDeclaration:
|
|
492
|
+
"function(element) { console.log(element); return window.generateUniqueCSSSelector(element); }",
|
|
493
|
+
objectId: objectId,
|
|
494
|
+
arguments: [
|
|
495
|
+
{
|
|
496
|
+
objectId: objectId,
|
|
497
|
+
},
|
|
498
|
+
],
|
|
499
|
+
returnByValue: true,
|
|
500
|
+
});
|
|
501
|
+
origenCss = origenCss.result?.value;
|
|
502
|
+
if (origenCss) {
|
|
503
|
+
cssLocators.push(origenCss);
|
|
504
|
+
}
|
|
505
|
+
let noClasses = await cdp.send("Runtime.callFunctionOn", {
|
|
506
|
+
functionDeclaration:
|
|
507
|
+
"function(element,options) { console.log(element,options); return window.CssSelectorGenerator.getCssSelector(element,options); }",
|
|
508
|
+
objectId: objectId,
|
|
509
|
+
arguments: [
|
|
510
|
+
{
|
|
511
|
+
objectId: objectId,
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
value: {
|
|
515
|
+
blacklist: [/^(?!.*h\d).*?\d.*/, /\[style/, /\[data-input-id/, /\[blinq-container/],
|
|
516
|
+
combineWithinSelector: true,
|
|
517
|
+
combineBetweenSelectors: true,
|
|
518
|
+
selectors: ["id", "attribute", "tag", "nthchild", "nthoftype"],
|
|
519
|
+
maxCombinations: 100,
|
|
520
|
+
},
|
|
521
|
+
},
|
|
522
|
+
],
|
|
523
|
+
returnByValue: true,
|
|
524
|
+
});
|
|
525
|
+
noClasses = noClasses.result?.value;
|
|
526
|
+
if (!cssLocators.includes(noClasses)) {
|
|
527
|
+
cssLocators.push(noClasses);
|
|
528
|
+
}
|
|
529
|
+
let withClasses = await cdp.send("Runtime.callFunctionOn", {
|
|
530
|
+
functionDeclaration:
|
|
531
|
+
"function(element,options) { console.log(element,options); return window.CssSelectorGenerator.getCssSelector(element,options); }",
|
|
532
|
+
objectId: objectId,
|
|
533
|
+
arguments: [
|
|
534
|
+
{
|
|
535
|
+
objectId: objectId,
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
value: {
|
|
539
|
+
blacklist: [/^(?!.*h\d).*?\d.*/, /\[style/, /\[data-input-id/, /\[blinq-container/],
|
|
540
|
+
combineWithinSelector: true,
|
|
541
|
+
combineBetweenSelectors: true,
|
|
542
|
+
selectors: ["id", "attribute", "tag", "nthchild", "nthoftype", "class"],
|
|
543
|
+
maxCombinations: 100,
|
|
544
|
+
},
|
|
545
|
+
},
|
|
546
|
+
],
|
|
547
|
+
returnByValue: true,
|
|
548
|
+
});
|
|
549
|
+
withClasses = withClasses.result?.value;
|
|
550
|
+
if (!cssLocators.includes(withClasses)) {
|
|
551
|
+
cssLocators.push(withClasses);
|
|
552
|
+
}
|
|
553
|
+
cssLocators.sort((a, b) => a.length - b.length);
|
|
554
|
+
|
|
555
|
+
cssLocators = await filterLocators(cssLocators, objectId);
|
|
556
|
+
} catch (err) {
|
|
557
|
+
console.error("Error in generateUniqueCSSSelector", error);
|
|
558
|
+
}
|
|
559
|
+
locators?.push(...cssLocators.map((css) => ({ mode: "NO_TEXT", css })));
|
|
560
|
+
|
|
561
|
+
const result = classifyLocatorsByStrategy(locators);
|
|
411
562
|
|
|
412
|
-
return
|
|
563
|
+
return { ...result, element_name: "" };
|
|
413
564
|
} finally {
|
|
414
565
|
await _closeCDP();
|
|
415
566
|
}
|
package/bin/client/project.js
CHANGED
|
@@ -4,6 +4,7 @@ import { CodePage } from "./code_gen/page_reflection.js";
|
|
|
4
4
|
import logger from "../logger.js";
|
|
5
5
|
import path from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
|
+
import { findFilesWithExtension } from "./cucumber/steps_definitions.js";
|
|
7
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
8
9
|
const __dirname = path.dirname(__filename);
|
|
9
10
|
|
|
@@ -85,7 +86,10 @@ class Project {
|
|
|
85
86
|
logger.error("Error loading utils_template");
|
|
86
87
|
}
|
|
87
88
|
|
|
88
|
-
|
|
89
|
+
const files = findFilesWithExtension(this.stepsFolder, "mjs");
|
|
90
|
+
|
|
91
|
+
//let files = readdirSync(this.stepsFolder);
|
|
92
|
+
|
|
89
93
|
for (let i = 0; i < files.length; i++) {
|
|
90
94
|
let file = files[i];
|
|
91
95
|
if (file.startsWith("_")) {
|
|
@@ -100,7 +104,7 @@ class Project {
|
|
|
100
104
|
this.pages.push(page);
|
|
101
105
|
}
|
|
102
106
|
}
|
|
103
|
-
return
|
|
107
|
+
return this.environment.name;
|
|
104
108
|
}
|
|
105
109
|
getPagesNames() {
|
|
106
110
|
let result = [];
|