appium-android-driver 5.14.7 → 6.0.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 (210) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/build/lib/commands/actions.d.ts +6 -224
  3. package/build/lib/commands/actions.d.ts.map +1 -1
  4. package/build/lib/commands/actions.js +306 -405
  5. package/build/lib/commands/actions.js.map +1 -1
  6. package/build/lib/commands/alert.d.ts +7 -9
  7. package/build/lib/commands/alert.d.ts.map +1 -1
  8. package/build/lib/commands/alert.js +24 -18
  9. package/build/lib/commands/alert.js.map +1 -1
  10. package/build/lib/commands/app-management.d.ts +7 -313
  11. package/build/lib/commands/app-management.d.ts.map +1 -1
  12. package/build/lib/commands/app-management.js +135 -293
  13. package/build/lib/commands/app-management.js.map +1 -1
  14. package/build/lib/commands/context.d.ts +8 -92
  15. package/build/lib/commands/context.d.ts.map +1 -1
  16. package/build/lib/commands/context.js +381 -439
  17. package/build/lib/commands/context.js.map +1 -1
  18. package/build/lib/commands/element.d.ts +8 -35
  19. package/build/lib/commands/element.d.ts.map +1 -1
  20. package/build/lib/commands/element.js +153 -136
  21. package/build/lib/commands/element.js.map +1 -1
  22. package/build/lib/commands/emu-console.d.ts +6 -48
  23. package/build/lib/commands/emu-console.d.ts.map +1 -1
  24. package/build/lib/commands/emu-console.js +19 -34
  25. package/build/lib/commands/emu-console.js.map +1 -1
  26. package/build/lib/commands/execute.d.ts +6 -5
  27. package/build/lib/commands/execute.d.ts.map +1 -1
  28. package/build/lib/commands/execute.js +77 -66
  29. package/build/lib/commands/execute.js.map +1 -1
  30. package/build/lib/commands/file-actions.d.ts +7 -128
  31. package/build/lib/commands/file-actions.d.ts.map +1 -1
  32. package/build/lib/commands/file-actions.js +183 -219
  33. package/build/lib/commands/file-actions.js.map +1 -1
  34. package/build/lib/commands/find.d.ts +8 -12
  35. package/build/lib/commands/find.d.ts.map +1 -1
  36. package/build/lib/commands/find.js +19 -23
  37. package/build/lib/commands/find.js.map +1 -1
  38. package/build/lib/commands/general.d.ts +9 -132
  39. package/build/lib/commands/general.d.ts.map +1 -1
  40. package/build/lib/commands/general.js +281 -312
  41. package/build/lib/commands/general.js.map +1 -1
  42. package/build/lib/commands/ime.d.ts +7 -10
  43. package/build/lib/commands/ime.d.ts.map +1 -1
  44. package/build/lib/commands/ime.js +47 -35
  45. package/build/lib/commands/ime.js.map +1 -1
  46. package/build/lib/commands/index.d.ts +27 -2
  47. package/build/lib/commands/index.d.ts.map +1 -1
  48. package/build/lib/commands/index.js +41 -19
  49. package/build/lib/commands/index.js.map +1 -1
  50. package/build/lib/commands/intent.d.ts +7 -417
  51. package/build/lib/commands/intent.d.ts.map +1 -1
  52. package/build/lib/commands/intent.js +104 -216
  53. package/build/lib/commands/intent.js.map +1 -1
  54. package/build/lib/commands/keyboard.d.ts +6 -5
  55. package/build/lib/commands/keyboard.d.ts.map +1 -1
  56. package/build/lib/commands/keyboard.js +16 -8
  57. package/build/lib/commands/keyboard.js.map +1 -1
  58. package/build/lib/commands/log.d.ts +7 -44
  59. package/build/lib/commands/log.d.ts.map +1 -1
  60. package/build/lib/commands/log.js +146 -108
  61. package/build/lib/commands/log.js.map +1 -1
  62. package/build/lib/commands/media-projection.d.ts +7 -143
  63. package/build/lib/commands/media-projection.d.ts.map +1 -1
  64. package/build/lib/commands/media-projection.js +113 -140
  65. package/build/lib/commands/media-projection.js.map +1 -1
  66. package/build/lib/commands/mixins.d.ts +740 -0
  67. package/build/lib/commands/mixins.d.ts.map +1 -0
  68. package/build/lib/commands/mixins.js +19 -0
  69. package/build/lib/commands/mixins.js.map +1 -0
  70. package/build/lib/commands/network.d.ts +7 -138
  71. package/build/lib/commands/network.d.ts.map +1 -1
  72. package/build/lib/commands/network.js +212 -254
  73. package/build/lib/commands/network.js.map +1 -1
  74. package/build/lib/commands/performance.d.ts +24 -70
  75. package/build/lib/commands/performance.d.ts.map +1 -1
  76. package/build/lib/commands/performance.js +144 -100
  77. package/build/lib/commands/performance.js.map +1 -1
  78. package/build/lib/commands/permissions.d.ts +8 -92
  79. package/build/lib/commands/permissions.d.ts.map +1 -1
  80. package/build/lib/commands/permissions.js +75 -87
  81. package/build/lib/commands/permissions.js.map +1 -1
  82. package/build/lib/commands/recordscreen.d.ts +7 -193
  83. package/build/lib/commands/recordscreen.d.ts.map +1 -1
  84. package/build/lib/commands/recordscreen.js +151 -182
  85. package/build/lib/commands/recordscreen.js.map +1 -1
  86. package/build/lib/commands/shell.d.ts +7 -7
  87. package/build/lib/commands/shell.d.ts.map +1 -1
  88. package/build/lib/commands/shell.js +40 -33
  89. package/build/lib/commands/shell.js.map +1 -1
  90. package/build/lib/commands/streamscreen.d.ts +9 -103
  91. package/build/lib/commands/streamscreen.d.ts.map +1 -1
  92. package/build/lib/commands/streamscreen.js +261 -218
  93. package/build/lib/commands/streamscreen.js.map +1 -1
  94. package/build/lib/commands/system-bars.d.ts +22 -90
  95. package/build/lib/commands/system-bars.d.ts.map +1 -1
  96. package/build/lib/commands/system-bars.js +76 -74
  97. package/build/lib/commands/system-bars.js.map +1 -1
  98. package/build/lib/commands/touch.d.ts +10 -29
  99. package/build/lib/commands/touch.d.ts.map +1 -1
  100. package/build/lib/commands/touch.js +301 -285
  101. package/build/lib/commands/touch.js.map +1 -1
  102. package/build/lib/commands/types.d.ts +978 -0
  103. package/build/lib/commands/types.d.ts.map +1 -0
  104. package/build/lib/commands/types.js +3 -0
  105. package/build/lib/commands/types.js.map +1 -0
  106. package/build/lib/constraints.d.ts +291 -0
  107. package/build/lib/constraints.d.ts.map +1 -0
  108. package/build/lib/{desired-caps.js → constraints.js} +103 -102
  109. package/build/lib/constraints.js.map +1 -0
  110. package/build/lib/driver.d.ts +68 -37
  111. package/build/lib/driver.d.ts.map +1 -1
  112. package/build/lib/driver.js +123 -80
  113. package/build/lib/driver.js.map +1 -1
  114. package/build/lib/helpers/android.d.ts +164 -0
  115. package/build/lib/helpers/android.d.ts.map +1 -0
  116. package/build/lib/helpers/android.js +819 -0
  117. package/build/lib/helpers/android.js.map +1 -0
  118. package/build/lib/helpers/index.d.ts +7 -0
  119. package/build/lib/helpers/index.d.ts.map +1 -0
  120. package/build/lib/helpers/index.js +29 -0
  121. package/build/lib/helpers/index.js.map +1 -0
  122. package/build/lib/helpers/types.d.ts +121 -0
  123. package/build/lib/helpers/types.d.ts.map +1 -0
  124. package/build/lib/helpers/types.js +3 -0
  125. package/build/lib/helpers/types.js.map +1 -0
  126. package/build/lib/helpers/unlock.d.ts +32 -0
  127. package/build/lib/helpers/unlock.d.ts.map +1 -0
  128. package/build/lib/helpers/unlock.js +273 -0
  129. package/build/lib/helpers/unlock.js.map +1 -0
  130. package/build/lib/helpers/webview.d.ts +74 -0
  131. package/build/lib/helpers/webview.d.ts.map +1 -0
  132. package/build/lib/helpers/webview.js +421 -0
  133. package/build/lib/helpers/webview.js.map +1 -0
  134. package/build/lib/index.d.ts +9 -0
  135. package/build/lib/index.d.ts.map +1 -0
  136. package/build/lib/index.js +37 -0
  137. package/build/lib/index.js.map +1 -0
  138. package/build/lib/method-map.d.ts +0 -8
  139. package/build/lib/method-map.d.ts.map +1 -1
  140. package/build/lib/method-map.js +63 -74
  141. package/build/lib/method-map.js.map +1 -1
  142. package/build/lib/stubs.d.ts +0 -1
  143. package/build/lib/stubs.d.ts.map +1 -1
  144. package/build/lib/stubs.js +1 -0
  145. package/build/lib/stubs.js.map +1 -1
  146. package/build/lib/utils.d.ts +1 -1
  147. package/build/lib/utils.d.ts.map +1 -1
  148. package/lib/commands/actions.js +351 -464
  149. package/lib/commands/alert.js +27 -17
  150. package/lib/commands/app-management.js +156 -314
  151. package/lib/commands/context.js +457 -441
  152. package/lib/commands/element.js +201 -157
  153. package/lib/commands/emu-console.js +25 -45
  154. package/lib/commands/execute.js +106 -90
  155. package/lib/commands/file-actions.js +222 -240
  156. package/lib/commands/find.ts +103 -0
  157. package/lib/commands/general.js +327 -339
  158. package/lib/commands/ime.js +50 -34
  159. package/lib/commands/{index.js → index.ts} +20 -24
  160. package/lib/commands/intent.js +108 -249
  161. package/lib/commands/keyboard.js +20 -8
  162. package/lib/commands/log.js +172 -116
  163. package/lib/commands/media-projection.js +134 -161
  164. package/lib/commands/mixins.ts +966 -0
  165. package/lib/commands/network.js +252 -281
  166. package/lib/commands/performance.js +203 -132
  167. package/lib/commands/permissions.js +108 -109
  168. package/lib/commands/recordscreen.js +212 -209
  169. package/lib/commands/shell.js +51 -40
  170. package/lib/commands/streamscreen.js +355 -289
  171. package/lib/commands/system-bars.js +92 -83
  172. package/lib/commands/touch.js +357 -294
  173. package/lib/commands/types.ts +1097 -0
  174. package/lib/{desired-caps.js → constraints.ts} +106 -103
  175. package/lib/{driver.js → driver.ts} +278 -132
  176. package/lib/helpers/android.ts +1143 -0
  177. package/lib/helpers/index.ts +6 -0
  178. package/lib/helpers/types.ts +134 -0
  179. package/lib/helpers/unlock.ts +329 -0
  180. package/lib/helpers/webview.ts +582 -0
  181. package/lib/index.ts +18 -0
  182. package/lib/method-map.js +87 -98
  183. package/lib/stubs.ts +0 -1
  184. package/package.json +26 -19
  185. package/build/index.js +0 -51
  186. package/build/lib/android-helpers.d.ts +0 -136
  187. package/build/lib/android-helpers.d.ts.map +0 -1
  188. package/build/lib/android-helpers.js +0 -855
  189. package/build/lib/android-helpers.js.map +0 -1
  190. package/build/lib/commands/coverage.d.ts +0 -5
  191. package/build/lib/commands/coverage.d.ts.map +0 -1
  192. package/build/lib/commands/coverage.js +0 -19
  193. package/build/lib/commands/coverage.js.map +0 -1
  194. package/build/lib/desired-caps.d.ts +0 -353
  195. package/build/lib/desired-caps.d.ts.map +0 -1
  196. package/build/lib/desired-caps.js.map +0 -1
  197. package/build/lib/unlock-helpers.d.ts +0 -38
  198. package/build/lib/unlock-helpers.d.ts.map +0 -1
  199. package/build/lib/unlock-helpers.js +0 -266
  200. package/build/lib/unlock-helpers.js.map +0 -1
  201. package/build/lib/webview-helpers.d.ts +0 -224
  202. package/build/lib/webview-helpers.d.ts.map +0 -1
  203. package/build/lib/webview-helpers.js +0 -528
  204. package/build/lib/webview-helpers.js.map +0 -1
  205. package/index.js +0 -24
  206. package/lib/android-helpers.js +0 -983
  207. package/lib/commands/coverage.js +0 -18
  208. package/lib/commands/find.js +0 -82
  209. package/lib/unlock-helpers.js +0 -278
  210. package/lib/webview-helpers.js +0 -602
@@ -1,24 +1,37 @@
1
- import { BaseDriver, DeviceSettings } from 'appium/driver';
2
- import desiredConstraints from './desired-caps';
3
- import commands from './commands/index';
4
- import { newMethodMap } from './method-map';
5
- import {
6
- helpers, ensureNetworkSpeed,
7
- SETTINGS_HELPER_PKG_ID,
8
- } from './android-helpers';
9
- import _ from 'lodash';
10
- import { DEFAULT_ADB_PORT } from 'appium-adb';
11
- import { fs, tempDir, util } from '@appium/support';
12
- import { retryInterval } from 'asyncbox';
13
- import { SharedPrefsBuilder } from 'shared-preferences-builder';
1
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
2
+
3
+ import {fs, tempDir, util} from '@appium/support';
4
+ import type {
5
+ DefaultCreateSessionResult,
6
+ DriverCaps,
7
+ DriverData,
8
+ DriverOpts,
9
+ ExternalDriver,
10
+ InitialOpts,
11
+ RouteMatcher,
12
+ StringRecord,
13
+ W3CDriverCaps,
14
+ } from '@appium/types';
15
+ import ADB, {DEFAULT_ADB_PORT} from 'appium-adb';
16
+ import type {default as AppiumChromedriver} from 'appium-chromedriver';
17
+ import {BaseDriver, DeviceSettings} from 'appium/driver';
18
+ import {retryInterval} from 'asyncbox';
14
19
  import B from 'bluebird';
20
+ import _ from 'lodash';
21
+ import {SharedPrefsBuilder} from 'shared-preferences-builder';
22
+ import AndroidBootstrap from './bootstrap';
23
+ import ANDROID_DRIVER_CONSTRAINTS, {AndroidDriverConstraints} from './constraints';
24
+ import {SETTINGS_HELPER_PKG_ID, ensureNetworkSpeed, helpers} from './helpers';
25
+ import {newMethodMap} from './method-map';
15
26
 
16
27
  const APP_EXTENSION = '.apk';
17
28
  const DEVICE_PORT = 4724;
18
29
 
19
- // This is a set of methods and paths that we never want to proxy to
20
- // Chromedriver
21
- const NO_PROXY = [
30
+ /**
31
+ * This is a set of methods and paths that we never want to proxy to
32
+ * Chromedriver
33
+ **/
34
+ const NO_PROXY: RouteMatcher[] = [
22
35
  ['POST', new RegExp('^/session/[^/]+/context')],
23
36
  ['GET', new RegExp('^/session/[^/]+/context')],
24
37
  ['POST', new RegExp('^/session/[^/]+/appium')],
@@ -33,11 +46,55 @@ const NO_PROXY = [
33
46
  ['POST', new RegExp('^/session/[^/]+/network_connection')],
34
47
  ];
35
48
 
36
- class AndroidDriver extends BaseDriver {
49
+ export type AndroidDriverCaps = DriverCaps<AndroidDriverConstraints>;
50
+ export type W3CAndroidDriverCaps = W3CDriverCaps<AndroidDriverConstraints>;
51
+ export type AndroidDriverOpts = DriverOpts<AndroidDriverConstraints>;
52
+
53
+ export interface AndroidSettings {
54
+ ignoreUnimportantViews: boolean;
55
+ }
37
56
 
57
+ export type AndroidDriverCreateResult = [string, AndroidDriverCaps];
58
+ type AndroidExternalDriver = ExternalDriver<AndroidDriverConstraints>;
59
+ class AndroidDriver<
60
+ Settings extends AndroidSettings = AndroidSettings,
61
+ CreateResult = AndroidDriverCreateResult
62
+ >
63
+ extends BaseDriver<AndroidDriverConstraints, StringRecord, Settings, CreateResult>
64
+ implements ExternalDriver<AndroidDriverConstraints, string, StringRecord, Settings, CreateResult>
65
+ {
38
66
  static newMethodMap = newMethodMap;
67
+ jwpProxyAvoid: RouteMatcher[];
68
+
69
+ bootstrap?: AndroidBootstrap;
70
+
71
+ adb?: ADB;
72
+
73
+ unlocker: typeof helpers.unlocker;
74
+
75
+ apkStrings: StringRecord<StringRecord<string>>;
76
+
77
+ proxyReqRes?: (...args: any) => any;
78
+
79
+ contexts?: string[];
80
+
81
+ sessionChromedrivers: StringRecord<AppiumChromedriver>;
82
+
83
+ chromedriver?: AppiumChromedriver;
84
+
85
+ proxyCommand?: AndroidExternalDriver['proxyCommand'];
86
+ jwpProxyActive: boolean;
87
+ curContext: string;
88
+
89
+ useUnlockHelperApp?: boolean;
90
+
91
+ defaultIME?: string;
92
+
93
+ _wasWindowAnimationDisabled?: boolean;
39
94
 
40
- constructor (opts = {}, shouldValidateCaps = true) {
95
+ opts: AndroidDriverOpts;
96
+
97
+ constructor(opts: InitialOpts = {} as InitialOpts, shouldValidateCaps = true) {
41
98
  super(opts, shouldValidateCaps);
42
99
 
43
100
  this.locatorStrategies = [
@@ -45,34 +102,41 @@ class AndroidDriver extends BaseDriver {
45
102
  'id',
46
103
  'class name',
47
104
  'accessibility id',
48
- '-android uiautomator'
105
+ '-android uiautomator',
49
106
  ];
50
- this.desiredCapConstraints = desiredConstraints;
107
+ this.desiredCapConstraints = _.cloneDeep(ANDROID_DRIVER_CONSTRAINTS);
51
108
  this.sessionChromedrivers = {};
52
109
  this.jwpProxyActive = false;
53
110
  this.jwpProxyAvoid = _.clone(NO_PROXY);
54
- this.settings = new DeviceSettings({ignoreUnimportantViews: false},
55
- this.onSettingsUpdate.bind(this));
56
- this.chromedriver = null;
111
+ this.settings = new DeviceSettings(
112
+ {ignoreUnimportantViews: false} as Settings,
113
+ this.onSettingsUpdate.bind(this)
114
+ );
57
115
  this.apkStrings = {};
58
116
  this.unlocker = helpers.unlocker;
59
117
 
60
- for (let [cmd, fn] of _.toPairs(commands)) {
61
- AndroidDriver.prototype[cmd] = fn;
62
- }
63
-
64
- // needs to be after the line which assigns commands to AndroidDriver.prototype, so that `this.defaultContextName` is defined.
65
118
  this.curContext = this.defaultContextName();
119
+ this.opts = opts as AndroidDriverOpts;
66
120
  }
67
121
 
68
- async createSession (...args) {
122
+ async createSession(
123
+ w3cCaps1: W3CAndroidDriverCaps,
124
+ w3cCaps2?: W3CAndroidDriverCaps,
125
+ w3cCaps3?: W3CAndroidDriverCaps,
126
+ driverData?: DriverData[]
127
+ ): Promise<CreateResult> {
69
128
  // the whole createSession flow is surrounded in a try-catch statement
70
129
  // if creating a session fails at any point, we teardown everything we
71
130
  // set up before throwing the error.
72
131
  try {
73
- let [sessionId, caps] = await super.createSession(...args);
74
-
75
- let serverDetails = {
132
+ const [sessionId, caps] = (await super.createSession(
133
+ w3cCaps1,
134
+ w3cCaps2,
135
+ w3cCaps3,
136
+ driverData
137
+ )) as DefaultCreateSessionResult<AndroidDriverConstraints>;
138
+
139
+ const serverDetails = {
76
140
  platform: 'LINUX',
77
141
  webStorageEnabled: false,
78
142
  takesScreenshot: true,
@@ -81,13 +145,13 @@ class AndroidDriver extends BaseDriver {
81
145
  networkConnectionEnabled: true,
82
146
  locationContextEnabled: false,
83
147
  warnings: {},
84
- desired: this.caps
148
+ desired: this.caps,
85
149
  };
86
150
 
87
151
  this.caps = Object.assign(serverDetails, this.caps);
88
152
 
89
153
  // assigning defaults
90
- let defaultOpts = {
154
+ const defaultOpts = {
91
155
  action: 'android.intent.action.MAIN',
92
156
  category: 'android.intent.category.LAUNCHER',
93
157
  flags: '0x10200000',
@@ -99,18 +163,10 @@ class AndroidDriver extends BaseDriver {
99
163
  bootstrapPort: DEVICE_PORT,
100
164
  androidInstallTimeout: 90000,
101
165
  };
102
- _.defaults(this.opts, defaultOpts);
103
- this.useUnlockHelperApp = _.isUndefined(this.caps.unlockType);
104
166
 
105
- // not user visible via caps
106
- if (this.opts.noReset === true) {
107
- this.opts.fullReset = false;
108
- }
109
- if (this.opts.fullReset === true) {
110
- this.opts.noReset = false;
111
- }
112
- this.opts.fastReset = !this.opts.fullReset && !this.opts.noReset;
113
- this.opts.skipUninstall = this.opts.fastReset || this.opts.noReset;
167
+ this.opts = {...defaultOpts, ...this.opts};
168
+
169
+ this.useUnlockHelperApp = _.isUndefined(this.caps.unlockType);
114
170
 
115
171
  if (this.isChromeSession) {
116
172
  helpers.adjustBrowserSessionCaps(this.opts);
@@ -120,18 +176,21 @@ class AndroidDriver extends BaseDriver {
120
176
  this.jwpProxyAvoid.push(['GET', new RegExp('^/session/[^/]+/screenshot')]);
121
177
  }
122
178
 
179
+ // @ts-expect-error do not put arbitrary properties on opts
123
180
  if (this.opts.reboot) {
124
181
  this.setAvdFromCapabilities(caps);
125
182
  }
126
183
 
127
184
  // get device udid for this session
128
- let {udid, emPort} = await helpers.getDeviceInfoFromCaps(this.opts);
185
+ const {udid, emPort} = await helpers.getDeviceInfoFromCaps(this.opts);
129
186
  this.opts.udid = udid;
187
+ // @ts-expect-error do not put arbitrary properties on opts
130
188
  this.opts.emPort = emPort;
131
189
 
132
190
  // set up an instance of ADB
133
191
  this.adb = await helpers.createADB({
134
192
  udid: this.opts.udid,
193
+ // @ts-expect-error: unknown
135
194
  emPort: this.opts.emPort,
136
195
  adbPort: this.opts.adbPort,
137
196
  suppressKillServer: this.opts.suppressKillServer,
@@ -141,15 +200,19 @@ class AndroidDriver extends BaseDriver {
141
200
  allowOfflineDevices: this.opts.allowOfflineDevices,
142
201
  });
143
202
 
144
- if (await this.adb.getApiLevel() >= 23) {
145
- this.log.warn("Consider setting 'automationName' capability to " +
146
- "'uiautomator2' on Android >= 6, since UIAutomator framework " +
147
- 'is not maintained anymore by the OS vendor.');
203
+ if ((await this.adb.getApiLevel()) >= 23) {
204
+ this.log.warn(
205
+ "Consider setting 'automationName' capability to " +
206
+ "'uiautomator2' on Android >= 6, since UIAutomator framework " +
207
+ 'is not maintained anymore by the OS vendor.'
208
+ );
148
209
  }
149
210
 
211
+ // @ts-expect-error no arbitrary props on opts
150
212
  if (this.helpers.isPackageOrBundle(this.opts.app)) {
151
213
  // user provided package instead of app for 'app' capability, massage options
152
214
  this.opts.appPackage = this.opts.app;
215
+ // @ts-expect-error no arbitrary props on opts
153
216
  this.opts.app = null;
154
217
  }
155
218
 
@@ -160,8 +223,10 @@ class AndroidDriver extends BaseDriver {
160
223
  } else if (this.appOnDevice) {
161
224
  // the app isn't an actual app file but rather something we want to
162
225
  // assume is on the device and just launch via the appPackage
163
- this.log.info(`App file was not listed, instead we're going to run ` +
164
- `${this.opts.appPackage} directly on the device`);
226
+ this.log.info(
227
+ `App file was not listed, instead we're going to run ` +
228
+ `${this.opts.appPackage} directly on the device`
229
+ );
165
230
  await this.checkPackagePresent();
166
231
  }
167
232
 
@@ -178,7 +243,9 @@ class AndroidDriver extends BaseDriver {
178
243
  // check if we have to enable/disable gps before running the application
179
244
  if (util.hasValue(this.opts.gpsEnabled)) {
180
245
  if (this.isEmulator()) {
181
- this.log.info(`Trying to ${this.opts.gpsEnabled ? 'enable' : 'disable'} gps location provider`);
246
+ this.log.info(
247
+ `Trying to ${this.opts.gpsEnabled ? 'enable' : 'disable'} gps location provider`
248
+ );
182
249
  await this.adb.toggleGPSLocationProvider(this.opts.gpsEnabled);
183
250
  } else {
184
251
  this.log.warn('Sorry! gpsEnabled capability is only available for emulators');
@@ -186,7 +253,7 @@ class AndroidDriver extends BaseDriver {
186
253
  }
187
254
 
188
255
  await this.startAndroidSession(this.opts);
189
- return [sessionId, this.caps];
256
+ return [sessionId, this.caps] as CreateResult;
190
257
  } catch (e) {
191
258
  // ignoring delete session exception if any and throw the real error
192
259
  // that happened while creating the session.
@@ -197,63 +264,82 @@ class AndroidDriver extends BaseDriver {
197
264
  }
198
265
  }
199
266
 
200
- isEmulator () {
267
+ isEmulator() {
201
268
  return helpers.isEmulator(this.adb, this.opts);
202
269
  }
203
270
 
204
- setAvdFromCapabilities (caps) {
271
+ setAvdFromCapabilities(caps: AndroidDriverCaps) {
205
272
  if (this.opts.avd) {
206
273
  this.log.info('avd name defined, ignoring device name and platform version');
207
274
  } else {
208
275
  if (!caps.deviceName) {
209
- this.log.errorAndThrow('avd or deviceName should be specified when reboot option is enables');
276
+ this.log.errorAndThrow(
277
+ 'avd or deviceName should be specified when reboot option is enables'
278
+ );
279
+ throw new Error(); // unreachable
210
280
  }
211
281
  if (!caps.platformVersion) {
212
- this.log.errorAndThrow('avd or platformVersion should be specified when reboot option is enabled');
282
+ this.log.errorAndThrow(
283
+ 'avd or platformVersion should be specified when reboot option is enabled'
284
+ );
285
+ throw new Error(); // unreachable
213
286
  }
214
- let avdDevice = caps.deviceName.replace(/[^a-zA-Z0-9_.]/g, '-');
287
+ const avdDevice = caps.deviceName.replace(/[^a-zA-Z0-9_.]/g, '-');
215
288
  this.opts.avd = `${avdDevice}__${caps.platformVersion}`;
216
289
  }
217
290
  }
218
291
 
219
- get appOnDevice () {
220
- return this.helpers.isPackageOrBundle(this.opts.app) || (!this.opts.app &&
221
- this.helpers.isPackageOrBundle(this.opts.appPackage));
292
+ get appOnDevice() {
293
+ return (
294
+ // @ts-expect-error no arbitrary props on opts
295
+ this.helpers.isPackageOrBundle(this.opts.app) ||
296
+ // @ts-expect-error no arbitrary props on opts
297
+ (!this.opts.app && this.helpers.isPackageOrBundle(this.opts.appPackage))
298
+ );
222
299
  }
223
300
 
224
- get isChromeSession () {
225
- return helpers.isChromeBrowser(this.opts.browserName);
301
+ get isChromeSession() {
302
+ return helpers.isChromeBrowser(String(this.opts.browserName));
226
303
  }
227
304
 
228
- async onSettingsUpdate (key, value) {
305
+ async onSettingsUpdate(key: keyof Settings, value: any) {
229
306
  if (key === 'ignoreUnimportantViews') {
230
307
  await this.setCompressedLayoutHierarchy(value);
231
308
  }
232
309
  }
233
310
 
234
- async startAndroidSession () {
311
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
312
+ async startAndroidSession(opts: AndroidDriverOpts) {
235
313
  this.log.info(`Starting Android session`);
314
+
236
315
  // set up the device to run on (real or emulator, etc)
237
- this.defaultIME = await helpers.initDevice(this.adb, this.opts);
316
+ this.defaultIME = (await helpers.initDevice(this.adb!, this.opts)) as string;
238
317
 
239
318
  // set actual device name, udid, platform version, screen size, model and manufacturer details.
240
- this.caps.deviceName = this.adb.curDeviceId;
319
+ this.caps.deviceName = this.adb!.curDeviceId as string;
320
+ // @ts-expect-error do not put arbitrary properties on caps
241
321
  this.caps.deviceUDID = this.opts.udid;
242
- this.caps.platformVersion = await this.adb.getPlatformVersion();
322
+ this.caps.platformVersion = await this.adb!.getPlatformVersion();
323
+ // @ts-expect-error do not put arbitrary properties on caps
243
324
  this.caps.deviceScreenSize = await this.adb.getScreenSize();
325
+ // @ts-expect-error do not put arbitrary properties on caps
244
326
  this.caps.deviceModel = await this.adb.getModel();
327
+ // @ts-expect-error do not put arbitrary properties on caps
245
328
  this.caps.deviceManufacturer = await this.adb.getManufacturer();
246
329
 
247
330
  if (this.opts.disableWindowAnimation) {
248
- if (await this.adb.isAnimationOn()) {
249
- if (await this.adb.getApiLevel() >= 28) { // API level 28 is Android P
331
+ if (await this.adb!.isAnimationOn()) {
332
+ if ((await this.adb!.getApiLevel()) >= 28) {
333
+ // API level 28 is Android P
250
334
  // Don't forget to reset the relaxing in delete session
251
335
  this.log.warn('Relaxing hidden api policy to manage animation scale');
252
- await this.adb.setHiddenApiPolicy('1', !!this.opts.ignoreHiddenApiPolicyError);
336
+ await this.adb!.setHiddenApiPolicy('1', !!this.opts.ignoreHiddenApiPolicyError);
253
337
  }
254
338
 
255
- this.log.info('Disabling window animation as it is requested by "disableWindowAnimation" capability');
256
- await this.adb.setAnimationState(false);
339
+ this.log.info(
340
+ 'Disabling window animation as it is requested by "disableWindowAnimation" capability'
341
+ );
342
+ await this.adb!.setAnimationState(false);
257
343
  this._wasWindowAnimationDisabled = true;
258
344
  } else {
259
345
  this.log.info('Window animation is already disabled');
@@ -264,32 +350,44 @@ class AndroidDriver extends BaseDriver {
264
350
  await this.initAUT();
265
351
 
266
352
  // start UiAutomator
267
- this.bootstrap = new helpers.bootstrap(this.adb, this.opts.bootstrapPort, this.opts.websocket);
268
- await this.bootstrap.start(this.opts.appPackage, this.opts.disableAndroidWatchers, this.opts.acceptSslCerts);
353
+ const bootstrap = (this.bootstrap = new helpers.bootstrap(
354
+ this.adb!,
355
+ this.opts.bootstrapPort,
356
+ // @ts-expect-error do not put arbitrary properties on opts
357
+ this.opts.websocket
358
+ ));
359
+ await bootstrap.start(
360
+ this.opts.appPackage,
361
+ this.opts.disableAndroidWatchers,
362
+ this.opts.acceptSslCerts
363
+ );
269
364
  // handling unexpected shutdown
270
365
  (async () => {
271
366
  try {
272
- await this.bootstrap.onUnexpectedShutdown;
367
+ await bootstrap.onUnexpectedShutdown;
273
368
  } catch (err) {
274
- if (!this.bootstrap.ignoreUnexpectedShutdown) {
275
- await this.startUnexpectedShutdown(err);
369
+ if (!bootstrap.ignoreUnexpectedShutdown) {
370
+ await this.startUnexpectedShutdown(err as Error);
276
371
  }
277
372
  }
278
373
  })();
279
374
 
280
-
281
375
  if (this.opts.skipUnlock) {
282
376
  this.log.info('Skipping lockscreen check');
283
377
  } else {
284
- this.log.info('Checking for lockscreen presence. ' +
285
- `This could be skipped by setting the 'appium:skipUnlock' capability to true.`);
286
- await helpers.unlock(this, this.adb, this.caps);
378
+ this.log.info(
379
+ 'Checking for lockscreen presence. ' +
380
+ `This could be skipped by setting the 'appium:skipUnlock' capability to true.`
381
+ );
382
+ await helpers.unlock(this as any, this.adb!, this.caps);
287
383
  }
288
384
 
289
385
  // Set CompressedLayoutHierarchy on the device based on current settings object
290
386
  // this has to happen _after_ bootstrap is initialized
291
387
  if (this.opts.ignoreUnimportantViews) {
292
- await this.settings.update({ignoreUnimportantViews: this.opts.ignoreUnimportantViews});
388
+ await this.settings.update({
389
+ ignoreUnimportantViews: this.opts.ignoreUnimportantViews,
390
+ } as Settings);
293
391
  }
294
392
 
295
393
  if (this.isChromeSession) {
@@ -304,16 +402,17 @@ class AndroidDriver extends BaseDriver {
304
402
 
305
403
  if (util.hasValue(this.opts.orientation)) {
306
404
  this.log.debug(`Setting initial orientation to '${this.opts.orientation}'`);
405
+ // @ts-expect-error no arbitrary props on opts
307
406
  await this.setOrientation(this.opts.orientation);
308
407
  }
309
408
 
310
409
  await this.initAutoWebview();
311
410
  }
312
411
 
313
- async initAutoWebview () {
412
+ async initAutoWebview() {
314
413
  if (this.opts.autoWebview) {
315
- let viewName = this.defaultWebviewName();
316
- let timeout = (this.opts.autoWebviewTimeout) || 2000;
414
+ const viewName = this.defaultWebviewName();
415
+ const timeout = this.opts.autoWebviewTimeout || 2000;
317
416
 
318
417
  this.log.info(`Setting auto webview to context '${viewName}' with timeout ${timeout}ms`);
319
418
 
@@ -324,11 +423,11 @@ class AndroidDriver extends BaseDriver {
324
423
  }
325
424
  }
326
425
 
327
- async initAUT () {
426
+ async initAUT() {
328
427
  // populate appPackage, appActivity, appWaitPackage, appWaitActivity,
329
428
  // and the device being used
330
429
  // in the opts and caps (so it gets back to the user on session creation)
331
- let launchInfo = await helpers.getLaunchInfo(this.adb, this.opts);
430
+ const launchInfo = await helpers.getLaunchInfo(this.adb!, this.opts);
332
431
  Object.assign(this.opts, launchInfo);
333
432
  Object.assign(this.caps, launchInfo);
334
433
 
@@ -337,7 +436,7 @@ class AndroidDriver extends BaseDriver {
337
436
  helpers.validateDesiredCaps(this.opts);
338
437
  // Only SETTINGS_HELPER_PKG_ID package is used by UIA1
339
438
  await helpers.uninstallOtherPackages(
340
- this.adb,
439
+ this.adb!,
341
440
  helpers.parseArray(this.opts.uninstallOtherPackages),
342
441
  [SETTINGS_HELPER_PKG_ID]
343
442
  );
@@ -345,32 +444,42 @@ class AndroidDriver extends BaseDriver {
345
444
 
346
445
  // Install any "otherApps" that were specified in caps
347
446
  if (this.opts.otherApps) {
348
- let otherApps;
447
+ /** @type {string[]} */
448
+ let otherApps: string[];
349
449
  try {
350
450
  otherApps = helpers.parseArray(this.opts.otherApps);
351
451
  } catch (e) {
352
- this.log.errorAndThrow(`Could not parse "otherApps" capability: ${e.message}`);
452
+ this.log.errorAndThrow(`Could not parse "otherApps" capability: ${(e as Error).message}`);
453
+ return; // unreachable
353
454
  }
354
- otherApps = await B.all(otherApps.map((app) => this.helpers.configureApp(app, APP_EXTENSION)));
355
- await helpers.installOtherApks(otherApps, this.adb, this.opts);
455
+ otherApps = await B.all(
456
+ otherApps.map((app) => this.helpers.configureApp(app, APP_EXTENSION))
457
+ );
458
+ await helpers.installOtherApks(otherApps, this.adb!, this.opts);
356
459
  }
357
460
 
358
461
  // install app
359
462
  if (!this.opts.app) {
360
463
  if (this.opts.fullReset) {
361
- this.log.errorAndThrow('Full reset requires an app capability, use fastReset if app is not provided');
464
+ this.log.errorAndThrow(
465
+ 'Full reset requires an app capability, use fastReset if app is not provided'
466
+ );
362
467
  }
363
468
  this.log.debug('No app capability. Assuming it is already on the device');
364
469
  if (this.opts.fastReset) {
365
- await helpers.resetApp(this.adb, this.opts);
470
+ await helpers.resetApp(this.adb!, this.opts);
366
471
  }
367
472
  return;
368
473
  }
369
474
  if (!this.opts.skipUninstall) {
370
- await this.adb.uninstallApk(this.opts.appPackage);
475
+ await this.adb!.uninstallApk(this.opts.appPackage!);
371
476
  }
372
- await helpers.installApk(this.adb, this.opts);
373
- const apkStringsForLanguage = await helpers.pushStrings(this.opts.language, this.adb, this.opts);
477
+ await helpers.installApk(this.adb!, this.opts);
478
+ const apkStringsForLanguage = await helpers.pushStrings(
479
+ this.opts.language,
480
+ this.adb!,
481
+ this.opts
482
+ );
374
483
  if (this.opts.language) {
375
484
  this.apkStrings[this.opts.language] = apkStringsForLanguage;
376
485
  }
@@ -382,26 +491,30 @@ class AndroidDriver extends BaseDriver {
382
491
  }
383
492
  }
384
493
 
385
- async checkAppPresent () {
494
+ async checkAppPresent() {
386
495
  this.log.debug('Checking whether app is actually present');
496
+ // @ts-expect-error do not put arbitrary properties on opts
387
497
  if (!(await fs.exists(this.opts.app))) {
388
498
  this.log.errorAndThrow(`Could not find app apk at ${this.opts.app}`);
389
499
  }
390
500
  }
391
501
 
392
- async checkPackagePresent () {
502
+ async checkPackagePresent() {
393
503
  this.log.debug('Checking whether package is present on the device');
394
- if (!(await this.adb.shell(['pm', 'list', 'packages', this.opts.appPackage]))) {
504
+ if (!(await this.adb!.shell(['pm', 'list', 'packages', String(this.opts.appPackage)]))) {
395
505
  this.log.errorAndThrow(`Could not find package ${this.opts.appPackage} on the device`);
396
506
  }
397
507
  }
398
508
 
399
- // Set CompressedLayoutHierarchy on the device
400
- async setCompressedLayoutHierarchy (compress) {
401
- await this.bootstrap.sendAction('compressedLayoutHierarchy', {compressLayout: compress});
509
+ /**
510
+ * Set CompressedLayoutHierarchy on the device
511
+ * @privateRemarks FIXME: unknown param type
512
+ */
513
+ async setCompressedLayoutHierarchy(compress: any) {
514
+ await this.bootstrap!.sendAction('compressedLayoutHierarchy', {compressLayout: compress});
402
515
  }
403
516
 
404
- async deleteSession () {
517
+ async deleteSession() {
405
518
  this.log.debug('Shutting down Android driver');
406
519
 
407
520
  try {
@@ -410,7 +523,7 @@ class AndroidDriver extends BaseDriver {
410
523
  }
411
524
  } catch (ign) {}
412
525
 
413
- await helpers.removeAllSessionWebSocketHandlers(this.server, this.sessionId);
526
+ await helpers.removeAllSessionWebSocketHandlers(this.server!, this.sessionId!);
414
527
 
415
528
  await this.mobileStopScreenStreaming();
416
529
 
@@ -424,14 +537,14 @@ class AndroidDriver extends BaseDriver {
424
537
  await this.adb?.setIME(this.defaultIME);
425
538
  }
426
539
  if (!this.isChromeSession && !this.opts.dontStopAppOnReset) {
427
- await this.adb?.forceStop(this.opts.appPackage);
540
+ await this.adb?.forceStop(this.opts.appPackage!);
428
541
  }
429
542
  await this.adb?.goToHome();
430
543
  if (this.opts.fullReset && !this.opts.skipUninstall && !this.appOnDevice) {
431
- await this.adb?.uninstallApk(this.opts.appPackage);
544
+ await this.adb?.uninstallApk(this.opts.appPackage!);
432
545
  }
433
546
  await this.bootstrap.shutdown();
434
- this.bootstrap = null;
547
+ this.bootstrap = undefined;
435
548
  } else {
436
549
  this.log.debug("Called deleteSession but bootstrap wasn't active");
437
550
  }
@@ -446,38 +559,48 @@ class AndroidDriver extends BaseDriver {
446
559
  await this.adb?.setAnimationState(true);
447
560
 
448
561
  // This was necessary to change animation scale over Android P. We must reset the policy for the security.
449
- if (await this.adb?.getApiLevel() >= 28) {
562
+ if (this.adb && (await this.adb.getApiLevel()) >= 28) {
450
563
  this.log.info('Restoring hidden api policy to the device default configuration');
451
564
  await this.adb?.setDefaultHiddenApiPolicy(!!this.opts.ignoreHiddenApiPolicyError);
452
565
  }
453
566
  }
454
567
 
568
+ // @ts-expect-error do not put arbitrary properties on opts
455
569
  if (this.opts.reboot) {
456
- let avdName = this.opts.avd.replace('@', '');
570
+ // @ts-expect-error do not put arbitrary properties on opts
571
+ const avdName = this.opts.avd.replace('@', '');
457
572
  this.log.debug(`closing emulator '${avdName}'`);
458
573
  await this.adb?.killEmulator(avdName);
459
574
  }
460
575
  }
461
576
 
462
- async setSharedPreferences () {
463
- let sharedPrefs = this.opts.sharedPreferences;
577
+ /**
578
+ *
579
+ * @param {AndroidDriverOpts} [opts]
580
+ */
581
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
582
+ async setSharedPreferences(opts: AndroidDriverOpts) {
583
+ const sharedPrefs = this.opts.sharedPreferences!;
464
584
  this.log.info('Trying to set shared preferences');
465
- let name = sharedPrefs.name;
585
+ const name = sharedPrefs.name;
466
586
  if (_.isUndefined(name)) {
467
- this.log.warn(`Skipping setting Shared preferences, name is undefined: ${JSON.stringify(sharedPrefs)}`);
587
+ this.log.warn(
588
+ `Skipping setting Shared preferences, name is undefined: ${JSON.stringify(sharedPrefs)}`
589
+ );
468
590
  return false;
469
591
  }
470
- let remotePath = `/data/data/${this.opts.appPackage}/shared_prefs`;
471
- let remoteFile = `${remotePath}/${name}.xml`;
472
- let localPath = `/tmp/${name}.xml`;
473
- let builder = this.getPrefsBuilder();
592
+ const remotePath = `/data/data/${this.opts.appPackage}/shared_prefs`;
593
+ const remoteFile = `${remotePath}/${name}.xml`;
594
+ const localPath = `/tmp/${name}.xml`;
595
+ const builder = this.getPrefsBuilder();
474
596
  builder.build(sharedPrefs.prefs);
475
597
  this.log.info(`Creating temporary shared preferences: ${localPath}`);
476
598
  builder.toFile(localPath);
477
599
  this.log.info(`Creating shared_prefs remote folder: ${remotePath}`);
478
- await this.adb.shell(['mkdir', '-p', remotePath]);
600
+
601
+ await this.adb!.shell(['mkdir', '-p', remotePath]);
479
602
  this.log.info(`Pushing shared_prefs to ${remoteFile}`);
480
- await this.adb.push(localPath, remoteFile);
603
+ await this.adb!.push(localPath, remoteFile);
481
604
  try {
482
605
  this.log.info(`Trying to remove shared preferences temporary file`);
483
606
  if (await fs.exists(localPath)) {
@@ -489,36 +612,59 @@ class AndroidDriver extends BaseDriver {
489
612
  return true;
490
613
  }
491
614
 
492
- getPrefsBuilder () {
615
+ getPrefsBuilder() {
493
616
  /* Add this method to create a new SharedPrefsBuilder instead of
494
617
  * directly creating the object on setSharedPreferences for testing purposes
495
- */
618
+ */
496
619
  return new SharedPrefsBuilder();
497
620
  }
498
621
 
499
- validateDesiredCaps (caps) {
622
+ /**
623
+ *
624
+ * @param {any} caps
625
+ * @returns {caps is AndroidDriverCaps}
626
+ */
627
+ validateDesiredCaps(caps: any): caps is AndroidDriverCaps {
500
628
  if (!super.validateDesiredCaps(caps)) {
501
629
  return false;
502
630
  }
503
- if ((!caps.browserName || !helpers.isChromeBrowser(caps.browserName)) && !caps.app && !caps.appPackage) {
504
- this.log.errorAndThrow('The desired capabilities must include either an app, appPackage or browserName');
631
+ if (
632
+ (!caps.browserName || !helpers.isChromeBrowser(caps.browserName)) &&
633
+ !caps.app &&
634
+ !caps.appPackage
635
+ ) {
636
+ this.log.errorAndThrow(
637
+ 'The desired capabilities must include either an app, appPackage or browserName'
638
+ );
505
639
  }
506
640
  return helpers.validateDesiredCaps(caps);
507
641
  }
508
642
 
509
- proxyActive (sessionId) {
643
+ /**
644
+ *
645
+ * @param {string} sessionId
646
+ */
647
+ proxyActive(sessionId: string) {
510
648
  super.proxyActive(sessionId);
511
649
 
512
650
  return this.jwpProxyActive;
513
651
  }
514
652
 
515
- getProxyAvoidList (sessionId) {
653
+ /**
654
+ *
655
+ * @param {string} sessionId
656
+ */
657
+ getProxyAvoidList(sessionId: string) {
516
658
  super.getProxyAvoidList(sessionId);
517
659
 
518
660
  return this.jwpProxyAvoid;
519
661
  }
520
662
 
521
- canProxy (sessionId) {
663
+ /**
664
+ *
665
+ * @param {string} sessionId
666
+ */
667
+ canProxy(sessionId: string) {
522
668
  super.canProxy(sessionId);
523
669
 
524
670
  // this will change depending on ChromeDriver status
@@ -526,5 +672,5 @@ class AndroidDriver extends BaseDriver {
526
672
  }
527
673
  }
528
674
 
529
- export { AndroidDriver };
530
- export default AndroidDriver;
675
+ export {commands as androidCommands} from './commands';
676
+ export {AndroidDriver};