@limrun/appium-xcuitest-driver 10.11.0-lim.4 → 10.14.6-lim.1

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 (279) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/build/lib/commands/active-app-info.d.ts +4 -3
  3. package/build/lib/commands/active-app-info.d.ts.map +1 -1
  4. package/build/lib/commands/active-app-info.js +2 -3
  5. package/build/lib/commands/active-app-info.js.map +1 -1
  6. package/build/lib/commands/alert.d.ts +26 -31
  7. package/build/lib/commands/alert.d.ts.map +1 -1
  8. package/build/lib/commands/alert.js +20 -29
  9. package/build/lib/commands/alert.js.map +1 -1
  10. package/build/lib/commands/app-management.d.ts +99 -76
  11. package/build/lib/commands/app-management.d.ts.map +1 -1
  12. package/build/lib/commands/app-management.js +83 -73
  13. package/build/lib/commands/app-management.js.map +1 -1
  14. package/build/lib/commands/app-strings.d.ts +6 -7
  15. package/build/lib/commands/app-strings.d.ts.map +1 -1
  16. package/build/lib/commands/app-strings.js +3 -8
  17. package/build/lib/commands/app-strings.js.map +1 -1
  18. package/build/lib/commands/appearance.d.ts +7 -9
  19. package/build/lib/commands/appearance.d.ts.map +1 -1
  20. package/build/lib/commands/appearance.js +13 -19
  21. package/build/lib/commands/appearance.js.map +1 -1
  22. package/build/lib/commands/audit.d.ts +5 -33
  23. package/build/lib/commands/audit.d.ts.map +1 -1
  24. package/build/lib/commands/audit.js +3 -16
  25. package/build/lib/commands/audit.js.map +1 -1
  26. package/build/lib/commands/battery.d.ts +4 -4
  27. package/build/lib/commands/battery.d.ts.map +1 -1
  28. package/build/lib/commands/battery.js +3 -7
  29. package/build/lib/commands/battery.js.map +1 -1
  30. package/build/lib/commands/biometric.d.ts +12 -14
  31. package/build/lib/commands/biometric.d.ts.map +1 -1
  32. package/build/lib/commands/biometric.js +10 -19
  33. package/build/lib/commands/biometric.js.map +1 -1
  34. package/build/lib/commands/certificate.d.ts +14 -19
  35. package/build/lib/commands/certificate.d.ts.map +1 -1
  36. package/build/lib/commands/certificate.js +24 -31
  37. package/build/lib/commands/certificate.js.map +1 -1
  38. package/build/lib/commands/clipboard.d.ts +9 -11
  39. package/build/lib/commands/clipboard.d.ts.map +1 -1
  40. package/build/lib/commands/clipboard.js +8 -13
  41. package/build/lib/commands/clipboard.js.map +1 -1
  42. package/build/lib/commands/condition.d.ts +9 -72
  43. package/build/lib/commands/condition.d.ts.map +1 -1
  44. package/build/lib/commands/condition.js +5 -66
  45. package/build/lib/commands/condition.js.map +1 -1
  46. package/build/lib/commands/content-size.d.ts +16 -19
  47. package/build/lib/commands/content-size.d.ts.map +1 -1
  48. package/build/lib/commands/content-size.js +14 -22
  49. package/build/lib/commands/content-size.js.map +1 -1
  50. package/build/lib/commands/context.d.ts +130 -161
  51. package/build/lib/commands/context.d.ts.map +1 -1
  52. package/build/lib/commands/context.js +123 -108
  53. package/build/lib/commands/context.js.map +1 -1
  54. package/build/lib/commands/device-info.d.ts +13 -0
  55. package/build/lib/commands/device-info.d.ts.map +1 -0
  56. package/build/lib/commands/device-info.js +20 -0
  57. package/build/lib/commands/device-info.js.map +1 -0
  58. package/build/lib/commands/element.d.ts +83 -67
  59. package/build/lib/commands/element.d.ts.map +1 -1
  60. package/build/lib/commands/element.js +111 -134
  61. package/build/lib/commands/element.js.map +1 -1
  62. package/build/lib/commands/execute.d.ts +10 -22
  63. package/build/lib/commands/execute.d.ts.map +1 -1
  64. package/build/lib/commands/execute.js +13 -29
  65. package/build/lib/commands/execute.js.map +1 -1
  66. package/build/lib/commands/file-movement.d.ts +31 -42
  67. package/build/lib/commands/file-movement.d.ts.map +1 -1
  68. package/build/lib/commands/file-movement.js +146 -205
  69. package/build/lib/commands/file-movement.js.map +1 -1
  70. package/build/lib/commands/find.d.ts +20 -12
  71. package/build/lib/commands/find.d.ts.map +1 -1
  72. package/build/lib/commands/find.js +27 -65
  73. package/build/lib/commands/find.js.map +1 -1
  74. package/build/lib/commands/general.d.ts +84 -80
  75. package/build/lib/commands/general.d.ts.map +1 -1
  76. package/build/lib/commands/general.js +67 -54
  77. package/build/lib/commands/general.js.map +1 -1
  78. package/build/lib/commands/geolocation.d.ts +16 -36
  79. package/build/lib/commands/geolocation.d.ts.map +1 -1
  80. package/build/lib/commands/geolocation.js +8 -25
  81. package/build/lib/commands/geolocation.js.map +1 -1
  82. package/build/lib/commands/gesture.d.ts +103 -119
  83. package/build/lib/commands/gesture.d.ts.map +1 -1
  84. package/build/lib/commands/gesture.js +98 -138
  85. package/build/lib/commands/gesture.js.map +1 -1
  86. package/build/lib/commands/increase-contrast.d.ts +10 -13
  87. package/build/lib/commands/increase-contrast.d.ts.map +1 -1
  88. package/build/lib/commands/increase-contrast.js +8 -16
  89. package/build/lib/commands/increase-contrast.js.map +1 -1
  90. package/build/lib/commands/iohid.d.ts +6 -1359
  91. package/build/lib/commands/iohid.d.ts.map +1 -1
  92. package/build/lib/commands/iohid.js +5 -10
  93. package/build/lib/commands/iohid.js.map +1 -1
  94. package/build/lib/commands/keyboard.d.ts +16 -13
  95. package/build/lib/commands/keyboard.d.ts.map +1 -1
  96. package/build/lib/commands/keyboard.js +14 -18
  97. package/build/lib/commands/keyboard.js.map +1 -1
  98. package/build/lib/commands/keychains.d.ts +2 -2
  99. package/build/lib/commands/keychains.d.ts.map +1 -1
  100. package/build/lib/commands/keychains.js +1 -4
  101. package/build/lib/commands/keychains.js.map +1 -1
  102. package/build/lib/commands/localization.d.ts +7 -6
  103. package/build/lib/commands/localization.d.ts.map +1 -1
  104. package/build/lib/commands/localization.js +7 -8
  105. package/build/lib/commands/localization.js.map +1 -1
  106. package/build/lib/commands/location.d.ts +8 -11
  107. package/build/lib/commands/location.d.ts.map +1 -1
  108. package/build/lib/commands/location.js +7 -15
  109. package/build/lib/commands/location.js.map +1 -1
  110. package/build/lib/commands/lock.d.ts +6 -10
  111. package/build/lib/commands/lock.d.ts.map +1 -1
  112. package/build/lib/commands/lock.js +3 -10
  113. package/build/lib/commands/lock.js.map +1 -1
  114. package/build/lib/commands/log.d.ts +42 -44
  115. package/build/lib/commands/log.d.ts.map +1 -1
  116. package/build/lib/commands/log.js +32 -53
  117. package/build/lib/commands/log.js.map +1 -1
  118. package/build/lib/commands/memory.d.ts +4 -5
  119. package/build/lib/commands/memory.d.ts.map +1 -1
  120. package/build/lib/commands/memory.js +3 -8
  121. package/build/lib/commands/memory.js.map +1 -1
  122. package/build/lib/commands/navigation.d.ts +14 -26
  123. package/build/lib/commands/navigation.d.ts.map +1 -1
  124. package/build/lib/commands/navigation.js +22 -32
  125. package/build/lib/commands/navigation.js.map +1 -1
  126. package/build/lib/commands/notifications.d.ts +10 -10
  127. package/build/lib/commands/notifications.d.ts.map +1 -1
  128. package/build/lib/commands/notifications.js +8 -12
  129. package/build/lib/commands/notifications.js.map +1 -1
  130. package/build/lib/commands/pasteboard.d.ts +9 -10
  131. package/build/lib/commands/pasteboard.d.ts.map +1 -1
  132. package/build/lib/commands/pasteboard.js +8 -13
  133. package/build/lib/commands/pasteboard.js.map +1 -1
  134. package/build/lib/commands/pcap.d.ts +18 -38
  135. package/build/lib/commands/pcap.d.ts.map +1 -1
  136. package/build/lib/commands/pcap.js +9 -14
  137. package/build/lib/commands/pcap.js.map +1 -1
  138. package/build/lib/commands/performance.d.ts +36 -55
  139. package/build/lib/commands/performance.d.ts.map +1 -1
  140. package/build/lib/commands/performance.js +93 -86
  141. package/build/lib/commands/performance.js.map +1 -1
  142. package/build/lib/commands/permissions.d.ts +15 -17
  143. package/build/lib/commands/permissions.d.ts.map +1 -1
  144. package/build/lib/commands/permissions.js +12 -18
  145. package/build/lib/commands/permissions.js.map +1 -1
  146. package/build/lib/commands/proxy-helper.d.ts +11 -11
  147. package/build/lib/commands/proxy-helper.d.ts.map +1 -1
  148. package/build/lib/commands/proxy-helper.js +15 -24
  149. package/build/lib/commands/proxy-helper.js.map +1 -1
  150. package/build/lib/commands/record-audio.d.ts +25 -52
  151. package/build/lib/commands/record-audio.d.ts.map +1 -1
  152. package/build/lib/commands/record-audio.js +17 -19
  153. package/build/lib/commands/record-audio.js.map +1 -1
  154. package/build/lib/commands/recordscreen.d.ts +31 -62
  155. package/build/lib/commands/recordscreen.d.ts.map +1 -1
  156. package/build/lib/commands/recordscreen.js +29 -28
  157. package/build/lib/commands/recordscreen.js.map +1 -1
  158. package/build/lib/commands/screenshots.d.ts +15 -9
  159. package/build/lib/commands/screenshots.d.ts.map +1 -1
  160. package/build/lib/commands/screenshots.js +16 -16
  161. package/build/lib/commands/screenshots.js.map +1 -1
  162. package/build/lib/commands/simctl.d.ts +16 -22
  163. package/build/lib/commands/simctl.d.ts.map +1 -1
  164. package/build/lib/commands/simctl.js +13 -17
  165. package/build/lib/commands/simctl.js.map +1 -1
  166. package/build/lib/commands/source.d.ts +10 -8
  167. package/build/lib/commands/source.d.ts.map +1 -1
  168. package/build/lib/commands/source.js +11 -14
  169. package/build/lib/commands/source.js.map +1 -1
  170. package/build/lib/commands/timeouts.d.ts +25 -32
  171. package/build/lib/commands/timeouts.d.ts.map +1 -1
  172. package/build/lib/commands/timeouts.js +19 -15
  173. package/build/lib/commands/timeouts.js.map +1 -1
  174. package/build/lib/commands/types.d.ts +80 -0
  175. package/build/lib/commands/types.d.ts.map +1 -1
  176. package/build/lib/commands/web.d.ts +199 -202
  177. package/build/lib/commands/web.d.ts.map +1 -1
  178. package/build/lib/commands/web.js +216 -175
  179. package/build/lib/commands/web.js.map +1 -1
  180. package/build/lib/commands/xctest-record-screen.d.ts +17 -47
  181. package/build/lib/commands/xctest-record-screen.d.ts.map +1 -1
  182. package/build/lib/commands/xctest-record-screen.js +28 -59
  183. package/build/lib/commands/xctest-record-screen.js.map +1 -1
  184. package/build/lib/commands/xctest.d.ts +37 -37
  185. package/build/lib/commands/xctest.d.ts.map +1 -1
  186. package/build/lib/commands/xctest.js +38 -50
  187. package/build/lib/commands/xctest.js.map +1 -1
  188. package/build/lib/desired-caps.js +1 -1
  189. package/build/lib/device/log/ios-simulator-log.d.ts.map +1 -1
  190. package/build/lib/device/log/ios-simulator-log.js +2 -0
  191. package/build/lib/device/log/ios-simulator-log.js.map +1 -1
  192. package/build/lib/device/simulator-management.d.ts.map +1 -1
  193. package/build/lib/device/simulator-management.js +0 -2
  194. package/build/lib/device/simulator-management.js.map +1 -1
  195. package/build/lib/doctor/optional-checks.d.ts +0 -9
  196. package/build/lib/doctor/optional-checks.d.ts.map +1 -1
  197. package/build/lib/doctor/optional-checks.js +1 -30
  198. package/build/lib/doctor/optional-checks.js.map +1 -1
  199. package/build/lib/driver.d.ts +6 -5
  200. package/build/lib/driver.d.ts.map +1 -1
  201. package/build/lib/driver.js +16 -14
  202. package/build/lib/driver.js.map +1 -1
  203. package/build/lib/execute-method-map.d.ts.map +1 -1
  204. package/build/lib/execute-method-map.js +0 -9
  205. package/build/lib/execute-method-map.js.map +1 -1
  206. package/lib/commands/active-app-info.ts +15 -0
  207. package/lib/commands/alert.ts +98 -0
  208. package/lib/commands/app-management.ts +414 -0
  209. package/lib/commands/{app-strings.js → app-strings.ts} +10 -9
  210. package/lib/commands/appearance.ts +70 -0
  211. package/lib/commands/audit.ts +25 -0
  212. package/lib/commands/{battery.js → battery.ts} +10 -12
  213. package/lib/commands/biometric.ts +52 -0
  214. package/lib/commands/{certificate.js → certificate.ts} +55 -50
  215. package/lib/commands/clipboard.ts +37 -0
  216. package/lib/commands/{condition.js → condition.ts} +21 -77
  217. package/lib/commands/content-size.ts +67 -0
  218. package/lib/commands/{context.js → context.ts} +174 -146
  219. package/lib/commands/device-info.ts +24 -0
  220. package/lib/commands/element.ts +419 -0
  221. package/lib/commands/{execute.js → execute.ts} +42 -38
  222. package/lib/commands/{file-movement.js → file-movement.ts} +212 -235
  223. package/lib/commands/find.ts +277 -0
  224. package/lib/commands/{general.js → general.ts} +102 -77
  225. package/lib/commands/geolocation.ts +55 -0
  226. package/lib/commands/{gesture.js → gesture.ts} +225 -183
  227. package/lib/commands/increase-contrast.ts +49 -0
  228. package/lib/commands/{iohid.js → iohid.ts} +15 -13
  229. package/lib/commands/keyboard.ts +70 -0
  230. package/lib/commands/keychains.ts +16 -0
  231. package/lib/commands/{localization.js → localization.ts} +22 -12
  232. package/lib/commands/{location.js → location.ts} +19 -22
  233. package/lib/commands/lock.ts +43 -0
  234. package/lib/commands/{log.js → log.ts} +68 -68
  235. package/lib/commands/{memory.js → memory.ts} +9 -9
  236. package/lib/commands/{navigation.js → navigation.ts} +42 -39
  237. package/lib/commands/{notifications.js → notifications.ts} +22 -14
  238. package/lib/commands/pasteboard.ts +44 -0
  239. package/lib/commands/{pcap.js → pcap.ts} +28 -28
  240. package/lib/commands/{performance.js → performance.ts} +133 -114
  241. package/lib/commands/permissions.ts +90 -0
  242. package/lib/commands/{proxy-helper.js → proxy-helper.ts} +26 -26
  243. package/lib/commands/{record-audio.js → record-audio.ts} +35 -33
  244. package/lib/commands/{recordscreen.js → recordscreen.ts} +78 -50
  245. package/lib/commands/{screenshots.js → screenshots.ts} +27 -21
  246. package/lib/commands/simctl.ts +82 -0
  247. package/lib/commands/{source.js → source.ts} +23 -20
  248. package/lib/commands/timeouts.ts +95 -0
  249. package/lib/commands/types.ts +86 -0
  250. package/lib/commands/{web.js → web.ts} +314 -264
  251. package/lib/commands/{xctest-record-screen.js → xctest-record-screen.ts} +54 -71
  252. package/lib/commands/{xctest.js → xctest.ts} +78 -71
  253. package/lib/desired-caps.ts +1 -1
  254. package/lib/device/log/ios-simulator-log.ts +2 -0
  255. package/lib/device/simulator-management.ts +0 -2
  256. package/lib/doctor/optional-checks.ts +0 -33
  257. package/lib/driver.ts +19 -17
  258. package/lib/execute-method-map.ts +0 -9
  259. package/package.json +6 -6
  260. package/lib/commands/active-app-info.js +0 -12
  261. package/lib/commands/alert.js +0 -88
  262. package/lib/commands/app-management.js +0 -346
  263. package/lib/commands/appearance.js +0 -71
  264. package/lib/commands/audit.js +0 -31
  265. package/lib/commands/biometric.js +0 -52
  266. package/lib/commands/clipboard.js +0 -35
  267. package/lib/commands/content-size.js +0 -68
  268. package/lib/commands/deviceInfo.js +0 -27
  269. package/lib/commands/element.js +0 -423
  270. package/lib/commands/find.js +0 -205
  271. package/lib/commands/geolocation.js +0 -56
  272. package/lib/commands/increase-contrast.js +0 -50
  273. package/lib/commands/keyboard.js +0 -62
  274. package/lib/commands/keychains.js +0 -17
  275. package/lib/commands/lock.js +0 -46
  276. package/lib/commands/pasteboard.js +0 -43
  277. package/lib/commands/permissions.js +0 -85
  278. package/lib/commands/simctl.js +0 -71
  279. package/lib/commands/timeouts.js +0 -68
@@ -0,0 +1,419 @@
1
+ import _ from 'lodash';
2
+ import {errors} from 'appium/driver';
3
+ import {util} from 'appium/support';
4
+ import type {Element, Position, Size, Rect} from '@appium/types';
5
+ import type {XCUITestDriver} from '../driver';
6
+ import type {AtomsElement} from './types';
7
+
8
+ /**
9
+ * Checks whether an element is displayed.
10
+ *
11
+ * @param el - Element or element ID
12
+ */
13
+ export async function elementDisplayed(this: XCUITestDriver, el: Element | string): Promise<boolean> {
14
+ const elementId = util.unwrapElement(el);
15
+ if (this.isWebContext()) {
16
+ const atomsElement = this.getAtomsElement(elementId);
17
+ return await this.executeAtom('is_displayed', [atomsElement]) as boolean;
18
+ }
19
+ return await this.proxyCommand(`/element/${elementId}/displayed`, 'GET') as boolean;
20
+ }
21
+
22
+ /**
23
+ * Checks whether an element is enabled.
24
+ *
25
+ * @param el - Element or element ID
26
+ */
27
+ export async function elementEnabled(this: XCUITestDriver, el: Element | string): Promise<boolean> {
28
+ const elementId = util.unwrapElement(el);
29
+ if (this.isWebContext()) {
30
+ const atomsElement = this.getAtomsElement(elementId);
31
+ return await this.executeAtom('is_enabled', [atomsElement]) as boolean;
32
+ }
33
+ return await this.proxyCommand(`/element/${elementId}/enabled`, 'GET') as boolean;
34
+ }
35
+
36
+ /**
37
+ * Checks whether an element is selected.
38
+ *
39
+ * @param el - Element or element ID
40
+ */
41
+ export async function elementSelected(this: XCUITestDriver, el: Element | string): Promise<boolean> {
42
+ const elementId = util.unwrapElement(el);
43
+ if (this.isWebContext()) {
44
+ const atomsElement = this.getAtomsElement(elementId);
45
+ return await this.executeAtom('is_selected', [atomsElement]) as boolean;
46
+ }
47
+ return await this.proxyCommand(`/element/${elementId}/selected`, 'GET') as boolean;
48
+ }
49
+
50
+ /**
51
+ * Gets the tag/name of an element.
52
+ *
53
+ * @param el - Element or element ID
54
+ */
55
+ export async function getName(this: XCUITestDriver, el: Element | string): Promise<string> {
56
+ const elementId = util.unwrapElement(el);
57
+ if (this.isWebContext()) {
58
+ const atomsElement = this.getAtomsElement(elementId);
59
+ const script = 'return arguments[0].tagName.toLowerCase()';
60
+ return await this.executeAtom('execute_script', [script, [atomsElement]]) as string;
61
+ }
62
+ return await this.proxyCommand(`/element/${elementId}/name`, 'GET') as string;
63
+ }
64
+
65
+ /**
66
+ * Gets a native attribute (non-web) from an element.
67
+ *
68
+ * @param attribute - Attribute name
69
+ * @param el - Element or element ID
70
+ */
71
+ export async function getNativeAttribute(
72
+ this: XCUITestDriver,
73
+ attribute: string,
74
+ el: Element | string,
75
+ ): Promise<string | null> {
76
+ if (attribute === 'contentSize') {
77
+ return await this.getContentSize(el);
78
+ }
79
+
80
+ const elementId = util.unwrapElement(el);
81
+ let value = await this.proxyCommand(`/element/${elementId}/attribute/${attribute}`, 'GET') as
82
+ | string
83
+ | number
84
+ | null
85
+ | undefined
86
+ | boolean;
87
+ if ([0, 1].includes(value as number)) {
88
+ value = !!value;
89
+ }
90
+ return _.isNull(value) || _.isString(value) ? value : JSON.stringify(value);
91
+ }
92
+
93
+ /**
94
+ * Gets an element attribute (web or native).
95
+ *
96
+ * @param attribute - Attribute name
97
+ * @param el - Element or element ID
98
+ */
99
+ export async function getAttribute(
100
+ this: XCUITestDriver,
101
+ attribute: string,
102
+ el: Element | string,
103
+ ): Promise<string | null> {
104
+ const elementId = util.unwrapElement(el);
105
+ if (!this.isWebContext()) {
106
+ return await this.getNativeAttribute(attribute, elementId);
107
+ }
108
+ const atomsElement = this.getAtomsElement(elementId);
109
+ return await this.executeAtom('get_attribute_value', [atomsElement, attribute]) as string | null;
110
+ }
111
+
112
+ /**
113
+ * Gets an element property (web) or native attribute fallback.
114
+ *
115
+ * @param property - Property name
116
+ * @param el - Element or element ID
117
+ */
118
+ export async function getProperty(
119
+ this: XCUITestDriver,
120
+ property: string,
121
+ el: Element | string,
122
+ ): Promise<string | null> {
123
+ const elementId = util.unwrapElement(el);
124
+ if (!this.isWebContext()) {
125
+ return await this.getNativeAttribute(property, elementId);
126
+ }
127
+ const atomsElement = this.getAtomsElement(elementId);
128
+ return await this.executeAtom('get_attribute_value', [atomsElement, property]) as string | null;
129
+ }
130
+
131
+ /**
132
+ * Gets the text content of an element.
133
+ *
134
+ * @param el - Element or element ID
135
+ */
136
+ export async function getText(this: XCUITestDriver, el: Element | string): Promise<string> {
137
+ const elementId = util.unwrapElement(el);
138
+ if (!this.isWebContext()) {
139
+ return await this.proxyCommand(`/element/${elementId}/text`, 'GET') as string;
140
+ }
141
+ const atomsElement = this.getAtomsElement(elementId);
142
+ return await this.executeAtom('get_text', [atomsElement]) as string;
143
+ }
144
+
145
+ /**
146
+ * Gets the bounding rect of an element.
147
+ *
148
+ * @param el - Element or element ID
149
+ */
150
+ export async function getElementRect(this: XCUITestDriver, el: Element | string): Promise<Rect> {
151
+ if (this.isWebContext()) {
152
+ const {x, y} = await this.getLocation(el);
153
+ const {width, height} = await this.getSize(el);
154
+ return {x, y, width, height};
155
+ }
156
+ const elementId = util.unwrapElement(el);
157
+ return await this.getNativeRect(elementId);
158
+ }
159
+
160
+ /**
161
+ * Gets the top-left location of an element.
162
+ *
163
+ * @param elementId - Element or element ID
164
+ */
165
+ export async function getLocation(this: XCUITestDriver, elementId: Element | string): Promise<Position> {
166
+ const el = util.unwrapElement(elementId);
167
+ if (this.isWebContext()) {
168
+ const atomsElement = this.getAtomsElement(el);
169
+ const loc = await this.executeAtom('get_top_left_coordinates', [atomsElement]) as Position;
170
+ if (this.opts.absoluteWebLocations) {
171
+ const script =
172
+ 'return [' +
173
+ 'Math.max(window.pageXOffset,document.documentElement.scrollLeft,document.body.scrollLeft),' +
174
+ 'Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop)];';
175
+ const [xOffset, yOffset] = await this.execute(script) as [number, number];
176
+ loc.x += xOffset;
177
+ loc.y += yOffset;
178
+ }
179
+ return loc;
180
+ }
181
+ const rect = await this.getElementRect(el);
182
+ return {x: rect.x, y: rect.y};
183
+ }
184
+
185
+ /**
186
+ * Alias for getLocation.
187
+ *
188
+ * @param elementId - Element or element ID
189
+ */
190
+ export async function getLocationInView(this: XCUITestDriver, elementId: Element | string): Promise<Position> {
191
+ return await this.getLocation(elementId);
192
+ }
193
+
194
+ /**
195
+ * Gets the size of an element.
196
+ *
197
+ * @param el - Element or element ID
198
+ */
199
+ export async function getSize(this: XCUITestDriver, el: Element | string): Promise<Size> {
200
+ const elementId = util.unwrapElement(el);
201
+ if (this.isWebContext()) {
202
+ return await this.executeAtom('get_size', [this.getAtomsElement(elementId)]) as Size;
203
+ }
204
+ const rect = await this.getElementRect(elementId);
205
+ return {width: rect.width, height: rect.height};
206
+ }
207
+
208
+ /**
209
+ * Legacy alias for setValue; always types via keyboard.
210
+ *
211
+ * @param value - Value to set
212
+ * @param el - Element or element ID
213
+ */
214
+ export async function setValueImmediate(
215
+ this: XCUITestDriver,
216
+ value: string | string[] | number,
217
+ el: Element | string,
218
+ ): Promise<void> {
219
+ this.log.info(
220
+ 'There is currently no way to bypass typing using XCUITest. Setting value through keyboard',
221
+ );
222
+ await this.setValue(value, el);
223
+ }
224
+
225
+ /**
226
+ * Sets an element value (native or web).
227
+ *
228
+ * @param value - Value to set
229
+ * @param el - Element or element ID
230
+ */
231
+ export async function setValue(
232
+ this: XCUITestDriver,
233
+ value: string | string[] | number,
234
+ el: Element | string,
235
+ ): Promise<void> {
236
+ const elementId = util.unwrapElement(el);
237
+ if (!this.isWebContext()) {
238
+ await this.proxyCommand(`/element/${elementId}/value`, 'POST', {
239
+ value: prepareInputValue(value),
240
+ });
241
+ return;
242
+ }
243
+
244
+ const atomsElement = this.getAtomsElement(elementId);
245
+ await this.executeAtom('click', [atomsElement]);
246
+
247
+ if (this.opts.sendKeyStrategy !== 'oneByOne') {
248
+ await this.setValueWithWebAtom(atomsElement, value);
249
+ return;
250
+ }
251
+ for (const char of prepareInputValue(value)) {
252
+ await this.setValueWithWebAtom(atomsElement, char);
253
+ }
254
+ }
255
+
256
+ /**
257
+ * Types text into a web element using atoms.
258
+ *
259
+ * @param atomsElement - Target atoms element
260
+ * @param value - Text to type
261
+ */
262
+ export async function setValueWithWebAtom(
263
+ this: XCUITestDriver,
264
+ atomsElement: AtomsElement<string>,
265
+ value: string | string[] | number,
266
+ ): Promise<void> {
267
+ await this.executeAtom('type', [atomsElement, value]);
268
+
269
+ if (this.opts.skipTriggerInputEventAfterSendkeys) {
270
+ return;
271
+ }
272
+
273
+ function triggerInputEvent(input: EventTarget & {_valueTracker?: any}) {
274
+ const lastValue = '';
275
+ const event = new Event('input', {bubbles: true});
276
+ const tracker = input._valueTracker;
277
+ if (tracker) {
278
+ tracker.setValue(lastValue);
279
+ }
280
+ input.dispatchEvent(event);
281
+ }
282
+
283
+ const scriptAsString = `return (${triggerInputEvent}).apply(null, arguments)`;
284
+ await this.executeAtom('execute_script', [scriptAsString, [atomsElement]]);
285
+ }
286
+
287
+ /**
288
+ * Sends raw key sequences via WDA.
289
+ *
290
+ * @param value - Keys to send
291
+ */
292
+ export async function keys(this: XCUITestDriver, value: string[] | string | number): Promise<void> {
293
+ await this.proxyCommand('/wda/keys', 'POST', {
294
+ value: prepareInputValue(value),
295
+ });
296
+ }
297
+
298
+ /**
299
+ * Clears the contents of an element.
300
+ *
301
+ * @param el - Element or element ID
302
+ */
303
+ export async function clear(this: XCUITestDriver, el: Element | string): Promise<void> {
304
+ const elementId = util.unwrapElement(el);
305
+ if (this.isWebContext()) {
306
+ const atomsElement = this.getAtomsElement(elementId);
307
+ await this.executeAtom('clear', [atomsElement]);
308
+ return;
309
+ }
310
+ await this.proxyCommand(`/element/${elementId}/clear`, 'POST');
311
+ }
312
+
313
+ /**
314
+ * Gets content size for table/collection views (native only).
315
+ *
316
+ * @param el - Element or element ID
317
+ */
318
+ export async function getContentSize(this: XCUITestDriver, el: Element | string): Promise<string> {
319
+ if (this.isWebContext()) {
320
+ throw new errors.NotYetImplementedError(
321
+ 'Support for getContentSize for web context is not yet implemented. Please contact an Appium dev',
322
+ );
323
+ }
324
+
325
+ const type = await this.getAttribute('type', el);
326
+
327
+ if (type !== 'XCUIElementTypeTable' && type !== 'XCUIElementTypeCollectionView') {
328
+ throw new Error(
329
+ `Can't get content size for type '${type}', only for tables and collection views`,
330
+ );
331
+ }
332
+ let locator = '*';
333
+ if (type === 'XCUIElementTypeTable') {
334
+ locator = 'XCUIElementTypeCell';
335
+ }
336
+
337
+ let contentHeight = 0;
338
+ const children = await this.findElOrEls('class chain', locator, true, el);
339
+ if (children.length === 1) {
340
+ const rect = await this.getElementRect(children[0]);
341
+ contentHeight = rect.height;
342
+ } else if (children.length) {
343
+ switch (type) {
344
+ case 'XCUIElementTypeTable': {
345
+ const firstRect = await this.getElementRect(_.head(children) as Element);
346
+ const lastRect = await this.getElementRect(_.last(children) as Element);
347
+ contentHeight = lastRect.y + lastRect.height - firstRect.y;
348
+ break;
349
+ }
350
+ case 'XCUIElementTypeCollectionView': {
351
+ let elsInRow = 1;
352
+ const firstRect = await this.getElementRect(_.head(children) as Element);
353
+ const initialRects = [firstRect];
354
+ for (let i = 1; i < children.length; i++) {
355
+ const rect = await this.getElementRect(children[i] as Element);
356
+ initialRects.push(rect);
357
+ if (rect.y !== firstRect.y) {
358
+ elsInRow = i;
359
+ break;
360
+ }
361
+ }
362
+ const spaceBetweenEls =
363
+ initialRects[elsInRow].y -
364
+ initialRects[elsInRow - 1].y -
365
+ initialRects[elsInRow - 1].height;
366
+ const numRows = Math.ceil(children.length / elsInRow);
367
+ contentHeight = numRows * firstRect.height + spaceBetweenEls * (numRows - 1);
368
+ break;
369
+ }
370
+ default:
371
+ throw new Error(
372
+ `Programming error: type '${type}' was not valid but should have already been rejected`,
373
+ );
374
+ }
375
+ }
376
+ const size = await this.getSize(el);
377
+ const origin = await this.getLocationInView(el);
378
+ return JSON.stringify({
379
+ width: size.width,
380
+ height: size.height,
381
+ top: origin.y,
382
+ left: origin.x,
383
+ scrollableOffset: contentHeight,
384
+ });
385
+ }
386
+
387
+ /**
388
+ * Gets the native rect of an element (no web fallback).
389
+ *
390
+ * @param el - Element or element ID
391
+ */
392
+ export async function getNativeRect(this: XCUITestDriver, el: Element | string): Promise<Rect> {
393
+ const elementId = util.unwrapElement(el);
394
+ return await this.proxyCommand(`/element/${elementId}/rect`, 'GET') as Rect;
395
+ }
396
+
397
+ function prepareInputValue(inp: string | string[] | number): string[] {
398
+ if (![_.isArray, _.isString, _.isFinite].some((f) => f(inp))) {
399
+ throw new Error(
400
+ `Only strings, numbers and arrays are supported as input arguments. ` +
401
+ `Received: ${JSON.stringify(inp)}`,
402
+ );
403
+ }
404
+
405
+ if (_.isArray(inp)) {
406
+ inp = inp.join('');
407
+ } else if (_.isFinite(inp)) {
408
+ inp = `${inp}`;
409
+ }
410
+ return [...String(inp)].map((k) => {
411
+ if (['\uE006', '\uE007'].includes(k)) {
412
+ return '\n';
413
+ }
414
+ if (['\uE003', '\ue017'].includes(k)) {
415
+ return '\b';
416
+ }
417
+ return k;
418
+ });
419
+ }
@@ -2,14 +2,18 @@ import _ from 'lodash';
2
2
  import {XCUITestDriver} from '../driver';
3
3
  import {errors, errorFromCode, errorFromW3CJsonCode} from 'appium/driver';
4
4
  import {util} from 'appium/support';
5
+ import type {Element, StringRecord} from '@appium/types';
5
6
 
6
7
  /**
7
8
  * Collect the response of an async script execution
8
- * @this {XCUITestDriver}
9
9
  * @deprecated
10
10
  * @privateRemarks It's unclear what this is for. Don't use it.
11
11
  */
12
- export async function receiveAsyncResponse(status, value) {
12
+ export async function receiveAsyncResponse(
13
+ this: XCUITestDriver,
14
+ status: number | null | undefined,
15
+ value: any,
16
+ ): Promise<void> {
13
17
  this.log.debug(`Received async response: ${JSON.stringify(value)}`);
14
18
  if (!util.hasValue(this.asyncPromise)) {
15
19
  this.log.warn(
@@ -33,21 +37,22 @@ export async function receiveAsyncResponse(status, value) {
33
37
  }
34
38
 
35
39
  /**
36
- * @template {ExecuteMethodArgs} [TArgs = unknown[]]
37
- * @template [TReturn = unknown]
38
- * @param {string} script - Either a script to run, or in the case of an Execute Method, the name of the script to execute.
39
- * @param {TArgs} [args]
40
- * @this {XCUITestDriver}
41
- * @returns {Promise<TReturn>}
40
+ * @template TReturn
41
+ * @param script - Either a script to run, or in the case of an Execute Method, the name of the script to execute.
42
+ * @param args
42
43
  */
43
- export async function execute(script, args) {
44
+ export async function execute<TReturn = unknown>(
45
+ this: XCUITestDriver,
46
+ script: string,
47
+ args?: ExecuteMethodArgs,
48
+ ): Promise<TReturn> {
44
49
  // TODO: create a type that converts args to the parameters of the associated method using the `command` prop of `executeMethodMap`
45
50
  script = script.trim().replace(/^mobile:\s*/, 'mobile: ');
46
51
  if (isExecuteMethod(script)) {
47
- const executeMethodArgs = preprocessExecuteMethodArgs(script, args);
52
+ const executeMethodArgs = preprocessExecuteMethodArgs(script, args as ExecuteMethodArgs | undefined);
48
53
  return await this.executeMethod(script, [executeMethodArgs]);
49
54
  } else if (this.isWebContext()) {
50
- const atomsArgs = this.convertElementsForAtoms(/** @type {readonly any[]} */ (args));
55
+ const atomsArgs = this.convertElementsForAtoms(args as readonly any[] | undefined);
51
56
  const result = await this.executeAtom('execute_script', [script, atomsArgs]);
52
57
  return this.cacheWebElements(result);
53
58
  } else {
@@ -56,17 +61,20 @@ export async function execute(script, args) {
56
61
  }
57
62
 
58
63
  /**
59
- * @this {XCUITestDriver}
60
64
  * @group Mobile Web Only
61
65
  */
62
- export async function executeAsync(script, args) {
66
+ export async function executeAsync(
67
+ this: XCUITestDriver,
68
+ script: string,
69
+ args?: readonly any[],
70
+ ): Promise<any> {
63
71
  if (!this.isWebContext()) {
64
72
  throw new errors.NotImplementedError();
65
73
  }
66
74
 
67
75
  args = this.convertElementsForAtoms(args);
68
76
  this.asyncWaitMs = this.asyncWaitMs || 0;
69
- const promise = (/** @type {import('appium-remote-debugger').RemoteDebugger} */ (this.remote)).executeAtomAsync(
77
+ const promise = this.remote.executeAtomAsync(
70
78
  'execute_async_script',
71
79
  [script, args, this.asyncWaitMs],
72
80
  this.curWebFrames,
@@ -77,16 +85,17 @@ export async function executeAsync(script, args) {
77
85
 
78
86
  /**
79
87
  * Checks if script expects a particular parameter (either optional or required).
80
- * @template {keyof XCUITestDriver.executeMethodMap} Script
81
- * @param {Script} script - Script name
82
- * @param {string} param - Parameter name
88
+ * @template Script
89
+ * @param script - Script name
90
+ * @param param - Parameter name
83
91
  * @returns {boolean}
84
92
  */
85
- function executeMethodExpectsParam(script, param) {
86
- /** @type {ReadonlyArray<string>|undefined} */
87
- let required;
88
- /** @type {ReadonlyArray<string>|undefined} */
89
- let optional;
93
+ function executeMethodExpectsParam<Script extends keyof typeof XCUITestDriver.executeMethodMap>(
94
+ script: Script,
95
+ param: string,
96
+ ): boolean {
97
+ let required: ReadonlyArray<string> | undefined;
98
+ let optional: ReadonlyArray<string> | undefined;
90
99
  const execMethodDef = XCUITestDriver.executeMethodMap[script];
91
100
  if ('params' in execMethodDef) {
92
101
  if ('required' in execMethodDef.params) {
@@ -101,24 +110,26 @@ function executeMethodExpectsParam(script, param) {
101
110
  }
102
111
 
103
112
  /**
104
- * @param {any} script
113
+ * @param script
105
114
  * @returns {script is keyof XCUITestDriver.executeMethodMap}
106
115
  */
107
- function isExecuteMethod(script) {
116
+ function isExecuteMethod(script: string): script is keyof typeof XCUITestDriver.executeMethodMap {
108
117
  return script in XCUITestDriver.executeMethodMap;
109
118
  }
110
119
 
111
120
  /**
112
121
  * Massages the arguments going into an execute method.
113
- * @param {keyof XCUITestDriver.executeMethodMap} script
114
- * @param {ExecuteMethodArgs} [args]
115
- * @returns {StringRecord<unknown>}
122
+ * @param script
123
+ * @param args
116
124
  */
117
- function preprocessExecuteMethodArgs(script, args) {
125
+ function preprocessExecuteMethodArgs(
126
+ script: keyof typeof XCUITestDriver.executeMethodMap,
127
+ args?: ExecuteMethodArgs,
128
+ ): StringRecord<unknown> {
118
129
  if (_.isArray(args)) {
119
130
  args = _.first(args);
120
131
  }
121
- const executeMethodArgs = /** @type {StringRecord<unknown>} */ (args ?? {});
132
+ const executeMethodArgs = (args ?? {}) as StringRecord<unknown>;
122
133
  /**
123
134
  * Renames the deprecated `element` key to `elementId`. Historically,
124
135
  * all of the pre-Execute-Method-Map execute methods accepted an `element` _or_ and `elementId` param.
@@ -136,18 +147,11 @@ function preprocessExecuteMethodArgs(script, args) {
136
147
  */
137
148
  if ('elementId' in executeMethodArgs && executeMethodExpectsParam(script, 'elementId')) {
138
149
  executeMethodArgs.elementId = util.unwrapElement(
139
- /** @type {import('@appium/types').Element|string} */ (executeMethodArgs.elementId),
150
+ executeMethodArgs.elementId as Element<string> | string,
140
151
  );
141
152
  }
142
153
 
143
154
  return executeMethodArgs;
144
155
  }
145
156
 
146
- /**
147
- * @template [T=any]
148
- * @typedef {import('@appium/types').StringRecord<T>} StringRecord
149
- */
150
-
151
- /**
152
- * @typedef {readonly any[] | readonly [StringRecord] | Readonly<StringRecord>} ExecuteMethodArgs
153
- */
157
+ type ExecuteMethodArgs = readonly any[] | readonly [StringRecord<unknown>] | Readonly<StringRecord<unknown>>;