@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 attrs2 = {};
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
- allAttributes: attrs2,
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];
@@ -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.1236-dev",
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.741-dev",
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",