@dev-blinq/cucumber_client 1.0.1406-dev → 1.0.1406-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 +105 -105
- 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 +163 -44
- 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_cleanup/utils.js +5 -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 +846 -906
- package/bin/client/code_gen/playwright_codeget.js +27 -3
- package/bin/client/cucumber/feature.js +4 -0
- 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 +6 -3
- package/bin/client/cucumber_selector.js +17 -1
- 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/project.js +186 -202
- package/bin/client/recorderv3/bvt_init.js +349 -0
- package/bin/client/recorderv3/bvt_recorder.js +1038 -76
- package/bin/client/recorderv3/implemented_steps.js +2 -0
- package/bin/client/recorderv3/index.js +4 -311
- package/bin/client/recorderv3/scriptTest.js +1 -1
- package/bin/client/recorderv3/services.js +814 -154
- package/bin/client/recorderv3/step_runner.js +36 -10
- package/bin/client/recorderv3/step_utils.js +499 -37
- package/bin/client/recorderv3/update_feature.js +9 -5
- package/bin/client/recorderv3/wbr_entry.js +61 -0
- package/bin/client/recording.js +1 -0
- package/bin/client/upload-service.js +3 -2
- package/bin/client/utils/socket_logger.js +132 -0
- package/bin/index.js +4 -1
- package/bin/logger.js +3 -2
- package/bin/min/consoleApi.min.cjs +2 -3
- package/bin/min/injectedScript.min.cjs +16 -16
- package/package.json +19 -9
|
@@ -150,6 +150,7 @@ class LocatorGenerator {
|
|
|
150
150
|
}
|
|
151
151
|
getTextLocators(element, options) {
|
|
152
152
|
const injectedScript = this.injectedScript;
|
|
153
|
+
const { textToIgnore = null } = options;
|
|
153
154
|
const selectorPartLists = this.PW.selectorGenerator.buildTextCandidates(injectedScript, element, options);
|
|
154
155
|
const result = [];
|
|
155
156
|
for (const selectorPartList of selectorPartLists) {
|
|
@@ -157,6 +158,9 @@ class LocatorGenerator {
|
|
|
157
158
|
const tSelectorList = [];
|
|
158
159
|
for (const selectorPart of selectorPartList) {
|
|
159
160
|
const { engine, selector } = selectorPart;
|
|
161
|
+
if (textToIgnore && selector.includes(textToIgnore)) {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
160
164
|
if (engine === "css") {
|
|
161
165
|
tSelectorList.push(selector);
|
|
162
166
|
} else {
|
|
@@ -213,6 +217,53 @@ class LocatorGenerator {
|
|
|
213
217
|
}
|
|
214
218
|
return result;
|
|
215
219
|
}
|
|
220
|
+
toContextLocators(element, contextElement, options = {}) {
|
|
221
|
+
const commonParent = this.dom_Parent.findLowestCommonAncestor([contextElement, element]);
|
|
222
|
+
const climb = this.dom_Parent.getClimbCountToParent(contextElement, commonParent);
|
|
223
|
+
const text = contextElement.innerText.trim();
|
|
224
|
+
|
|
225
|
+
const prefix = `internal:text="${text}" >> ${this.getXPathSelector(climb)}`;
|
|
226
|
+
const result = this.getElementLocators(element, {
|
|
227
|
+
root: commonParent,
|
|
228
|
+
strategies: {
|
|
229
|
+
[this.locatorStrategies.custom]: true,
|
|
230
|
+
[this.locatorStrategies.text]: true,
|
|
231
|
+
[this.locatorStrategies.no_text]: true,
|
|
232
|
+
},
|
|
233
|
+
prefix,
|
|
234
|
+
...options,
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
const attachContextToLocators = (locs) => {
|
|
238
|
+
locs.forEach((loc) => {
|
|
239
|
+
loc.climb = climb;
|
|
240
|
+
loc.text = text;
|
|
241
|
+
});
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
const allStrategyLocators = result.allStrategyLocators;
|
|
245
|
+
const locators = result.locators;
|
|
246
|
+
if (allStrategyLocators) {
|
|
247
|
+
const allLocators = [];
|
|
248
|
+
for (const strategy in allStrategyLocators) {
|
|
249
|
+
if (strategy === "strategy") continue;
|
|
250
|
+
const locators = allStrategyLocators[strategy];
|
|
251
|
+
if (locators.length === 0) continue;
|
|
252
|
+
allLocators.push(...locators);
|
|
253
|
+
allStrategyLocators[strategy] = [];
|
|
254
|
+
}
|
|
255
|
+
attachContextToLocators(allLocators);
|
|
256
|
+
allStrategyLocators[this.locatorStrategies.context] = allLocators;
|
|
257
|
+
allStrategyLocators.strategy = this.locatorStrategies.context;
|
|
258
|
+
result.locators = allLocators;
|
|
259
|
+
return result;
|
|
260
|
+
}
|
|
261
|
+
if (locators) {
|
|
262
|
+
attachContextToLocators(locators);
|
|
263
|
+
return result;
|
|
264
|
+
}
|
|
265
|
+
return result;
|
|
266
|
+
}
|
|
216
267
|
getContextLocators(element, locators) {
|
|
217
268
|
if (!locators || !Array.isArray(locators)) {
|
|
218
269
|
console.error("Locators must be an array");
|
|
@@ -437,8 +488,16 @@ class LocatorGenerator {
|
|
|
437
488
|
categorizeLocators(element, locators, options) {
|
|
438
489
|
const unique = [];
|
|
439
490
|
const nonUnique = [];
|
|
491
|
+
const visible = options?.visible ?? true;
|
|
440
492
|
try {
|
|
441
493
|
for (const locator of locators) {
|
|
494
|
+
if (!locator || !locator.css || typeof locator.css !== "string") {
|
|
495
|
+
console.error("Locator must have a valid css selector found: ", locator);
|
|
496
|
+
continue;
|
|
497
|
+
}
|
|
498
|
+
if (visible === false) {
|
|
499
|
+
locator.visible = false;
|
|
500
|
+
}
|
|
442
501
|
const elements = this.getMatchingElements(locator.css, options);
|
|
443
502
|
if (elements.length === 0) {
|
|
444
503
|
console.warn(`No elements found for locator: ${locator.css}`);
|
|
@@ -617,7 +676,7 @@ class LocatorGenerator {
|
|
|
617
676
|
|
|
618
677
|
getUniqueLocators2(element, locatorGenerator = this.getNoTextLocators, options = {}) {
|
|
619
678
|
try {
|
|
620
|
-
const { maxLocators = 5, root = window.document.body } = options;
|
|
679
|
+
const { maxLocators = 5, root = window.document.body, prefix } = options;
|
|
621
680
|
|
|
622
681
|
if (!element) {
|
|
623
682
|
return [];
|
|
@@ -637,13 +696,7 @@ class LocatorGenerator {
|
|
|
637
696
|
},
|
|
638
697
|
];
|
|
639
698
|
} else {
|
|
640
|
-
return [
|
|
641
|
-
{
|
|
642
|
-
css: ":root",
|
|
643
|
-
score: 1,
|
|
644
|
-
priority: 1,
|
|
645
|
-
},
|
|
646
|
-
];
|
|
699
|
+
return [];
|
|
647
700
|
}
|
|
648
701
|
}
|
|
649
702
|
|
|
@@ -670,12 +723,15 @@ class LocatorGenerator {
|
|
|
670
723
|
|
|
671
724
|
const elementsCache = new Map();
|
|
672
725
|
|
|
673
|
-
const allAncestors = this.dom_Parent.getFullAncestorChainToRoot(element, root);
|
|
726
|
+
const allAncestors = prefix ? [element] : this.dom_Parent.getFullAncestorChainToRoot(element, root);
|
|
674
727
|
allAncestors.shift(); // remove the element itself from the ancestors
|
|
675
728
|
|
|
729
|
+
const cache = new Map();
|
|
730
|
+
const textToIgnore = this.PW.selectorUtils.elementText(cache, element).full.trim();
|
|
676
731
|
const ancestorLocators = [];
|
|
732
|
+
let uniqueAncestor = null;
|
|
677
733
|
for (const ancestor of allAncestors) {
|
|
678
|
-
const _locators = locatorGenerator(ancestor, options);
|
|
734
|
+
const _locators = locatorGenerator(ancestor, { ...options, textToIgnore });
|
|
679
735
|
if (!_locators || !Array.isArray(_locators) || _locators.length === 0) {
|
|
680
736
|
continue;
|
|
681
737
|
}
|
|
@@ -686,11 +742,15 @@ class LocatorGenerator {
|
|
|
686
742
|
});
|
|
687
743
|
elementsCache.set(ancestor, _categorized);
|
|
688
744
|
if (_categorized.unique.length > 0) {
|
|
745
|
+
uniqueAncestor = {
|
|
746
|
+
element: ancestor,
|
|
747
|
+
locators: _categorized,
|
|
748
|
+
};
|
|
689
749
|
break;
|
|
690
750
|
}
|
|
691
751
|
}
|
|
692
752
|
|
|
693
|
-
const uniqueAncestor = ancestorLocators[ancestorLocators.length - 1];
|
|
753
|
+
// const uniqueAncestor = ancestorLocators[ancestorLocators.length - 1];
|
|
694
754
|
|
|
695
755
|
for (const locator of nonUnique) {
|
|
696
756
|
const selector = locator.css ?? locator.selector;
|
|
@@ -699,6 +759,27 @@ class LocatorGenerator {
|
|
|
699
759
|
console.warn(`No elements found for locator: ${selector}`);
|
|
700
760
|
continue;
|
|
701
761
|
}
|
|
762
|
+
if (!uniqueAncestor) {
|
|
763
|
+
const elements = this.getMatchingElements(selector, options);
|
|
764
|
+
if (elements.length === 1 && elements[0] === element) {
|
|
765
|
+
result.push({
|
|
766
|
+
css: selector,
|
|
767
|
+
score: locator.score,
|
|
768
|
+
priority: 1,
|
|
769
|
+
});
|
|
770
|
+
} else {
|
|
771
|
+
const index = elements.indexOf(element);
|
|
772
|
+
if (index !== -1) {
|
|
773
|
+
result.push({
|
|
774
|
+
css: selector,
|
|
775
|
+
index,
|
|
776
|
+
score: locator.score + 200,
|
|
777
|
+
priority: 2,
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
continue;
|
|
782
|
+
}
|
|
702
783
|
|
|
703
784
|
for (const unique_locator of uniqueAncestor.locators.unique) {
|
|
704
785
|
const fullSelector = `${unique_locator.css} >> ${selector}`;
|
|
@@ -737,9 +818,32 @@ class LocatorGenerator {
|
|
|
737
818
|
return [];
|
|
738
819
|
}
|
|
739
820
|
}
|
|
821
|
+
isElementVisible(element) {
|
|
822
|
+
if (!(element instanceof Element)) return false;
|
|
823
|
+
const style = window.getComputedStyle(element);
|
|
824
|
+
if (style.display === "none" || style.visibility === "hidden" || style.opacity === "0") return false;
|
|
825
|
+
const rect = element.getBoundingClientRect();
|
|
826
|
+
if (rect.width === 0 || rect.height === 0) return false;
|
|
827
|
+
return true;
|
|
828
|
+
}
|
|
740
829
|
getElementLocators(element, options = {}) {
|
|
830
|
+
const isVisible = this.isElementVisible(element);
|
|
831
|
+
if (isVisible === false) {
|
|
832
|
+
console.warn("Element is not visible: ", element);
|
|
833
|
+
options.visible = isVisible;
|
|
834
|
+
}
|
|
741
835
|
try {
|
|
742
|
-
const {
|
|
836
|
+
const {
|
|
837
|
+
excludeText = false,
|
|
838
|
+
strategies = {
|
|
839
|
+
[this.locatorStrategies.custom]: true,
|
|
840
|
+
[this.locatorStrategies.context]: true,
|
|
841
|
+
[this.locatorStrategies.text]: true,
|
|
842
|
+
[this.locatorStrategies.text_with_index]: true,
|
|
843
|
+
[this.locatorStrategies.digitIgnore]: true,
|
|
844
|
+
[this.locatorStrategies.no_text]: true,
|
|
845
|
+
},
|
|
846
|
+
} = options;
|
|
743
847
|
|
|
744
848
|
const allStrategyLocators = {
|
|
745
849
|
[this.locatorStrategies.custom]: [],
|
|
@@ -749,7 +853,12 @@ class LocatorGenerator {
|
|
|
749
853
|
[this.locatorStrategies.digitIgnore]: [],
|
|
750
854
|
[this.locatorStrategies.no_text]: [],
|
|
751
855
|
};
|
|
752
|
-
if (
|
|
856
|
+
if (
|
|
857
|
+
strategies[this.locatorStrategies.custom] &&
|
|
858
|
+
this.options?.customAttributes &&
|
|
859
|
+
Array.isArray(this.options.customAttributes) &&
|
|
860
|
+
this.options.customAttributes.length > 0
|
|
861
|
+
) {
|
|
753
862
|
console.groupCollapsed("Generating Custom locators for element:", element);
|
|
754
863
|
const customLocators = this.getUniqueLocators(element, this.getCustomLocators.bind(this), options);
|
|
755
864
|
if (customLocators.length > 0) {
|
|
@@ -758,43 +867,53 @@ class LocatorGenerator {
|
|
|
758
867
|
}
|
|
759
868
|
console.groupEnd();
|
|
760
869
|
if (!excludeText) {
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
console.groupEnd();
|
|
764
|
-
if (basicLocators.length > 0) {
|
|
765
|
-
allStrategyLocators[this.locatorStrategies.text] = basicLocators;
|
|
766
|
-
}
|
|
870
|
+
if (strategies[this.locatorStrategies.text]) {
|
|
871
|
+
console.groupCollapsed("Generating Text locators for element:", element);
|
|
767
872
|
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
873
|
+
const basicLocators = this.getUniqueLocators(element, this.getTextLocators.bind(this), options);
|
|
874
|
+
console.groupEnd();
|
|
875
|
+
if (basicLocators.length > 0) {
|
|
876
|
+
allStrategyLocators[this.locatorStrategies.text] = basicLocators;
|
|
877
|
+
}
|
|
878
|
+
if (strategies[this.locatorStrategies.text_with_index]) {
|
|
879
|
+
const textWithIndexLocators = this.getTextwithIndexLocators(basicLocators);
|
|
880
|
+
if (textWithIndexLocators.length > 0) {
|
|
881
|
+
allStrategyLocators[this.locatorStrategies.text_with_index] = textWithIndexLocators;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
if (strategies[this.locatorStrategies.digitIgnore]) {
|
|
885
|
+
const digitIgnoreLocators = this.getDigitIgnoreLocators(element, basicLocators);
|
|
886
|
+
if (digitIgnoreLocators.length > 0) {
|
|
887
|
+
allStrategyLocators[this.locatorStrategies.digitIgnore] = digitIgnoreLocators;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
if (strategies[this.locatorStrategies.context]) {
|
|
891
|
+
const contextLocators = this.getContextLocators(element, basicLocators);
|
|
892
|
+
if (contextLocators.length > 0) {
|
|
893
|
+
allStrategyLocators[this.locatorStrategies.context] = contextLocators;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
779
896
|
}
|
|
780
897
|
}
|
|
781
|
-
|
|
782
|
-
|
|
898
|
+
if (strategies[this.locatorStrategies.no_text]) {
|
|
899
|
+
console.groupCollapsed("Generating No Text locators for element:", element);
|
|
900
|
+
const noTextLocators = this.getUniqueLocators(element, this.getNoTextLocators.bind(this), options);
|
|
783
901
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
902
|
+
if (noTextLocators.length > 0) {
|
|
903
|
+
allStrategyLocators[this.locatorStrategies.no_text] = noTextLocators;
|
|
904
|
+
} else {
|
|
905
|
+
const _locators = [];
|
|
906
|
+
_locators.push({
|
|
907
|
+
css: this.generateUniqueCSSSelector(element, options),
|
|
908
|
+
score: 500,
|
|
909
|
+
priority: 3,
|
|
910
|
+
});
|
|
911
|
+
if (_locators.length > 0) {
|
|
912
|
+
allStrategyLocators[this.locatorStrategies.no_text] = _locators;
|
|
913
|
+
}
|
|
795
914
|
}
|
|
915
|
+
console.groupEnd();
|
|
796
916
|
}
|
|
797
|
-
console.groupEnd();
|
|
798
917
|
|
|
799
918
|
let bestStrategy = this.getBestStrategy(allStrategyLocators);
|
|
800
919
|
if (!bestStrategy) {
|