ff-automationv2 2.2.29 → 2.2.30

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.
Files changed (113) hide show
  1. package/dist/ai/llmcalls/llmAction.js +49 -13
  2. package/dist/ai/llmcalls/parseLlmOputput.js +5 -5
  3. package/dist/ai/llmprompts/promptRegistry.js +4 -0
  4. package/dist/ai/llmprompts/systemPrompts/actionExtractorPrompt.js +39 -11
  5. package/dist/ai/llmprompts/systemPrompts/fireflinkElementIndexExtactors.js +6 -6
  6. package/dist/ai/llmprompts/systemPrompts/fireflinkElementIndexExtractor_Mob.js +32 -0
  7. package/dist/ai/llmprompts/systemPrompts/mobileKeywordExtractor.js +17 -8
  8. package/dist/ai/llmprompts/systemPrompts/otpExtractorPrompt.d.ts +1 -0
  9. package/dist/ai/llmprompts/systemPrompts/otpExtractorPrompt.js +22 -0
  10. package/dist/ai/llmprompts/systemPrompts/verifyActionExtractorPrompt.js +3 -1
  11. package/dist/ai/llmprompts/systemPrompts/visionPrompt.js +14 -6
  12. package/dist/ai/llmprompts/systemPrompts/visionPromptMobile.js +3 -0
  13. package/dist/ai/llmprompts/userPrompts/userPrompt.js +1 -0
  14. package/dist/automation/actions/executor.d.ts +4 -0
  15. package/dist/automation/actions/executor.js +20 -0
  16. package/dist/automation/actions/interaction/clear/clear.js +1 -1
  17. package/dist/automation/actions/interaction/clear/clearAndEnter.js +1 -1
  18. package/dist/automation/actions/interaction/click/click.js +10 -3
  19. package/dist/automation/actions/interaction/click/clickNtimes.js +1 -1
  20. package/dist/automation/actions/interaction/click/doubleClick.js +1 -1
  21. package/dist/automation/actions/interaction/click/rightClick.js +1 -1
  22. package/dist/automation/actions/interaction/elementlessActions/getOtp.d.ts +2 -0
  23. package/dist/automation/actions/interaction/elementlessActions/getOtp.js +101 -0
  24. package/dist/automation/actions/interaction/enterActions/enterInput.js +11 -6
  25. package/dist/automation/actions/interaction/enterActions/enterInputAndPress.js +2 -2
  26. package/dist/automation/actions/interaction/enterActions/enterusingJs.js +2 -2
  27. package/dist/automation/actions/interaction/enterActions/waitAndEnter.js +1 -1
  28. package/dist/automation/actions/interaction/upload/uploadfile.js +1 -1
  29. package/dist/automation/actions/interaction/verify/VerifyNavigateURL.js +38 -11
  30. package/dist/automation/actions/interface/FireFlinkResponseSchema.d.ts +12 -0
  31. package/dist/automation/actions/interface/FireFlinkResponseSchema.js +19 -3
  32. package/dist/automation/actions/interface/getOtpInterface.d.ts +15 -0
  33. package/dist/automation/actions/interface/getOtpInterface.js +2 -0
  34. package/dist/automation/browserSession/initiateBrowserSession.d.ts +1 -1
  35. package/dist/automation/browserSession/initiateBrowserSession.js +15 -7
  36. package/dist/automation/driverState.d.ts +2 -0
  37. package/dist/automation/driverState.js +4 -0
  38. package/dist/automation/mobileSession/initiateMobileSession.d.ts +4 -5
  39. package/dist/automation/mobileSession/initiateMobileSession.js +83 -19
  40. package/dist/core/constants/allAction.js +5 -1
  41. package/dist/core/constants/supportedActions.js +5 -2
  42. package/dist/core/interfaces/actionInterface.d.ts +4 -0
  43. package/dist/core/interfaces/browserConfigurationInterface.d.ts +0 -4
  44. package/dist/core/interfaces/browserConfigurationInterface.js +0 -1
  45. package/dist/core/interfaces/executionDetails.d.ts +6 -3
  46. package/dist/core/interfaces/fireflinkScriptPayloadInterface.d.ts +22 -16
  47. package/dist/core/interfaces/llmResponseInterface.d.ts +1 -0
  48. package/dist/core/interfaces/promptInterface.d.ts +1 -0
  49. package/dist/core/main/SessionManager.d.ts +9 -0
  50. package/dist/core/main/SessionManager.js +23 -0
  51. package/dist/core/main/actionHandlerFactory.js +261 -64
  52. package/dist/core/main/executionContext.d.ts +7 -1
  53. package/dist/core/main/executionContext.js +93 -3
  54. package/dist/core/main/runAutomationScript.d.ts +1 -0
  55. package/dist/core/main/runAutomationScript.js +912 -304
  56. package/dist/core/main/stepProcessor.js +7 -2
  57. package/dist/core/types/browserType.d.ts +3 -3
  58. package/dist/core/types/browserType.js +2 -2
  59. package/dist/core/types/messageType.d.ts +13 -0
  60. package/dist/core/types/messageType.js +15 -0
  61. package/dist/core/types/promptType.d.ts +2 -1
  62. package/dist/core/types/promptType.js +1 -0
  63. package/dist/domAnalysis/searchBest.js +15 -16
  64. package/dist/domAnalysis/simplifyAndFlatten.js +6 -4
  65. package/dist/fireflinkData/fireflinkLocators/getListOfLocators.d.ts +3 -0
  66. package/dist/fireflinkData/fireflinkLocators/getListOfLocators.js +23 -15
  67. package/dist/fireflinkData/fireflinkLocators/parser/getElementsFromHTML.d.ts +3 -3
  68. package/dist/fireflinkData/fireflinkLocators/parser/getElementsFromHTML.js +134 -118
  69. package/dist/fireflinkData/fireflinkLocators/types/locator.d.ts +11 -1
  70. package/dist/fireflinkData/fireflinkLocators/utils/androidSelector.d.ts +1 -1
  71. package/dist/fireflinkData/fireflinkLocators/utils/androidSelector.js +35 -9
  72. package/dist/fireflinkData/fireflinkLocators/utils/cssSelector.d.ts +10 -10
  73. package/dist/fireflinkData/fireflinkLocators/utils/cssSelector.js +56 -59
  74. package/dist/fireflinkData/fireflinkLocators/utils/iosSelector.d.ts +1 -1
  75. package/dist/fireflinkData/fireflinkLocators/utils/iosSelector.js +53 -29
  76. package/dist/fireflinkData/fireflinkLocators/utils/referenceXpath.d.ts +8 -8
  77. package/dist/fireflinkData/fireflinkLocators/utils/referenceXpath.js +113 -190
  78. package/dist/fireflinkData/fireflinkLocators/utils/xpath.d.ts +17 -26
  79. package/dist/fireflinkData/fireflinkLocators/utils/xpath.js +314 -786
  80. package/dist/fireflinkData/fireflinkLocators/utils/xpathHelpers.d.ts +68 -70
  81. package/dist/fireflinkData/fireflinkLocators/utils/xpathHelpers.js +498 -517
  82. package/dist/fireflinkData/fireflinkScript/appendScriptData.d.ts +1 -1
  83. package/dist/fireflinkData/fireflinkScript/appendScriptData.js +5 -8
  84. package/dist/fireflinkData/fireflinkScript/scriptGenrationData.d.ts +2 -2
  85. package/dist/fireflinkData/fireflinkScript/scriptGenrationData.js +17 -27
  86. package/dist/llmConfig/llmConfiguration.js +13 -6
  87. package/dist/service/api/fireflinkApi.service.d.ts +1 -1
  88. package/dist/service/api/fireflinkApi.service.js +1 -2
  89. package/dist/service/fireflink.service.d.ts +3 -3
  90. package/dist/service/fireflink.service.js +23 -21
  91. package/dist/service/kafka/fireflinkKafka.service.d.ts +1 -2
  92. package/dist/service/kafka/fireflinkKafka.service.js +6 -4
  93. package/dist/tests/test12.d.ts +0 -1
  94. package/dist/tests/test12.js +65 -78
  95. package/dist/tests/testkaf.d.ts +0 -1
  96. package/dist/tests/testkaf.js +51 -55
  97. package/dist/utils/InstancesDetails/getInstancesInfo.js +1 -1
  98. package/dist/utils/browserCap/capability.d.ts +5 -1
  99. package/dist/utils/browserCap/capability.js +91 -15
  100. package/dist/utils/helpers/domSanitizer.d.ts +1 -0
  101. package/dist/utils/helpers/domSanitizer.js +9 -0
  102. package/dist/utils/helpers/enterActionHelper.js +23 -4
  103. package/dist/utils/helpers/xpathcreation.js +2 -2
  104. package/dist/utils/javascript/jsFindElement.d.ts +1 -1
  105. package/dist/utils/javascript/jsFindElement.js +2 -2
  106. package/dist/utils/newTab/newTabTracker.js +18 -6
  107. package/dist/utils/workers/LocatorWorkerInterface.d.ts +22 -0
  108. package/dist/utils/workers/LocatorWorkerInterface.js +2 -0
  109. package/dist/utils/workers/LocatorWorkerPool.d.ts +13 -0
  110. package/dist/utils/workers/LocatorWorkerPool.js +89 -0
  111. package/dist/utils/workers/locatorWorker.d.ts +1 -0
  112. package/dist/utils/workers/locatorWorker.js +44 -0
  113. package/package.json +3 -1
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.xpathUtils = exports.getPlatformFallbackXpath = exports.findMatchingParenthesis = exports.normalizeXPath = exports.getReferenceElementsXpath = exports.replaceActualAttributes = exports.getXpathString = exports.getTextXpathFunction = exports.getUniqueNodeAnchorXpaths = exports.getAxisNodeTest = exports.isExactUniqueXpath = exports.getFirstMatchedNode = exports.getTagOnlyXPath = exports.getOrAttributesXPath = exports.getContainsPropertyXPath = exports.getStartsWithPropertyXPath = exports.getNormalizedPropertyXPath = exports.getFilteredTextXPath = exports.intermediateXpathStep = exports.getAttributeCombinationXpath = exports.getCombinationXpath = exports.getRelativeXPath = exports.getAbsoluteXPath = exports.getPropertyXPath = exports.replaceTempAttributes = exports.isSvg = exports.getRelationship = exports.checkBlockedAttributes = exports.createShadowEvaluationContext = exports.getShadowRoot = exports.replaceWhiteSpaces = exports.findXpathWithIndex = exports.removeParenthesis = exports.escapeCharacters = exports.getCountOfXPath = exports.getFilteredText = exports.getTextContent = exports.buildPattern = exports.isNumberExist = exports.sanitizeAttributeValue = exports.modifiedElementAttributes = exports.evaluateXPathOnce = exports.clearXPathEvalCache = exports.timeLog = exports.cspEnabled = exports.reWhiteSpace = void 0;
4
- exports.evaluateXPath = evaluateXPath;
3
+ exports.xpathUtils = exports.findMatchingParenthesis = exports.normalizeXPath = exports.getReferenceElementsXpath = exports.replaceAiActualAttributes = exports.getAiXpathString = exports.getAiTextXpathFunction = exports.getAiUniqueNodeAnchorXpaths = exports.getAiAxisNodeTest = exports.isAiExactUniqueXpath = exports.getAiFirstMatchedNode = exports.getAiTagOnlyXPath = exports.getOrAttributesAiXPath = exports.getAiContainsPropertyXPath = exports.getAiStartsWithPropertyXPath = exports.getAiNormalizedPropertyXPath = exports.getAiFilteredTextXPath = exports.intermediateAiXpathStep = exports.getAiAttributeCombinationXpath = exports.getAiCombinationXpath = exports.getAIRelativeXPath = exports.getAiAbsoluteXPath = exports.getAiPropertyXPath = exports.replaceAiTempAttributes = exports.isAiSvg = exports.getAiRelationship = exports.checkAiBlockedAttributes = exports.createAIShadowEvaluationContext = exports.getAiShadowRoot = exports.aiReplaceWhiteSpaces = exports.findAiXpathWithIndex = exports.removeAiParenthesis = exports.escapeAiCharacters = exports.getAiCountOfXPath = exports.getAiFilteredText = exports.getAiTextContent = exports.buildAiPattern = exports.isAiNumberExist = exports.sanitizeAiAttributeValue = exports.modifiedElementAttributes = exports.evaluateAIXPathOnce = exports.clearAiXPathEvalCache = exports.timeLog = exports.cspEnabled = exports.reWhiteSpace = void 0;
4
+ exports.evaluateAiXPath = evaluateAiXPath;
5
5
  exports.escapeAttrValue = escapeAttrValue;
6
- exports.isUniqueInDOM = isUniqueInDOM;
6
+ exports.isAiUniqueInDOM = isAiUniqueInDOM;
7
7
  const logData_1 = require("../../../utils/logger/logData");
8
8
  exports.reWhiteSpace = /^[\S]+( [\S]+)*$/i;
9
9
  exports.cspEnabled = false;
@@ -15,45 +15,57 @@ const timeLog = (label, start) => {
15
15
  exports.timeLog = timeLog;
16
16
  // cache per context node → avoids cross-context pollution
17
17
  let xpathEvalCache = new WeakMap();
18
- const getXPathContext = (docmt) => {
18
+ const XPathResultConst = {
19
+ ANY_TYPE: 0,
20
+ NUMBER_TYPE: 1,
21
+ STRING_TYPE: 2,
22
+ BOOLEAN_TYPE: 3,
23
+ UNORDERED_NODE_ITERATOR_TYPE: 4,
24
+ ORDERED_NODE_ITERATOR_TYPE: 5,
25
+ UNORDERED_NODE_SNAPSHOT_TYPE: 6,
26
+ ORDERED_NODE_SNAPSHOT_TYPE: 7,
27
+ ANY_UNORDERED_NODE_TYPE: 8,
28
+ FIRST_ORDERED_NODE_TYPE: 9
29
+ };
30
+ const getAiXPathContext = (docmt) => {
19
31
  const owner = docmt.nodeType === 9
20
32
  ? docmt
21
- : docmt.ownerDocument || document;
33
+ : docmt.ownerDocument;
22
34
  // valid XPath context nodes: Element(1), Document(9), DocumentFragment/ShadowRoot(11)
23
35
  const contextNode = docmt.nodeType === 1 || docmt.nodeType === 9 || docmt.nodeType === 11
24
36
  ? docmt
25
37
  : owner;
26
38
  return contextNode;
27
39
  };
28
- const getMutationCacheContexts = (node) => {
40
+ const getAiMutationCacheContexts = (node) => {
29
41
  const contexts = [];
30
- const addContext = (candidate) => {
42
+ const addAiContext = (candidate) => {
31
43
  if (!candidate || contexts.includes(candidate))
32
44
  return;
33
45
  contexts.push(candidate);
34
46
  };
35
- addContext(node);
47
+ addAiContext(node);
36
48
  const rootNode = node.getRootNode?.();
37
- if (rootNode instanceof Document || rootNode instanceof ShadowRoot) {
38
- addContext(rootNode);
49
+ if (rootNode && (rootNode.nodeType === 9 || rootNode.nodeType === 11)) {
50
+ addAiContext(rootNode);
39
51
  }
40
52
  const ownerDocument = node.nodeType === 9
41
53
  ? node
42
54
  : node.ownerDocument;
43
- addContext(ownerDocument);
55
+ addAiContext(ownerDocument);
44
56
  return contexts;
45
57
  };
46
- const clearXPathEvalCache = (node) => {
58
+ const clearAiXPathEvalCache = (node) => {
47
59
  if (!node) {
48
60
  xpathEvalCache = new WeakMap();
49
61
  return;
50
62
  }
51
- getMutationCacheContexts(node).forEach((contextNode) => {
63
+ getAiMutationCacheContexts(node).forEach((contextNode) => {
52
64
  xpathEvalCache.delete(contextNode);
53
65
  });
54
66
  };
55
- exports.clearXPathEvalCache = clearXPathEvalCache;
56
- function svgXPathFallback(xpath, root) {
67
+ exports.clearAiXPathEvalCache = clearAiXPathEvalCache;
68
+ function svgAiXPathFallback(xpath, root) {
57
69
  const tag = xpath.match(/local-name\(\)\s*=\s*['"]([^'"]+)['"]/)?.[1];
58
70
  if (!tag)
59
71
  return [];
@@ -78,26 +90,24 @@ function svgXPathFallback(xpath, root) {
78
90
  }
79
91
  return elements;
80
92
  }
81
- function evaluateXPath(xpath, contextNode, mode = "iterator") {
93
+ function evaluateAiXPath(xpath, contextNode, mode = "iterator") {
82
94
  const owner = contextNode.nodeType === 9
83
95
  ? contextNode
84
96
  : contextNode.ownerDocument;
85
97
  try {
86
- switch (mode) {
87
- case "first":
88
- return owner.evaluate(xpath, contextNode, null, owner.defaultView.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
89
- case "snapshot":
90
- return owner.evaluate(xpath, contextNode, null, owner.defaultView.XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
91
- default:
92
- return owner.evaluate(xpath, contextNode, null, owner.defaultView.XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
93
- }
98
+ const resultType = mode === "first"
99
+ ? (owner.defaultView?.XPathResult?.FIRST_ORDERED_NODE_TYPE ?? XPathResultConst.FIRST_ORDERED_NODE_TYPE)
100
+ : mode === "snapshot"
101
+ ? (owner.defaultView?.XPathResult?.ORDERED_NODE_SNAPSHOT_TYPE ?? XPathResultConst.ORDERED_NODE_SNAPSHOT_TYPE)
102
+ : (owner.defaultView?.XPathResult?.ORDERED_NODE_ITERATOR_TYPE ?? XPathResultConst.ORDERED_NODE_ITERATOR_TYPE);
103
+ return owner.evaluate(xpath, contextNode, null, resultType, null);
94
104
  }
95
105
  catch (e) {
96
106
  logData_1.logger.error(` Error in evaluating xpath: ${e.message}`);
97
107
  const root = contextNode.nodeType === 9
98
108
  ? contextNode
99
109
  : contextNode.ownerDocument;
100
- const nodes = svgXPathFallback(xpath, root);
110
+ const nodes = svgAiXPathFallback(xpath, root);
101
111
  if (mode === "first") {
102
112
  return {
103
113
  singleNodeValue: nodes[0] ?? null
@@ -115,67 +125,93 @@ function evaluateXPath(xpath, contextNode, mode = "iterator") {
115
125
  };
116
126
  }
117
127
  }
118
- const evaluateXPathOnce = (xpath, docmt) => {
119
- const contextNode = getXPathContext(docmt);
120
- // get or create cache for this context node
121
- let nodeCache = xpathEvalCache.get(contextNode);
122
- if (!nodeCache) {
123
- nodeCache = new Map();
124
- xpathEvalCache.set(contextNode, nodeCache);
125
- }
126
- // cache hit
127
- const cached = nodeCache.get(xpath);
128
- if (cached)
129
- return cached;
130
- // evaluate once, stop after 2 nodes
131
- // const result = owner.evaluate(
132
- // xpath,
133
- // contextNode,
134
- // null,
135
- // owner.defaultView!.XPathResult.ORDERED_NODE_ITERATOR_TYPE,
136
- // null
137
- // );
138
- const result = evaluateXPath(xpath, contextNode);
139
- const first = result.iterateNext();
140
- const second = result.iterateNext();
141
- const evalResult = { first, second };
142
- nodeCache.set(xpath, evalResult);
143
- return evalResult;
128
+ const evaluateAIXPathOnce = (xpath, docmt) => {
129
+ try {
130
+ const contextNode = getAiXPathContext(docmt);
131
+ // get or create cache for this context node
132
+ let nodeCache = xpathEvalCache.get(contextNode);
133
+ if (!nodeCache) {
134
+ nodeCache = new Map();
135
+ xpathEvalCache.set(contextNode, nodeCache);
136
+ }
137
+ // cache hit
138
+ const cached = nodeCache.get(xpath);
139
+ if (cached)
140
+ return cached;
141
+ // evaluate once, stop after 2 nodes
142
+ // const result = owner.evaluate(
143
+ // xpath,
144
+ // contextNode,
145
+ // null,
146
+ // owner.defaultView!.XPathResult.ORDERED_NODE_ITERATOR_TYPE,
147
+ // null
148
+ // );
149
+ // const result = evaluateAiXPath(xpath, contextNode);
150
+ const owner = contextNode.nodeType === 9
151
+ ? contextNode
152
+ : contextNode.ownerDocument;
153
+ // const result = owner.evaluate(
154
+ // xpath,
155
+ // contextNode,
156
+ // null,
157
+ // owner.defaultView!.XPathResult.ORDERED_NODE_ITERATOR_TYPE,
158
+ // null
159
+ // );
160
+ let result;
161
+ try {
162
+ const iteratorType = owner.defaultView?.XPathResult?.ORDERED_NODE_ITERATOR_TYPE ??
163
+ XPathResultConst.ORDERED_NODE_ITERATOR_TYPE;
164
+ result = owner.evaluate(xpath, contextNode, null, iteratorType, null);
165
+ }
166
+ catch (err) {
167
+ logData_1.logger.error("evaluate exception", err);
168
+ return { first: null, second: null };
169
+ }
170
+ const first = result.iterateNext();
171
+ const second = result.iterateNext();
172
+ const evalResult = { first, second };
173
+ nodeCache.set(xpath, evalResult);
174
+ return evalResult;
175
+ }
176
+ catch (e) {
177
+ logData_1.logger.error(e);
178
+ return { first: null, second: null };
179
+ }
144
180
  };
145
- exports.evaluateXPathOnce = evaluateXPathOnce;
181
+ exports.evaluateAIXPathOnce = evaluateAIXPathOnce;
146
182
  const relativeXPathCache = new Map();
147
183
  exports.modifiedElementAttributes = [];
148
184
  const INTERNAL_CLASS_TOKENS = new Set([
149
185
  "marked-element-temp",
150
186
  "removePointers"
151
187
  ]);
152
- const normalizeClassTokens = (classValue) => (classValue || "")
188
+ const normalizeAiClassTokens = (classValue) => (classValue || "")
153
189
  .split(/\s+/)
154
190
  .map((token) => token.trim())
155
191
  .filter((token) => token && !INTERNAL_CLASS_TOKENS.has(token))
156
192
  .sort();
157
- const sanitizeAttributeValue = (attributeName, attributeValue) => {
193
+ const sanitizeAiAttributeValue = (attributeName, attributeValue) => {
158
194
  if (!attributeValue) {
159
195
  return "";
160
196
  }
161
197
  if (attributeName === "class" || attributeName === "className") {
162
- return normalizeClassTokens(attributeValue).join(" ");
198
+ return normalizeAiClassTokens(attributeValue).join(" ");
163
199
  }
164
200
  return attributeValue.replace("removePointers", "").trim();
165
201
  };
166
- exports.sanitizeAttributeValue = sanitizeAttributeValue;
167
- const isNumberExist = (str) => {
202
+ exports.sanitizeAiAttributeValue = sanitizeAiAttributeValue;
203
+ const isAiNumberExist = (str) => {
168
204
  const hasNumber = /\d/;
169
205
  return hasNumber.test(str);
170
206
  };
171
- exports.isNumberExist = isNumberExist;
172
- const buildPattern = (pattern, isSvg, tagName) => {
173
- return isSvg
207
+ exports.isAiNumberExist = isAiNumberExist;
208
+ const buildAiPattern = (pattern, isAiSvg, tagName) => {
209
+ return isAiSvg
174
210
  ? `//*[local-name()='${tagName}' and ${pattern}]`
175
211
  : `//${tagName}[${pattern}]`;
176
212
  };
177
- exports.buildPattern = buildPattern;
178
- const getTextContent = (targetElement) => {
213
+ exports.buildAiPattern = buildAiPattern;
214
+ const getAiTextContent = (targetElement) => {
179
215
  const textContent = targetElement?.textContent;
180
216
  if (exports.cspEnabled) {
181
217
  if (textContent) {
@@ -197,14 +233,14 @@ const getTextContent = (targetElement) => {
197
233
  }
198
234
  return "";
199
235
  };
200
- exports.getTextContent = getTextContent;
201
- const getFilteredText = (element) => {
236
+ exports.getAiTextContent = getAiTextContent;
237
+ const getAiFilteredText = (element) => {
202
238
  return element?.childNodes[0]?.nodeValue || "";
203
239
  };
204
- exports.getFilteredText = getFilteredText;
205
- const getCountOfXPath = (xpath, element, docmt, multiElementReferenceMode = false) => {
240
+ exports.getAiFilteredText = getAiFilteredText;
241
+ const getAiCountOfXPath = (xpath, element, docmt, multiElementReferenceMode = false) => {
206
242
  try {
207
- const { first, second } = (0, exports.evaluateXPathOnce)(xpath, docmt);
243
+ const { first, second } = (0, exports.evaluateAIXPathOnce)(xpath, docmt);
208
244
  if (!first)
209
245
  return 0;
210
246
  // exactly one match
@@ -227,7 +263,7 @@ const getCountOfXPath = (xpath, element, docmt, multiElementReferenceMode = fals
227
263
  // owner.defaultView!.XPathResult.ORDERED_NODE_ITERATOR_TYPE,
228
264
  // null
229
265
  // );
230
- const result = evaluateXPath(xpath, docmt);
266
+ const result = evaluateAiXPath(xpath, docmt);
231
267
  let node;
232
268
  while ((node = result.iterateNext())) {
233
269
  if (element.includes(node)) {
@@ -240,13 +276,12 @@ const getCountOfXPath = (xpath, element, docmt, multiElementReferenceMode = fals
240
276
  }
241
277
  return 2;
242
278
  }
243
- catch (error) {
244
- console.error(`Error evaluating XPath: ${xpath}`, error);
279
+ catch {
245
280
  return 0;
246
281
  }
247
282
  };
248
- exports.getCountOfXPath = getCountOfXPath;
249
- const escapeCharacters = (text) => {
283
+ exports.getAiCountOfXPath = getAiCountOfXPath;
284
+ const escapeAiCharacters = (text) => {
250
285
  if (text) {
251
286
  if (!(text.indexOf('"') === -1)) {
252
287
  return `'${text}'`;
@@ -257,8 +292,8 @@ const escapeCharacters = (text) => {
257
292
  }
258
293
  return `'${text}'`;
259
294
  };
260
- exports.escapeCharacters = escapeCharacters;
261
- const removeParenthesis = (xpath) => {
295
+ exports.escapeAiCharacters = escapeAiCharacters;
296
+ const removeAiParenthesis = (xpath) => {
262
297
  const charArr = xpath.split("");
263
298
  let count = charArr.length;
264
299
  const indexArray = [];
@@ -281,28 +316,28 @@ const removeParenthesis = (xpath) => {
281
316
  }
282
317
  return firstpart;
283
318
  };
284
- exports.removeParenthesis = removeParenthesis;
285
- const findXpathWithIndex = (val, node, docmt, count) => {
319
+ exports.removeAiParenthesis = removeAiParenthesis;
320
+ const findAiXpathWithIndex = (val, node, docmt, count) => {
286
321
  try {
287
322
  let index = 0;
288
323
  if (count) {
289
- if ((0, exports.getCountOfXPath)(`${val}[${count}]`, node, docmt) === 1) {
324
+ if ((0, exports.getAiCountOfXPath)(`${val}[${count}]`, node, docmt) === 1) {
290
325
  return `${val}[${count}]`;
291
326
  }
292
- if ((0, exports.getCountOfXPath)(`(${val})[${count}]`, node, docmt) === 1) {
327
+ if ((0, exports.getAiCountOfXPath)(`(${val})[${count}]`, node, docmt) === 1) {
293
328
  return `(${val})[${count}]`;
294
329
  }
295
330
  }
296
331
  // const nodes = owner.evaluate(val, docmt, null, owner.defaultView!.XPathResult.ANY_TYPE, null);
297
- const nodes = evaluateXPath(val, docmt);
332
+ const nodes = evaluateAiXPath(val, docmt);
298
333
  let nodex = null;
299
334
  while ((nodex = nodes.iterateNext())) {
300
335
  index++;
301
336
  if (nodex.isSameNode(node)) {
302
- if ((0, exports.getCountOfXPath)(`${val}[${index}]`, node, docmt) === 1) {
337
+ if ((0, exports.getAiCountOfXPath)(`${val}[${index}]`, node, docmt) === 1) {
303
338
  return `${val}[${index}]`;
304
339
  }
305
- if ((0, exports.getCountOfXPath)(`(${val})[${index}]`, node, docmt) === 1) {
340
+ if ((0, exports.getAiCountOfXPath)(`(${val})[${index}]`, node, docmt) === 1) {
306
341
  return `(${val})[${index}]`;
307
342
  }
308
343
  return;
@@ -313,13 +348,13 @@ const findXpathWithIndex = (val, node, docmt, count) => {
313
348
  logData_1.logger.error(error);
314
349
  }
315
350
  };
316
- exports.findXpathWithIndex = findXpathWithIndex;
317
- const deleteLineGap = (a) => {
351
+ exports.findAiXpathWithIndex = findAiXpathWithIndex;
352
+ const deleteAiLineGap = (a) => {
318
353
  a && (a = a.split("\n")[0].length > 0 ? a.split("\n")[0] : a.split("\n")[1]);
319
354
  return a;
320
355
  };
321
- const deleteGarbageFromInnerText = (a) => {
322
- a = deleteLineGap(a);
356
+ const deleteAiGarbageFromInnerText = (a) => {
357
+ a = deleteAiLineGap(a);
323
358
  a = a
324
359
  .split(/[^\p{ASCII}\u0080-\u00FF]/u)
325
360
  .reduce((b, c) => {
@@ -328,24 +363,24 @@ const deleteGarbageFromInnerText = (a) => {
328
363
  .trim();
329
364
  return (a.split("/")[0].trim());
330
365
  };
331
- const replaceWhiteSpaces = (str) => {
366
+ const aiReplaceWhiteSpaces = (str) => {
332
367
  if (str) {
333
368
  return str.replace(/\s\s+/g, " ").trim();
334
369
  }
335
370
  return str;
336
371
  };
337
- exports.replaceWhiteSpaces = replaceWhiteSpaces;
338
- const getShadowRoot = (el) => {
372
+ exports.aiReplaceWhiteSpaces = aiReplaceWhiteSpaces;
373
+ const getAiShadowRoot = (el) => {
339
374
  if (!el || !el?.getRootNode)
340
375
  return null;
341
376
  const root = el.getRootNode();
342
377
  return root && root?.host ? root : null;
343
378
  };
344
- exports.getShadowRoot = getShadowRoot;
345
- const isShadowRootNode = (node) => {
379
+ exports.getAiShadowRoot = getAiShadowRoot;
380
+ const isAiShadowRootNode = (node) => {
346
381
  return node?.nodeType === 11 && "host" in node;
347
382
  };
348
- const getElementPathFromRoot = (root, element) => {
383
+ const getAiElementPathFromRoot = (root, element) => {
349
384
  const path = [];
350
385
  let current = element;
351
386
  while (current && current.parentElement) {
@@ -359,7 +394,7 @@ const getElementPathFromRoot = (root, element) => {
359
394
  path.unshift(Array.from(root.children).indexOf(current));
360
395
  return path;
361
396
  };
362
- const getElementAtPath = (container, path) => {
397
+ const getAiElementAtPath = (container, path) => {
363
398
  let current = container;
364
399
  for (const index of path) {
365
400
  const next = current.children.item(index);
@@ -370,34 +405,34 @@ const getElementAtPath = (container, path) => {
370
405
  }
371
406
  return current;
372
407
  };
373
- const createShadowEvaluationContext = (root, element) => {
408
+ const createAIShadowEvaluationContext = (root, element) => {
374
409
  const tempDoc = root.ownerDocument.implementation.createHTMLDocument("shadow-xpath");
375
410
  const wrapper = tempDoc.createElement("div");
376
411
  wrapper.innerHTML = root.innerHTML;
377
412
  tempDoc.body.appendChild(wrapper);
378
- const cloneForElement = (candidate) => {
413
+ const cloneAiForElement = (candidate) => {
379
414
  if (!candidate ||
380
- !(candidate instanceof root.ownerDocument.defaultView.Element)) {
415
+ candidate.nodeType !== 1) {
381
416
  return null;
382
417
  }
383
- const path = getElementPathFromRoot(root, candidate);
384
- return path ? getElementAtPath(wrapper, path) : null;
418
+ const path = getAiElementPathFromRoot(root, candidate);
419
+ return path ? getAiElementAtPath(wrapper, path) : null;
385
420
  };
386
421
  const cloneElements = Array.isArray(element)
387
- ? element.map((candidate) => cloneForElement(candidate)).filter(Boolean)
422
+ ? element.map((candidate) => cloneAiForElement(candidate)).filter(Boolean)
388
423
  : [];
389
424
  const cloneElement = Array.isArray(element)
390
425
  ? null
391
- : cloneForElement(element ?? null);
426
+ : cloneAiForElement(element ?? null);
392
427
  return {
393
428
  contextNode: wrapper,
394
429
  cloneElement,
395
430
  cloneElements
396
431
  };
397
432
  };
398
- exports.createShadowEvaluationContext = createShadowEvaluationContext;
399
- const checkBlockedAttributes = (attribute, targetElement, isTarget) => {
400
- const sanitizedValue = (0, exports.sanitizeAttributeValue)(attribute.name, attribute.value);
433
+ exports.createAIShadowEvaluationContext = createAIShadowEvaluationContext;
434
+ const checkAiBlockedAttributes = (attribute, targetElement, isTarget) => {
435
+ const sanitizedValue = (0, exports.sanitizeAiAttributeValue)(attribute.name, attribute.value);
401
436
  if (!sanitizedValue || typeof attribute?.value === "boolean") {
402
437
  return false;
403
438
  }
@@ -435,13 +470,13 @@ const checkBlockedAttributes = (attribute, targetElement, isTarget) => {
435
470
  if (typeof attribute.value === "function") {
436
471
  return false;
437
472
  }
438
- if (isTarget && (0, exports.isNumberExist)(sanitizedValue)) {
473
+ if (isTarget && (0, exports.isAiNumberExist)(sanitizedValue)) {
439
474
  return false;
440
475
  }
441
476
  return true;
442
477
  };
443
- exports.checkBlockedAttributes = checkBlockedAttributes;
444
- const getRelationship = (a, b) => {
478
+ exports.checkAiBlockedAttributes = checkAiBlockedAttributes;
479
+ const getAiRelationship = (a, b) => {
445
480
  const pos = a.compareDocumentPosition(b);
446
481
  return pos === 2
447
482
  ? "preceding"
@@ -455,18 +490,23 @@ const getRelationship = (a, b) => {
455
490
  ? "self"
456
491
  : "";
457
492
  };
458
- exports.getRelationship = getRelationship;
459
- const isSvg = (element) => {
460
- return element instanceof element.ownerDocument.defaultView.SVGElement;
493
+ exports.getAiRelationship = getAiRelationship;
494
+ const isAiSvg = (element) => {
495
+ if (!element || element.nodeType !== 1)
496
+ return false;
497
+ const svgClass = element.ownerDocument?.defaultView?.SVGElement;
498
+ if (svgClass && element instanceof svgClass)
499
+ return true;
500
+ return element.tagName?.toLowerCase() === "svg" || element.namespaceURI === "http://www.w3.org/2000/svg";
461
501
  };
462
- exports.isSvg = isSvg;
463
- const replaceTempAttributes = (str) => {
502
+ exports.isAiSvg = isAiSvg;
503
+ const replaceAiTempAttributes = (str) => {
464
504
  if (!str)
465
505
  return str;
466
506
  return str.replace(/\b[a-zA-Z_]*disabled\b/gi, "disabled");
467
507
  };
468
- exports.replaceTempAttributes = replaceTempAttributes;
469
- const getPropertyXPath = (element, docmt, prop, value, isIndex, isTarget, platform) => {
508
+ exports.replaceAiTempAttributes = replaceAiTempAttributes;
509
+ const getAiPropertyXPath = (element, docmt, prop, value, isTarget, platform) => {
470
510
  if (value) {
471
511
  const { tagName } = element;
472
512
  let count;
@@ -474,18 +514,18 @@ const getPropertyXPath = (element, docmt, prop, value, isIndex, isTarget, platfo
474
514
  const mergePattern = [];
475
515
  let pattern;
476
516
  let elementTagName = element.tagName;
477
- if (value && (!isTarget || !(0, exports.isNumberExist)(value))) {
517
+ if (value && (!isTarget || !(0, exports.isAiNumberExist)(value))) {
478
518
  if (!exports.reWhiteSpace.test(value)) {
479
519
  if (platform == 'web') {
480
520
  elementTagName = element.tagName.toLowerCase();
481
521
  }
482
- pattern = (0, exports.buildPattern)(`normalize-space(${prop})=${(0, exports.escapeCharacters)((0, exports.replaceWhiteSpaces)(value)).trim()}`, (0, exports.isSvg)(element), elementTagName);
522
+ pattern = (0, exports.buildAiPattern)(`normalize-space(${prop})=${(0, exports.escapeAiCharacters)((0, exports.aiReplaceWhiteSpaces)(value)).trim()}`, (0, exports.isAiSvg)(element), elementTagName);
483
523
  }
484
524
  else {
485
- pattern = `//${elementTagName}[${prop}=${(0, exports.escapeCharacters)(value)}]`;
525
+ pattern = `//${elementTagName}[${prop}=${(0, exports.escapeAiCharacters)(value)}]`;
486
526
  }
487
- count = (0, exports.getCountOfXPath)(pattern, element, docmt);
488
- if (count === 1 && !isIndex) {
527
+ count = (0, exports.getAiCountOfXPath)(pattern, element, docmt);
528
+ if (count === 1) {
489
529
  return pattern;
490
530
  }
491
531
  }
@@ -496,40 +536,40 @@ const getPropertyXPath = (element, docmt, prop, value, isIndex, isTarget, platfo
496
536
  const contentRes = [...new Set(splitText[0].match(/([^0-9]+)/g))];
497
537
  if (contentRes?.length >= 1) {
498
538
  if (contentRes[0] &&
499
- (0, exports.replaceWhiteSpaces)(contentRes[0].trim())?.length > 1) {
539
+ (0, exports.aiReplaceWhiteSpaces)(contentRes[0].trim())?.length > 1) {
500
540
  if (value.startsWith(contentRes[0])) {
501
541
  if (!exports.reWhiteSpace.test(contentRes[0])) {
502
- combinePattern = `starts-with(${prop},${(0, exports.escapeCharacters)((0, exports.replaceWhiteSpaces)(contentRes[0])).trim()})`;
542
+ combinePattern = `starts-with(${prop},${(0, exports.escapeAiCharacters)((0, exports.aiReplaceWhiteSpaces)(contentRes[0])).trim()})`;
503
543
  }
504
544
  else {
505
- combinePattern = `starts-with(${prop},${(0, exports.escapeCharacters)(contentRes[0]).trim()})`;
545
+ combinePattern = `starts-with(${prop},${(0, exports.escapeAiCharacters)(contentRes[0]).trim()})`;
506
546
  }
507
547
  }
508
548
  }
509
549
  }
510
550
  if (contentRes?.length > 1) {
511
551
  if (contentRes[contentRes.length - 1] &&
512
- (0, exports.replaceWhiteSpaces)(contentRes[contentRes.length - 1].trim())
552
+ (0, exports.aiReplaceWhiteSpaces)(contentRes[contentRes.length - 1].trim())
513
553
  ?.length > 1) {
514
554
  if (value.endsWith(contentRes[contentRes.length - 1])) {
515
555
  if (!exports.reWhiteSpace.test(contentRes[contentRes.length - 1])) {
516
- combinePattern = `ends-with(${prop},${(0, exports.escapeCharacters)((0, exports.replaceWhiteSpaces)(contentRes[contentRes.length - 1])).trim()})`;
556
+ combinePattern = `ends-with(${prop},${(0, exports.escapeAiCharacters)((0, exports.aiReplaceWhiteSpaces)(contentRes[contentRes.length - 1])).trim()})`;
517
557
  }
518
558
  else {
519
- combinePattern = `ends-with(${prop},${(0, exports.escapeCharacters)(contentRes[contentRes.length - 1]).trim()})`;
559
+ combinePattern = `ends-with(${prop},${(0, exports.escapeAiCharacters)(contentRes[contentRes.length - 1]).trim()})`;
520
560
  }
521
561
  }
522
562
  }
523
563
  }
524
564
  if (combinePattern?.length) {
525
- if ((0, exports.isSvg)(element)) {
565
+ if ((0, exports.isAiSvg)(element)) {
526
566
  pattern = `//*[local-name()='${tagName}' and ${combinePattern}]`;
527
567
  }
528
568
  else {
529
569
  pattern = `//${tagName}[${combinePattern}]`;
530
570
  }
531
- count = (0, exports.getCountOfXPath)(pattern, element, docmt);
532
- if (count === 1 && !isIndex) {
571
+ count = (0, exports.getAiCountOfXPath)(pattern, element, docmt);
572
+ if (count === 1) {
533
573
  return pattern;
534
574
  }
535
575
  }
@@ -542,26 +582,26 @@ const getPropertyXPath = (element, docmt, prop, value, isIndex, isTarget, platfo
542
582
  let contentRes = [...new Set(startIndexString.match(/([^0-9]+)/g))];
543
583
  if (contentRes?.length) {
544
584
  if (contentRes[0] &&
545
- (0, exports.replaceWhiteSpaces)(contentRes[0].trim())?.length) {
585
+ (0, exports.aiReplaceWhiteSpaces)(contentRes[0].trim())?.length) {
546
586
  if (value.startsWith(contentRes[0])) {
547
587
  if (!exports.reWhiteSpace.test(contentRes[0])) {
548
- combinePattern = `starts-with(${prop},${(0, exports.escapeCharacters)((0, exports.replaceWhiteSpaces)(contentRes[0])).trim()})`;
588
+ combinePattern = `starts-with(${prop},${(0, exports.escapeAiCharacters)((0, exports.aiReplaceWhiteSpaces)(contentRes[0])).trim()})`;
549
589
  }
550
590
  else {
551
- combinePattern = `starts-with(${prop},${(0, exports.escapeCharacters)(contentRes[0]).trim()})`;
591
+ combinePattern = `starts-with(${prop},${(0, exports.escapeAiCharacters)(contentRes[0]).trim()})`;
552
592
  }
553
593
  }
554
594
  }
555
595
  }
556
596
  if (combinePattern?.length) {
557
- if ((0, exports.isSvg)(element)) {
597
+ if ((0, exports.isAiSvg)(element)) {
558
598
  pattern = `//*[local-name()='${tagName}' and ${combinePattern}]`;
559
599
  }
560
600
  else {
561
601
  pattern = `//${tagName}[${combinePattern}]`;
562
602
  }
563
- count = (0, exports.getCountOfXPath)(pattern, element, docmt);
564
- if (count === 1 && !isIndex) {
603
+ count = (0, exports.getAiCountOfXPath)(pattern, element, docmt);
604
+ if (count === 1) {
565
605
  return pattern;
566
606
  }
567
607
  }
@@ -571,107 +611,100 @@ const getPropertyXPath = (element, docmt, prop, value, isIndex, isTarget, platfo
571
611
  contentRes = [...new Set(endIndexString.match(/([^0-9]+)/g))];
572
612
  if (contentRes?.length) {
573
613
  if (contentRes[0] &&
574
- (0, exports.replaceWhiteSpaces)(contentRes[0].trim())?.length > 3) {
614
+ (0, exports.aiReplaceWhiteSpaces)(contentRes[0].trim())?.length > 3) {
575
615
  if (value.endsWith(contentRes[0])) {
576
616
  if (!exports.reWhiteSpace.test(contentRes[0])) {
577
- combinePattern = `ends-with(${prop},${(0, exports.escapeCharacters)((0, exports.replaceWhiteSpaces)(contentRes[0])).trim()})`;
617
+ combinePattern = `ends-with(${prop},${(0, exports.escapeAiCharacters)((0, exports.aiReplaceWhiteSpaces)(contentRes[0])).trim()})`;
578
618
  }
579
619
  else {
580
- combinePattern = `ends-with(${prop},${(0, exports.escapeCharacters)(contentRes[0]).trim()})`;
620
+ combinePattern = `ends-with(${prop},${(0, exports.escapeAiCharacters)(contentRes[0]).trim()})`;
581
621
  }
582
622
  }
583
623
  }
584
624
  }
585
625
  if (combinePattern?.length) {
586
- if ((0, exports.isSvg)(element)) {
626
+ if ((0, exports.isAiSvg)(element)) {
587
627
  pattern = `//*[local-name()='${tagName}' and ${combinePattern}]`;
588
628
  }
589
629
  else {
590
630
  pattern = `//${tagName}[${combinePattern}]`;
591
631
  }
592
- count = (0, exports.getCountOfXPath)(pattern, element, docmt);
593
- if (count === 1 && !isIndex) {
632
+ count = (0, exports.getAiCountOfXPath)(pattern, element, docmt);
633
+ if (count === 1) {
594
634
  return pattern;
595
635
  }
596
636
  }
597
637
  }
598
638
  }
599
639
  }
600
- if (value && isTarget && (0, exports.isNumberExist)(value)) {
640
+ if (value && isTarget && (0, exports.isAiNumberExist)(value)) {
601
641
  const contentRes = [...new Set(value.match(/([^0-9]+)/g))];
602
642
  if (contentRes?.length) {
603
643
  for (let i = 0; i < contentRes?.length; i++) {
604
644
  if (contentRes[i] &&
605
- (0, exports.replaceWhiteSpaces)(contentRes[i].trim())?.length > 1) {
645
+ (0, exports.aiReplaceWhiteSpaces)(contentRes[i].trim())?.length > 1) {
606
646
  if (!exports.reWhiteSpace.test(contentRes[i])) {
607
- mergePattern.push(`contains(${prop},${(0, exports.escapeCharacters)((0, exports.replaceWhiteSpaces)(contentRes[i])).trim()})`);
647
+ mergePattern.push(`contains(${prop},${(0, exports.escapeAiCharacters)((0, exports.aiReplaceWhiteSpaces)(contentRes[i])).trim()})`);
608
648
  }
609
649
  else {
610
- mergePattern.push(`contains(${prop},${(0, exports.escapeCharacters)(contentRes[i].trim()).trim()})`);
650
+ mergePattern.push(`contains(${prop},${(0, exports.escapeAiCharacters)(contentRes[i].trim()).trim()})`);
611
651
  }
612
652
  }
613
653
  }
614
654
  }
615
655
  if (mergePattern?.length) {
616
- if ((0, exports.isSvg)(element)) {
656
+ if ((0, exports.isAiSvg)(element)) {
617
657
  pattern = `//*[local-name()='${tagName}' and ${mergePattern.join(" and ")}]`;
618
658
  }
619
659
  else {
620
660
  pattern = `//${tagName}[${mergePattern.join(" and ")}]`;
621
661
  }
622
- count = (0, exports.getCountOfXPath)(pattern, element, docmt);
623
- if (count === 1 && !isIndex) {
662
+ count = (0, exports.getAiCountOfXPath)(pattern, element, docmt);
663
+ if (count === 1) {
624
664
  return pattern;
625
665
  }
626
666
  }
627
667
  }
628
- if ((0, exports.isSvg)(element)) {
668
+ if ((0, exports.isAiSvg)(element)) {
629
669
  pattern = `//*[local-name()='${tagName}' and text()]`;
630
670
  }
631
671
  else {
632
672
  pattern = `//${tagName}[text()]`;
633
673
  }
634
- count = (0, exports.getCountOfXPath)(pattern, element, docmt);
635
- if (count === 1 && !isIndex) {
674
+ count = (0, exports.getAiCountOfXPath)(pattern, element, docmt);
675
+ if (count === 1) {
636
676
  return pattern;
637
677
  }
638
678
  }
639
679
  };
640
- exports.getPropertyXPath = getPropertyXPath;
641
- const getAbsoluteXPath = (domNode, docmt) => {
680
+ exports.getAiPropertyXPath = getAiPropertyXPath;
681
+ const getAiAbsoluteXPath = (domNode, docmt) => {
642
682
  try {
643
- if (!domNode) {
683
+ if (!domNode || domNode.nodeType !== 1) {
644
684
  return "";
645
685
  }
646
- let xpathe = (0, exports.isSvg)(domNode)
686
+ let xpathe = (0, exports.isAiSvg)(domNode)
647
687
  ? `/*[local-name()='${domNode.tagName}']`
648
688
  : `/${domNode.tagName}`;
649
689
  // // If this node has siblings of the same tagName, get the index of this node
650
- if (domNode.parentElement) {
690
+ const parent = domNode.parentElement || domNode.parentNode;
691
+ if (parent && parent.nodeType === 1) {
651
692
  // Get the siblings
652
693
  const childNodes = Array.prototype.slice
653
- .call(domNode.parentElement.children, 0)
654
- .filter((childNode) => childNode.tagName === domNode.tagName);
694
+ .call(parent.children || parent.childNodes, 0)
695
+ .filter((childNode) => childNode && childNode.nodeType === 1 && childNode.tagName === domNode.tagName);
655
696
  // // If there's more than one sibling, append the index
656
697
  if (childNodes.length > 1) {
657
698
  const index = childNodes.indexOf(domNode);
658
699
  xpathe += `[${index + 1}]`;
659
700
  }
660
701
  }
661
- else if (domNode instanceof HTMLElement) {
662
- if (domNode.offsetParent) {
663
- const childNodes = Array.prototype.slice
664
- .call(domNode.offsetParent.children, 0)
665
- .filter((childNode) => childNode.tagName === domNode.tagName);
666
- // // If there's more than one sibling, append the index
667
- if (childNodes.length > 1) {
668
- const index = childNodes.indexOf(domNode);
669
- xpathe += `[${index + 1}]`;
670
- }
671
- }
672
- }
673
702
  // // Make a recursive call to this nodes parents and prepend it to this xpath
674
- return (0, exports.getAbsoluteXPath)(domNode?.parentElement, docmt) + xpathe;
703
+ const parentNode = domNode.parentElement || domNode.parentNode;
704
+ if (parentNode && parentNode.nodeType === 1) {
705
+ return (0, exports.getAiAbsoluteXPath)(parentNode, docmt) + xpathe;
706
+ }
707
+ return xpathe;
675
708
  }
676
709
  catch (error) {
677
710
  // If there's an unexpected exception, abort and don't get an XPath
@@ -679,10 +712,12 @@ const getAbsoluteXPath = (domNode, docmt) => {
679
712
  return "";
680
713
  }
681
714
  };
682
- exports.getAbsoluteXPath = getAbsoluteXPath;
683
- const getRelativeXPath = (domNode, docmt, isIndex, isTarget = false, attributesArray) => {
715
+ exports.getAiAbsoluteXPath = getAiAbsoluteXPath;
716
+ const getAIRelativeXPath = (domNode, docmt, _isTarget = false, attributesArray, platform = "web") => {
684
717
  try {
685
- // Generate a cache key based on the node's identifier, index, and target flag
718
+ if (!domNode || domNode.nodeType !== 1) {
719
+ return null;
720
+ }
686
721
  // Check if the result for this node is already cached
687
722
  if (relativeXPathCache.has(domNode)) {
688
723
  return relativeXPathCache.get(domNode);
@@ -690,137 +725,108 @@ const getRelativeXPath = (domNode, docmt, isIndex, isTarget = false, attributesA
690
725
  // Initialize an array to hold parts of the XPath
691
726
  const xpathParts = [];
692
727
  let currentNode = domNode;
728
+ let hasUniqueAttr = false;
693
729
  // Traverse up the DOM tree iteratively instead of using recursion
694
- while (currentNode) {
695
- let xpathe = "";
696
- let hasUniqueAttr = false;
697
- const attributes = domNode === currentNode
698
- ? (attributesArray ?? currentNode.attributes)
699
- : currentNode.attributes;
730
+ while (currentNode && currentNode.nodeType === 1) {
731
+ const isTargetNode = domNode === currentNode;
732
+ const attributes = isTargetNode
733
+ ? (attributesArray ?? Array.from(currentNode.attributes))
734
+ : Array.from(currentNode.attributes);
700
735
  // Loop through attributes to check for unique identifiers
701
- for (const attrName of Array.from(attributes)) {
702
- if ((0, exports.checkBlockedAttributes)(attrName, currentNode, isTarget)) {
703
- const attrValue = (0, exports.sanitizeAttributeValue)(attrName.name, attrName.nodeValue);
736
+ for (const attrName of attributes) {
737
+ const checkTarget = platform === "android" ? true : (isTargetNode ? _isTarget : false);
738
+ if ((0, exports.checkAiBlockedAttributes)(attrName, currentNode, checkTarget)) {
739
+ const attrValue = (0, exports.sanitizeAiAttributeValue)(attrName.name, attrName.nodeValue);
740
+ if (platform === "android" && attrValue && (0, exports.isAiNumberExist)(attrValue)) {
741
+ continue;
742
+ }
704
743
  const elementName = attrName.name;
705
744
  // Construct an XPath based on attribute
706
- xpathe = (0, exports.getXpathString)(currentNode, elementName, attrValue);
707
- let othersWithAttr = 0;
745
+ const xpathe = (0, exports.getAiXpathString)(currentNode, elementName, attrValue);
708
746
  if (xpathe) {
709
- othersWithAttr = (0, exports.getCountOfXPath)(xpathe, currentNode, docmt);
747
+ const othersWithAttr = (0, exports.getAiCountOfXPath)(xpathe, currentNode, docmt);
710
748
  if (othersWithAttr === 1) {
711
- xpathParts.unshift((0, exports.replaceTempAttributes)(xpathe));
749
+ xpathParts.unshift((0, exports.replaceAiTempAttributes)(xpathe));
712
750
  hasUniqueAttr = true;
713
751
  break;
714
752
  }
715
753
  }
716
- if (othersWithAttr > 1 && isIndex) {
717
- xpathe = (0, exports.findXpathWithIndex)(xpathe, currentNode, docmt, othersWithAttr);
718
- if (xpathe) {
719
- xpathParts.unshift((0, exports.replaceTempAttributes)(xpathe));
720
- hasUniqueAttr = true;
721
- break;
722
- }
723
- // return replaceTempAttributes(xpathe);
724
- }
725
754
  }
726
755
  }
756
+ if (hasUniqueAttr) {
757
+ break;
758
+ }
727
759
  if (currentNode.textContent) {
728
- if (!isTarget ||
729
- (isTarget && !(0, exports.isNumberExist)(currentNode.textContent))) {
730
- const reWhiteSpace = new RegExp(/^[\S]+( [\S]+)*$/gi);
731
- if (!reWhiteSpace.test(currentNode.textContent)) {
732
- xpathe = (0, exports.isSvg)(currentNode)
733
- ? `//*[local-name()='${currentNode.tagName}' and normalize-space(.)=${(0, exports.escapeCharacters)((0, exports.getFilteredText)(currentNode))}]`
734
- : `//${currentNode.tagName || "*"}[normalize-space(.)=${(0, exports.escapeCharacters)((0, exports.getFilteredText)(currentNode))}]`;
735
- }
736
- else {
737
- xpathe = (0, exports.isSvg)(currentNode)
738
- ? `//*[local-name()='${currentNode.tagName}' and .=${(0, exports.escapeCharacters)((0, exports.getFilteredText)(currentNode))}]`
739
- : `//${currentNode.tagName || "*"}[.=${(0, exports.escapeCharacters)((0, exports.getFilteredText)(currentNode))}]`;
740
- }
741
- const othersWithAttr = (0, exports.getCountOfXPath)(xpathe, currentNode, docmt);
742
- if (othersWithAttr === 1) {
743
- return xpathe;
744
- }
745
- if (othersWithAttr > 1 && isIndex) {
746
- xpathe = (0, exports.findXpathWithIndex)(xpathe, currentNode, docmt, othersWithAttr);
747
- return xpathe;
748
- }
749
- }
750
- else {
751
- const combinePattern = [];
752
- const contentRes = [
753
- ...new Set((0, exports.getFilteredText)(currentNode).match(/([^0-9]+)/g))
754
- ];
760
+ const canCheckText = platform === "android"
761
+ ? !(0, exports.isAiNumberExist)(currentNode.textContent)
762
+ : (!isTargetNode || !_isTarget || !(0, exports.isAiNumberExist)(currentNode.textContent));
763
+ if (canCheckText) {
755
764
  const reWhiteSpace = new RegExp(/^[\S]+( [\S]+)*$/gi);
756
- if (contentRes?.length) {
757
- for (let i = 0; i < contentRes?.length; i++) {
758
- if (contentRes[i] &&
759
- (0, exports.replaceWhiteSpaces)(contentRes[i].trim())) {
760
- if (!reWhiteSpace.test(contentRes[i])) {
761
- combinePattern.push(`contains(.,${(0, exports.escapeCharacters)((0, exports.replaceWhiteSpaces)(contentRes[i])).trim()})`);
762
- }
763
- else {
764
- combinePattern.push(`contains(.,${(0, exports.escapeCharacters)(contentRes[i].trim()).trim()})`);
765
- }
766
- }
765
+ const filteredText = (0, exports.getAiFilteredText)(currentNode);
766
+ if (filteredText && (platform !== "android" || !(0, exports.isAiNumberExist)(filteredText))) {
767
+ let xpathe = "";
768
+ if (!reWhiteSpace.test(currentNode.textContent)) {
769
+ xpathe = (0, exports.isAiSvg)(currentNode)
770
+ ? `//*[local-name()='${currentNode.tagName}' and normalize-space(.)=${(0, exports.escapeAiCharacters)(filteredText)}]`
771
+ : `//${currentNode.tagName || "*"}[normalize-space(.)=${(0, exports.escapeAiCharacters)(filteredText)}]`;
767
772
  }
768
- }
769
- if (combinePattern?.length) {
770
- xpathe = (0, exports.isSvg)(currentNode)
771
- ? `//*[local-name()='${currentNode.tagName}' and ${combinePattern.join(" and ")}]`
772
- : `//${currentNode.tagName || "*"}[${combinePattern.join(" and ")}]`;
773
- const othersWithAttr = (0, exports.getCountOfXPath)(xpathe, currentNode, docmt);
774
- if (othersWithAttr === 1) {
775
- return xpathe;
773
+ else {
774
+ xpathe = (0, exports.isAiSvg)(currentNode)
775
+ ? `//*[local-name()='${currentNode.tagName}' and .=${(0, exports.escapeAiCharacters)(filteredText)}]`
776
+ : `//${currentNode.tagName || "*"}[.=${(0, exports.escapeAiCharacters)(filteredText)}]`;
776
777
  }
777
- if (othersWithAttr > 1 && isIndex) {
778
- xpathe = (0, exports.findXpathWithIndex)(xpathe, currentNode, docmt, othersWithAttr);
779
- return xpathe;
778
+ const othersWithAttr = (0, exports.getAiCountOfXPath)(xpathe, currentNode, docmt);
779
+ if (othersWithAttr === 1) {
780
+ xpathParts.unshift((0, exports.replaceAiTempAttributes)(xpathe));
781
+ hasUniqueAttr = true;
782
+ break;
780
783
  }
781
784
  }
782
785
  }
783
786
  }
784
787
  // If no unique attribute was found, construct XPath by tag name
785
- if (!hasUniqueAttr) {
786
- let tagBasedXPath = (0, exports.isSvg)(currentNode)
787
- ? `/*[local-name()='${currentNode.tagName}']`
788
- : `/${currentNode.tagName}`;
789
- // Handle sibling nodes
790
- if (currentNode.parentElement) {
791
- const siblings = Array.from(currentNode.parentElement.children).filter((childNode) => childNode.tagName === currentNode.tagName);
792
- // Append index to distinguish between siblings
793
- if (siblings.length > 1) {
794
- const index = siblings.indexOf(currentNode);
795
- tagBasedXPath += `[${index + 1}]`;
796
- }
788
+ const currentTag = currentNode.tagName;
789
+ const currentEl = currentNode;
790
+ let tagBasedXPath = (0, exports.isAiSvg)(currentNode)
791
+ ? `/*[local-name()='${currentTag}']`
792
+ : `/${currentTag}`;
793
+ // Handle sibling nodes
794
+ const parent = currentNode.parentElement || currentNode.parentNode;
795
+ if (parent && parent.nodeType === 1) {
796
+ const siblings = Array.from(parent.children || parent.childNodes).filter((childNode) => childNode && childNode.nodeType === 1 && childNode.tagName === currentTag);
797
+ // Append index to distinguish between siblings
798
+ if (siblings.length > 1) {
799
+ const index = siblings.indexOf(currentEl);
800
+ tagBasedXPath += `[${index + 1}]`;
797
801
  }
798
- // Add the constructed tag-based XPath to the parts array
799
- xpathParts.unshift(tagBasedXPath);
800
- }
801
- else {
802
- break;
803
802
  }
803
+ // Add the constructed tag-based XPath to the parts array
804
+ xpathParts.unshift(tagBasedXPath);
804
805
  // Move up to the parent node for the next iteration
805
- currentNode = currentNode.parentElement;
806
+ currentNode = parent;
806
807
  }
807
808
  // Combine all parts into the final XPath
808
- const finalXPath = `${xpathParts.join("")}`;
809
- // Cache the final XPath for this node
810
- relativeXPathCache.set(domNode, finalXPath);
811
- return finalXPath;
809
+ const finalXPath = xpathParts.join("");
810
+ if (finalXPath && finalXPath.startsWith("//")) {
811
+ const count = (0, exports.getAiCountOfXPath)(finalXPath, domNode, docmt);
812
+ if (count === 1) {
813
+ relativeXPathCache.set(domNode, finalXPath);
814
+ return finalXPath;
815
+ }
816
+ }
817
+ return null;
812
818
  }
813
819
  catch (error) {
814
- logData_1.logger.error(error);
820
+ logData_1.logger.error("error in getAIRelativeXPath", error);
815
821
  return null;
816
822
  }
817
823
  };
818
- exports.getRelativeXPath = getRelativeXPath;
819
- const getCombinationXpath = (attribute, domNode) => {
824
+ exports.getAIRelativeXPath = getAIRelativeXPath;
825
+ const getAiCombinationXpath = (attribute, domNode) => {
820
826
  const combinePattern = [];
821
827
  let pattern;
822
828
  if (attribute &&
823
- !(0, exports.isNumberExist)(attribute.value) &&
829
+ !(0, exports.isAiNumberExist)(attribute.value) &&
824
830
  typeof attribute.nodeValue !== "function" // &&
825
831
  // !modifiedElementAttributes?.find(
826
832
  // (x) => x.element === domNode && x.attributeName === attribute.name
@@ -830,30 +836,30 @@ const getCombinationXpath = (attribute, domNode) => {
830
836
  if (contentRes?.length) {
831
837
  for (let i = 0; i < contentRes?.length; i++) {
832
838
  if (contentRes[i] &&
833
- (0, exports.replaceWhiteSpaces)(contentRes[i].trim())?.length > 2) {
839
+ (0, exports.aiReplaceWhiteSpaces)(contentRes[i].trim())?.length > 2) {
834
840
  if (!exports.reWhiteSpace.test(contentRes[i])) {
835
- combinePattern.push(`contains(@${attribute.name},${(0, exports.escapeCharacters)((0, exports.replaceWhiteSpaces)(contentRes[i])).trim()})`);
841
+ combinePattern.push(`contains(@${attribute.name},${(0, exports.escapeAiCharacters)((0, exports.aiReplaceWhiteSpaces)(contentRes[i])).trim()})`);
836
842
  }
837
843
  else {
838
- combinePattern.push(`contains(@${attribute.name},${(0, exports.escapeCharacters)(contentRes[i].trim())})`);
844
+ combinePattern.push(`contains(@${attribute.name},${(0, exports.escapeAiCharacters)(contentRes[i].trim())})`);
839
845
  }
840
846
  }
841
847
  }
842
848
  }
843
849
  if (combinePattern?.length) {
844
- pattern = (0, exports.isSvg)(domNode)
850
+ pattern = (0, exports.isAiSvg)(domNode)
845
851
  ? `//*[local-name()='${domNode.tagName}' and ${combinePattern.join(" and ")}]`
846
852
  : `//${domNode.tagName}[${combinePattern.join(" and ")}]`;
847
853
  return pattern;
848
854
  }
849
855
  }
850
856
  };
851
- exports.getCombinationXpath = getCombinationXpath;
852
- const getAttributeCombinationXpath = (domNode, docmt, uniqueAttributes, isTarget, platform) => {
857
+ exports.getAiCombinationXpath = getAiCombinationXpath;
858
+ const getAiAttributeCombinationXpath = (domNode, docmt, uniqueAttributes, isTarget, platform) => {
853
859
  try {
854
- const candidateAttributes = uniqueAttributes.filter((attr) => (0, exports.checkBlockedAttributes)(attr, domNode, isTarget));
855
- const buildAttributeConditions = (attribute) => {
856
- const attrValue = (0, exports.sanitizeAttributeValue)(attribute.name, attribute.nodeValue);
860
+ const candidateAttributes = uniqueAttributes.filter((attr) => (0, exports.checkAiBlockedAttributes)(attr, domNode, isTarget));
861
+ const buildAiAttributeConditions = (attribute) => {
862
+ const attrValue = (0, exports.sanitizeAiAttributeValue)(attribute.name, attribute.nodeValue);
857
863
  if (!attrValue)
858
864
  return [];
859
865
  if (attribute.name === "class") {
@@ -865,10 +871,10 @@ const getAttributeCombinationXpath = (domNode, docmt, uniqueAttributes, isTarget
865
871
  return [];
866
872
  const rankedTokens = classTokens
867
873
  .map((token) => {
868
- const xpath = (0, exports.buildPattern)(`contains(@class,${(0, exports.escapeCharacters)(token)})`, (0, exports.isSvg)(domNode), platform === "web" ? domNode.tagName.toLowerCase() : domNode.localName);
874
+ const xpath = (0, exports.buildAiPattern)(`contains(@class,${(0, exports.escapeAiCharacters)(token)})`, (0, exports.isAiSvg)(domNode), platform === "web" ? domNode.tagName.toLowerCase() : domNode.localName);
869
875
  return {
870
876
  token,
871
- count: getTagOnlyXpathCandidateCount(xpath, domNode, docmt)
877
+ count: getAiTagOnlyXpathCandidateCount(xpath, domNode, docmt)
872
878
  };
873
879
  })
874
880
  .sort((left, right) => {
@@ -878,7 +884,7 @@ const getAttributeCombinationXpath = (domNode, docmt, uniqueAttributes, isTarget
878
884
  return right.token.length - left.token.length;
879
885
  });
880
886
  return rankedTokens[0]?.token
881
- ? [`contains(@class,${(0, exports.escapeCharacters)(rankedTokens[0].token)})`]
887
+ ? [`contains(@class,${(0, exports.escapeAiCharacters)(rankedTokens[0].token)})`]
882
888
  : [];
883
889
  }
884
890
  if (!exports.reWhiteSpace.test(attrValue)) {
@@ -886,22 +892,22 @@ const getAttributeCombinationXpath = (domNode, docmt, uniqueAttributes, isTarget
886
892
  }
887
893
  return [`@${attribute.name}="${attrValue}"`];
888
894
  };
889
- const getTextConditions = () => {
890
- const rawText = (0, exports.replaceWhiteSpaces)((0, exports.getTextContent)(domNode)?.trim() || "");
895
+ const getAiTextConditions = () => {
896
+ const rawText = (0, exports.aiReplaceWhiteSpaces)((0, exports.getAiTextContent)(domNode)?.trim() || "");
891
897
  if (!rawText || rawText.length > 80 || /^\d+$/.test(rawText)) {
892
898
  return [];
893
899
  }
894
900
  const conditions = new Set();
895
901
  if (exports.reWhiteSpace.test(rawText) && rawText.length <= 40) {
896
- conditions.add(`text()=${(0, exports.escapeCharacters)(rawText)}`);
902
+ conditions.add(`text()=${(0, exports.escapeAiCharacters)(rawText)}`);
897
903
  }
898
904
  if (rawText.includes(" ")) {
899
- conditions.add(`normalize-space(text())=${(0, exports.escapeCharacters)((0, exports.replaceWhiteSpaces)(rawText))}`);
905
+ conditions.add(`normalize-space(text())=${(0, exports.escapeAiCharacters)((0, exports.aiReplaceWhiteSpaces)(rawText))}`);
900
906
  }
901
- conditions.add(`contains(text(),${(0, exports.escapeCharacters)(rawText)})`);
907
+ conditions.add(`contains(text(),${(0, exports.escapeAiCharacters)(rawText)})`);
902
908
  return Array.from(conditions);
903
909
  };
904
- const generateAttributeCombinations = (attributes, combinationSize) => {
910
+ const generateAiAttributeCombinations = (attributes, combinationSize) => {
905
911
  const results = [];
906
912
  const build = (startIndex, currentGroup) => {
907
913
  if (currentGroup.length === combinationSize) {
@@ -917,29 +923,30 @@ const getAttributeCombinationXpath = (domNode, docmt, uniqueAttributes, isTarget
917
923
  build(0, []);
918
924
  return results;
919
925
  };
920
- const buildXPath = (conditions) => (0, exports.isSvg)(domNode)
926
+ const buildAiXPath = (conditions) => (0, exports.isAiSvg)(domNode)
921
927
  ? `//*[local-name()='${domNode.tagName}' and ${conditions.join(" and ")}]`
922
928
  : `//${domNode.tagName}[${conditions.join(" and ")}]`;
923
- const tryAttributeOnlyCombinations = () => {
929
+ const tryAiAttributeOnlyCombinations = () => {
924
930
  if (candidateAttributes.length < 2) {
925
931
  return undefined;
926
932
  }
927
- for (let combinationSize = 2; combinationSize <= candidateAttributes.length; combinationSize++) {
928
- const attributeGroups = generateAttributeCombinations(candidateAttributes, combinationSize);
933
+ const maxCombinationSize = Math.min(2, candidateAttributes.length);
934
+ for (let combinationSize = 2; combinationSize <= maxCombinationSize; combinationSize++) {
935
+ const attributeGroups = generateAiAttributeCombinations(candidateAttributes, combinationSize);
929
936
  for (const attributeGroup of attributeGroups) {
930
937
  const xpathConditions = [];
931
938
  for (const attribute of attributeGroup) {
932
- const attributeConditions = buildAttributeConditions(attribute);
939
+ const attributeConditions = buildAiAttributeConditions(attribute);
933
940
  if (!attributeConditions.length)
934
941
  continue;
935
942
  xpathConditions.push(...attributeConditions);
936
943
  }
937
944
  if (xpathConditions.length < 2)
938
945
  continue;
939
- const xpath = buildXPath(xpathConditions);
946
+ const xpath = buildAiXPath(xpathConditions);
940
947
  let matchCount;
941
948
  try {
942
- matchCount = (0, exports.getCountOfXPath)(xpath, domNode, docmt);
949
+ matchCount = (0, exports.getAiCountOfXPath)(xpath, domNode, docmt);
943
950
  }
944
951
  catch {
945
952
  continue;
@@ -951,29 +958,30 @@ const getAttributeCombinationXpath = (domNode, docmt, uniqueAttributes, isTarget
951
958
  }
952
959
  return undefined;
953
960
  };
954
- const attributeOnlyXpath = tryAttributeOnlyCombinations();
961
+ const attributeOnlyXpath = tryAiAttributeOnlyCombinations();
955
962
  if (attributeOnlyXpath) {
956
963
  return attributeOnlyXpath;
957
964
  }
958
- const textConditions = getTextConditions();
965
+ const textConditions = getAiTextConditions();
959
966
  if (!textConditions.length || !candidateAttributes.length) {
960
967
  return;
961
968
  }
962
- for (let combinationSize = 1; combinationSize <= candidateAttributes.length; combinationSize++) {
963
- const attributeGroups = generateAttributeCombinations(candidateAttributes, combinationSize);
969
+ const maxCombinationSize = Math.min(2, candidateAttributes.length);
970
+ for (let combinationSize = 1; combinationSize <= maxCombinationSize; combinationSize++) {
971
+ const attributeGroups = generateAiAttributeCombinations(candidateAttributes, combinationSize);
964
972
  for (const attributeGroup of attributeGroups) {
965
973
  const attributeConditions = [];
966
974
  for (const attribute of attributeGroup) {
967
- attributeConditions.push(...buildAttributeConditions(attribute));
975
+ attributeConditions.push(...buildAiAttributeConditions(attribute));
968
976
  }
969
977
  if (!attributeConditions.length) {
970
978
  continue;
971
979
  }
972
980
  for (const textCondition of textConditions) {
973
981
  const xpathConditions = [...attributeConditions, textCondition];
974
- const xpath = buildXPath(xpathConditions);
982
+ const xpath = buildAiXPath(xpathConditions);
975
983
  try {
976
- if ((0, exports.getCountOfXPath)(xpath, domNode, docmt) === 1) {
984
+ if ((0, exports.getAiCountOfXPath)(xpath, domNode, docmt) === 1) {
977
985
  return xpath;
978
986
  }
979
987
  }
@@ -988,70 +996,70 @@ const getAttributeCombinationXpath = (domNode, docmt, uniqueAttributes, isTarget
988
996
  logData_1.logger.error(`XPath generation error: ${JSON.stringify(error, null, 2)}`);
989
997
  }
990
998
  };
991
- exports.getAttributeCombinationXpath = getAttributeCombinationXpath;
992
- const intermediateXpathStep = (targetElemt, attr, isTarget) => {
993
- const isSvgElement = (0, exports.isSvg)(targetElemt);
999
+ exports.getAiAttributeCombinationXpath = getAiAttributeCombinationXpath;
1000
+ const intermediateAiXpathStep = (targetElemt, attr, isTarget) => {
1001
+ const isSvgElement = (0, exports.isAiSvg)(targetElemt);
994
1002
  let expression = "";
995
- if ((0, exports.checkBlockedAttributes)(attr, targetElemt, isTarget)) {
996
- const attrValue = (0, exports.sanitizeAttributeValue)(attr.name, attr.value);
1003
+ if ((0, exports.checkAiBlockedAttributes)(attr, targetElemt, isTarget)) {
1004
+ const attrValue = (0, exports.sanitizeAiAttributeValue)(attr.name, attr.value);
997
1005
  const elementName = attr.name;
998
1006
  if (!exports.reWhiteSpace.test(attrValue)) {
999
1007
  expression = isSvgElement
1000
- ? `*[local-name()='${targetElemt.tagName}' and normalize-space(@${elementName})=${(0, exports.escapeCharacters)(attrValue)}]`
1001
- : `${targetElemt.tagName || "*"}[normalize-space(@${elementName})=${(0, exports.escapeCharacters)(attrValue)}]`;
1008
+ ? `*[local-name()='${targetElemt.tagName}' and normalize-space(@${elementName})=${(0, exports.escapeAiCharacters)(attrValue)}]`
1009
+ : `${targetElemt.tagName || "*"}[normalize-space(@${elementName})=${(0, exports.escapeAiCharacters)(attrValue)}]`;
1002
1010
  }
1003
1011
  else {
1004
1012
  expression = isSvgElement
1005
- ? `*[local-name()='${targetElemt.tagName}' and @${elementName}=${(0, exports.escapeCharacters)(attrValue)}]`
1006
- : `${targetElemt.tagName || "*"}[@${elementName}=${(0, exports.escapeCharacters)(attrValue)}]`;
1013
+ ? `*[local-name()='${targetElemt.tagName}' and @${elementName}=${(0, exports.escapeAiCharacters)(attrValue)}]`
1014
+ : `${targetElemt.tagName || "*"}[@${elementName}=${(0, exports.escapeAiCharacters)(attrValue)}]`;
1007
1015
  }
1008
1016
  }
1009
1017
  return expression;
1010
1018
  };
1011
- exports.intermediateXpathStep = intermediateXpathStep;
1012
- const getFilteredTextXPath = (node) => {
1019
+ exports.intermediateAiXpathStep = intermediateAiXpathStep;
1020
+ const getAiFilteredTextXPath = (node) => {
1013
1021
  if (!node.textContent)
1014
1022
  return "";
1015
- const filteredText = (0, exports.getFilteredText)(node);
1023
+ const filteredText = (0, exports.getAiFilteredText)(node);
1016
1024
  let xpathe;
1017
1025
  if (!exports.reWhiteSpace.test(filteredText)) {
1018
- xpathe = (0, exports.isSvg)(node)
1019
- ? `//*[local-name()='${node.tagName}' and normalize-space(.)=${(0, exports.escapeCharacters)(filteredText)}]`
1020
- : `//${node.tagName || "*"}[normalize-space(.)=${(0, exports.escapeCharacters)(filteredText)}]`;
1026
+ xpathe = (0, exports.isAiSvg)(node)
1027
+ ? `//*[local-name()='${node.tagName}' and normalize-space(.)=${(0, exports.escapeAiCharacters)(filteredText)}]`
1028
+ : `//${node.tagName || "*"}[normalize-space(.)=${(0, exports.escapeAiCharacters)(filteredText)}]`;
1021
1029
  }
1022
1030
  else {
1023
- xpathe = (0, exports.isSvg)(node)
1024
- ? `//*[local-name()='${node.tagName}' and .=${(0, exports.escapeCharacters)(filteredText)}]`
1025
- : `//${node.tagName || "*"}[.=${(0, exports.escapeCharacters)(filteredText)}]`;
1031
+ xpathe = (0, exports.isAiSvg)(node)
1032
+ ? `//*[local-name()='${node.tagName}' and .=${(0, exports.escapeAiCharacters)(filteredText)}]`
1033
+ : `//${node.tagName || "*"}[.=${(0, exports.escapeAiCharacters)(filteredText)}]`;
1026
1034
  }
1027
1035
  return xpathe;
1028
1036
  };
1029
- exports.getFilteredTextXPath = getFilteredTextXPath;
1030
- const getNormalizedPropertyXPath = (element, prop, value, platform) => {
1037
+ exports.getAiFilteredTextXPath = getAiFilteredTextXPath;
1038
+ const getAiNormalizedPropertyXPath = (element, prop, value, platform) => {
1031
1039
  const elementTagName = platform === "web" ? element.tagName.toLowerCase() : element.localName;
1032
- const xpath = (0, exports.buildPattern)(`normalize-space(${prop})=${(0, exports.escapeCharacters)((0, exports.replaceWhiteSpaces)(value)).trim()}`, (0, exports.isSvg)(element), elementTagName);
1040
+ const xpath = (0, exports.buildAiPattern)(`normalize-space(${prop})=${(0, exports.escapeAiCharacters)((0, exports.aiReplaceWhiteSpaces)(value)).trim()}`, (0, exports.isAiSvg)(element), elementTagName);
1033
1041
  // logger.info("normalizedPropertyXPath", xpath)
1034
1042
  return xpath;
1035
1043
  };
1036
- exports.getNormalizedPropertyXPath = getNormalizedPropertyXPath;
1037
- const getStartsWithPropertyXPath = (element, prop, value, platform) => {
1044
+ exports.getAiNormalizedPropertyXPath = getAiNormalizedPropertyXPath;
1045
+ const getAiStartsWithPropertyXPath = (element, prop, value, platform) => {
1038
1046
  const elementTagName = platform === "web" ? element.tagName.toLowerCase() : element.localName;
1039
- const xpath = (0, exports.buildPattern)(`starts-with(${prop},${(0, exports.escapeCharacters)((0, exports.replaceWhiteSpaces)(value)).trim()})`, (0, exports.isSvg)(element), elementTagName);
1040
- // logger.info("getStartsWithPropertyXPath", xpath)
1047
+ const xpath = (0, exports.buildAiPattern)(`starts-with(${prop},${(0, exports.escapeAiCharacters)((0, exports.aiReplaceWhiteSpaces)(value)).trim()})`, (0, exports.isAiSvg)(element), elementTagName);
1048
+ // logger.info("getAiStartsWithPropertyXPath", xpath)
1041
1049
  return xpath;
1042
1050
  };
1043
- exports.getStartsWithPropertyXPath = getStartsWithPropertyXPath;
1044
- const getContainsPropertyXPath = (element, prop, value, platform) => {
1051
+ exports.getAiStartsWithPropertyXPath = getAiStartsWithPropertyXPath;
1052
+ const getAiContainsPropertyXPath = (element, prop, value, platform) => {
1045
1053
  const elementTagName = platform === "web" ? element.tagName.toLowerCase() : element.localName;
1046
- const xpath = (0, exports.buildPattern)(`contains(${prop},${(0, exports.escapeCharacters)((0, exports.replaceWhiteSpaces)(value)).trim()})`, (0, exports.isSvg)(element), elementTagName);
1047
- // logger.info("getContainsPropertyXPath", xpath)
1054
+ const xpath = (0, exports.buildAiPattern)(`contains(${prop},${(0, exports.escapeAiCharacters)((0, exports.aiReplaceWhiteSpaces)(value)).trim()})`, (0, exports.isAiSvg)(element), elementTagName);
1055
+ // logger.info("getAiContainsPropertyXPath", xpath)
1048
1056
  return xpath;
1049
1057
  };
1050
- exports.getContainsPropertyXPath = getContainsPropertyXPath;
1051
- const getOrAttributesXPath = (element, attributes, platform) => {
1058
+ exports.getAiContainsPropertyXPath = getAiContainsPropertyXPath;
1059
+ const getOrAttributesAiXPath = (element, attributes, platform) => {
1052
1060
  const elementTagName = platform === "web" ? element.tagName.toLowerCase() : element.localName;
1053
- const buildAttributeCondition = (attribute) => {
1054
- const attrValue = (0, exports.sanitizeAttributeValue)(attribute.name, attribute.value);
1061
+ const buildAiAttributeCondition = (attribute) => {
1062
+ const attrValue = (0, exports.sanitizeAiAttributeValue)(attribute.name, attribute.value);
1055
1063
  if (!attrValue) {
1056
1064
  return null;
1057
1065
  }
@@ -1064,10 +1072,10 @@ const getOrAttributesXPath = (element, attributes, platform) => {
1064
1072
  element.ownerDocument;
1065
1073
  const rankedToken = classTokens
1066
1074
  .map((token) => {
1067
- const xpath = (0, exports.buildPattern)(`contains(@class,${(0, exports.escapeCharacters)(token)})`, (0, exports.isSvg)(element), elementTagName);
1075
+ const xpath = (0, exports.buildAiPattern)(`contains(@class,${(0, exports.escapeAiCharacters)(token)})`, (0, exports.isAiSvg)(element), elementTagName);
1068
1076
  return {
1069
1077
  token,
1070
- count: getTagOnlyXpathCandidateCount(xpath, element, docmt)
1078
+ count: getAiTagOnlyXpathCandidateCount(xpath, element, docmt)
1071
1079
  };
1072
1080
  })
1073
1081
  .sort((left, right) => {
@@ -1077,46 +1085,46 @@ const getOrAttributesXPath = (element, attributes, platform) => {
1077
1085
  return right.token.length - left.token.length;
1078
1086
  })[0]?.token;
1079
1087
  return rankedToken
1080
- ? `contains(@class,${(0, exports.escapeCharacters)(rankedToken)})`
1088
+ ? `contains(@class,${(0, exports.escapeAiCharacters)(rankedToken)})`
1081
1089
  : null;
1082
1090
  }
1083
1091
  if (!exports.reWhiteSpace.test(attrValue)) {
1084
- return `normalize-space(@${attribute.name})=${(0, exports.escapeCharacters)(attrValue)}`;
1092
+ return `normalize-space(@${attribute.name})=${(0, exports.escapeAiCharacters)(attrValue)}`;
1085
1093
  }
1086
- return `@${attribute.name}=${(0, exports.escapeCharacters)(attrValue)}`;
1094
+ return `@${attribute.name}=${(0, exports.escapeAiCharacters)(attrValue)}`;
1087
1095
  };
1088
1096
  const buildTextCondition = () => {
1089
- const rawText = (0, exports.replaceWhiteSpaces)((0, exports.getTextContent)(element)?.trim() || "");
1097
+ const rawText = (0, exports.aiReplaceWhiteSpaces)((0, exports.getAiTextContent)(element)?.trim() || "");
1090
1098
  if (!rawText || rawText.length > 80 || /^\d+$/.test(rawText)) {
1091
1099
  return null;
1092
1100
  }
1093
1101
  if (exports.reWhiteSpace.test(rawText) && rawText.length <= 40) {
1094
- return `text()=${(0, exports.escapeCharacters)(rawText)}`;
1102
+ return `text()=${(0, exports.escapeAiCharacters)(rawText)}`;
1095
1103
  }
1096
1104
  if (rawText.includes(" ")) {
1097
- return `normalize-space(text())=${(0, exports.escapeCharacters)(rawText)}`;
1105
+ return `normalize-space(text())=${(0, exports.escapeAiCharacters)(rawText)}`;
1098
1106
  }
1099
- return `contains(text(),${(0, exports.escapeCharacters)(rawText)})`;
1107
+ return `contains(text(),${(0, exports.escapeAiCharacters)(rawText)})`;
1100
1108
  };
1101
1109
  const attributeConditions = attributes
1102
- .map((attribute) => buildAttributeCondition(attribute))
1110
+ .map((attribute) => buildAiAttributeCondition(attribute))
1103
1111
  .filter(Boolean);
1104
1112
  if (attributeConditions.length >= 2) {
1105
- return (0, exports.buildPattern)(`${attributeConditions[0]} or ${attributeConditions[1]}`, (0, exports.isSvg)(element), elementTagName);
1113
+ return (0, exports.buildAiPattern)(`${attributeConditions[0]} or ${attributeConditions[1]}`, (0, exports.isAiSvg)(element), elementTagName);
1106
1114
  }
1107
1115
  const textCondition = buildTextCondition();
1108
1116
  if (attributeConditions.length === 1 && textCondition) {
1109
- return (0, exports.buildPattern)(`${attributeConditions[0]} or ${textCondition}`, (0, exports.isSvg)(element), elementTagName);
1117
+ return (0, exports.buildAiPattern)(`${attributeConditions[0]} or ${textCondition}`, (0, exports.isAiSvg)(element), elementTagName);
1110
1118
  }
1111
1119
  return "";
1112
1120
  };
1113
- exports.getOrAttributesXPath = getOrAttributesXPath;
1114
- const getTagOnlyXpathCandidateCount = (xpath, element, docmt) => {
1121
+ exports.getOrAttributesAiXPath = getOrAttributesAiXPath;
1122
+ const getAiTagOnlyXpathCandidateCount = (xpath, element, docmt) => {
1115
1123
  try {
1116
- return (0, exports.getCountOfXPath)(xpath, element, docmt);
1124
+ return (0, exports.getAiCountOfXPath)(xpath, element, docmt);
1117
1125
  }
1118
1126
  catch (_error) {
1119
- logData_1.logger.error(`error in getTagOnlyXpathCandidateCount ${_error.message}`);
1127
+ logData_1.logger.error(`error in getAiTagOnlyXpathCandidateCount ${_error.message}`);
1120
1128
  return 0;
1121
1129
  }
1122
1130
  };
@@ -1142,30 +1150,30 @@ const getAncestorAnchorCandidates = (node, docmt, platform) => {
1142
1150
  const pushAnchor = (xpath) => {
1143
1151
  if (!xpath || seen.has(xpath))
1144
1152
  return;
1145
- if ((0, exports.isExactUniqueXpath)(xpath, node, docmt)) {
1153
+ if ((0, exports.isAiExactUniqueXpath)(xpath, node, docmt)) {
1146
1154
  seen.add(xpath);
1147
1155
  anchors.push(xpath);
1148
1156
  }
1149
1157
  };
1150
1158
  orderedAttributes.forEach((attr) => {
1151
- if (!(0, exports.checkBlockedAttributes)(attr, node, false))
1159
+ if (!(0, exports.checkAiBlockedAttributes)(attr, node, false))
1152
1160
  return;
1153
1161
  const xpath = attr.name === "id"
1154
- ? `//*[@id=${(0, exports.escapeCharacters)((0, exports.sanitizeAttributeValue)(attr.name, attr.value))}]`
1155
- : (0, exports.getXpathString)(node, attr.name, attr.value);
1162
+ ? `//*[@id=${(0, exports.escapeAiCharacters)((0, exports.sanitizeAiAttributeValue)(attr.name, attr.value))}]`
1163
+ : (0, exports.getAiXpathString)(node, attr.name, attr.value);
1156
1164
  if (xpath) {
1157
1165
  pushAnchor(xpath);
1158
1166
  }
1159
1167
  });
1160
1168
  const text = node.textContent?.trim();
1161
1169
  if (text && text.length < 40 && node.children.length === 0) {
1162
- const textXpath = (0, exports.getFilteredTextXPath)(node);
1170
+ const textXpath = (0, exports.getAiFilteredTextXPath)(node);
1163
1171
  if (textXpath) {
1164
1172
  pushAnchor(textXpath);
1165
1173
  }
1166
1174
  }
1167
1175
  if (attributes.length > 1) {
1168
- const combinationXpath = (0, exports.getAttributeCombinationXpath)(node, docmt, attributes, false, platform);
1176
+ const combinationXpath = (0, exports.getAiAttributeCombinationXpath)(node, docmt, attributes, false, platform);
1169
1177
  if (combinationXpath) {
1170
1178
  pushAnchor(combinationXpath);
1171
1179
  }
@@ -1176,62 +1184,55 @@ const getStructuralPathFromAncestor = (ancestor, element, platform) => {
1176
1184
  const steps = [];
1177
1185
  let current = element;
1178
1186
  while (current && current !== ancestor) {
1179
- steps.unshift((0, exports.getAxisNodeTest)(current, platform));
1187
+ steps.unshift((0, exports.getAiAxisNodeTest)(current, platform));
1180
1188
  current = current.parentElement;
1181
1189
  }
1182
1190
  return current === ancestor ? steps.join("/") : "";
1183
1191
  };
1184
- const getTagOnlyXPath = (element, platform, docmt) => {
1192
+ const getAiTagOnlyXPath = (element, platform, docmt) => {
1185
1193
  const root = docmt ??
1186
1194
  (element.getRootNode?.() ||
1187
1195
  element.ownerDocument);
1188
- const tagName = (0, exports.getAxisNodeTest)(element, platform);
1196
+ const tagName = (0, exports.getAiAxisNodeTest)(element, platform);
1189
1197
  const elementTagName = platform === "web" ? element.tagName.toLowerCase() : element.localName;
1190
- const fallbackXpath = (0, exports.isSvg)(element)
1198
+ const fallbackXpath = (0, exports.isAiSvg)(element)
1191
1199
  ? `//*[local-name()='${elementTagName}']`
1192
1200
  : `//${elementTagName}`;
1193
- for (let ancestor = element.parentElement; ancestor; ancestor = ancestor.parentElement) {
1201
+ let depth = 0;
1202
+ for (let ancestor = element.parentElement; ancestor && depth < 5; ancestor = ancestor.parentElement,
1203
+ depth++) {
1194
1204
  const ancestorAnchors = getAncestorAnchorCandidates(ancestor, root, platform);
1195
1205
  for (const ancestorXpath of ancestorAnchors) {
1196
1206
  // logger.info(`Trying ancestor XPath: ${ancestorXpath}`);
1197
1207
  const descendantXpath = `${ancestorXpath}/descendant::${tagName}`;
1198
1208
  // logger.info(`Trying descendant XPath: ${descendantXpath}`);
1199
- const count = getTagOnlyXpathCandidateCount(descendantXpath, element, root);
1200
- // logger.info(`Match count: ${count}`);
1201
- if (count === 1 &&
1202
- (0, exports.getFirstMatchedNode)(descendantXpath, root) === element) {
1203
- // logger.info(`Selected XPath: ${descendantXpath}`);
1209
+ const { first, second } = (0, exports.evaluateAIXPathOnce)(descendantXpath, root);
1210
+ if (first === element && !second) {
1204
1211
  return descendantXpath;
1205
1212
  }
1206
1213
  const structuralPath = getStructuralPathFromAncestor(ancestor, element, platform);
1207
1214
  if (structuralPath) {
1208
1215
  const parentChainXpath = `${ancestorXpath}/${structuralPath}`;
1209
1216
  // logger.info(`Trying descendant XPath: ${parentChainXpath}`);
1210
- const parentChainCount = getTagOnlyXpathCandidateCount(parentChainXpath, element, root);
1211
- // logger.info(`Match count: ${parentChainCount}`);
1212
- if (parentChainCount === 1 &&
1213
- (0, exports.getFirstMatchedNode)(parentChainXpath, root) === element) {
1214
- // logger.info(`Selected XPath: ${parentChainXpath}`);
1217
+ const { first, second } = (0, exports.evaluateAIXPathOnce)(parentChainXpath, root);
1218
+ if (first === element && !second) {
1215
1219
  return parentChainXpath;
1216
1220
  }
1217
1221
  }
1218
1222
  }
1219
1223
  }
1220
1224
  // logger.info(`Trying descendant XPath: ${fallbackXpath}`);
1221
- const fallbackCount = getTagOnlyXpathCandidateCount(fallbackXpath, element, root);
1222
- // logger.info(`Match count: ${fallbackCount}`);
1223
- if (fallbackCount === 1 &&
1224
- (0, exports.getFirstMatchedNode)(fallbackXpath, root) === element) {
1225
- // logger.info(`Selected XPath: ${fallbackXpath}`);
1225
+ const { first, second } = (0, exports.evaluateAIXPathOnce)(fallbackXpath, root);
1226
+ if (first === element && !second) {
1226
1227
  return fallbackXpath;
1227
1228
  }
1228
1229
  return "";
1229
1230
  };
1230
- exports.getTagOnlyXPath = getTagOnlyXPath;
1231
- const getFirstMatchedNode = (xpath, docmt) => {
1231
+ exports.getAiTagOnlyXPath = getAiTagOnlyXPath;
1232
+ const getAiFirstMatchedNode = (xpath, docmt) => {
1232
1233
  try {
1233
- if (isShadowRootNode(docmt)) {
1234
- const { contextNode, cloneElement } = (0, exports.createShadowEvaluationContext)(docmt);
1234
+ if (isAiShadowRootNode(docmt)) {
1235
+ const { contextNode, cloneElement } = (0, exports.createAIShadowEvaluationContext)(docmt);
1235
1236
  // const result = owner.evaluate(
1236
1237
  // xpath,
1237
1238
  // contextNode,
@@ -1239,7 +1240,7 @@ const getFirstMatchedNode = (xpath, docmt) => {
1239
1240
  // owner.defaultView!.XPathResult.FIRST_ORDERED_NODE_TYPE,
1240
1241
  // null
1241
1242
  // );
1242
- const result = evaluateXPath(xpath, contextNode, "first");
1243
+ const result = evaluateAiXPath(xpath, contextNode, "first");
1243
1244
  return (result.singleNodeValue || cloneElement);
1244
1245
  }
1245
1246
  // const result = docmt.evaluate(
@@ -1249,44 +1250,46 @@ const getFirstMatchedNode = (xpath, docmt) => {
1249
1250
  // docmt.defaultView!.XPathResult.FIRST_ORDERED_NODE_TYPE,
1250
1251
  // null
1251
1252
  // );
1252
- const result = evaluateXPath(xpath, docmt, "first");
1253
+ const result = evaluateAiXPath(xpath, docmt, "first");
1253
1254
  return result.singleNodeValue;
1254
1255
  }
1255
1256
  catch (_error) {
1256
- logData_1.logger.error(`error in getFirstMatchedNode ${_error.message}`);
1257
+ logData_1.logger.error(`error in getAiFirstMatchedNode ${_error.message}`);
1257
1258
  return null;
1258
1259
  }
1259
1260
  };
1260
- exports.getFirstMatchedNode = getFirstMatchedNode;
1261
- const isExactUniqueXpath = (xpath, element, docmt) => {
1261
+ exports.getAiFirstMatchedNode = getAiFirstMatchedNode;
1262
+ const isAiExactUniqueXpath = (xpath, element, docmt) => {
1262
1263
  try {
1263
- const { first, second } = (0, exports.evaluateXPathOnce)(xpath, docmt);
1264
+ const { first, second } = (0, exports.evaluateAIXPathOnce)(xpath, docmt);
1264
1265
  return !!first && !second && first === element;
1265
1266
  }
1266
1267
  catch {
1267
1268
  return false;
1268
1269
  }
1269
1270
  };
1270
- exports.isExactUniqueXpath = isExactUniqueXpath;
1271
- const getAxisNodeTest = (element, platform) => {
1271
+ exports.isAiExactUniqueXpath = isAiExactUniqueXpath;
1272
+ const getAiAxisNodeTest = (element, platform) => {
1272
1273
  const elementTagName = platform === "web" ? element.tagName.toLowerCase() : element.localName;
1273
- return (0, exports.isSvg)(element)
1274
+ return (0, exports.isAiSvg)(element)
1274
1275
  ? `*[local-name()='${elementTagName}']`
1275
1276
  : elementTagName;
1276
1277
  };
1277
- exports.getAxisNodeTest = getAxisNodeTest;
1278
+ exports.getAiAxisNodeTest = getAiAxisNodeTest;
1278
1279
  const hasAnyNumber = (value) => /\d/.test(value);
1279
- const getUniqueNodeAnchorXpaths = (node, docmt, isTarget, platform) => {
1280
- if (!(node instanceof node.ownerDocument.defaultView.Element))
1280
+ const getAiUniqueNodeAnchorXpaths = (node, docmt, isTarget, platform) => {
1281
+ if (!node || node.nodeType !== 1)
1281
1282
  return [];
1282
1283
  const seen = new Set();
1283
1284
  const anchors = [];
1285
+ const MAX_ANCHORS = 3;
1284
1286
  const attributes = Array.from(node.attributes || []).filter((attribute) => attribute?.value &&
1285
1287
  !hasAnyNumber(attribute.value) &&
1286
- (0, exports.checkBlockedAttributes)(attribute, node, isTarget));
1288
+ (0, exports.checkAiBlockedAttributes)(attribute, node, isTarget));
1287
1289
  const pushAnchor = (key, value) => {
1288
- if (!value || seen.has(value))
1290
+ if (!value || seen.has(value) || anchors.length >= MAX_ANCHORS) {
1289
1291
  return;
1292
+ }
1290
1293
  seen.add(value);
1291
1294
  anchors.push({ key, value });
1292
1295
  };
@@ -1300,53 +1303,67 @@ const getUniqueNodeAnchorXpaths = (node, docmt, isTarget, platform) => {
1300
1303
  "aria-label",
1301
1304
  "role"
1302
1305
  ];
1303
- priorityAttrs.forEach((attrName) => {
1304
- const attr = attributes.find((a) => a.name === attrName);
1306
+ const attributeMap = new Map(attributes.map(attr => [attr.name, attr]));
1307
+ const priorityAttrSet = new Set(priorityAttrs);
1308
+ for (const attrName of priorityAttrs) {
1309
+ if (anchors.length >= MAX_ANCHORS) {
1310
+ return anchors;
1311
+ }
1312
+ const attr = attributeMap.get(attrName);
1305
1313
  if (!attr)
1306
- return;
1314
+ continue;
1307
1315
  const xpath = attrName === "id"
1308
1316
  ? `//*[@id='${attr.value}']`
1309
- : (0, exports.getXpathString)(node, attr.name, attr.value);
1310
- if (xpath && (0, exports.isExactUniqueXpath)(xpath, node, docmt)) {
1317
+ : (0, exports.getAiXpathString)(node, attr.name, attr.value);
1318
+ if (xpath && (0, exports.isAiExactUniqueXpath)(xpath, node, docmt)) {
1311
1319
  pushAnchor(`anchor by ${attr.name}`, xpath);
1312
1320
  }
1313
- });
1321
+ }
1314
1322
  // Other attributes
1315
- attributes.forEach((attribute) => {
1316
- if (priorityAttrs.includes(attribute.name))
1317
- return;
1318
- const xpath = (0, exports.getXpathString)(node, attribute.name, attribute.value);
1319
- if (xpath && (0, exports.isExactUniqueXpath)(xpath, node, docmt)) {
1323
+ for (const attribute of attributes) {
1324
+ if (anchors.length >= MAX_ANCHORS) {
1325
+ return anchors;
1326
+ }
1327
+ if (priorityAttrSet.has(attribute.name))
1328
+ continue;
1329
+ const xpath = (0, exports.getAiXpathString)(node, attribute.name, attribute.value);
1330
+ if (xpath && (0, exports.isAiExactUniqueXpath)(xpath, node, docmt)) {
1320
1331
  pushAnchor(`anchor by ${attribute.name}`, xpath);
1321
1332
  }
1322
- });
1333
+ }
1323
1334
  // Text (controlled)
1324
1335
  const text = node.textContent?.trim();
1325
1336
  if (text && text.length < 40 && node.children.length === 0) {
1326
- const textXpath = (0, exports.getFilteredTextXPath)(node);
1327
- if (textXpath && (0, exports.isExactUniqueXpath)(textXpath, node, docmt)) {
1337
+ const textXpath = (0, exports.getAiFilteredTextXPath)(node);
1338
+ if (textXpath && (0, exports.isAiExactUniqueXpath)(textXpath, node, docmt)) {
1328
1339
  pushAnchor("anchor by text", textXpath);
1329
1340
  }
1330
1341
  }
1342
+ if (anchors.length >= MAX_ANCHORS) {
1343
+ return anchors;
1344
+ }
1331
1345
  // Combination
1332
1346
  if (attributes.length > 1) {
1333
- const combinationXpath = (0, exports.getAttributeCombinationXpath)(node, docmt, attributes, isTarget, platform);
1334
- if (combinationXpath && (0, exports.isExactUniqueXpath)(combinationXpath, node, docmt)) {
1347
+ const combinationXpath = (0, exports.getAiAttributeCombinationXpath)(node, docmt, attributes, isTarget, platform);
1348
+ if (combinationXpath && (0, exports.isAiExactUniqueXpath)(combinationXpath, node, docmt)) {
1335
1349
  pushAnchor("anchor by combination", combinationXpath);
1336
1350
  }
1337
1351
  }
1352
+ if (anchors.length >= MAX_ANCHORS) {
1353
+ return anchors;
1354
+ }
1338
1355
  // Tag (last fallback)
1339
- const tagXpath = (0, exports.getTagOnlyXPath)(node, platform, docmt);
1340
- if (tagXpath && (0, exports.isExactUniqueXpath)(tagXpath, node, docmt)) {
1356
+ const tagXpath = (0, exports.getAiTagOnlyXPath)(node, platform, docmt);
1357
+ if (tagXpath && (0, exports.isAiExactUniqueXpath)(tagXpath, node, docmt)) {
1341
1358
  pushAnchor("anchor by tag", tagXpath);
1342
1359
  }
1343
1360
  return anchors;
1344
1361
  };
1345
- exports.getUniqueNodeAnchorXpaths = getUniqueNodeAnchorXpaths;
1346
- const getTextXpathFunction = (domNode) => {
1347
- const trimmedText = (0, exports.getTextContent)(domNode)?.trim();
1362
+ exports.getAiUniqueNodeAnchorXpaths = getAiUniqueNodeAnchorXpaths;
1363
+ const getAiTextXpathFunction = (domNode) => {
1364
+ const trimmedText = (0, exports.getAiTextContent)(domNode)?.trim();
1348
1365
  const filteredText = trimmedText
1349
- ? (0, exports.escapeCharacters)(deleteGarbageFromInnerText(trimmedText))
1366
+ ? (0, exports.escapeAiCharacters)(deleteAiGarbageFromInnerText(trimmedText))
1350
1367
  : trimmedText;
1351
1368
  if (filteredText) {
1352
1369
  if (filteredText !== `'${trimmedText}'`) {
@@ -1355,45 +1372,45 @@ const getTextXpathFunction = (domNode) => {
1355
1372
  return `normalize-space(.)='${trimmedText}'`;
1356
1373
  }
1357
1374
  };
1358
- exports.getTextXpathFunction = getTextXpathFunction;
1359
- const getXpathString = (node, attrName, attrValue) => {
1375
+ exports.getAiTextXpathFunction = getAiTextXpathFunction;
1376
+ const getAiXpathString = (node, attrName, attrValue) => {
1360
1377
  const reWhiteSpace = new RegExp(/^[\S]+( [\S]+)*$/gi);
1361
1378
  let xpathe = "";
1362
- attrValue = (0, exports.sanitizeAttributeValue)(attrName, attrValue);
1379
+ attrValue = (0, exports.sanitizeAiAttributeValue)(attrName, attrValue);
1363
1380
  if (attrValue) {
1364
1381
  if (!reWhiteSpace.test(attrValue)) {
1365
- xpathe = (0, exports.isSvg)(node)
1366
- ? `//*[local-name()='${node.tagName}' and contains(@${attrName},${(0, exports.escapeCharacters)(attrValue)})]`
1367
- : `//${node.tagName || "*"}[contains(@${attrName},${(0, exports.escapeCharacters)(attrValue)})]`;
1382
+ xpathe = (0, exports.isAiSvg)(node)
1383
+ ? `//*[local-name()='${node.tagName}' and contains(@${attrName},${(0, exports.escapeAiCharacters)(attrValue)})]`
1384
+ : `//${node.tagName || "*"}[contains(@${attrName},${(0, exports.escapeAiCharacters)(attrValue)})]`;
1368
1385
  }
1369
1386
  else if (attrName === "class") {
1370
- xpathe = (0, exports.isSvg)(node)
1371
- ? `//*[local-name()='${node.tagName}' and contains(@${attrName},${(0, exports.escapeCharacters)(attrValue)})]`
1372
- : `//${node.tagName || "*"}[contains(@${attrName},${(0, exports.escapeCharacters)(attrValue)})]`;
1387
+ xpathe = (0, exports.isAiSvg)(node)
1388
+ ? `//*[local-name()='${node.tagName}' and contains(@${attrName},${(0, exports.escapeAiCharacters)(attrValue)})]`
1389
+ : `//${node.tagName || "*"}[contains(@${attrName},${(0, exports.escapeAiCharacters)(attrValue)})]`;
1373
1390
  }
1374
1391
  else {
1375
- xpathe = (0, exports.isSvg)(node)
1376
- ? `//*[local-name()='${node.tagName}' and @${attrName}=${(0, exports.escapeCharacters)(attrValue)}]`
1377
- : `//${node.tagName || "*"}[@${attrName}=${(0, exports.escapeCharacters)(attrValue)}]`;
1392
+ xpathe = (0, exports.isAiSvg)(node)
1393
+ ? `//*[local-name()='${node.tagName}' and @${attrName}=${(0, exports.escapeAiCharacters)(attrValue)}]`
1394
+ : `//${node.tagName || "*"}[@${attrName}=${(0, exports.escapeAiCharacters)(attrValue)}]`;
1378
1395
  }
1379
1396
  }
1380
1397
  return xpathe;
1381
1398
  };
1382
- exports.getXpathString = getXpathString;
1383
- const replaceActualAttributes = (str) => {
1399
+ exports.getAiXpathString = getAiXpathString;
1400
+ const replaceAiActualAttributes = (str) => {
1384
1401
  if (str) {
1385
1402
  return str.replace(/\bdisabled\b/gi, "flndisabled");
1386
1403
  }
1387
1404
  return str;
1388
1405
  };
1389
- exports.replaceActualAttributes = replaceActualAttributes;
1406
+ exports.replaceAiActualAttributes = replaceAiActualAttributes;
1390
1407
  const addAttributeSplitCombineXpaths = (attributes, targetElemt, docmt, isTarget) => {
1391
1408
  const attributesArray = Array.prototype.slice.call(attributes);
1392
1409
  const xpaths = [];
1393
1410
  try {
1394
1411
  attributesArray.map((element) => {
1395
- if ((0, exports.checkBlockedAttributes)(element, targetElemt, isTarget)) {
1396
- const xpth = (0, exports.getCombinationXpath)(element, targetElemt);
1412
+ if ((0, exports.checkAiBlockedAttributes)(element, targetElemt, isTarget)) {
1413
+ const xpth = (0, exports.getAiCombinationXpath)(element, targetElemt);
1397
1414
  if (xpth) {
1398
1415
  xpaths.push({
1399
1416
  key: `split xpath by ${element.name}`,
@@ -1412,19 +1429,19 @@ const getReferenceElementsXpath = (domNode, docmt, isTarget, platform) => {
1412
1429
  let nodeXpath1;
1413
1430
  const xpaths1 = [];
1414
1431
  if (domNode.textContent &&
1415
- (!isTarget || (isTarget && !(0, exports.isNumberExist)(domNode.textContent)))) {
1432
+ (!isTarget || (isTarget && !(0, exports.isAiNumberExist)(domNode.textContent)))) {
1416
1433
  if (!exports.reWhiteSpace.test(domNode.textContent)) {
1417
- nodeXpath1 = (0, exports.isSvg)(domNode)
1418
- ? `*[local-name()='${domNode.tagName}' and ${(0, exports.getTextXpathFunction)(domNode)})]`
1419
- : `${domNode.tagName}[${(0, exports.getTextXpathFunction)(domNode)}]`;
1434
+ nodeXpath1 = (0, exports.isAiSvg)(domNode)
1435
+ ? `*[local-name()='${domNode.tagName}' and ${(0, exports.getAiTextXpathFunction)(domNode)})]`
1436
+ : `${domNode.tagName}[${(0, exports.getAiTextXpathFunction)(domNode)}]`;
1420
1437
  if (nodeXpath1) {
1421
1438
  xpaths1.push({ key: "getReferenceElementsXpath", value: nodeXpath1 });
1422
1439
  }
1423
1440
  }
1424
1441
  else {
1425
- nodeXpath1 = (0, exports.isSvg)(domNode)
1426
- ? `*[local-name()='${domNode.tagName}' and .=${(0, exports.escapeCharacters)((0, exports.getTextContent)(domNode))}]`
1427
- : `${domNode.tagName}[.=${(0, exports.escapeCharacters)((0, exports.getTextContent)(domNode))}]`;
1442
+ nodeXpath1 = (0, exports.isAiSvg)(domNode)
1443
+ ? `*[local-name()='${domNode.tagName}' and .=${(0, exports.escapeAiCharacters)((0, exports.getAiTextContent)(domNode))}]`
1444
+ : `${domNode.tagName}[.=${(0, exports.escapeAiCharacters)((0, exports.getAiTextContent)(domNode))}]`;
1428
1445
  if (nodeXpath1) {
1429
1446
  xpaths1.push({ key: "getReferenceElementsXpath", value: nodeXpath1 });
1430
1447
  }
@@ -1432,20 +1449,20 @@ const getReferenceElementsXpath = (domNode, docmt, isTarget, platform) => {
1432
1449
  }
1433
1450
  if (domNode.attributes) {
1434
1451
  for (const attrName of Array.from(domNode.attributes)) {
1435
- if ((0, exports.checkBlockedAttributes)(attrName, domNode, isTarget)) {
1452
+ if ((0, exports.checkAiBlockedAttributes)(attrName, domNode, isTarget)) {
1436
1453
  let attrValue = attrName.nodeValue;
1437
1454
  if (attrValue) {
1438
- attrValue = (0, exports.sanitizeAttributeValue)(attrName.name, attrValue);
1455
+ attrValue = (0, exports.sanitizeAiAttributeValue)(attrName.name, attrValue);
1439
1456
  const elementName = attrName.name;
1440
1457
  if (elementName === "class") {
1441
- nodeXpath1 = (0, exports.isSvg)(domNode)
1442
- ? `*[local-name()='${domNode.tagName}' and contains(@${elementName},${(0, exports.escapeCharacters)(attrValue)})]`
1443
- : `${domNode.tagName}[contains(@${elementName},${(0, exports.escapeCharacters)(attrValue)})]`;
1458
+ nodeXpath1 = (0, exports.isAiSvg)(domNode)
1459
+ ? `*[local-name()='${domNode.tagName}' and contains(@${elementName},${(0, exports.escapeAiCharacters)(attrValue)})]`
1460
+ : `${domNode.tagName}[contains(@${elementName},${(0, exports.escapeAiCharacters)(attrValue)})]`;
1444
1461
  }
1445
1462
  else {
1446
- nodeXpath1 = (0, exports.isSvg)(domNode)
1447
- ? `*[local-name()='${domNode.tagName}' and @${elementName}=${(0, exports.escapeCharacters)(attrValue)}]`
1448
- : `${domNode.tagName}[@${elementName}=${(0, exports.escapeCharacters)(attrValue)}]`;
1463
+ nodeXpath1 = (0, exports.isAiSvg)(domNode)
1464
+ ? `*[local-name()='${domNode.tagName}' and @${elementName}=${(0, exports.escapeAiCharacters)(attrValue)}]`
1465
+ : `${domNode.tagName}[@${elementName}=${(0, exports.escapeAiCharacters)(attrValue)}]`;
1449
1466
  }
1450
1467
  if (nodeXpath1) {
1451
1468
  xpaths1.push({
@@ -1460,7 +1477,7 @@ const getReferenceElementsXpath = (domNode, docmt, isTarget, platform) => {
1460
1477
  if (!xpaths1?.length) {
1461
1478
  const attributesArray = Array.prototype.slice.call(domNode.attributes);
1462
1479
  if (attributesArray?.length > 1) {
1463
- const combinationXpath = (0, exports.getAttributeCombinationXpath)(domNode, docmt, Array.prototype.slice.call(domNode.attributes), isTarget, platform);
1480
+ const combinationXpath = (0, exports.getAiAttributeCombinationXpath)(domNode, docmt, Array.prototype.slice.call(domNode.attributes), isTarget, platform);
1464
1481
  if (combinationXpath) {
1465
1482
  xpaths1.push({
1466
1483
  key: "getReferenceElementsXpath",
@@ -1472,18 +1489,18 @@ const getReferenceElementsXpath = (domNode, docmt, isTarget, platform) => {
1472
1489
  if (!xpaths1?.length) {
1473
1490
  const combinePattern = [];
1474
1491
  let pattern;
1475
- const tag = (0, exports.isSvg)(domNode);
1476
- if (domNode.textContent && isTarget && (0, exports.isNumberExist)(domNode.textContent)) {
1492
+ const tag = (0, exports.isAiSvg)(domNode);
1493
+ if (domNode.textContent && isTarget && (0, exports.isAiNumberExist)(domNode.textContent)) {
1477
1494
  const contentRes = [...new Set(domNode.textContent.match(/([^0-9]+)/g))];
1478
1495
  if (contentRes?.length) {
1479
1496
  for (let i = 0; i < contentRes?.length; i++) {
1480
1497
  if (contentRes[i] &&
1481
- (0, exports.replaceWhiteSpaces)(contentRes[i].trim())?.length > 1) {
1498
+ (0, exports.aiReplaceWhiteSpaces)(contentRes[i].trim())?.length > 1) {
1482
1499
  if (!exports.reWhiteSpace.test(contentRes[i])) {
1483
- combinePattern.push(`contains(.,${(0, exports.escapeCharacters)((0, exports.replaceWhiteSpaces)(contentRes[i])).trim()})`);
1500
+ combinePattern.push(`contains(.,${(0, exports.escapeAiCharacters)((0, exports.aiReplaceWhiteSpaces)(contentRes[i])).trim()})`);
1484
1501
  }
1485
1502
  else {
1486
- combinePattern.push(`contains(.,${(0, exports.escapeCharacters)(contentRes[i]).trim()})`);
1503
+ combinePattern.push(`contains(.,${(0, exports.escapeAiCharacters)(contentRes[i]).trim()})`);
1487
1504
  }
1488
1505
  }
1489
1506
  }
@@ -1535,7 +1552,7 @@ exports.findMatchingParenthesis = findMatchingParenthesis;
1535
1552
  function escapeAttrValue(value) {
1536
1553
  return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/ /g, "\\ ");
1537
1554
  }
1538
- function isUniqueInDOM(docmt, name, value, element) {
1555
+ function isAiUniqueInDOM(docmt, name, value, element) {
1539
1556
  const root = element?.getRootNode?.() ?? docmt;
1540
1557
  const queryAll = (selector) => {
1541
1558
  try {
@@ -1571,77 +1588,41 @@ function isUniqueInDOM(docmt, name, value, element) {
1571
1588
  return false;
1572
1589
  }
1573
1590
  }
1574
- const getPlatformFallbackXpath = (element, platform) => {
1575
- const tag = element.tagName;
1576
- if (platform === "android") {
1577
- const bounds = element.getAttribute("bounds");
1578
- const index = element.getAttribute("index");
1579
- if (bounds) {
1580
- return index
1581
- ? `//${tag}[@index="${index}" and @bounds="${bounds}"]`
1582
- : `//${tag}[@bounds="${bounds}"]`;
1583
- }
1584
- }
1585
- if (platform === "ios") {
1586
- const name = element.getAttribute("name");
1587
- if (name) {
1588
- return `//${tag}[@name="${name}"]`;
1589
- }
1590
- const label = element.getAttribute("label");
1591
- if (label) {
1592
- return `//${tag}[@label="${label}"]`;
1593
- }
1594
- const value = element.getAttribute("value");
1595
- if (value) {
1596
- return `//${tag}[@value="${value}"]`;
1597
- }
1598
- const x = element.getAttribute("x");
1599
- const y = element.getAttribute("y");
1600
- const width = element.getAttribute("width");
1601
- const height = element.getAttribute("height");
1602
- if (x && y && width && height) {
1603
- return `//${tag}[@x="${x}" and @y="${y}" and @width="${width}" and @height="${height}"]`;
1604
- }
1605
- }
1606
- return null;
1607
- };
1608
- exports.getPlatformFallbackXpath = getPlatformFallbackXpath;
1609
1591
  exports.xpathUtils = {
1610
1592
  getReferenceElementsXpath: exports.getReferenceElementsXpath,
1611
- getAbsoluteXPath: exports.getAbsoluteXPath,
1612
- getRelativeXPath: exports.getRelativeXPath,
1613
- getCombinationXpath: exports.getCombinationXpath,
1614
- getAttributeCombinationXpath: exports.getAttributeCombinationXpath,
1615
- isSvg: exports.isSvg,
1616
- getPlatformFallbackXpath: exports.getPlatformFallbackXpath,
1617
- findXpathWithIndex: exports.findXpathWithIndex,
1618
- isNumberExist: exports.isNumberExist,
1619
- getTextContent: exports.getTextContent,
1620
- getCountOfXPath: exports.getCountOfXPath,
1593
+ getAiAbsoluteXPath: exports.getAiAbsoluteXPath,
1594
+ getAIRelativeXPath: exports.getAIRelativeXPath,
1595
+ getAiCombinationXpath: exports.getAiCombinationXpath,
1596
+ getAiAttributeCombinationXpath: exports.getAiAttributeCombinationXpath,
1597
+ isAiSvg: exports.isAiSvg,
1598
+ findAiXpathWithIndex: exports.findAiXpathWithIndex,
1599
+ isAiNumberExist: exports.isAiNumberExist,
1600
+ getAiTextContent: exports.getAiTextContent,
1601
+ getAiCountOfXPath: exports.getAiCountOfXPath,
1621
1602
  normalizeXPath: exports.normalizeXPath,
1622
- getShadowRoot: exports.getShadowRoot,
1623
- escapeCharacters: exports.escapeCharacters,
1624
- removeParenthesis: exports.removeParenthesis,
1625
- checkBlockedAttributes: exports.checkBlockedAttributes,
1626
- getRelationship: exports.getRelationship,
1603
+ getAiShadowRoot: exports.getAiShadowRoot,
1604
+ escapeAiCharacters: exports.escapeAiCharacters,
1605
+ removeAiParenthesis: exports.removeAiParenthesis,
1606
+ checkAiBlockedAttributes: exports.checkAiBlockedAttributes,
1607
+ getAiRelationship: exports.getAiRelationship,
1627
1608
  findMatchingParenthesis: exports.findMatchingParenthesis,
1628
- deleteGarbageFromInnerText,
1629
- replaceTempAttributes: exports.replaceTempAttributes,
1609
+ deleteAiGarbageFromInnerText,
1610
+ replaceAiTempAttributes: exports.replaceAiTempAttributes,
1630
1611
  // createObserver,
1631
1612
  // startObserver,
1632
1613
  // stopObserver,
1633
1614
  modifiedElementAttributes: exports.modifiedElementAttributes,
1634
1615
  cspEnabled: exports.cspEnabled,
1635
- getNormalizedPropertyXPath: exports.getNormalizedPropertyXPath,
1636
- getStartsWithPropertyXPath: exports.getStartsWithPropertyXPath,
1637
- getContainsPropertyXPath: exports.getContainsPropertyXPath,
1638
- getOrAttributesXPath: exports.getOrAttributesXPath,
1639
- getTagOnlyXPath: exports.getTagOnlyXPath,
1640
- getFirstMatchedNode: exports.getFirstMatchedNode,
1641
- isExactUniqueXpath: exports.isExactUniqueXpath,
1642
- getAxisNodeTest: exports.getAxisNodeTest,
1643
- getUniqueNodeAnchorXpaths: exports.getUniqueNodeAnchorXpaths,
1616
+ getAiNormalizedPropertyXPath: exports.getAiNormalizedPropertyXPath,
1617
+ getAiStartsWithPropertyXPath: exports.getAiStartsWithPropertyXPath,
1618
+ getAiContainsPropertyXPath: exports.getAiContainsPropertyXPath,
1619
+ getOrAttributesAiXPath: exports.getOrAttributesAiXPath,
1620
+ getAiTagOnlyXPath: exports.getAiTagOnlyXPath,
1621
+ getAiFirstMatchedNode: exports.getAiFirstMatchedNode,
1622
+ isAiExactUniqueXpath: exports.isAiExactUniqueXpath,
1623
+ getAiAxisNodeTest: exports.getAiAxisNodeTest,
1624
+ getAiUniqueNodeAnchorXpaths: exports.getAiUniqueNodeAnchorXpaths,
1644
1625
  escapeAttrValue,
1645
- isUniqueInDOM,
1646
- sanitizeAttributeValue: exports.sanitizeAttributeValue
1626
+ isAiUniqueInDOM,
1627
+ sanitizeAiAttributeValue: exports.sanitizeAiAttributeValue
1647
1628
  };