@dev-blinq/cucumber_client 1.0.1432-dev → 1.0.1432-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/preload/css_gen.js +10 -10
- package/bin/assets/preload/toolbar.js +27 -29
- package/bin/assets/preload/unique_locators.js +1 -1
- package/bin/assets/preload/yaml.js +288 -275
- package/bin/assets/scripts/aria_snapshot.js +223 -220
- package/bin/assets/scripts/dom_attr.js +329 -329
- package/bin/assets/scripts/dom_parent.js +169 -174
- package/bin/assets/scripts/event_utils.js +94 -94
- package/bin/assets/scripts/pw.js +2050 -1949
- package/bin/assets/scripts/recorder.js +70 -45
- package/bin/assets/scripts/snapshot_capturer.js +147 -147
- package/bin/assets/scripts/unique_locators.js +170 -49
- package/bin/assets/scripts/yaml.js +796 -783
- package/bin/assets/templates/_hooks_template.txt +6 -2
- package/bin/assets/templates/utils_template.txt +16 -16
- package/bin/client/code_cleanup/find_step_definition_references.js +0 -1
- package/bin/client/code_gen/api_codegen.js +2 -2
- package/bin/client/code_gen/code_inversion.js +63 -2
- package/bin/client/code_gen/function_signature.js +4 -0
- package/bin/client/code_gen/page_reflection.js +52 -11
- package/bin/client/code_gen/playwright_codeget.js +28 -22
- package/bin/client/cucumber/feature_data.js +2 -2
- package/bin/client/cucumber/project_to_document.js +8 -2
- package/bin/client/cucumber/steps_definitions.js +19 -3
- package/bin/client/local_agent.js +3 -2
- package/bin/client/parse_feature_file.js +23 -26
- package/bin/client/playground/projects/env.json +2 -2
- package/bin/client/recorderv3/bvt_init.js +363 -0
- package/bin/client/recorderv3/bvt_recorder.js +1009 -47
- package/bin/client/recorderv3/implemented_steps.js +2 -0
- package/bin/client/recorderv3/index.js +3 -283
- package/bin/client/recorderv3/scriptTest.js +1 -1
- package/bin/client/recorderv3/services.js +818 -142
- package/bin/client/recorderv3/step_runner.js +27 -8
- package/bin/client/recorderv3/step_utils.js +514 -39
- package/bin/client/recorderv3/update_feature.js +32 -13
- package/bin/client/recorderv3/wbr_entry.js +61 -0
- package/bin/client/recording.js +1 -0
- package/bin/client/upload-service.js +4 -2
- package/bin/client/utils/socket_logger.js +1 -1
- package/bin/index.js +4 -1
- package/package.json +6 -4
|
@@ -158,8 +158,7 @@ class LocatorGenerator {
|
|
|
158
158
|
const tSelectorList = [];
|
|
159
159
|
for (const selectorPart of selectorPartList) {
|
|
160
160
|
const { engine, selector } = selectorPart;
|
|
161
|
-
if (textToIgnore && selector.includes(textToIgnore)
|
|
162
|
-
) {
|
|
161
|
+
if (textToIgnore && selector.includes(textToIgnore)) {
|
|
163
162
|
continue;
|
|
164
163
|
}
|
|
165
164
|
if (engine === "css") {
|
|
@@ -218,6 +217,59 @@ class LocatorGenerator {
|
|
|
218
217
|
}
|
|
219
218
|
return result;
|
|
220
219
|
}
|
|
220
|
+
getMixedLocators(element, options) {
|
|
221
|
+
const noTextLocators = this.getNoTextLocators(element, options);
|
|
222
|
+
const textLocators = this.getTextLocators(element, options);
|
|
223
|
+
const customLocators = this.getCustomLocators(element, options);
|
|
224
|
+
return [...customLocators, ...textLocators, ...noTextLocators];
|
|
225
|
+
}
|
|
226
|
+
toContextLocators(element, contextElement, options = {}) {
|
|
227
|
+
const commonParent = this.dom_Parent.findLowestCommonAncestor([contextElement, element]);
|
|
228
|
+
const climb = this.dom_Parent.getClimbCountToParent(contextElement, commonParent);
|
|
229
|
+
const text = contextElement.innerText.trim();
|
|
230
|
+
|
|
231
|
+
const prefix = `internal:text="${text}" >> ${this.getXPathSelector(climb)}`;
|
|
232
|
+
const result = this.getElementLocators(element, {
|
|
233
|
+
root: commonParent,
|
|
234
|
+
strategies: {
|
|
235
|
+
[this.locatorStrategies.custom]: true,
|
|
236
|
+
[this.locatorStrategies.text]: true,
|
|
237
|
+
[this.locatorStrategies.no_text]: true,
|
|
238
|
+
},
|
|
239
|
+
prefix,
|
|
240
|
+
...options,
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
const attachContextToLocators = (locs) => {
|
|
244
|
+
locs.forEach((loc) => {
|
|
245
|
+
loc.climb = climb;
|
|
246
|
+
loc.text = text;
|
|
247
|
+
});
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const allStrategyLocators = result.allStrategyLocators;
|
|
251
|
+
const locators = result.locators;
|
|
252
|
+
if (allStrategyLocators) {
|
|
253
|
+
const allLocators = [];
|
|
254
|
+
for (const strategy in allStrategyLocators) {
|
|
255
|
+
if (strategy === "strategy") continue;
|
|
256
|
+
const locators = allStrategyLocators[strategy];
|
|
257
|
+
if (locators.length === 0) continue;
|
|
258
|
+
allLocators.push(...locators);
|
|
259
|
+
allStrategyLocators[strategy] = [];
|
|
260
|
+
}
|
|
261
|
+
attachContextToLocators(allLocators);
|
|
262
|
+
allStrategyLocators[this.locatorStrategies.context] = allLocators;
|
|
263
|
+
allStrategyLocators.strategy = this.locatorStrategies.context;
|
|
264
|
+
result.locators = allLocators;
|
|
265
|
+
return result;
|
|
266
|
+
}
|
|
267
|
+
if (locators) {
|
|
268
|
+
attachContextToLocators(locators);
|
|
269
|
+
return result;
|
|
270
|
+
}
|
|
271
|
+
return result;
|
|
272
|
+
}
|
|
221
273
|
getContextLocators(element, locators) {
|
|
222
274
|
if (!locators || !Array.isArray(locators)) {
|
|
223
275
|
console.error("Locators must be an array");
|
|
@@ -442,12 +494,16 @@ class LocatorGenerator {
|
|
|
442
494
|
categorizeLocators(element, locators, options) {
|
|
443
495
|
const unique = [];
|
|
444
496
|
const nonUnique = [];
|
|
497
|
+
const visible = options?.visible ?? true;
|
|
445
498
|
try {
|
|
446
499
|
for (const locator of locators) {
|
|
447
500
|
if (!locator || !locator.css || typeof locator.css !== "string") {
|
|
448
501
|
console.error("Locator must have a valid css selector found: ", locator);
|
|
449
502
|
continue;
|
|
450
503
|
}
|
|
504
|
+
if (visible === false) {
|
|
505
|
+
locator.visible = false;
|
|
506
|
+
}
|
|
451
507
|
const elements = this.getMatchingElements(locator.css, options);
|
|
452
508
|
if (elements.length === 0) {
|
|
453
509
|
console.warn(`No elements found for locator: ${locator.css}`);
|
|
@@ -572,7 +628,7 @@ class LocatorGenerator {
|
|
|
572
628
|
result.push(_locator);
|
|
573
629
|
} else {
|
|
574
630
|
const index = _elements.indexOf(element);
|
|
575
|
-
if (index !== -1 && index <
|
|
631
|
+
if (index !== -1 && index < 10) {
|
|
576
632
|
// _locator.selector = fullSelector;
|
|
577
633
|
_locator.css = fullSelector;
|
|
578
634
|
_locator.index = index;
|
|
@@ -584,7 +640,7 @@ class LocatorGenerator {
|
|
|
584
640
|
}
|
|
585
641
|
} else {
|
|
586
642
|
const index = elements.indexOf(element);
|
|
587
|
-
if (index !== -1 && index <
|
|
643
|
+
if (index !== -1 && index < 10) {
|
|
588
644
|
locator.index = index;
|
|
589
645
|
locator.priority = 2; // non-unique locators have lower priority
|
|
590
646
|
result.push(locator);
|
|
@@ -592,7 +648,7 @@ class LocatorGenerator {
|
|
|
592
648
|
}
|
|
593
649
|
} else {
|
|
594
650
|
const index = elements.indexOf(element);
|
|
595
|
-
if (index !== -1 && index <
|
|
651
|
+
if (index !== -1 && index < 10) {
|
|
596
652
|
locator.index = index;
|
|
597
653
|
locator.priority = 2; // non-unique locators have lower priority
|
|
598
654
|
result.push(locator);
|
|
@@ -626,7 +682,7 @@ class LocatorGenerator {
|
|
|
626
682
|
|
|
627
683
|
getUniqueLocators2(element, locatorGenerator = this.getNoTextLocators, options = {}) {
|
|
628
684
|
try {
|
|
629
|
-
const { maxLocators = 5, root = window.document.body } = options;
|
|
685
|
+
const { maxLocators = 5, root = window.document.body, prefix } = options;
|
|
630
686
|
|
|
631
687
|
if (!element) {
|
|
632
688
|
return [];
|
|
@@ -646,13 +702,7 @@ class LocatorGenerator {
|
|
|
646
702
|
},
|
|
647
703
|
];
|
|
648
704
|
} else {
|
|
649
|
-
return [
|
|
650
|
-
{
|
|
651
|
-
css: ":root",
|
|
652
|
-
score: 1,
|
|
653
|
-
priority: 1,
|
|
654
|
-
},
|
|
655
|
-
];
|
|
705
|
+
return [];
|
|
656
706
|
}
|
|
657
707
|
}
|
|
658
708
|
|
|
@@ -679,12 +729,13 @@ class LocatorGenerator {
|
|
|
679
729
|
|
|
680
730
|
const elementsCache = new Map();
|
|
681
731
|
|
|
682
|
-
const allAncestors = this.dom_Parent.getFullAncestorChainToRoot(element, root);
|
|
732
|
+
const allAncestors = prefix ? [element] : this.dom_Parent.getFullAncestorChainToRoot(element, root);
|
|
683
733
|
allAncestors.shift(); // remove the element itself from the ancestors
|
|
684
734
|
|
|
685
735
|
const cache = new Map();
|
|
686
736
|
const textToIgnore = this.PW.selectorUtils.elementText(cache, element).full.trim();
|
|
687
737
|
const ancestorLocators = [];
|
|
738
|
+
let uniqueAncestor = null;
|
|
688
739
|
for (const ancestor of allAncestors) {
|
|
689
740
|
const _locators = locatorGenerator(ancestor, { ...options, textToIgnore });
|
|
690
741
|
if (!_locators || !Array.isArray(_locators) || _locators.length === 0) {
|
|
@@ -697,11 +748,15 @@ class LocatorGenerator {
|
|
|
697
748
|
});
|
|
698
749
|
elementsCache.set(ancestor, _categorized);
|
|
699
750
|
if (_categorized.unique.length > 0) {
|
|
751
|
+
uniqueAncestor = {
|
|
752
|
+
element: ancestor,
|
|
753
|
+
locators: _categorized,
|
|
754
|
+
};
|
|
700
755
|
break;
|
|
701
756
|
}
|
|
702
757
|
}
|
|
703
758
|
|
|
704
|
-
const uniqueAncestor = ancestorLocators[ancestorLocators.length - 1];
|
|
759
|
+
// const uniqueAncestor = ancestorLocators[ancestorLocators.length - 1];
|
|
705
760
|
|
|
706
761
|
for (const locator of nonUnique) {
|
|
707
762
|
const selector = locator.css ?? locator.selector;
|
|
@@ -710,6 +765,27 @@ class LocatorGenerator {
|
|
|
710
765
|
console.warn(`No elements found for locator: ${selector}`);
|
|
711
766
|
continue;
|
|
712
767
|
}
|
|
768
|
+
if (!uniqueAncestor) {
|
|
769
|
+
const elements = this.getMatchingElements(selector, options);
|
|
770
|
+
if (elements.length === 1 && elements[0] === element) {
|
|
771
|
+
result.push({
|
|
772
|
+
css: selector,
|
|
773
|
+
score: locator.score,
|
|
774
|
+
priority: 1,
|
|
775
|
+
});
|
|
776
|
+
} else {
|
|
777
|
+
const index = elements.indexOf(element);
|
|
778
|
+
if (index !== -1) {
|
|
779
|
+
result.push({
|
|
780
|
+
css: selector,
|
|
781
|
+
index,
|
|
782
|
+
score: locator.score + 200,
|
|
783
|
+
priority: 2,
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
713
789
|
|
|
714
790
|
for (const unique_locator of uniqueAncestor.locators.unique) {
|
|
715
791
|
const fullSelector = `${unique_locator.css} >> ${selector}`;
|
|
@@ -725,7 +801,7 @@ class LocatorGenerator {
|
|
|
725
801
|
result.push(newLocator);
|
|
726
802
|
} else {
|
|
727
803
|
const index = elements.indexOf(element);
|
|
728
|
-
if (index !== -1 && index <
|
|
804
|
+
if (index !== -1 && index < 10) {
|
|
729
805
|
const effectiveScore = (unique_locator.score + locator.score) / 2;
|
|
730
806
|
const newLocator = {
|
|
731
807
|
...unique_locator,
|
|
@@ -748,9 +824,32 @@ class LocatorGenerator {
|
|
|
748
824
|
return [];
|
|
749
825
|
}
|
|
750
826
|
}
|
|
827
|
+
isElementVisible(element) {
|
|
828
|
+
if (!(element instanceof Element)) return false;
|
|
829
|
+
const style = window.getComputedStyle(element);
|
|
830
|
+
if (style.display === "none" || style.visibility === "hidden" || style.opacity === "0") return false;
|
|
831
|
+
const rect = element.getBoundingClientRect();
|
|
832
|
+
if (rect.width === 0 || rect.height === 0) return false;
|
|
833
|
+
return true;
|
|
834
|
+
}
|
|
751
835
|
getElementLocators(element, options = {}) {
|
|
836
|
+
const isVisible = this.isElementVisible(element);
|
|
837
|
+
if (isVisible === false) {
|
|
838
|
+
console.warn("Element is not visible: ", element);
|
|
839
|
+
options.visible = isVisible;
|
|
840
|
+
}
|
|
752
841
|
try {
|
|
753
|
-
const {
|
|
842
|
+
const {
|
|
843
|
+
excludeText = false,
|
|
844
|
+
strategies = {
|
|
845
|
+
[this.locatorStrategies.custom]: true,
|
|
846
|
+
[this.locatorStrategies.context]: true,
|
|
847
|
+
[this.locatorStrategies.text]: true,
|
|
848
|
+
[this.locatorStrategies.text_with_index]: true,
|
|
849
|
+
[this.locatorStrategies.digitIgnore]: true,
|
|
850
|
+
[this.locatorStrategies.no_text]: true,
|
|
851
|
+
},
|
|
852
|
+
} = options;
|
|
754
853
|
|
|
755
854
|
const allStrategyLocators = {
|
|
756
855
|
[this.locatorStrategies.custom]: [],
|
|
@@ -760,7 +859,12 @@ class LocatorGenerator {
|
|
|
760
859
|
[this.locatorStrategies.digitIgnore]: [],
|
|
761
860
|
[this.locatorStrategies.no_text]: [],
|
|
762
861
|
};
|
|
763
|
-
if (
|
|
862
|
+
if (
|
|
863
|
+
strategies[this.locatorStrategies.custom] &&
|
|
864
|
+
this.options?.customAttributes &&
|
|
865
|
+
Array.isArray(this.options.customAttributes) &&
|
|
866
|
+
this.options.customAttributes.length > 0
|
|
867
|
+
) {
|
|
764
868
|
console.groupCollapsed("Generating Custom locators for element:", element);
|
|
765
869
|
const customLocators = this.getUniqueLocators(element, this.getCustomLocators.bind(this), options);
|
|
766
870
|
if (customLocators.length > 0) {
|
|
@@ -769,43 +873,60 @@ class LocatorGenerator {
|
|
|
769
873
|
}
|
|
770
874
|
console.groupEnd();
|
|
771
875
|
if (!excludeText) {
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
console.groupEnd();
|
|
775
|
-
if (basicLocators.length > 0) {
|
|
776
|
-
allStrategyLocators[this.locatorStrategies.text] = basicLocators;
|
|
777
|
-
}
|
|
876
|
+
if (strategies[this.locatorStrategies.text]) {
|
|
877
|
+
console.groupCollapsed("Generating Text locators for element:", element);
|
|
778
878
|
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
879
|
+
const basicLocators = this.getUniqueLocators(element, this.getTextLocators.bind(this), options);
|
|
880
|
+
console.groupEnd();
|
|
881
|
+
if (basicLocators.length > 0) {
|
|
882
|
+
allStrategyLocators[this.locatorStrategies.text] = basicLocators;
|
|
883
|
+
}
|
|
884
|
+
if (strategies[this.locatorStrategies.text_with_index]) {
|
|
885
|
+
const textWithIndexLocators = this.getTextwithIndexLocators(basicLocators);
|
|
886
|
+
if (textWithIndexLocators.length > 0) {
|
|
887
|
+
allStrategyLocators[this.locatorStrategies.text_with_index] = textWithIndexLocators;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
if (strategies[this.locatorStrategies.digitIgnore]) {
|
|
891
|
+
const digitIgnoreLocators = this.getDigitIgnoreLocators(element, basicLocators);
|
|
892
|
+
if (digitIgnoreLocators.length > 0) {
|
|
893
|
+
allStrategyLocators[this.locatorStrategies.digitIgnore] = digitIgnoreLocators;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
if (strategies[this.locatorStrategies.context]) {
|
|
897
|
+
const contextLocators = this.getContextLocators(element, basicLocators);
|
|
898
|
+
if (contextLocators.length > 0) {
|
|
899
|
+
allStrategyLocators[this.locatorStrategies.context] = contextLocators;
|
|
900
|
+
}
|
|
901
|
+
}
|
|
790
902
|
}
|
|
791
903
|
}
|
|
792
|
-
|
|
793
|
-
|
|
904
|
+
if (strategies[this.locatorStrategies.no_text]) {
|
|
905
|
+
console.groupCollapsed("Generating No Text locators for element:", element);
|
|
906
|
+
const noTextLocators = this.getUniqueLocators(element, this.getNoTextLocators.bind(this), options);
|
|
794
907
|
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
908
|
+
if (noTextLocators.length > 0) {
|
|
909
|
+
allStrategyLocators[this.locatorStrategies.no_text] = noTextLocators;
|
|
910
|
+
} else {
|
|
911
|
+
|
|
912
|
+
// try mixed locator strategy as last resort
|
|
913
|
+
const mixedLocators = this.getUniqueLocators(element, this.getMixedLocators.bind(this), options);
|
|
914
|
+
if (mixedLocators.length > 0) {
|
|
915
|
+
allStrategyLocators[this.locatorStrategies.no_text] = mixedLocators;
|
|
916
|
+
} else {
|
|
917
|
+
const _locators = [];
|
|
918
|
+
_locators.push({
|
|
919
|
+
css: this.generateUniqueCSSSelector(element, options),
|
|
920
|
+
score: 500,
|
|
921
|
+
priority: 3,
|
|
922
|
+
});
|
|
923
|
+
if (_locators.length > 0) {
|
|
924
|
+
allStrategyLocators[this.locatorStrategies.no_text] = _locators;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
806
927
|
}
|
|
928
|
+
console.groupEnd();
|
|
807
929
|
}
|
|
808
|
-
console.groupEnd();
|
|
809
930
|
|
|
810
931
|
let bestStrategy = this.getBestStrategy(allStrategyLocators);
|
|
811
932
|
if (!bestStrategy) {
|