appium-uiautomator2-driver 2.29.11 → 2.31.0

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 (135) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/build/index.d.ts +4 -0
  3. package/build/index.d.ts.map +1 -0
  4. package/build/index.js +8 -15
  5. package/build/index.js.map +1 -0
  6. package/build/lib/commands/actions.d.ts +2 -0
  7. package/build/lib/commands/actions.d.ts.map +1 -0
  8. package/build/lib/commands/actions.js +67 -62
  9. package/build/lib/commands/actions.js.map +1 -1
  10. package/build/lib/commands/alert.d.ts +2 -0
  11. package/build/lib/commands/alert.d.ts.map +1 -0
  12. package/build/lib/commands/alert.js +28 -26
  13. package/build/lib/commands/alert.js.map +1 -1
  14. package/build/lib/commands/app-strings.d.ts +3 -0
  15. package/build/lib/commands/app-strings.d.ts.map +1 -0
  16. package/build/lib/commands/app-strings.js +86 -57
  17. package/build/lib/commands/app-strings.js.map +1 -1
  18. package/build/lib/commands/battery.d.ts +2 -0
  19. package/build/lib/commands/battery.d.ts.map +1 -0
  20. package/build/lib/commands/battery.js +26 -16
  21. package/build/lib/commands/battery.js.map +1 -1
  22. package/build/lib/commands/element.d.ts +2 -0
  23. package/build/lib/commands/element.d.ts.map +1 -0
  24. package/build/lib/commands/element.js +140 -159
  25. package/build/lib/commands/element.js.map +1 -1
  26. package/build/lib/commands/find.d.ts +2 -0
  27. package/build/lib/commands/find.d.ts.map +1 -0
  28. package/build/lib/commands/find.js +39 -25
  29. package/build/lib/commands/find.js.map +1 -1
  30. package/build/lib/commands/general.d.ts +4 -0
  31. package/build/lib/commands/general.d.ts.map +1 -0
  32. package/build/lib/commands/general.js +209 -215
  33. package/build/lib/commands/general.js.map +1 -1
  34. package/build/lib/commands/gestures.d.ts +2 -0
  35. package/build/lib/commands/gestures.d.ts.map +1 -0
  36. package/build/lib/commands/gestures.js +206 -193
  37. package/build/lib/commands/gestures.js.map +1 -1
  38. package/build/lib/commands/index.d.ts +2 -0
  39. package/build/lib/commands/index.d.ts.map +1 -0
  40. package/build/lib/commands/index.js +13 -22
  41. package/build/lib/commands/index.js.map +1 -1
  42. package/build/lib/commands/mixins.d.ts +87 -0
  43. package/build/lib/commands/mixins.d.ts.map +1 -0
  44. package/build/lib/commands/mixins.js +26 -0
  45. package/build/lib/commands/mixins.js.map +1 -0
  46. package/build/lib/commands/screenshot.d.ts +2 -0
  47. package/build/lib/commands/screenshot.d.ts.map +1 -0
  48. package/build/lib/commands/screenshot.js +77 -62
  49. package/build/lib/commands/screenshot.js.map +1 -1
  50. package/build/lib/commands/touch.d.ts +2 -0
  51. package/build/lib/commands/touch.d.ts.map +1 -0
  52. package/build/lib/commands/touch.js +48 -38
  53. package/build/lib/commands/touch.js.map +1 -1
  54. package/build/lib/commands/types.d.ts +452 -0
  55. package/build/lib/commands/types.d.ts.map +1 -0
  56. package/build/lib/commands/types.js +3 -0
  57. package/build/lib/commands/types.js.map +1 -0
  58. package/build/lib/commands/viewport.d.ts +2 -0
  59. package/build/lib/commands/viewport.d.ts.map +1 -0
  60. package/build/lib/commands/viewport.js +37 -35
  61. package/build/lib/commands/viewport.js.map +1 -1
  62. package/build/lib/constraints.d.ts +325 -0
  63. package/build/lib/constraints.d.ts.map +1 -0
  64. package/build/lib/constraints.js +51 -0
  65. package/build/lib/constraints.js.map +1 -0
  66. package/build/lib/css-converter.d.ts +45 -0
  67. package/build/lib/css-converter.d.ts.map +1 -0
  68. package/build/lib/css-converter.js +272 -175
  69. package/build/lib/css-converter.js.map +1 -1
  70. package/build/lib/driver.d.ts +904 -0
  71. package/build/lib/driver.d.ts.map +1 -0
  72. package/build/lib/driver.js +726 -485
  73. package/build/lib/driver.js.map +1 -1
  74. package/build/lib/execute-method-map.d.ts +477 -0
  75. package/build/lib/execute-method-map.d.ts.map +1 -0
  76. package/build/lib/execute-method-map.js +542 -0
  77. package/build/lib/execute-method-map.js.map +1 -0
  78. package/build/lib/extensions.d.ts +3 -0
  79. package/build/lib/extensions.d.ts.map +1 -0
  80. package/build/lib/extensions.js +7 -9
  81. package/build/lib/extensions.js.map +1 -1
  82. package/build/lib/helpers.d.ts +7 -0
  83. package/build/lib/helpers.d.ts.map +1 -0
  84. package/build/lib/helpers.js +36 -29
  85. package/build/lib/helpers.js.map +1 -1
  86. package/build/lib/logger.d.ts +3 -0
  87. package/build/lib/logger.d.ts.map +1 -0
  88. package/build/lib/logger.js +5 -10
  89. package/build/lib/logger.js.map +1 -1
  90. package/build/lib/method-map.d.ts +389 -0
  91. package/build/lib/method-map.d.ts.map +1 -0
  92. package/build/lib/method-map.js +11 -17
  93. package/build/lib/method-map.js.map +1 -1
  94. package/build/lib/types.d.ts +44 -0
  95. package/build/lib/types.d.ts.map +1 -0
  96. package/build/lib/types.js +3 -0
  97. package/build/lib/types.js.map +1 -0
  98. package/build/lib/uiautomator2.d.ts +45 -0
  99. package/build/lib/uiautomator2.d.ts.map +1 -0
  100. package/build/lib/uiautomator2.js +340 -299
  101. package/build/lib/uiautomator2.js.map +1 -1
  102. package/build/lib/utils.d.ts +10 -0
  103. package/build/lib/utils.d.ts.map +1 -0
  104. package/build/lib/utils.js +23 -16
  105. package/build/lib/utils.js.map +1 -1
  106. package/build/tsconfig.tsbuildinfo +1 -0
  107. package/index.js +5 -3
  108. package/lib/commands/actions.js +115 -101
  109. package/lib/commands/alert.js +36 -44
  110. package/lib/commands/app-strings.js +79 -58
  111. package/lib/commands/battery.js +27 -28
  112. package/lib/commands/element.js +231 -134
  113. package/lib/commands/find.js +40 -21
  114. package/lib/commands/general.js +262 -336
  115. package/lib/commands/gestures.js +252 -366
  116. package/lib/commands/index.js +11 -31
  117. package/lib/commands/mixins.ts +169 -0
  118. package/lib/commands/screenshot.js +80 -76
  119. package/lib/commands/touch.js +64 -31
  120. package/lib/commands/types.ts +473 -0
  121. package/lib/commands/viewport.js +43 -31
  122. package/lib/constraints.ts +53 -0
  123. package/lib/css-converter.js +9 -1
  124. package/lib/{driver.js → driver.ts} +374 -239
  125. package/lib/execute-method-map.ts +573 -0
  126. package/lib/method-map.ts +11 -0
  127. package/lib/types.ts +57 -0
  128. package/lib/uiautomator2.js +21 -2
  129. package/lib/utils.js +2 -2
  130. package/npm-shrinkwrap.json +395 -528
  131. package/package.json +96 -70
  132. package/build/lib/desired-caps.js +0 -71
  133. package/build/lib/desired-caps.js.map +0 -1
  134. package/lib/desired-caps.js +0 -70
  135. package/lib/method-map.js +0 -11
@@ -1,31 +1,11 @@
1
- import alertCmds from './alert';
2
- import findCmds from './find';
3
- import generalCmds from './general';
4
- import touchCmds from './touch';
5
- import elementCmds from './element';
6
- import actionsCmds from './actions';
7
- import viewportCmds from './viewport';
8
- import screenshotCmds from './screenshot';
9
- import batteryCmds from './battery';
10
- import gesturesCmds from './gestures';
11
- import appStringsCmds from './app-strings';
12
-
13
- let commands = {};
14
- Object.assign(
15
- commands,
16
- alertCmds,
17
- findCmds,
18
- generalCmds,
19
- touchCmds,
20
- actionsCmds,
21
- elementCmds,
22
- viewportCmds,
23
- screenshotCmds,
24
- batteryCmds,
25
- gesturesCmds,
26
- appStringsCmds,
27
- // add other command types here
28
- );
29
-
30
- export default commands;
31
-
1
+ import './alert';
2
+ import './find';
3
+ import './general';
4
+ import './touch';
5
+ import './element';
6
+ import './actions';
7
+ import './viewport';
8
+ import './screenshot';
9
+ import './battery';
10
+ import './gestures';
11
+ import './app-strings';
@@ -0,0 +1,169 @@
1
+ /**
2
+ * @module
3
+ * @privateRemarks These mixins are kind of a mishmash of stuff from `appium-android-driver`,
4
+ * @privateRemarks unique things, and stuff from `ExternalDriver`. Ideally, we should be pulling the method
5
+ * @privateRemarks definitions right out of `ExternalDriver` whenever possible. Also note that the mixins
6
+ * @privateRemarks contain _more stuff than just commands or execute methods_.
7
+ */
8
+
9
+ import type {Element, ExternalDriver, StringRecord} from '@appium/types';
10
+ import type {
11
+ ActionsMixin,
12
+ AlertMixin,
13
+ ElementMixin,
14
+ ExecuteMixin,
15
+ FindMixin,
16
+ GeneralMixin,
17
+ NetworkMixin,
18
+ TouchMixin,
19
+ } from 'appium-android-driver';
20
+ import type {EmptyObject} from 'type-fest';
21
+ import {AndroidUiautomator2Driver} from '../driver';
22
+ import type * as types from './types';
23
+
24
+ type UIA2Mixin<T = EmptyObject> = ThisType<import('../driver').AndroidUiautomator2Driver> & T;
25
+
26
+ export type UIA2ActionsMixin = UIA2Mixin<
27
+ Pick<
28
+ ActionsMixin,
29
+ 'pressKeyCode' | 'longPressKeyCode' | 'doSwipe' | 'doDrag' | 'getOrientation' | 'setOrientation'
30
+ >
31
+ > & {
32
+ mobilePressKey(opts: types.PressKeyOptions): Promise<void>;
33
+ mobileScheduleAction(opts?: StringRecord): Promise<unknown>;
34
+ mobileGetActionHistory(opts?: types.ActionArgs): Promise<types.ActionResult>;
35
+ mobileUnscheduleAction(opts?: types.ActionArgs): Promise<unknown>;
36
+ };
37
+
38
+ export type UIA2AlertMixin = UIA2Mixin<
39
+ Pick<AlertMixin, 'getAlertText' | 'postAcceptAlert' | 'postDismissAlert'>
40
+ > & {
41
+ mobileAcceptAlert(opts?: types.AcceptAlertOptions): Promise<void>;
42
+ mobileDismissAlert(opts?: types.DismissAlertOptions): Promise<void>;
43
+ };
44
+
45
+ export type UIA2AppStringsMixin = UIA2Mixin<Pick<GeneralMixin, 'getStrings'>> & {
46
+ mobileGetAppStrings(opts?: types.GetAppStringsOptions): Promise<StringRecord>;
47
+ };
48
+
49
+ export type UIA2BatteryMixin = UIA2Mixin & {
50
+ mobileGetBatteryInfo(): Promise<types.BatteryInfo>;
51
+ };
52
+
53
+ export type UIA2ElementMixin = UIA2Mixin<
54
+ Pick<
55
+ ElementMixin,
56
+ | 'getAttribute'
57
+ | 'elementDisplayed'
58
+ | 'elementEnabled'
59
+ | 'elementSelected'
60
+ | 'getName'
61
+ | 'getLocation'
62
+ | 'getSize'
63
+ | 'touchLongClick'
64
+ | 'touchDown'
65
+ | 'touchUp'
66
+ | 'touchMove'
67
+ | 'doSetElementValue'
68
+ | 'setValueImmediate'
69
+ | 'getText'
70
+ | 'click'
71
+ | 'tap'
72
+ | 'clear'
73
+ | 'getElementRect'
74
+ >
75
+ > & {
76
+ active(): Promise<Element>;
77
+ mobileReplaceElementValue(opts: types.ReplaceValueOptions): Promise<void>;
78
+ getElementScreenshot(elementId: string): Promise<string>;
79
+ };
80
+
81
+ export type UIA2FindMixin = UIA2Mixin<Pick<FindMixin, 'doFindElementOrEls'>>;
82
+
83
+ export type UIA2GeneralMixin = UIA2Mixin<
84
+ Pick<
85
+ GeneralMixin & NetworkMixin & ActionsMixin & ExecuteMixin,
86
+ | 'getPageSource'
87
+ | 'doSendKeys'
88
+ | 'back'
89
+ | 'getDisplayDensity'
90
+ | 'getWindowSize'
91
+ | 'getWindowRect'
92
+ | 'setUrl'
93
+ | 'keyevent'
94
+ | 'execute'
95
+ | 'executeMobile'
96
+ >
97
+ > & {
98
+ getClipboard(): Promise<string>;
99
+ mobileViewportScreenshot(): Promise<string>;
100
+ mobileViewPortRect(): Promise<types.RelativeRect>;
101
+ mobileDeepLink(opts: types.DeepLinkOpts): Promise<void>;
102
+ openNotifications(): Promise<void>;
103
+ suspendChromedriverProxy(): void;
104
+ mobileGetDeviceInfo(): Promise<StringRecord>;
105
+ mobileType(opts: types.TypingOptions): Promise<boolean>;
106
+ mobileInstallMultipleApks(opts: types.InstallMultipleApksOptions): Promise<void>;
107
+ mobileBackgroundApp(opts?: types.BackgroundAppOptions): Promise<void>;
108
+ };
109
+
110
+ export type UIA2ViewportMixin = UIA2Mixin & {
111
+ getStatusBarHeight(): Promise<number>;
112
+ getDevicePixelRatio(): Promise<string>;
113
+ getViewportScreenshot(): Promise<string>;
114
+ getViewPortRect(): Promise<types.RelativeRect>;
115
+ };
116
+
117
+ export type UIA2GesturesMixin = UIA2Mixin & {
118
+ mobileClickGesture(opts?: types.ClickOptions): Promise<void>;
119
+ mobileDoubleClickGesture(opts?: types.ClickOptions): Promise<void>;
120
+ mobileDragGesture(opts: types.DragOptions): Promise<void>;
121
+ mobileFlingGesture(opts: types.FlingOptions): Promise<boolean>;
122
+ mobilePinchCloseGesture(opts: types.PinchOptions): Promise<void>;
123
+ mobilePinchOpenGesture(opts: types.PinchOptions): Promise<void>;
124
+ mobileSwipeGesture(opts: types.SwipeOptions): Promise<void>;
125
+ mobileScrollGesture(opts: types.ScrollGestureOptions): Promise<boolean>;
126
+ mobileScrollBackTo(opts: types.ScrollElementToElementOpts): Promise<void>;
127
+ mobileScroll(opts: types.ScrollOptions): Promise<void>;
128
+ mobileLongClickGesture(opts: types.LongClickOptions): Promise<void>;
129
+ };
130
+
131
+ export type UIA2ScreenshotMixin = UIA2Mixin<Pick<ActionsMixin, 'getScreenshot'>> & {
132
+ mobileScreenshots(opts: types.ScreenshotsOpts): Promise<StringRecord<types.Screenshot>>;
133
+ };
134
+
135
+ export type UIA2TouchMixin = UIA2Mixin<
136
+ // Required needed because ExternalDriver's methods are all optional
137
+ Required<
138
+ Pick<ExternalDriver & TouchMixin, 'performActions' | 'releaseActions' | 'doPerformMultiAction'>
139
+ >
140
+ >;
141
+
142
+ declare module '../driver' {
143
+ interface AndroidUiautomator2Driver
144
+ extends UIA2ActionsMixin,
145
+ UIA2AlertMixin,
146
+ UIA2AppStringsMixin,
147
+ UIA2BatteryMixin,
148
+ UIA2ElementMixin,
149
+ UIA2FindMixin,
150
+ UIA2GeneralMixin,
151
+ UIA2GesturesMixin,
152
+ UIA2ScreenshotMixin,
153
+ UIA2TouchMixin,
154
+ UIA2ViewportMixin {}
155
+ }
156
+
157
+ /**
158
+ * This function assigns a mixin `T` to the `AndroidUiautomator2Driver` class' prototype.
159
+ *
160
+ * While each mixin has its own interface which is (in isolation) unrelated to
161
+ * `AndroidUiautomator2Driver`, the constraint on this generic type `T` is that it must be a
162
+ * partial of `AndroidUiautomator2Driver`'s interface. This enforces that it does not
163
+ * conflict with the existing interface of `AndroidUiautomator2Driver`. In that way, you
164
+ * can think of it as a type guard.
165
+ * @param mixin Mixin implementation
166
+ */
167
+ export function mixin<T extends Partial<AndroidUiautomator2Driver>>(mixin: T): void {
168
+ Object.assign(AndroidUiautomator2Driver.prototype, mixin);
169
+ }
@@ -1,91 +1,95 @@
1
+ // @ts-check
2
+
3
+ import {mixin} from './mixins';
1
4
  import _ from 'lodash';
2
5
  import B from 'bluebird';
3
6
 
4
- const commands = {};
5
-
6
7
  // Display 4619827259835644672 (HWC display 0): port=0 pnpId=GGL displayName="EMU_display_0"
7
8
  const DISPLAY_PATTERN = /^Display\s+(\d+)\s+\(.+display\s+(\d+)\).+displayName="([^"]*)/gm;
8
9
 
9
- commands.getScreenshot = async function () {
10
- if (this.mjpegStream) {
11
- const data = await this.mjpegStream.lastChunkPNGBase64();
12
- if (data) {
13
- return data;
14
- }
15
- this.log.warn('Tried to get screenshot from active MJPEG stream, but there ' +
16
- 'was no data yet. Falling back to regular screenshot methods.');
17
- }
18
- return await this.uiautomator2.jwproxy.command('/screenshot', 'GET');
19
- };
20
-
21
- /**
22
- * @typedef {Object} ScreenshotsInfo
23
- *
24
- * A dictionary where each key contains a unique display identifier
25
- * and values are dictionaries with following items:
26
- * - id: Display identifier
27
- * - name: Display name, could be empty
28
- * - isDefault: Whether this display is the default one
29
- * - payload: The actual PNG screenshot data encoded to base64 string
30
- */
31
-
32
- /**
33
- * @typedef {Object} ScreenshotsOpts
34
- * @property {number|string?} displayId Android display identifier to take a screenshot for.
35
- * If not provided then screenshots of all displays are going to be returned.
36
- * If no matches were found then an error is thrown.
37
- */
38
-
39
10
  /**
40
- * Retrieves screenshots of each display available to Android.
41
- * This functionality is only supported since Android 10.
42
- *
43
- * @param {ScreenshotsOpts} opts
44
- * @returns {Promise<ScreenshotsInfo>}
11
+ * @type {import('./mixins').UIA2ScreenshotMixin}
12
+ * @satisfies {import('@appium/types').ExternalDriver}
45
13
  */
46
- commands.mobileScreenshots = async function mobileScreenshots (opts = {}) {
47
- const displaysInfo = await this.adb.shell(['dumpsys', 'SurfaceFlinger', '--display-id']);
48
- const infos = {};
49
- let match;
50
- while ((match = DISPLAY_PATTERN.exec(displaysInfo))) {
51
- infos[match[1]] = {
52
- id: match[1],
53
- isDefault: match[2] === '0',
54
- name: match[3],
55
- };
56
- }
57
- if (_.isEmpty(infos)) {
58
- this.log.debug(displaysInfo);
59
- throw new Error('Cannot determine the information about connected Android displays');
60
- }
61
- this.log.info(`Parsed Android display infos: ${JSON.stringify(infos)}`);
14
+ const ScreenshotMixin = {
15
+ async getScreenshot() {
16
+ if (this.mjpegStream) {
17
+ const data = await this.mjpegStream.lastChunkPNGBase64();
18
+ if (data) {
19
+ return data;
20
+ }
21
+ this.log.warn(
22
+ 'Tried to get screenshot from active MJPEG stream, but there ' +
23
+ 'was no data yet. Falling back to regular screenshot methods.'
24
+ );
25
+ }
26
+ return String(
27
+ await /** @type {import('../uiautomator2').UiAutomator2Server} */ (
28
+ this.uiautomator2
29
+ ).jwproxy.command('/screenshot', 'GET')
30
+ );
31
+ },
62
32
 
63
- const toB64Screenshot = async (dispId) => (await this.adb.takeScreenshot(dispId))
64
- .toString('base64');
33
+ /**
34
+ * Retrieves screenshots of each display available to Android.
35
+ * This functionality is only supported since Android 10.
36
+ */
37
+ async mobileScreenshots(opts = {}) {
38
+ const displaysInfo = await /** @type {import('appium-adb').ADB} */ (this.adb).shell([
39
+ 'dumpsys',
40
+ 'SurfaceFlinger',
41
+ '--display-id',
42
+ ]);
43
+ /** @type {import('@appium/types').StringRecord<import('./types').Screenshot>} */
44
+ const infos = {};
45
+ let match;
46
+ while ((match = DISPLAY_PATTERN.exec(displaysInfo))) {
47
+ infos[match[1]] = /** @type {any} */ ({
48
+ id: match[1],
49
+ isDefault: match[2] === '0',
50
+ name: match[3],
51
+ });
52
+ }
53
+ if (_.isEmpty(infos)) {
54
+ this.log.debug(displaysInfo);
55
+ throw new Error('Cannot determine the information about connected Android displays');
56
+ }
57
+ this.log.info(`Parsed Android display infos: ${JSON.stringify(infos)}`);
65
58
 
66
- const {displayId} = opts;
67
- const displayIdStr = isNaN(displayId) ? null : `${displayId}`;
68
- if (displayIdStr) {
69
- if (!infos[displayIdStr]) {
70
- throw new Error(
71
- `The provided display identifier '${displayId}' is not known. ` +
72
- `Only the following displays have been detected: ${JSON.stringify(infos)}`
59
+ /**
60
+ * @param {string} dispId
61
+ */
62
+ const toB64Screenshot = async (dispId) =>
63
+ (await /** @type {import('appium-adb').ADB} */ (this.adb).takeScreenshot(dispId)).toString(
64
+ 'base64'
73
65
  );
74
- }
75
- return {
76
- [displayIdStr]: {
77
- ...infos[displayIdStr],
78
- payload: await toB64Screenshot(displayIdStr),
66
+
67
+ const {displayId} = opts;
68
+ const displayIdStr = _.isNaN(displayId) ? null : `${displayId}`;
69
+ if (displayIdStr) {
70
+ if (!infos[displayIdStr]) {
71
+ throw new Error(
72
+ `The provided display identifier '${displayId}' is not known. ` +
73
+ `Only the following displays have been detected: ${JSON.stringify(infos)}`
74
+ );
79
75
  }
80
- };
81
- }
76
+ return {
77
+ [displayIdStr]: {
78
+ ...infos[displayIdStr],
79
+ payload: await toB64Screenshot(displayIdStr),
80
+ },
81
+ };
82
+ }
82
83
 
83
- const allInfos = _.values(infos);
84
- const screenshots = await B.all(allInfos.map(({id}) => toB64Screenshot(id)));
85
- for (const [info, payload] of _.zip(allInfos, screenshots)) {
86
- info.payload = payload;
87
- }
88
- return infos;
84
+ const allInfos = _.values(infos);
85
+ const screenshots = await B.all(allInfos.map(({id}) => toB64Screenshot(id)));
86
+ for (const [info, payload] of /** @type {[import('./types').Screenshot, string][]} */ (
87
+ _.zip(allInfos, screenshots)
88
+ )) {
89
+ info.payload = payload;
90
+ }
91
+ return infos;
92
+ },
89
93
  };
90
94
 
91
- export default commands;
95
+ mixin(ScreenshotMixin);
@@ -1,38 +1,71 @@
1
- const commands = {};
1
+ // @ts-check
2
2
 
3
- commands.doPerformMultiAction = async function (elementId, states) {
4
- let opts;
5
- if (elementId) {
6
- opts = {
7
- elementId,
8
- actions: states
9
- };
3
+ import {mixin} from './mixins';
10
4
 
11
- return await this.uiautomator2.jwproxy.command('/touch/multi/perform', 'POST', opts);
12
- } else {
13
- opts = {
14
- actions: states
15
- };
16
- return await this.uiautomator2.jwproxy.command('/touch/multi/perform', 'POST', opts);
17
- }
18
- };
5
+ /**
6
+ * @type {import('./mixins').UIA2TouchMixin}
7
+ * @satisfies {import('@appium/types').ExternalDriver}
8
+ */
9
+ const TouchMixin = {
10
+ async doPerformMultiAction(elementId, states) {
11
+ let opts;
12
+ if (elementId) {
13
+ opts = {
14
+ elementId,
15
+ actions: states,
16
+ };
17
+
18
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
19
+ '/touch/multi/perform',
20
+ 'POST',
21
+ opts
22
+ );
23
+ } else {
24
+ opts = {
25
+ actions: states,
26
+ };
27
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
28
+ '/touch/multi/perform',
29
+ 'POST',
30
+ opts
31
+ );
32
+ }
33
+ },
19
34
 
20
- commands.performActions = async function (actions) {
21
- this.log.debug(`Received the following W3C actions: ${JSON.stringify(actions, null, ' ')}`);
22
- // This is mandatory, since Selenium API uses MOUSE as the default pointer type
23
- const preprocessedActions = actions
24
- .map((action) => Object.assign({}, action, action.type === 'pointer' ? {
25
- parameters: {
26
- pointerType: 'touch'
35
+ async performActions(actions) {
36
+ this.log.debug(`Received the following W3C actions: ${JSON.stringify(actions, null, ' ')}`);
37
+ // This is mandatory, since Selenium API uses MOUSE as the default pointer type
38
+ const preprocessedActions = actions.map((action) =>
39
+ Object.assign(
40
+ {},
41
+ action,
42
+ action.type === 'pointer'
43
+ ? {
44
+ parameters: {
45
+ pointerType: 'touch',
46
+ },
47
+ }
48
+ : {}
49
+ )
50
+ );
51
+ this.log.debug(`Preprocessed actions: ${JSON.stringify(preprocessedActions, null, ' ')}`);
52
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
53
+ '/actions',
54
+ 'POST',
55
+ {
56
+ actions: preprocessedActions,
27
57
  }
28
- } : {}));
29
- this.log.debug(`Preprocessed actions: ${JSON.stringify(preprocessedActions, null, ' ')}`);
30
- return await this.uiautomator2.jwproxy.command('/actions', 'POST', {actions: preprocessedActions});
31
- };
58
+ );
59
+ },
32
60
 
33
- // eslint-disable-next-line require-await
34
- commands.releaseActions = async function releaseActions () {
35
- this.log.info('On this platform, releaseActions is a no-op');
61
+ // eslint-disable-next-line require-await
62
+ async releaseActions() {
63
+ this.log.info('On this platform, releaseActions is a no-op');
64
+ },
36
65
  };
37
66
 
38
- export default commands;
67
+ mixin(TouchMixin);
68
+
69
+ /**
70
+ * @typedef {import('../uiautomator2').UiAutomator2Server} UiAutomator2Server
71
+ */