@dev-blinq/cucumber_client 1.0.1236-dev → 1.0.1238-dev
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.
|
@@ -919,6 +919,63 @@ class BVTRecorder {
|
|
|
919
919
|
}
|
|
920
920
|
this.contextElement = null;
|
|
921
921
|
}
|
|
922
|
+
getElementProperties(element) {
|
|
923
|
+
if (!element || !(element instanceof HTMLElement)) {
|
|
924
|
+
throw new Error("Please provide a valid HTML element");
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
const result = {
|
|
928
|
+
properties: {},
|
|
929
|
+
attributes: {},
|
|
930
|
+
dataset: {},
|
|
931
|
+
};
|
|
932
|
+
|
|
933
|
+
const unsortedProperties = {};
|
|
934
|
+
const unsortedAttributes = {};
|
|
935
|
+
const unsortedDataset = {};
|
|
936
|
+
|
|
937
|
+
// Get enumerable properties
|
|
938
|
+
for (const prop in element) {
|
|
939
|
+
try {
|
|
940
|
+
const value = element[prop];
|
|
941
|
+
if (
|
|
942
|
+
typeof value !== "function" &&
|
|
943
|
+
typeof value !== "object" &&
|
|
944
|
+
value !== null &&
|
|
945
|
+
value !== undefined &&
|
|
946
|
+
!prop.includes("_")
|
|
947
|
+
) {
|
|
948
|
+
unsortedProperties[prop] = value;
|
|
949
|
+
}
|
|
950
|
+
} catch (error) {
|
|
951
|
+
unsortedProperties[prop] = "[Error accessing property]";
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
// Get all attributes
|
|
956
|
+
if (element.attributes) {
|
|
957
|
+
for (const attr of element.attributes) {
|
|
958
|
+
unsortedAttributes[attr.name] = attr.value;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
// Get dataset properties (data-* attributes)
|
|
963
|
+
if (element.dataset) {
|
|
964
|
+
for (const [key, value] of Object.entries(element.dataset)) {
|
|
965
|
+
unsortedDataset[key] = value;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
// Sort each object by key
|
|
970
|
+
const sortByKey = (obj) => Object.fromEntries(Object.entries(obj).sort(([a], [b]) => a.localeCompare(b)));
|
|
971
|
+
|
|
972
|
+
result.properties = sortByKey(unsortedProperties);
|
|
973
|
+
result.attributes = sortByKey(unsortedAttributes);
|
|
974
|
+
result.dataset = sortByKey(unsortedDataset);
|
|
975
|
+
|
|
976
|
+
return result;
|
|
977
|
+
}
|
|
978
|
+
|
|
922
979
|
getElementDetails(el, type) {
|
|
923
980
|
if (lastInputId !== el.dataset.inputId || type !== "input") {
|
|
924
981
|
el.dataset.inputId = getNextInputId();
|
|
@@ -933,11 +990,7 @@ class BVTRecorder {
|
|
|
933
990
|
}
|
|
934
991
|
const role = window.getAriaRole(el);
|
|
935
992
|
const label = window.getElementAccessibleName(el, false) || window.getElementAccessibleName(el, true) || role || "";
|
|
936
|
-
const
|
|
937
|
-
for (var att, i = 0, atts = el.attributes, n = atts.length; i < n; i++) {
|
|
938
|
-
const att = atts[i];
|
|
939
|
-
attrs2[att.nodeName] = att.nodeValue;
|
|
940
|
-
}
|
|
993
|
+
const result = this.getElementProperties(el);
|
|
941
994
|
return {
|
|
942
995
|
role,
|
|
943
996
|
label,
|
|
@@ -961,7 +1014,9 @@ class BVTRecorder {
|
|
|
961
1014
|
checked: el.checked,
|
|
962
1015
|
innerText: el.innerText,
|
|
963
1016
|
},
|
|
964
|
-
|
|
1017
|
+
attributes: result.attributes,
|
|
1018
|
+
properties: result.properties,
|
|
1019
|
+
dataset: result.dataset,
|
|
965
1020
|
};
|
|
966
1021
|
}
|
|
967
1022
|
handleEvent(e) {
|
|
@@ -47,6 +47,7 @@ const _isCodeGenerationStep = (step) => {
|
|
|
47
47
|
step.type === Types.SELECT ||
|
|
48
48
|
step.type === Types.HOVER ||
|
|
49
49
|
step.type === Types.EXTRACT_ATTRIBUTE ||
|
|
50
|
+
step.type === Types.EXTRACT_PROPERTY ||
|
|
50
51
|
step.type === Types.SET_DATE_TIME ||
|
|
51
52
|
step.type === Types.CHECK ||
|
|
52
53
|
step.type === Types.PRESS ||
|
|
@@ -55,6 +56,7 @@ const _isCodeGenerationStep = (step) => {
|
|
|
55
56
|
step.type === "context_click" ||
|
|
56
57
|
step.type === "parameterized_click" ||
|
|
57
58
|
step.type === Types.VERIFY_ATTRIBUTE ||
|
|
59
|
+
step.type === Types.VERIFY_PROPERTY ||
|
|
58
60
|
step.type === Types.SET_INPUT_FILES ||
|
|
59
61
|
step.type === Types.VERIFY_PAGE_SNAPSHOT
|
|
60
62
|
) {
|
|
@@ -164,6 +166,7 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
164
166
|
let variable = null;
|
|
165
167
|
let format = null;
|
|
166
168
|
let options = null;
|
|
169
|
+
let property = null;
|
|
167
170
|
switch (step.type) {
|
|
168
171
|
case Types.SET_INPUT:
|
|
169
172
|
line = `await context.web.setInputValue(elements["${elementIdentifier}"], `;
|
|
@@ -293,6 +296,30 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
293
296
|
codeLines.push(line);
|
|
294
297
|
break;
|
|
295
298
|
}
|
|
299
|
+
case Types.EXTRACT_PROPERTY: {
|
|
300
|
+
property = escapeNonPrintables(step.parameters[0]);
|
|
301
|
+
variable = escapeNonPrintables(step.parameters[1]);
|
|
302
|
+
input = `"${variable}"`;
|
|
303
|
+
if (step.dataSource === "userData" || step.dataSource === "parameters") {
|
|
304
|
+
input = "_" + step.dataKey;
|
|
305
|
+
}
|
|
306
|
+
let options = "null";
|
|
307
|
+
if (step.regex !== "") {
|
|
308
|
+
options = `{regex: ${JSON.stringify(step.regex)},trimSpaces: ${step.trimSpaces}}`;
|
|
309
|
+
} else if (step.trimSpaces) {
|
|
310
|
+
options = `{trimSpaces: ${step.trimSpaces}}`;
|
|
311
|
+
} else {
|
|
312
|
+
options = "null";
|
|
313
|
+
}
|
|
314
|
+
line = `await context.web.extractProperty(elements["${elementIdentifier}"], "${property}", ${input}, _params,${options}, this);`;
|
|
315
|
+
|
|
316
|
+
if (element_name) {
|
|
317
|
+
comment = `// Extract property ${property} from ${element_name} to ${variable}`;
|
|
318
|
+
codeLines.push(escapeNonPrintables(comment));
|
|
319
|
+
}
|
|
320
|
+
codeLines.push(line);
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
296
323
|
case Types.VERIFY_PAGE_SNAPSHOT:
|
|
297
324
|
comment = step.nestFrmLoc
|
|
298
325
|
? `// Verify page snapshot ${step.parameters[0]} in the frame ${step.selectors.iframe_src}`
|
|
@@ -548,6 +575,16 @@ const _generateCodeFromCommand = (step, elements, userData) => {
|
|
|
548
575
|
codeLines.push(line);
|
|
549
576
|
break;
|
|
550
577
|
}
|
|
578
|
+
case Types.VERIFY_PROPERTY: {
|
|
579
|
+
line = `await context.web.verifyProperty(elements["${elementIdentifier}"], `;
|
|
580
|
+
input = `"${escapeNonPrintables(step.parameters[1].replaceAll('"', '\\"'))}"`;
|
|
581
|
+
if (step.dataSource === "userData" || step.dataSource === "parameters") {
|
|
582
|
+
input = "_" + step.dataKey;
|
|
583
|
+
}
|
|
584
|
+
line += `"${step.parameters[0]}", ${input}, _params, null, this);`;
|
|
585
|
+
codeLines.push(line);
|
|
586
|
+
break;
|
|
587
|
+
}
|
|
551
588
|
case Types.SET_INPUT_FILES: {
|
|
552
589
|
line = `await context.web.setInputFiles(elements["${elementIdentifier}"], `;
|
|
553
590
|
let files = step.parameters[0];
|
package/bin/client/recording.js
CHANGED
|
@@ -30,6 +30,7 @@ const Types = {
|
|
|
30
30
|
SET_COMBO: "set_combo",
|
|
31
31
|
HOVER: "hover_element",
|
|
32
32
|
EXTRACT_ATTRIBUTE: "extract_attribute",
|
|
33
|
+
EXTRACT_PROPERTY: "extract_property",
|
|
33
34
|
CLOSE_PAGE: "close_page",
|
|
34
35
|
SET_DATE_TIME: "set_date_time",
|
|
35
36
|
SET_VIEWPORT: "set_viewport",
|
|
@@ -41,6 +42,7 @@ const Types = {
|
|
|
41
42
|
SET_INPUT: "set_input",
|
|
42
43
|
WAIT_FOR_USER_INPUT: "wait_for_user_input",
|
|
43
44
|
VERIFY_ATTRIBUTE: "verify_element_attribute",
|
|
45
|
+
VERIFY_PROPERTY: "verify_element_property",
|
|
44
46
|
FILL_UNKNOWN: "fill_unknown",
|
|
45
47
|
VERIFY_TEXT_RELATED_TO_TEXT: "verify_text_in_relation",
|
|
46
48
|
VERIFY_FILE_EXISTS: "verify_file_exists",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dev-blinq/cucumber_client",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1238-dev",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "bin/index.js",
|
|
6
6
|
"types": "bin/index.d.ts",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@cucumber/tag-expressions": "^6.1.1",
|
|
29
29
|
"@dev-blinq/cucumber-js": "1.0.173-dev",
|
|
30
30
|
"@faker-js/faker": "^8.1.0",
|
|
31
|
-
"automation_model": "1.0.
|
|
31
|
+
"automation_model": "1.0.742-dev",
|
|
32
32
|
"axios": "^1.7.4",
|
|
33
33
|
"chokidar": "^3.6.0",
|
|
34
34
|
"create-require": "^1.1.1",
|