appium-desktop-driver 1.7.2-preview.1 → 1.7.2

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 (111) hide show
  1. package/README.md +2 -0
  2. package/build/eslint.config.d.mts +3 -0
  3. package/build/eslint.config.d.mts.map +1 -0
  4. package/build/eslint.config.mjs +22 -0
  5. package/build/eslint.config.mjs.map +1 -0
  6. package/build/lib/commands/actions.d.ts +3 -5
  7. package/build/lib/commands/actions.d.ts.map +1 -1
  8. package/build/lib/commands/actions.js +91 -83
  9. package/build/lib/commands/actions.js.map +1 -1
  10. package/build/lib/commands/app.d.ts +1 -53
  11. package/build/lib/commands/app.d.ts.map +1 -1
  12. package/build/lib/commands/app.js +147 -415
  13. package/build/lib/commands/app.js.map +1 -1
  14. package/build/lib/commands/device.d.ts +8 -0
  15. package/build/lib/commands/device.d.ts.map +1 -1
  16. package/build/lib/commands/device.js +229 -4
  17. package/build/lib/commands/device.js.map +1 -1
  18. package/build/lib/commands/element.d.ts +3 -0
  19. package/build/lib/commands/element.d.ts.map +1 -1
  20. package/build/lib/commands/element.js +53 -102
  21. package/build/lib/commands/element.js.map +1 -1
  22. package/build/lib/commands/extension.d.ts +0 -2
  23. package/build/lib/commands/extension.d.ts.map +1 -1
  24. package/build/lib/commands/extension.js +184 -111
  25. package/build/lib/commands/extension.js.map +1 -1
  26. package/build/lib/commands/index.d.ts +17 -28
  27. package/build/lib/commands/index.d.ts.map +1 -1
  28. package/build/lib/commands/index.js +2 -4
  29. package/build/lib/commands/index.js.map +1 -1
  30. package/build/lib/commands/powershell.d.ts +6 -0
  31. package/build/lib/commands/powershell.d.ts.map +1 -0
  32. package/build/lib/commands/powershell.js +202 -0
  33. package/build/lib/commands/powershell.js.map +1 -0
  34. package/build/lib/commands/screen-recorder.d.ts +3 -3
  35. package/build/lib/commands/screen-recorder.d.ts.map +1 -1
  36. package/build/lib/commands/screen-recorder.js +24 -33
  37. package/build/lib/commands/screen-recorder.js.map +1 -1
  38. package/build/lib/constraints.d.ts +7 -26
  39. package/build/lib/constraints.d.ts.map +1 -1
  40. package/build/lib/constraints.js +6 -25
  41. package/build/lib/constraints.js.map +1 -1
  42. package/build/lib/driver.d.ts +13 -22
  43. package/build/lib/driver.d.ts.map +1 -1
  44. package/build/lib/driver.js +49 -130
  45. package/build/lib/driver.js.map +1 -1
  46. package/build/lib/mcp/tools/index.d.ts.map +1 -1
  47. package/build/lib/mcp/tools/index.js +0 -2
  48. package/build/lib/mcp/tools/index.js.map +1 -1
  49. package/build/lib/powershell/conditions.d.ts.map +1 -1
  50. package/build/lib/powershell/conditions.js +0 -7
  51. package/build/lib/powershell/conditions.js.map +1 -1
  52. package/build/lib/util.d.ts +1 -11
  53. package/build/lib/util.d.ts.map +1 -1
  54. package/build/lib/util.js +7 -158
  55. package/build/lib/util.js.map +1 -1
  56. package/build/lib/winapi/user32.d.ts +6 -5
  57. package/build/lib/winapi/user32.d.ts.map +1 -1
  58. package/build/lib/winapi/user32.js +88 -131
  59. package/build/lib/winapi/user32.js.map +1 -1
  60. package/build/lib/xpath/core.d.ts +4 -10
  61. package/build/lib/xpath/core.d.ts.map +1 -1
  62. package/build/lib/xpath/core.js +224 -205
  63. package/build/lib/xpath/core.js.map +1 -1
  64. package/build/lib/xpath/functions.d.ts +2 -7
  65. package/build/lib/xpath/functions.d.ts.map +1 -1
  66. package/build/lib/xpath/functions.js +25 -49
  67. package/build/lib/xpath/functions.js.map +1 -1
  68. package/build/tsconfig.tsbuildinfo +1 -0
  69. package/package.json +12 -18
  70. package/CHANGELOG.md +0 -249
  71. package/build/lib/commands/contexts.d.ts +0 -64
  72. package/build/lib/commands/contexts.d.ts.map +0 -1
  73. package/build/lib/commands/contexts.js +0 -166
  74. package/build/lib/commands/contexts.js.map +0 -1
  75. package/build/lib/commands/server-session.d.ts +0 -9
  76. package/build/lib/commands/server-session.d.ts.map +0 -1
  77. package/build/lib/commands/server-session.js +0 -158
  78. package/build/lib/commands/server-session.js.map +0 -1
  79. package/build/lib/log-file.d.ts +0 -10
  80. package/build/lib/log-file.d.ts.map +0 -1
  81. package/build/lib/log-file.js +0 -86
  82. package/build/lib/log-file.js.map +0 -1
  83. package/build/lib/mcp/tools/context.d.ts +0 -4
  84. package/build/lib/mcp/tools/context.d.ts.map +0 -1
  85. package/build/lib/mcp/tools/context.js +0 -49
  86. package/build/lib/mcp/tools/context.js.map +0 -1
  87. package/build/lib/server/client.d.ts +0 -15
  88. package/build/lib/server/client.d.ts.map +0 -1
  89. package/build/lib/server/client.js +0 -169
  90. package/build/lib/server/client.js.map +0 -1
  91. package/build/lib/server/conditions.d.ts +0 -13
  92. package/build/lib/server/conditions.d.ts.map +0 -1
  93. package/build/lib/server/conditions.js +0 -71
  94. package/build/lib/server/conditions.js.map +0 -1
  95. package/build/lib/server/converter-bridge.d.ts +0 -26
  96. package/build/lib/server/converter-bridge.d.ts.map +0 -1
  97. package/build/lib/server/converter-bridge.js +0 -171
  98. package/build/lib/server/converter-bridge.js.map +0 -1
  99. package/build/lib/server/index.d.ts +0 -5
  100. package/build/lib/server/index.d.ts.map +0 -1
  101. package/build/lib/server/index.js +0 -25
  102. package/build/lib/server/index.js.map +0 -1
  103. package/build/lib/server/protocol.d.ts +0 -40
  104. package/build/lib/server/protocol.d.ts.map +0 -1
  105. package/build/lib/server/protocol.js +0 -3
  106. package/build/lib/server/protocol.js.map +0 -1
  107. package/build/lib/version.d.ts +0 -2
  108. package/build/lib/version.d.ts.map +0 -1
  109. package/build/lib/version.js +0 -20
  110. package/build/lib/version.js.map +0 -1
  111. package/scripts/postinstall.js +0 -39
@@ -39,45 +39,33 @@ exports.processExprNodeAsPredicate = processExprNodeAsPredicate;
39
39
  exports.predicateProcessableBeforeNode = predicateProcessableBeforeNode;
40
40
  const base_driver_1 = require("@appium/base-driver");
41
41
  const xpath_analyzer_1 = __importStar(require("xpath-analyzer"));
42
- const types_1 = require("../powershell/types");
43
- const converter_bridge_1 = require("../server/converter-bridge");
44
- const conditions_1 = require("../powershell/conditions");
45
- const common_1 = require("../powershell/common");
42
+ const powershell_1 = require("../powershell");
46
43
  const functions_1 = require("./functions");
47
44
  const OptimizeLastStep = Symbol.for('LastStep');
48
45
  const XPathAllowedProperties = Object.freeze([
49
- types_1.Property.ACCELERATOR_KEY,
50
- types_1.Property.ACCESS_KEY,
51
- types_1.Property.AUTOMATION_ID,
52
- types_1.Property.CLASS_NAME,
53
- types_1.Property.FRAMEWORK_ID,
54
- types_1.Property.HAS_KEYBOARD_FOCUS,
55
- types_1.Property.HELP_TEXT,
56
- types_1.Property.IS_CONTENT_ELEMENT,
57
- types_1.Property.IS_CONTROL_ELEMENT,
58
- types_1.Property.IS_ENABLED,
59
- types_1.Property.IS_KEYBOARD_FOCUSABLE,
60
- types_1.Property.IS_OFFSCREEN,
61
- types_1.Property.IS_PASSWORD,
62
- types_1.Property.IS_REQUIRED_FOR_FORM,
63
- types_1.Property.ITEM_STATUS,
64
- types_1.Property.ITEM_TYPE,
65
- types_1.Property.LOCALIZED_CONTROL_TYPE,
66
- types_1.Property.NAME,
67
- types_1.Property.ORIENTATION,
68
- types_1.Property.PROCESS_ID,
69
- types_1.Property.RUNTIME_ID,
46
+ powershell_1.Property.ACCELERATOR_KEY,
47
+ powershell_1.Property.ACCESS_KEY,
48
+ powershell_1.Property.AUTOMATION_ID,
49
+ powershell_1.Property.CLASS_NAME,
50
+ powershell_1.Property.FRAMEWORK_ID,
51
+ powershell_1.Property.HAS_KEYBOARD_FOCUS,
52
+ powershell_1.Property.HELP_TEXT,
53
+ powershell_1.Property.IS_CONTENT_ELEMENT,
54
+ powershell_1.Property.IS_CONTROL_ELEMENT,
55
+ powershell_1.Property.IS_ENABLED,
56
+ powershell_1.Property.IS_KEYBOARD_FOCUSABLE,
57
+ powershell_1.Property.IS_OFFSCREEN,
58
+ powershell_1.Property.IS_PASSWORD,
59
+ powershell_1.Property.IS_REQUIRED_FOR_FORM,
60
+ powershell_1.Property.ITEM_STATUS,
61
+ powershell_1.Property.ITEM_TYPE,
62
+ powershell_1.Property.LOCALIZED_CONTROL_TYPE,
63
+ powershell_1.Property.NAME,
64
+ powershell_1.Property.ORIENTATION,
65
+ powershell_1.Property.PROCESS_ID,
66
+ powershell_1.Property.RUNTIME_ID,
70
67
  ]);
71
- function rootElement() {
72
- return { type: 'root' };
73
- }
74
- function foundElement(elementId) {
75
- return { type: 'found', elementId };
76
- }
77
- function getContextElementId(el) {
78
- return el.type === 'found' && el.elementId ? el.elementId : null;
79
- }
80
- async function xpathToElIdOrIds(selector, mult, context, sendCommand) {
68
+ async function xpathToElIdOrIds(selector, mult, context, sendPowerShellCommand) {
81
69
  let parsedXPath;
82
70
  try {
83
71
  parsedXPath = new xpath_analyzer_1.default(selector).parse();
@@ -111,11 +99,8 @@ async function xpathToElIdOrIds(selector, mult, context, sendCommand) {
111
99
  if (parsedXPath.type === 'absolute-location-path' && parsedXPath.steps[0].axis === xpath_analyzer_1.CHILD) {
112
100
  parsedXPath.steps[0].axis = xpath_analyzer_1.SELF;
113
101
  }
114
- const contextEl = context ? foundElement(context) : rootElement();
115
- const foundElements = await processExprNode(parsedXPath, contextEl, sendCommand);
116
- const els = foundElements
117
- .filter((el) => typeof el === 'object' && el !== null && 'type' in el && el.type === 'found')
118
- .map((el) => ({ [base_driver_1.W3C_ELEMENT_KEY]: el.elementId ?? '' }));
102
+ const foundElements = await processExprNode(parsedXPath, context ? new powershell_1.FoundAutomationElement(context) : powershell_1.AutomationElement.automationRoot, sendPowerShellCommand);
103
+ const els = foundElements.filter((el) => el instanceof powershell_1.FoundAutomationElement).map((el) => ({ [base_driver_1.W3C_ELEMENT_KEY]: el.runtimeId }));
119
104
  if (mult) {
120
105
  return els;
121
106
  }
@@ -124,33 +109,33 @@ async function xpathToElIdOrIds(selector, mult, context, sendCommand) {
124
109
  }
125
110
  return els[0];
126
111
  }
127
- async function processExprNode(exprNode, context, sendCommand) {
112
+ async function processExprNode(exprNode, context, sendPowerShellCommand) {
128
113
  switch (exprNode.type) {
129
114
  case xpath_analyzer_1.NUMBER:
130
115
  return [exprNode.number];
131
116
  case xpath_analyzer_1.LITERAL:
132
117
  return [exprNode.string];
133
118
  case xpath_analyzer_1.UNION:
134
- return [...await processExprNode(exprNode.lhs, context, sendCommand), ...await processExprNode(exprNode.rhs, context, sendCommand)];
119
+ return [...await processExprNode(exprNode.lhs, context, sendPowerShellCommand), ...await processExprNode(exprNode.rhs, context, sendPowerShellCommand)];
135
120
  case xpath_analyzer_1.FUNCTION_CALL:
136
- return await (0, functions_1.handleFunctionCall)(exprNode.name, context, sendCommand, ...exprNode.args);
121
+ return await (0, functions_1.handleFunctionCall)(exprNode.name, context, sendPowerShellCommand, ...exprNode.args);
137
122
  case xpath_analyzer_1.ABSOLUTE_LOCATION_PATH:
138
123
  case xpath_analyzer_1.RELATIVE_LOCATION_PATH: {
139
124
  const result = [];
140
125
  for (const element of convertToElementArray(context)) {
141
- result.push(await handleLocationNode(exprNode, element, sendCommand));
126
+ result.push(await handleLocationNode(exprNode, element, sendPowerShellCommand));
142
127
  }
143
128
  return result.flat();
144
129
  }
145
130
  case xpath_analyzer_1.PATH: {
146
- const filterResult = await processExprNode(exprNode.filter, context, sendCommand);
131
+ const filterResult = await processExprNode(exprNode.filter, context, sendPowerShellCommand);
147
132
  const result = [];
148
133
  for (const item of filterResult) {
149
- if (isXPathElement(item)) {
134
+ if (item instanceof powershell_1.AutomationElement) {
150
135
  const itemAfterSteps = await handleLocationNode({
151
136
  type: xpath_analyzer_1.RELATIVE_LOCATION_PATH,
152
137
  steps: exprNode.steps,
153
- }, item, sendCommand);
138
+ }, item, sendPowerShellCommand);
154
139
  result.push(itemAfterSteps);
155
140
  }
156
141
  }
@@ -158,14 +143,17 @@ async function processExprNode(exprNode, context, sendCommand) {
158
143
  }
159
144
  case xpath_analyzer_1.FILTER: {
160
145
  const result = [];
161
- const exprResult = await processExprNode(exprNode.primary, context, sendCommand);
146
+ const exprResult = await processExprNode(exprNode.primary, context, sendPowerShellCommand);
162
147
  for (const item of exprResult) {
163
- if (isXPathElement(item)) {
148
+ if (item instanceof powershell_1.AutomationElement) {
164
149
  const filteredItem = await executeStep({
165
150
  axis: xpath_analyzer_1.SELF,
166
- test: { type: xpath_analyzer_1.NODE_TYPE_TEST, name: xpath_analyzer_1.NODE },
151
+ test: {
152
+ type: xpath_analyzer_1.NODE_TYPE_TEST,
153
+ name: xpath_analyzer_1.NODE,
154
+ },
167
155
  predicates: exprNode.predicates,
168
- }, item, sendCommand);
156
+ }, item, sendPowerShellCommand);
169
157
  result.push(filteredItem);
170
158
  }
171
159
  }
@@ -173,8 +161,8 @@ async function processExprNode(exprNode, context, sendCommand) {
173
161
  }
174
162
  case xpath_analyzer_1.OR:
175
163
  case xpath_analyzer_1.AND: {
176
- const [lhs] = await (0, functions_1.handleFunctionCall)(xpath_analyzer_1.BOOLEAN, context, sendCommand, exprNode.lhs);
177
- const [rhs] = await (0, functions_1.handleFunctionCall)(xpath_analyzer_1.BOOLEAN, context, sendCommand, exprNode.rhs);
164
+ const [lhs] = await (0, functions_1.handleFunctionCall)(xpath_analyzer_1.BOOLEAN, context, sendPowerShellCommand, exprNode.lhs);
165
+ const [rhs] = await (0, functions_1.handleFunctionCall)(xpath_analyzer_1.BOOLEAN, context, sendPowerShellCommand, exprNode.rhs);
178
166
  if (exprNode.type === xpath_analyzer_1.AND) {
179
167
  return [lhs && rhs];
180
168
  }
@@ -183,11 +171,11 @@ async function processExprNode(exprNode, context, sendCommand) {
183
171
  }
184
172
  }
185
173
  case xpath_analyzer_1.NEGATION:
186
- return [-await (0, functions_1.handleFunctionCall)(xpath_analyzer_1.NUMBER, context, sendCommand, exprNode.lhs)];
174
+ return [-await (0, functions_1.handleFunctionCall)(xpath_analyzer_1.NUMBER, context, sendPowerShellCommand, exprNode.lhs)];
187
175
  case xpath_analyzer_1.EQUALITY:
188
176
  case xpath_analyzer_1.INEQUALITY: {
189
- const [lhs] = await (0, functions_1.handleFunctionCall)(xpath_analyzer_1.STRING, context, sendCommand, exprNode.lhs);
190
- const [rhs] = await (0, functions_1.handleFunctionCall)(xpath_analyzer_1.STRING, context, sendCommand, exprNode.rhs);
177
+ const [lhs] = await (0, functions_1.handleFunctionCall)(xpath_analyzer_1.STRING, context, sendPowerShellCommand, exprNode.lhs);
178
+ const [rhs] = await (0, functions_1.handleFunctionCall)(xpath_analyzer_1.STRING, context, sendPowerShellCommand, exprNode.rhs);
191
179
  if (isNaN(Number(lhs)) || isNaN(Number(rhs))) {
192
180
  return [exprNode.type === xpath_analyzer_1.EQUALITY ? (lhs === rhs) : (lhs !== rhs)];
193
181
  }
@@ -201,74 +189,86 @@ async function processExprNode(exprNode, context, sendCommand) {
201
189
  case xpath_analyzer_1.LESS_THAN_OR_EQUAL:
202
190
  case xpath_analyzer_1.MODULUS:
203
191
  case xpath_analyzer_1.MULTIPLICATIVE:
204
- case xpath_analyzer_1.SUBTRACTIVE: {
205
- const [lhs] = await (0, functions_1.handleFunctionCall)(xpath_analyzer_1.NUMBER, context, sendCommand, exprNode.lhs);
206
- const [rhs] = await (0, functions_1.handleFunctionCall)(xpath_analyzer_1.NUMBER, context, sendCommand, exprNode.rhs);
207
- switch (exprNode.type) {
208
- case xpath_analyzer_1.ADDITIVE: return [(lhs + rhs)];
209
- case xpath_analyzer_1.DIVISIONAL: return [(lhs / rhs)];
210
- case xpath_analyzer_1.GREATER_THAN: return [(lhs > rhs)];
211
- case xpath_analyzer_1.GREATER_THAN_OR_EQUAL: return [(lhs >= rhs)];
212
- case xpath_analyzer_1.LESS_THAN: return [(lhs < rhs)];
213
- case xpath_analyzer_1.LESS_THAN_OR_EQUAL: return [(lhs <= rhs)];
214
- case xpath_analyzer_1.MODULUS: return [(lhs % rhs)];
215
- case xpath_analyzer_1.MULTIPLICATIVE: return [(lhs * rhs)];
216
- case xpath_analyzer_1.SUBTRACTIVE: return [(lhs - rhs)];
192
+ case xpath_analyzer_1.SUBTRACTIVE:
193
+ {
194
+ const [lhs] = await (0, functions_1.handleFunctionCall)(xpath_analyzer_1.NUMBER, context, sendPowerShellCommand, exprNode.lhs);
195
+ const [rhs] = await (0, functions_1.handleFunctionCall)(xpath_analyzer_1.NUMBER, context, sendPowerShellCommand, exprNode.rhs);
196
+ switch (exprNode.type) {
197
+ case xpath_analyzer_1.ADDITIVE:
198
+ return [(lhs + rhs)];
199
+ case xpath_analyzer_1.DIVISIONAL:
200
+ return [(lhs / rhs)];
201
+ case xpath_analyzer_1.GREATER_THAN:
202
+ return [(lhs > rhs)];
203
+ case xpath_analyzer_1.GREATER_THAN_OR_EQUAL:
204
+ return [(lhs >= rhs)];
205
+ case xpath_analyzer_1.LESS_THAN:
206
+ return [(lhs < rhs)];
207
+ case xpath_analyzer_1.LESS_THAN_OR_EQUAL:
208
+ return [(lhs <= rhs)];
209
+ case xpath_analyzer_1.MODULUS:
210
+ return [(lhs % rhs)];
211
+ case xpath_analyzer_1.MULTIPLICATIVE:
212
+ return [(lhs * rhs)];
213
+ case xpath_analyzer_1.SUBTRACTIVE:
214
+ return [(lhs - rhs)];
215
+ }
217
216
  }
218
- }
219
217
  }
220
218
  }
221
- async function handleLocationNode(location, context, sendCommand) {
219
+ async function handleLocationNode(location, context, sendPowerShellCommand) {
222
220
  if (location.steps.some((step) => step.test.name === null)) {
223
221
  throw new base_driver_1.errors.InvalidSelectorError('Expected path step expression.');
224
222
  }
225
223
  if (location.type === xpath_analyzer_1.ABSOLUTE_LOCATION_PATH) {
226
- context = rootElement();
224
+ context = powershell_1.AutomationElement.automationRoot;
225
+ }
226
+ if (context instanceof powershell_1.AutomationElementGroup && context.groups.length > 1) {
227
+ throw new base_driver_1.errors.InvalidArgumentError(`handleLocationNode expects single context, but received ${context.groups.length} contexts.`);
227
228
  }
228
229
  optimizeDoubleSlash(location.steps);
229
230
  for (const [index, step] of location.steps.entries()) {
230
231
  if (step.axis === xpath_analyzer_1.ATTRIBUTE) {
231
232
  if (index === location.steps.length - 1) {
232
- return await convertAttributeNodeTestToStringArray(step.test, context, sendCommand);
233
+ return await convertAttributeNodeTestToStringArray(step.test, context, sendPowerShellCommand);
233
234
  }
234
235
  else {
235
236
  return [];
236
237
  }
237
238
  }
238
- const result = await executeStep(step, context, sendCommand);
239
- if (Array.isArray(result)) {
240
- // Multi-element result - process remaining steps for each element
241
- if (index < location.steps.length - 1) {
242
- const combinedResults = [];
243
- for (const el of result) {
244
- const subResults = await handleLocationNode({
245
- type: xpath_analyzer_1.RELATIVE_LOCATION_PATH,
246
- steps: location.steps.slice(index + 1),
247
- }, el, sendCommand);
248
- combinedResults.push(...subResults);
249
- }
250
- return removeDuplicateElements(combinedResults);
239
+ if (context instanceof powershell_1.AutomationElementGroup) {
240
+ const results = [];
241
+ for (const el of context.groups) {
242
+ results.push(await executeStep(step, el, sendPowerShellCommand));
251
243
  }
252
- context = result[0] ?? rootElement();
253
- return removeDuplicateElements(result);
244
+ context = new powershell_1.AutomationElementGroup(...flattenElementGroupsAndRemoveDuplicates(results));
245
+ }
246
+ else {
247
+ context = await executeStep(step, context, sendPowerShellCommand);
254
248
  }
255
- context = result;
256
249
  }
257
250
  return convertToElementArray(context);
258
251
  }
259
- async function processExprNodeAsPredicate(exprNode, context, positions, sendCommand, relativeExprNodes) {
252
+ async function processExprNodeAsPredicate(exprNode, context, positions, sendPowerShellCommand, relativeExprNodes) {
260
253
  relativeExprNodes ??= [];
261
254
  switch (exprNode.type) {
262
255
  case xpath_analyzer_1.NUMBER:
263
256
  return await processExprNodeAsPredicate({
264
257
  type: xpath_analyzer_1.EQUALITY,
265
- lhs: { type: xpath_analyzer_1.FUNCTION_CALL, name: xpath_analyzer_1.POSITION, args: [] },
266
- rhs: { type: xpath_analyzer_1.NUMBER, number: exprNode.number }
267
- }, context, positions, sendCommand, relativeExprNodes);
258
+ lhs: {
259
+ type: xpath_analyzer_1.FUNCTION_CALL,
260
+ name: xpath_analyzer_1.POSITION,
261
+ args: [],
262
+ },
263
+ rhs: {
264
+ type: xpath_analyzer_1.NUMBER,
265
+ number: exprNode.number,
266
+ }
267
+ }, context, positions, sendPowerShellCommand, relativeExprNodes);
268
268
  case xpath_analyzer_1.OR:
269
- return [new conditions_1.OrCondition((await processExprNodeAsPredicate(exprNode.lhs, context, positions, sendCommand, relativeExprNodes))[0], (await processExprNodeAsPredicate(exprNode.rhs, context, positions, sendCommand, relativeExprNodes))[0]), relativeExprNodes];
269
+ return [new powershell_1.OrCondition((await processExprNodeAsPredicate(exprNode.lhs, context, positions, sendPowerShellCommand, relativeExprNodes))[0], (await processExprNodeAsPredicate(exprNode.rhs, context, positions, sendPowerShellCommand, relativeExprNodes))[0]), relativeExprNodes];
270
270
  case xpath_analyzer_1.AND:
271
- return [new conditions_1.AndCondition((await processExprNodeAsPredicate(exprNode.lhs, context, positions, sendCommand, relativeExprNodes))[0], (await processExprNodeAsPredicate(exprNode.rhs, context, positions, sendCommand, relativeExprNodes))[0]), relativeExprNodes];
271
+ return [new powershell_1.AndCondition((await processExprNodeAsPredicate(exprNode.lhs, context, positions, sendPowerShellCommand, relativeExprNodes))[0], (await processExprNodeAsPredicate(exprNode.rhs, context, positions, sendPowerShellCommand, relativeExprNodes))[0]), relativeExprNodes];
272
272
  case xpath_analyzer_1.EQUALITY:
273
273
  case xpath_analyzer_1.INEQUALITY: {
274
274
  if ((exprNode.lhs.type === xpath_analyzer_1.RELATIVE_LOCATION_PATH) !== (exprNode.rhs.type === xpath_analyzer_1.RELATIVE_LOCATION_PATH)) {
@@ -277,21 +277,21 @@ async function processExprNodeAsPredicate(exprNode, context, positions, sendComm
277
277
  && exprNode.lhs.steps[0].test.type === xpath_analyzer_1.NODE_NAME_TEST
278
278
  && XPathAllowedProperties.includes(exprNode.lhs.steps[0].test.name?.toLowerCase())) {
279
279
  const propertyName = exprNode.lhs.steps[0].test.name?.toLowerCase();
280
- const [value] = await processExprNode(exprNode.rhs, context, sendCommand);
281
- if (propertyName === types_1.Property.RUNTIME_ID) {
282
- return [new conditions_1.PropertyCondition(propertyName, new common_1.PSInt32Array(String(value).split('.').map(Number))), relativeExprNodes];
280
+ const [value] = await processExprNode(exprNode.rhs, context, sendPowerShellCommand);
281
+ if (propertyName === powershell_1.Property.RUNTIME_ID) {
282
+ return [new powershell_1.PropertyCondition(propertyName, new powershell_1.PSInt32Array(String(value).split('.').map(Number))), relativeExprNodes];
283
283
  }
284
- if (propertyName === types_1.Property.ORIENTATION) {
285
- return [new conditions_1.PropertyCondition(propertyName, new common_1.PSOrientationType(String(value))), relativeExprNodes];
284
+ if (propertyName === powershell_1.Property.ORIENTATION) {
285
+ return [new powershell_1.PropertyCondition(propertyName, new powershell_1.PSOrientationType(String(value))), relativeExprNodes];
286
286
  }
287
- if (Object.values(types_1.Int32Property).includes(propertyName)) {
288
- return [new conditions_1.PropertyCondition(propertyName, new common_1.PSInt32(Number(value))), relativeExprNodes];
287
+ if (Object.values(powershell_1.Int32Property).includes(propertyName)) {
288
+ return [new powershell_1.PropertyCondition(propertyName, new powershell_1.PSInt32(Number(value))), relativeExprNodes];
289
289
  }
290
- if (Object.values(types_1.StringProperty).includes(propertyName)) {
291
- return [new conditions_1.PropertyCondition(propertyName, new common_1.PSString(String(value))), relativeExprNodes];
290
+ if (Object.values(powershell_1.StringProperty).includes(propertyName)) {
291
+ return [new powershell_1.PropertyCondition(propertyName, new powershell_1.PSString(String(value))), relativeExprNodes];
292
292
  }
293
- if (Object.values(types_1.BooleanProperty).includes(propertyName)) {
294
- return [new conditions_1.PropertyCondition(propertyName, new common_1.PSBoolean(Boolean(value))), relativeExprNodes];
293
+ if (Object.values(powershell_1.BooleanProperty).includes(propertyName)) {
294
+ return [new powershell_1.PropertyCondition(propertyName, new powershell_1.PSBoolean(Boolean(value))), relativeExprNodes];
295
295
  }
296
296
  }
297
297
  if (exprNode.rhs.type === xpath_analyzer_1.RELATIVE_LOCATION_PATH
@@ -299,21 +299,21 @@ async function processExprNodeAsPredicate(exprNode, context, positions, sendComm
299
299
  && exprNode.rhs.steps[0].test.type === xpath_analyzer_1.NODE_NAME_TEST
300
300
  && XPathAllowedProperties.includes(exprNode.rhs.steps[0].test.name?.toLowerCase())) {
301
301
  const propertyName = exprNode.rhs.steps[0].test.name?.toLowerCase();
302
- const [value] = await processExprNode(exprNode.lhs, context, sendCommand);
303
- if (propertyName === types_1.Property.RUNTIME_ID) {
304
- return [new conditions_1.PropertyCondition(propertyName, new common_1.PSInt32Array(String(value).split('.').map(Number))), relativeExprNodes];
302
+ const [value] = await processExprNode(exprNode.lhs, context, sendPowerShellCommand);
303
+ if (propertyName === powershell_1.Property.RUNTIME_ID) {
304
+ return [new powershell_1.PropertyCondition(propertyName, new powershell_1.PSInt32Array(String(value).split('.').map(Number))), relativeExprNodes];
305
305
  }
306
- if (propertyName === types_1.Property.ORIENTATION) {
307
- return [new conditions_1.PropertyCondition(propertyName, new common_1.PSOrientationType(String(value))), relativeExprNodes];
306
+ if (propertyName === powershell_1.Property.ORIENTATION) {
307
+ return [new powershell_1.PropertyCondition(propertyName, new powershell_1.PSOrientationType(String(value))), relativeExprNodes];
308
308
  }
309
- if (Object.values(types_1.Int32Property).includes(propertyName)) {
310
- return [new conditions_1.PropertyCondition(propertyName, new common_1.PSInt32(Number(value))), relativeExprNodes];
309
+ if (Object.values(powershell_1.Int32Property).includes(propertyName)) {
310
+ return [new powershell_1.PropertyCondition(propertyName, new powershell_1.PSInt32(Number(value))), relativeExprNodes];
311
311
  }
312
- if (Object.values(types_1.StringProperty).includes(propertyName)) {
313
- return [new conditions_1.PropertyCondition(propertyName, new common_1.PSString(String(value))), relativeExprNodes];
312
+ if (Object.values(powershell_1.StringProperty).includes(propertyName)) {
313
+ return [new powershell_1.PropertyCondition(propertyName, new powershell_1.PSString(String(value))), relativeExprNodes];
314
314
  }
315
- if (Object.values(types_1.BooleanProperty).includes(propertyName)) {
316
- return [new conditions_1.PropertyCondition(propertyName, new common_1.PSBoolean(Boolean(value))), relativeExprNodes];
315
+ if (Object.values(powershell_1.BooleanProperty).includes(propertyName)) {
316
+ return [new powershell_1.PropertyCondition(propertyName, new powershell_1.PSBoolean(Boolean(value))), relativeExprNodes];
317
317
  }
318
318
  }
319
319
  }
@@ -323,149 +323,159 @@ async function processExprNodeAsPredicate(exprNode, context, positions, sendComm
323
323
  positions.add(0x7FFFFFFF);
324
324
  }
325
325
  else {
326
- const [value] = await processExprNode(exprNode.rhs, context, sendCommand);
326
+ const [value] = await processExprNode(exprNode.rhs, context, sendPowerShellCommand);
327
327
  if (typeof value !== 'number') {
328
- return [new conditions_1.FalseCondition()];
328
+ return [new powershell_1.FalseCondition()];
329
329
  }
330
330
  positions.add(value);
331
331
  }
332
- return [new conditions_1.TrueCondition()];
332
+ return [new powershell_1.TrueCondition];
333
333
  }
334
334
  if (exprNode.rhs.type === xpath_analyzer_1.FUNCTION_CALL && exprNode.rhs.name === xpath_analyzer_1.POSITION) {
335
335
  if (exprNode.lhs.type === xpath_analyzer_1.FUNCTION_CALL && exprNode.lhs.name === xpath_analyzer_1.LAST) {
336
336
  positions.add(0x7FFFFFFF);
337
337
  }
338
338
  else {
339
- const [value] = await processExprNode(exprNode.lhs, context, sendCommand);
339
+ const [value] = await processExprNode(exprNode.lhs, context, sendPowerShellCommand);
340
340
  if (typeof value !== 'number') {
341
- return [new conditions_1.FalseCondition()];
341
+ return [new powershell_1.FalseCondition()];
342
342
  }
343
343
  positions.add(value);
344
344
  }
345
- return [new conditions_1.TrueCondition()];
345
+ return [new powershell_1.TrueCondition];
346
346
  }
347
347
  }
348
348
  }
349
349
  // eslint-disable-next-line no-fallthrough
350
350
  default: {
351
- const result = await processExprNode(exprNode, context, sendCommand);
351
+ const result = await processExprNode(exprNode, context, sendPowerShellCommand);
352
352
  if (result.length === 1 && typeof result[0] === 'number' && !isNaN(result[0])) {
353
353
  return await processExprNodeAsPredicate({
354
354
  type: xpath_analyzer_1.EQUALITY,
355
- lhs: { type: xpath_analyzer_1.FUNCTION_CALL, name: xpath_analyzer_1.POSITION, args: [] },
356
- rhs: { type: xpath_analyzer_1.NUMBER, number: result[0] }
357
- }, context, positions, sendCommand, relativeExprNodes);
355
+ lhs: {
356
+ type: xpath_analyzer_1.FUNCTION_CALL,
357
+ name: xpath_analyzer_1.POSITION,
358
+ args: [],
359
+ },
360
+ rhs: {
361
+ type: xpath_analyzer_1.NUMBER,
362
+ number: result[0],
363
+ }
364
+ }, context, positions, sendPowerShellCommand, relativeExprNodes);
358
365
  }
359
366
  relativeExprNodes.push(exprNode);
360
- return [new conditions_1.TrueCondition(), relativeExprNodes];
367
+ return [new powershell_1.TrueCondition(), relativeExprNodes];
361
368
  }
362
369
  }
363
370
  }
364
- const SCOPE_MAP = new Map([
365
- [xpath_analyzer_1.ANCESTOR, 'ancestors'],
366
- [xpath_analyzer_1.ANCESTOR_OR_SELF, 'ancestors-or-self'],
367
- [xpath_analyzer_1.CHILD, 'children'],
368
- [xpath_analyzer_1.DESCENDANT, 'descendants'],
369
- [xpath_analyzer_1.DESCENDANT_OR_SELF, 'subtree'],
370
- [xpath_analyzer_1.FOLLOWING, 'following'],
371
- [xpath_analyzer_1.FOLLOWING_SIBLING, 'following-sibling'],
372
- [xpath_analyzer_1.PARENT, 'parent'],
373
- [xpath_analyzer_1.PRECEDING, 'preceding'],
374
- [xpath_analyzer_1.PRECEDING_SIBLING, 'preceding-sibling'],
375
- [xpath_analyzer_1.SELF, 'element'],
376
- ]);
377
- async function executeStep(step, context, sendCommand) {
371
+ async function executeStep(step, context, sendPowerShellCommand) {
378
372
  const predicateConditions = [];
379
373
  const relativeExprNodes = [];
380
374
  const positions = new Set();
381
375
  for (const predicate of step.predicates) {
382
- const [condition, exprNodes] = await processExprNodeAsPredicate(predicate, context, positions, sendCommand);
376
+ const [condition, exprNodes] = await processExprNodeAsPredicate(predicate, context, positions, sendPowerShellCommand);
383
377
  predicateConditions.push(condition);
384
378
  if (exprNodes) {
385
379
  relativeExprNodes.push(...exprNodes);
386
380
  }
387
381
  }
388
- const nodeTestCondition = convertNodeTestToCondition(step.test);
389
- const condition = predicateConditions.length > 0
390
- ? new conditions_1.AndCondition(nodeTestCondition, ...predicateConditions)
391
- : nodeTestCondition;
392
- if (step.axis === xpath_analyzer_1.NAMESPACE) {
393
- return [];
394
- }
395
- const scope = SCOPE_MAP.get(step.axis);
396
- if (!scope) {
397
- throw new base_driver_1.errors.InvalidArgumentError(`Unsupported axis: ${step.axis}`);
398
- }
399
- const conditionDto = (0, converter_bridge_1.conditionToDto)(condition);
400
- const contextElementId = getContextElementId(context);
401
- let elIds;
402
- if (step[OptimizeLastStep]) {
403
- const result = await sendCommand('findElement', { scope, condition: conditionDto, contextElementId });
404
- elIds = result ? [result] : [];
405
- }
406
- else {
407
- elIds = await sendCommand('findElements', { scope, condition: conditionDto, contextElementId }) ?? [];
382
+ const condition = predicateConditions.length > 0 ? new powershell_1.AndCondition(convertNodeTestToCondition(step.test), ...predicateConditions) : convertNodeTestToCondition(step.test);
383
+ let find;
384
+ switch (step.axis) {
385
+ case xpath_analyzer_1.ANCESTOR:
386
+ find = step[OptimizeLastStep] ? context.findFirst(powershell_1.TreeScope.ANCESTORS, condition) : context.findAll(powershell_1.TreeScope.ANCESTORS, condition);
387
+ break;
388
+ case xpath_analyzer_1.ANCESTOR_OR_SELF:
389
+ find = step[OptimizeLastStep] ? context.findFirst(powershell_1.TreeScope.ANCESTORS_OR_SELF, condition) : context.findAll(powershell_1.TreeScope.ANCESTORS_OR_SELF, condition);
390
+ break;
391
+ case xpath_analyzer_1.CHILD:
392
+ find = step[OptimizeLastStep] ? context.findFirst(powershell_1.TreeScope.CHILDREN, condition) : context.findAll(powershell_1.TreeScope.CHILDREN, condition);
393
+ break;
394
+ case xpath_analyzer_1.DESCENDANT:
395
+ find = step[OptimizeLastStep] ? context.findFirst(powershell_1.TreeScope.DESCENDANTS, condition) : context.findAll(powershell_1.TreeScope.DESCENDANTS, condition);
396
+ break;
397
+ case xpath_analyzer_1.DESCENDANT_OR_SELF:
398
+ find = step[OptimizeLastStep] ? context.findFirst(powershell_1.TreeScope.SUBTREE, condition) : context.findAll(powershell_1.TreeScope.SUBTREE, condition);
399
+ break;
400
+ case xpath_analyzer_1.FOLLOWING:
401
+ find = step[OptimizeLastStep] ? context.findFirst(powershell_1.TreeScope.FOLLOWING, condition) : context.findAll(powershell_1.TreeScope.FOLLOWING, condition);
402
+ break;
403
+ case xpath_analyzer_1.FOLLOWING_SIBLING:
404
+ find = step[OptimizeLastStep] ? context.findFirst(powershell_1.TreeScope.FOLLOWING_SIBLING, condition) : context.findAll(powershell_1.TreeScope.FOLLOWING_SIBLING, condition);
405
+ break;
406
+ case xpath_analyzer_1.NAMESPACE:
407
+ return new powershell_1.AutomationElementGroup( /* empty */);
408
+ case xpath_analyzer_1.PARENT:
409
+ find = step[OptimizeLastStep] ? context.findFirst(powershell_1.TreeScope.PARENT, condition) : context.findAll(powershell_1.TreeScope.PARENT, condition);
410
+ break;
411
+ case xpath_analyzer_1.PRECEDING:
412
+ find = step[OptimizeLastStep] ? context.findFirst(powershell_1.TreeScope.PRECEDING, condition) : context.findAll(powershell_1.TreeScope.PRECEDING, condition);
413
+ break;
414
+ case xpath_analyzer_1.PRECEDING_SIBLING:
415
+ find = step[OptimizeLastStep] ? context.findFirst(powershell_1.TreeScope.PRECEDING_SIBLING, condition) : context.findAll(powershell_1.TreeScope.PRECEDING_SIBLING, condition);
416
+ break;
417
+ case xpath_analyzer_1.SELF:
418
+ find = step[OptimizeLastStep] ? context.findFirst(powershell_1.TreeScope.ELEMENT, condition) : context.findAll(powershell_1.TreeScope.ELEMENT, condition);
419
+ break;
420
+ default:
421
+ throw new base_driver_1.errors.InvalidArgumentError(); // should not be reached, attribute is handled before that
408
422
  }
423
+ const result = await sendPowerShellCommand(find.buildCommand());
424
+ const els = result.split('\n').map((id) => id.trim()).filter(Boolean).map((id) => new powershell_1.FoundAutomationElement(id));
409
425
  const validEls = [];
410
- for (const elId of elIds) {
426
+ for (const el of els) {
411
427
  let isValid = true;
412
428
  for (const exprNode of relativeExprNodes) {
413
- const el = foundElement(elId);
414
- const [isTrue] = await (0, functions_1.handleFunctionCall)(xpath_analyzer_1.BOOLEAN, el, sendCommand, exprNode);
429
+ const [isTrue] = await (0, functions_1.handleFunctionCall)(xpath_analyzer_1.BOOLEAN, el, sendPowerShellCommand, exprNode);
415
430
  if (!isTrue) {
416
431
  isValid = false;
417
432
  break;
418
433
  }
419
434
  }
420
435
  if (isValid) {
421
- validEls.push(foundElement(elId));
436
+ validEls.push(el);
422
437
  }
423
438
  }
424
439
  const positionsArray = Array.from(positions);
425
440
  if (positionsArray.length === 0) {
426
- return validEls;
441
+ return new powershell_1.AutomationElementGroup(...validEls);
427
442
  }
428
443
  else {
429
- return positionsArray
430
- .map((index) => index === 0x7FFFFFFF ? validEls[validEls.length - 1] : validEls[index - 1])
431
- .filter(Boolean);
444
+ return new powershell_1.AutomationElementGroup(...positionsArray.map((index) => index === 0x7FFFFFFF ? validEls[validEls.length - 1] : validEls[index - 1]).filter(Boolean));
432
445
  }
433
446
  }
434
447
  function convertNodeTestToCondition(nodeTest) {
435
448
  switch (nodeTest.type) {
436
449
  case xpath_analyzer_1.NODE_NAME_TEST:
437
450
  if (nodeTest.name === '*') {
438
- return new conditions_1.TrueCondition();
451
+ return new powershell_1.TrueCondition();
439
452
  }
453
+ // workaround for ControlType 50039 and 50040 not supported in UIAutomationClient
440
454
  if (nodeTest.name.toLowerCase() === 'appbar' || nodeTest.name.toLowerCase() === 'semanticzoom') {
441
- return new conditions_1.PropertyCondition(types_1.Property.LOCALIZED_CONTROL_TYPE, new common_1.PSString(new common_1.PSControlType(nodeTest.name).toString()));
455
+ // PSControlType already has a logic to correct the value to localized control type
456
+ return new powershell_1.PropertyCondition(powershell_1.Property.LOCALIZED_CONTROL_TYPE, new powershell_1.PSString(new powershell_1.PSControlType(nodeTest.name).toString()));
442
457
  }
443
- return new conditions_1.PropertyCondition(types_1.Property.CONTROL_TYPE, new common_1.PSControlType(nodeTest.name));
458
+ return new powershell_1.PropertyCondition(powershell_1.Property.CONTROL_TYPE, new powershell_1.PSControlType(nodeTest.name));
444
459
  case xpath_analyzer_1.NODE_TYPE_TEST:
445
460
  if (nodeTest.name === xpath_analyzer_1.NODE) {
446
- return new conditions_1.TrueCondition();
461
+ return new powershell_1.TrueCondition();
447
462
  }
448
463
  // eslint-disable-next-line no-fallthrough
449
464
  case xpath_analyzer_1.PROCESSING_INSTRUCTION_TEST:
450
- return new conditions_1.FalseCondition();
465
+ return new powershell_1.FalseCondition();
451
466
  }
452
467
  }
453
- async function convertAttributeNodeTestToStringArray(nodeTest, context, sendCommand) {
454
- const contextId = getContextElementId(context);
455
- // Get the runtime IDs for the context element(s)
456
- const runtimeId = await sendCommand('getProperty', {
457
- elementId: contextId ?? await sendCommand('saveRootElementToTable', {}),
458
- property: 'RuntimeId',
459
- });
460
- const elIds = runtimeId.split('\n').map((id) => id.trim()).filter(Boolean);
468
+ async function convertAttributeNodeTestToStringArray(nodeTest, context, sendPowerShellCommand) {
469
+ const result = await sendPowerShellCommand(context.buildGetPropertyCommand(powershell_1.Property.RUNTIME_ID));
470
+ const els = result.split('\n').map((id) => id.trim()).filter(Boolean).map((id) => new powershell_1.FoundAutomationElement(id.trim()));
461
471
  const extraProperties = ['x', 'y', 'width', 'height'];
462
472
  switch (nodeTest.type) {
463
473
  case xpath_analyzer_1.NODE_TYPE_TEST:
464
474
  if (nodeTest.name === xpath_analyzer_1.NODE) {
465
475
  const results = [];
466
- for (const name of Object.values(types_1.Property)) {
467
- for (const elId of elIds) {
468
- results.push(await sendCommand('getProperty', { elementId: elId, property: name }));
476
+ for (const name of Object.values(powershell_1.Property)) {
477
+ for (const el of els) {
478
+ results.push(await sendPowerShellCommand(el.buildGetPropertyCommand(name)));
469
479
  }
470
480
  }
471
481
  return results;
@@ -474,16 +484,16 @@ async function convertAttributeNodeTestToStringArray(nodeTest, context, sendComm
474
484
  case xpath_analyzer_1.NODE_NAME_TEST:
475
485
  if (extraProperties.includes(nodeTest.name.toLowerCase())) {
476
486
  const results = [];
477
- for (const elId of elIds) {
478
- const rect = await sendCommand('getRect', { elementId: elId });
479
- results.push(String(rect[nodeTest.name.toLowerCase()]));
487
+ for (const el of els) {
488
+ const rectJson = await sendPowerShellCommand(el.buildGetElementRectCommand());
489
+ results.push(JSON.parse(rectJson.replaceAll(/(?:infinity)/gi, 0x7FFFFFFF.toString()))[nodeTest.name.toLowerCase()]);
480
490
  }
481
491
  return results;
482
492
  }
483
- if (Object.values(types_1.Property).includes(nodeTest.name.toLowerCase())) {
493
+ if (Object.values(powershell_1.Property).includes(nodeTest.name.toLowerCase())) {
484
494
  const results = [];
485
- for (const elId of elIds) {
486
- results.push(await sendCommand('getProperty', { elementId: elId, property: nodeTest.name }));
495
+ for (const el of els) {
496
+ results.push(await sendPowerShellCommand(el.buildGetPropertyCommand(nodeTest.name)));
487
497
  }
488
498
  return results;
489
499
  }
@@ -493,26 +503,33 @@ async function convertAttributeNodeTestToStringArray(nodeTest, context, sendComm
493
503
  return [];
494
504
  }
495
505
  }
496
- function isXPathElement(value) {
497
- return typeof value === 'object' && value !== null && 'type' in value && (value.type === 'root' || value.type === 'found');
498
- }
499
506
  function convertToElementArray(element) {
507
+ if (element instanceof powershell_1.AutomationElementGroup) {
508
+ return flattenElementGroupsAndRemoveDuplicates(element.groups);
509
+ }
500
510
  return [element];
501
511
  }
502
- function removeDuplicateElements(elements) {
512
+ function flattenElementGroupsAndRemoveDuplicates(elements) {
503
513
  const seen = new Set();
504
- return elements.filter((el) => {
505
- if (el.type === 'found' && el.elementId) {
506
- if (seen.has(el.elementId)) {
507
- return false;
514
+ return elements.reduce((acc, el) => {
515
+ if (el instanceof powershell_1.AutomationElementGroup) {
516
+ return acc.concat(flattenElementGroupsAndRemoveDuplicates(el.groups));
517
+ }
518
+ else {
519
+ if (el instanceof powershell_1.FoundAutomationElement && seen.has(el.runtimeId)) {
520
+ return acc;
521
+ }
522
+ if (el instanceof powershell_1.FoundAutomationElement) {
523
+ seen.add(el.runtimeId);
508
524
  }
509
- seen.add(el.elementId);
525
+ acc.push(el);
526
+ return acc;
510
527
  }
511
- return true;
512
- });
528
+ }, []);
513
529
  }
514
530
  function optimizeDoubleSlash(steps) {
515
531
  for (let i = 0; i < steps.length - 1; i++) {
532
+ // detect double slash: //element is the same as /descendant-or-self::node()/child::element
516
533
  if (steps[i].axis === xpath_analyzer_1.DESCENDANT_OR_SELF && steps[i].test.type === xpath_analyzer_1.NODE_TYPE_TEST && steps[i].predicates.length === 0 && steps[i + 1].axis === xpath_analyzer_1.CHILD) {
517
534
  const optimizedStep = { axis: xpath_analyzer_1.DESCENDANT, test: steps[i + 1].test, predicates: steps[i + 1].predicates };
518
535
  if (steps[i + 1][OptimizeLastStep]) {
@@ -522,6 +539,7 @@ function optimizeDoubleSlash(steps) {
522
539
  if (steps[i].predicates.some((predicate) => predicate.type === xpath_analyzer_1.FUNCTION_CALL && (predicate.name === xpath_analyzer_1.LAST || predicate.name === xpath_analyzer_1.POSITION))) {
523
540
  stepsToAdd.push({ axis: xpath_analyzer_1.PARENT, test: { type: xpath_analyzer_1.NODE_TYPE_TEST, name: 'node' }, predicates: [] }, steps[i + 1]);
524
541
  }
542
+ // mutates the original array by reference
525
543
  steps.splice(i, 2, ...stepsToAdd);
526
544
  }
527
545
  }
@@ -567,8 +585,9 @@ function predicateProcessableBeforeNode(exprNode) {
567
585
  }
568
586
  }
569
587
  // eslint-disable-next-line no-fallthrough
570
- default:
588
+ default: {
571
589
  return false;
590
+ }
572
591
  }
573
592
  }
574
593
  //# sourceMappingURL=core.js.map