appium-uiautomator2-driver 2.42.2 → 2.43.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 (114) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/build/lib/commands/actions.d.ts +22 -1
  3. package/build/lib/commands/actions.d.ts.map +1 -1
  4. package/build/lib/commands/actions.js +30 -62
  5. package/build/lib/commands/actions.js.map +1 -1
  6. package/build/lib/commands/alert.d.ts +28 -1
  7. package/build/lib/commands/alert.d.ts.map +1 -1
  8. package/build/lib/commands/alert.js +42 -23
  9. package/build/lib/commands/alert.js.map +1 -1
  10. package/build/lib/commands/app-management.d.ts +19 -0
  11. package/build/lib/commands/app-management.d.ts.map +1 -0
  12. package/build/lib/commands/app-management.js +45 -0
  13. package/build/lib/commands/app-management.js.map +1 -0
  14. package/build/lib/commands/app-strings.d.ts +9 -0
  15. package/build/lib/commands/app-strings.d.ts.map +1 -1
  16. package/build/lib/commands/app-strings.js +11 -79
  17. package/build/lib/commands/app-strings.js.map +1 -1
  18. package/build/lib/commands/battery.d.ts +7 -0
  19. package/build/lib/commands/battery.d.ts.map +1 -1
  20. package/build/lib/commands/battery.js +14 -20
  21. package/build/lib/commands/battery.js.map +1 -1
  22. package/build/lib/commands/element.d.ts +100 -1
  23. package/build/lib/commands/element.d.ts.map +1 -1
  24. package/build/lib/commands/element.js +175 -125
  25. package/build/lib/commands/element.js.map +1 -1
  26. package/build/lib/commands/execute.d.ts +25 -0
  27. package/build/lib/commands/execute.d.ts.map +1 -0
  28. package/build/lib/commands/execute.js +109 -0
  29. package/build/lib/commands/execute.js.map +1 -0
  30. package/build/lib/commands/find.d.ts +10 -0
  31. package/build/lib/commands/find.d.ts.map +1 -1
  32. package/build/lib/commands/find.js +25 -27
  33. package/build/lib/commands/find.js.map +1 -1
  34. package/build/lib/commands/gestures.d.ts +103 -1
  35. package/build/lib/commands/gestures.d.ts.map +1 -1
  36. package/build/lib/commands/gestures.js +202 -173
  37. package/build/lib/commands/gestures.js.map +1 -1
  38. package/build/lib/commands/keyboard.d.ts +47 -0
  39. package/build/lib/commands/keyboard.d.ts.map +1 -0
  40. package/build/lib/commands/keyboard.js +92 -0
  41. package/build/lib/commands/keyboard.js.map +1 -0
  42. package/build/lib/commands/misc.d.ts +48 -0
  43. package/build/lib/commands/misc.d.ts.map +1 -0
  44. package/build/lib/commands/misc.js +75 -0
  45. package/build/lib/commands/misc.js.map +1 -0
  46. package/build/lib/commands/navigation.d.ts +20 -0
  47. package/build/lib/commands/navigation.d.ts.map +1 -0
  48. package/build/lib/commands/navigation.js +35 -0
  49. package/build/lib/commands/navigation.js.map +1 -0
  50. package/build/lib/commands/screenshot.d.ts +24 -1
  51. package/build/lib/commands/screenshot.d.ts.map +1 -1
  52. package/build/lib/commands/screenshot.js +87 -64
  53. package/build/lib/commands/screenshot.js.map +1 -1
  54. package/build/lib/commands/touch.d.ts +81 -0
  55. package/build/lib/commands/touch.d.ts.map +1 -1
  56. package/build/lib/commands/touch.js +158 -41
  57. package/build/lib/commands/touch.js.map +1 -1
  58. package/build/lib/commands/viewport.d.ts +37 -1
  59. package/build/lib/commands/viewport.d.ts.map +1 -1
  60. package/build/lib/commands/viewport.js +80 -36
  61. package/build/lib/commands/viewport.js.map +1 -1
  62. package/build/lib/driver.d.ts +94 -24
  63. package/build/lib/driver.d.ts.map +1 -1
  64. package/build/lib/driver.js +114 -28
  65. package/build/lib/driver.js.map +1 -1
  66. package/build/lib/helpers.d.ts +12 -6
  67. package/build/lib/helpers.d.ts.map +1 -1
  68. package/build/lib/helpers.js +18 -18
  69. package/build/lib/helpers.js.map +1 -1
  70. package/build/lib/method-map.d.ts +0 -23
  71. package/build/lib/method-map.d.ts.map +1 -1
  72. package/build/lib/uiautomator2.js +3 -3
  73. package/build/lib/uiautomator2.js.map +1 -1
  74. package/build/tsconfig.tsbuildinfo +1 -1
  75. package/lib/commands/actions.js +37 -114
  76. package/lib/commands/alert.js +51 -37
  77. package/lib/commands/app-management.js +42 -0
  78. package/lib/commands/app-strings.js +9 -89
  79. package/lib/commands/battery.js +16 -26
  80. package/lib/commands/element.js +235 -214
  81. package/lib/commands/execute.js +120 -0
  82. package/lib/commands/find.js +31 -37
  83. package/lib/commands/gestures.js +252 -234
  84. package/lib/commands/keyboard.js +103 -0
  85. package/lib/commands/misc.js +106 -0
  86. package/lib/commands/navigation.js +31 -0
  87. package/lib/commands/screenshot.js +96 -77
  88. package/lib/commands/touch.js +190 -48
  89. package/lib/commands/viewport.js +100 -50
  90. package/lib/driver.ts +225 -36
  91. package/lib/helpers.js +15 -22
  92. package/lib/uiautomator2.js +3 -3
  93. package/npm-shrinkwrap.json +34 -34
  94. package/package.json +2 -2
  95. package/build/lib/commands/general.d.ts +0 -4
  96. package/build/lib/commands/general.d.ts.map +0 -1
  97. package/build/lib/commands/general.js +0 -214
  98. package/build/lib/commands/general.js.map +0 -1
  99. package/build/lib/commands/index.d.ts +0 -2
  100. package/build/lib/commands/index.d.ts.map +0 -1
  101. package/build/lib/commands/index.js +0 -14
  102. package/build/lib/commands/index.js.map +0 -1
  103. package/build/lib/commands/mixins.d.ts +0 -87
  104. package/build/lib/commands/mixins.d.ts.map +0 -1
  105. package/build/lib/commands/mixins.js +0 -26
  106. package/build/lib/commands/mixins.js.map +0 -1
  107. package/build/lib/utils.d.ts +0 -10
  108. package/build/lib/utils.d.ts.map +0 -1
  109. package/build/lib/utils.js +0 -26
  110. package/build/lib/utils.js.map +0 -1
  111. package/lib/commands/general.js +0 -289
  112. package/lib/commands/index.js +0 -11
  113. package/lib/commands/mixins.ts +0 -169
  114. package/lib/utils.js +0 -19
@@ -1,50 +1,100 @@
1
- // @ts-check
2
-
3
- import {imageUtil} from 'appium/support';
4
- import {mixin} from './mixins';
5
-
6
- /**
7
- * @type {import('./mixins').UIA2ViewportMixin}
8
- * @satisfies {import('@appium/types').ExternalDriver}
9
- */
10
- const ViewportMixin = {
11
- // memoized in constructor
12
- async getStatusBarHeight() {
13
- const {statusBar} = /** @type {{statusBar: number}} */ (
14
- await /** @type {import('../uiautomator2').UiAutomator2Server} */ (
15
- this.uiautomator2
16
- ).jwproxy.command(`/appium/device/system_bars`, 'GET', {})
17
- );
18
- return statusBar;
19
- },
20
-
21
- // memoized in constructor
22
- async getDevicePixelRatio() {
23
- return String(
24
- await /** @type {import('../uiautomator2').UiAutomator2Server} */ (
25
- this.uiautomator2
26
- ).jwproxy.command('/appium/device/pixel_ratio', 'GET', {})
27
- );
28
- },
29
-
30
- async getViewportScreenshot() {
31
- const screenshot = await this.getScreenshot();
32
- const rect = await this.getViewPortRect();
33
- return await imageUtil.cropBase64Image(screenshot, rect);
34
- },
35
-
36
- async getViewPortRect() {
37
- const windowSize = await this.getWindowSize();
38
- const statusBarHeight = await this.getStatusBarHeight();
39
- // android returns the upscaled window size, so to get the true size of the
40
- // rect we have to downscale
41
- return {
42
- left: 0,
43
- top: statusBarHeight,
44
- width: windowSize.width,
45
- height: windowSize.height - statusBarHeight,
46
- };
47
- },
48
- };
49
-
50
- mixin(ViewportMixin);
1
+
2
+ // memoized in constructor
3
+ /**
4
+ * @this {AndroidUiautomator2Driver}
5
+ * @returns {Promise<number>}
6
+ */
7
+ export async function getStatusBarHeight() {
8
+ const {statusBar} = /** @type {{statusBar: number}} */ (
9
+ await /** @type {import('../uiautomator2').UiAutomator2Server} */ (
10
+ this.uiautomator2
11
+ ).jwproxy.command(`/appium/device/system_bars`, 'GET', {})
12
+ );
13
+ return statusBar;
14
+ }
15
+
16
+ // memoized in constructor
17
+ /**
18
+ * @this {AndroidUiautomator2Driver}
19
+ * @returns {Promise<string>}
20
+ */
21
+ export async function getDevicePixelRatio() {
22
+ return String(
23
+ await /** @type {import('../uiautomator2').UiAutomator2Server} */ (
24
+ this.uiautomator2
25
+ ).jwproxy.command('/appium/device/pixel_ratio', 'GET', {})
26
+ );
27
+ }
28
+
29
+ /**
30
+ * @this {AndroidUiautomator2Driver}
31
+ * @returns {Promise<import('./types').RelativeRect>}
32
+ */
33
+ export async function getViewPortRect() {
34
+ const windowSize = await this.getWindowSize();
35
+ const statusBarHeight = await this.getStatusBarHeight();
36
+ // android returns the upscaled window size, so to get the true size of the
37
+ // rect we have to downscale
38
+ return {
39
+ left: 0,
40
+ top: statusBarHeight,
41
+ width: windowSize.width,
42
+ height: windowSize.height - statusBarHeight,
43
+ };
44
+ }
45
+
46
+ /**
47
+ * Returns the viewport coordinates.
48
+ * @this {AndroidUiautomator2Driver}
49
+ * @returns {Promise<import('./types').RelativeRect>} The viewport coordinates.
50
+ */
51
+ export async function mobileViewPortRect() {
52
+ return await this.getViewPortRect();
53
+ }
54
+
55
+ // For W3C
56
+ /**
57
+ * @this {AndroidUiautomator2Driver}
58
+ * @returns {Promise<import('@appium/types').Rect>}
59
+ */
60
+ export async function getWindowRect() {
61
+ const {width, height} = await this.getWindowSize();
62
+ return {
63
+ width,
64
+ height,
65
+ x: 0,
66
+ y: 0,
67
+ };
68
+ }
69
+
70
+ /**
71
+ * @this {AndroidUiautomator2Driver}
72
+ * @returns {Promise<number>}
73
+ */
74
+ export async function getDisplayDensity() {
75
+ return /** @type {number} */ (
76
+ await this.uiautomator2.jwproxy.command(
77
+ '/appium/device/display_density',
78
+ 'GET',
79
+ {}
80
+ )
81
+ );
82
+ }
83
+
84
+ /**
85
+ * @this {AndroidUiautomator2Driver}
86
+ * @returns {Promise<import('@appium/types').Size>}
87
+ */
88
+ export async function getWindowSize() {
89
+ return /** @type {import('@appium/types').Size} */ (
90
+ await this.uiautomator2.jwproxy.command(
91
+ '/window/current/size',
92
+ 'GET',
93
+ {}
94
+ )
95
+ );
96
+ }
97
+
98
+ /**
99
+ * @typedef {import('../driver').AndroidUiautomator2Driver} AndroidUiautomator2Driver
100
+ */
package/lib/driver.ts CHANGED
@@ -10,7 +10,7 @@ import type {
10
10
  StringRecord,
11
11
  } from '@appium/types';
12
12
  import {DEFAULT_ADB_PORT} from 'appium-adb';
13
- import AndroidDriver, {androidHelpers} from 'appium-android-driver';
13
+ import AndroidDriver, {utils} from 'appium-android-driver';
14
14
  import {SETTINGS_HELPER_ID} from 'io.appium.settings';
15
15
  import {BaseDriver, DeviceSettings} from 'appium/driver';
16
16
  import {fs, mjpeg, util} from 'appium/support';
@@ -24,8 +24,8 @@ import type {ExecError} from 'teen_process';
24
24
  import UIAUTOMATOR2_CONSTRAINTS, {type Uiautomator2Constraints} from './constraints';
25
25
  import {executeMethodMap} from './execute-method-map';
26
26
  import {APKS_EXTENSION, APK_EXTENSION} from './extensions';
27
- import uiautomator2Helpers from './helpers';
28
27
  import {newMethodMap} from './method-map';
28
+ import { signApp } from './helpers';
29
29
  import type { EmptyObject } from 'type-fest';
30
30
  import type {
31
31
  Uiautomator2Settings,
@@ -38,8 +38,115 @@ import type {
38
38
  W3CUiautomator2DriverCaps,
39
39
  } from './types';
40
40
  import {SERVER_PACKAGE_ID, SERVER_TEST_PACKAGE_ID, UiAutomator2Server} from './uiautomator2';
41
-
42
- const helpers = {...uiautomator2Helpers, ...androidHelpers};
41
+ import {
42
+ mobileGetActionHistory,
43
+ mobileScheduleAction,
44
+ mobileUnscheduleAction,
45
+ } from './commands/actions';
46
+ import {
47
+ getAlertText,
48
+ mobileAcceptAlert,
49
+ mobileDismissAlert,
50
+ postAcceptAlert,
51
+ postDismissAlert,
52
+ } from './commands/alert';
53
+ import {
54
+ mobileInstallMultipleApks,
55
+ mobileBackgroundApp,
56
+ } from './commands/app-management';
57
+ import {
58
+ mobileGetAppStrings,
59
+ } from './commands/app-strings';
60
+ import {
61
+ mobileGetBatteryInfo,
62
+ } from './commands/battery';
63
+ import {
64
+ active,
65
+ getAttribute,
66
+ elementEnabled,
67
+ elementDisplayed,
68
+ elementSelected,
69
+ getName,
70
+ getLocation,
71
+ getSize,
72
+ getElementRect,
73
+ getElementScreenshot,
74
+ getText,
75
+ setValueImmediate,
76
+ doSetElementValue,
77
+ click,
78
+ clear,
79
+ mobileReplaceElementValue,
80
+ } from './commands/element';
81
+ import {
82
+ execute,
83
+ executeMobile,
84
+ } from './commands/execute';
85
+ import {
86
+ doFindElementOrEls,
87
+ } from './commands/find';
88
+ import {
89
+ mobileClickGesture,
90
+ mobileDoubleClickGesture,
91
+ mobileDragGesture,
92
+ mobileFlingGesture,
93
+ mobileLongClickGesture,
94
+ mobilePinchCloseGesture,
95
+ mobilePinchOpenGesture,
96
+ mobileScroll,
97
+ mobileScrollBackTo,
98
+ mobileScrollGesture,
99
+ mobileSwipeGesture,
100
+ } from './commands/gestures';
101
+ import {
102
+ pressKeyCode,
103
+ longPressKeyCode,
104
+ mobilePressKey,
105
+ mobileType,
106
+ doSendKeys,
107
+ keyevent,
108
+ } from './commands/keyboard';
109
+ import {
110
+ getPageSource,
111
+ getOrientation,
112
+ setOrientation,
113
+ getClipboard,
114
+ openNotifications,
115
+ suspendChromedriverProxy,
116
+ mobileGetDeviceInfo,
117
+ } from './commands/misc';
118
+ import {
119
+ setUrl,
120
+ mobileDeepLink,
121
+ back,
122
+ } from './commands/navigation';
123
+ import {
124
+ mobileScreenshots,
125
+ mobileViewportScreenshot,
126
+ getScreenshot,
127
+ getViewportScreenshot,
128
+ } from './commands/screenshot';
129
+ import {
130
+ doSwipe,
131
+ doDrag,
132
+ touchDown,
133
+ touchLongClick,
134
+ touchMove,
135
+ touchUp,
136
+ tap,
137
+ doPerformMultiAction,
138
+ performActions,
139
+ releaseActions,
140
+ } from './commands/touch';
141
+ import {
142
+ getStatusBarHeight,
143
+ getDevicePixelRatio,
144
+ getDisplayDensity,
145
+ getViewPortRect,
146
+ getWindowRect,
147
+ getWindowSize,
148
+ mobileViewPortRect,
149
+ } from './commands/viewport';
43
150
 
44
151
  // The range of ports we can use on the system for communicating to the
45
152
  // UiAutomator2 HTTP server on the device
@@ -207,7 +314,6 @@ class AndroidUiautomator2Driver
207
314
  this.desiredCapConstraints = _.cloneDeep(UIAUTOMATOR2_CONSTRAINTS);
208
315
  this.jwpProxyActive = false;
209
316
  this.jwpProxyAvoid = NO_PROXY;
210
- this.apkStrings = {}; // map of language -> strings obj
211
317
  this._originalIme = null;
212
318
 
213
319
  this.settings = new DeviceSettings(
@@ -226,10 +332,7 @@ class AndroidUiautomator2Driver
226
332
  }
227
333
 
228
334
  override validateDesiredCaps(caps: any): caps is Uiautomator2DriverCaps {
229
- return (
230
- BaseDriver.prototype.validateDesiredCaps.call(this, caps) &&
231
- androidHelpers.validateDesiredCaps(caps)
232
- );
335
+ return super.validateDesiredCaps(caps);
233
336
  }
234
337
 
235
338
  async createSession(
@@ -271,7 +374,7 @@ class AndroidUiautomator2Driver
271
374
 
272
375
  if (this.isChromeSession) {
273
376
  this.log.info("We're going to run a Chrome-based session");
274
- const {pkg, activity} = helpers.getChromePkg(this.opts.browserName!);
377
+ const {pkg, activity} = utils.getChromePkg(this.opts.browserName!);
275
378
  this.opts.appPackage = this.caps.appPackage = pkg;
276
379
  this.opts.appActivity = this.caps.appActivity = activity;
277
380
  this.log.info(`Chrome-type package and activity are ${pkg} and ${activity}`);
@@ -354,7 +457,7 @@ class AndroidUiautomator2Driver
354
457
  `Forwarding UiAutomator2 Server port ${DEVICE_PORT} to local port ${localPort}`
355
458
  );
356
459
  if ((await checkPortStatus(localPort, LOCALHOST_IP4)) === 'open') {
357
- this.log.errorAndThrow(
460
+ throw this.log.errorAndThrow(
358
461
  `UiAutomator2 Server cannot start because the local port #${localPort} is busy. ` +
359
462
  `Make sure the port you provide via 'systemPort' capability is not occupied. ` +
360
463
  `This situation might often be a result of an inaccurate sessions management, e.g. ` +
@@ -374,13 +477,12 @@ class AndroidUiautomator2Driver
374
477
  try {
375
478
  this.systemPort = await findAPortNotInUse(startPort, endPort);
376
479
  } catch (e) {
377
- this.log.errorAndThrow(
480
+ throw this.log.errorAndThrow(
378
481
  `Cannot find any free port in range ${startPort}..${endPort}}. ` +
379
482
  `Please set the available port number by providing the systemPort capability or ` +
380
483
  `double check the processes that are locking ports within this range and terminate ` +
381
484
  `these which are not needed anymore`
382
485
  );
383
- throw new Error(); // unreachable
384
486
  }
385
487
  await forwardPort(this.systemPort);
386
488
  });
@@ -422,14 +524,14 @@ class AndroidUiautomator2Driver
422
524
  caps: Uiautomator2StartSessionOpts
423
525
  ): Promise<Uiautomator2SessionCaps> {
424
526
  // get device udid for this session
425
- const {udid, emPort} = await helpers.getDeviceInfoFromCaps(this.opts);
527
+ const {udid, emPort} = await this.getDeviceInfoFromCaps();
426
528
  this.opts.udid = udid;
427
529
  // @ts-expect-error do not put random stuff on opts
428
530
  this.opts.emPort = emPort;
429
531
 
430
532
  // now that we know our java version and device info, we can create our
431
533
  // ADB instance
432
- this.adb = await androidHelpers.createADB(this.opts);
534
+ this.adb = await this.createADB();
433
535
 
434
536
  const apiLevel = await this.adb.getApiLevel();
435
537
 
@@ -470,7 +572,7 @@ class AndroidUiautomator2Driver
470
572
  }
471
573
 
472
574
  // get appPackage et al from manifest if necessary
473
- const appInfo = await helpers.getLaunchInfo(this.adb, this.opts);
575
+ const appInfo = await this.getLaunchInfo();
474
576
  // and get it onto our 'opts' object so we use it from now on
475
577
  this.opts = {...this.opts, ...(appInfo ?? {})};
476
578
 
@@ -489,7 +591,7 @@ class AndroidUiautomator2Driver
489
591
  if (this.opts.hideKeyboard) {
490
592
  this._originalIme = await this.adb.defaultIME();
491
593
  }
492
- await helpers.initDevice(this.adb, this.opts);
594
+ await this.initDevice();
493
595
 
494
596
  // Prepare the device by forwarding the UiAutomator2 port
495
597
  // This call mutates this.systemPort if it is not set explicitly
@@ -544,7 +646,7 @@ class AndroidUiautomator2Driver
544
646
  // Unlock the device after the session is started.
545
647
  if (!this.opts.skipUnlock) {
546
648
  // unlock the device to prepare it for testing
547
- await helpers.unlock(this as any, this.adb, this.caps);
649
+ await this.unlock();
548
650
  } else {
549
651
  this.log.debug(`'skipUnlock' capability set, so skipping device unlock`);
550
652
  }
@@ -623,9 +725,8 @@ class AndroidUiautomator2Driver
623
725
  async initAUT() {
624
726
  // Uninstall any uninstallOtherPackages which were specified in caps
625
727
  if (this.opts.uninstallOtherPackages) {
626
- await helpers.uninstallOtherPackages(
627
- this.adb!,
628
- helpers.parseArray(this.opts.uninstallOtherPackages),
728
+ await this.uninstallOtherPackages(
729
+ utils.parseArray(this.opts.uninstallOtherPackages),
629
730
  [SETTINGS_HELPER_ID, SERVER_PACKAGE_ID, SERVER_TEST_PACKAGE_ID]
630
731
  );
631
732
  }
@@ -634,15 +735,14 @@ class AndroidUiautomator2Driver
634
735
  if (this.opts.otherApps) {
635
736
  let otherApps;
636
737
  try {
637
- otherApps = helpers.parseArray(this.opts.otherApps);
738
+ otherApps = utils.parseArray(this.opts.otherApps);
638
739
  } catch (e) {
639
- this.log.errorAndThrow(`Could not parse "otherApps" capability: ${(e as Error).message}`);
640
- throw new Error(); // unrechable
740
+ throw this.log.errorAndThrow(`Could not parse "otherApps" capability: ${(e as Error).message}`);
641
741
  }
642
742
  otherApps = await B.all(
643
743
  otherApps.map((app) => this.helpers.configureApp(app, [APK_EXTENSION, APKS_EXTENSION]))
644
744
  );
645
- await helpers.installOtherApks(otherApps, this.adb!, this.opts);
745
+ await this.installOtherApks(otherApps);
646
746
  }
647
747
 
648
748
  if (this.opts.app) {
@@ -656,12 +756,12 @@ class AndroidUiautomator2Driver
656
756
  requireDefaultCert: false,
657
757
  }))
658
758
  ) {
659
- await helpers.signApp(this.adb!, this.opts.app);
759
+ await signApp(this.adb!, this.opts.app);
660
760
  }
661
761
  if (!this.opts.skipUninstall) {
662
762
  await this.adb!.uninstallApk(this.opts.appPackage!);
663
763
  }
664
- await helpers.installApk(this.adb!, this.opts);
764
+ await this.installAUT();
665
765
  } else {
666
766
  this.log.debug(
667
767
  'noReset has been requested and the app is already installed. Doing nothing'
@@ -669,13 +769,13 @@ class AndroidUiautomator2Driver
669
769
  }
670
770
  } else {
671
771
  if (this.opts.fullReset) {
672
- this.log.errorAndThrow(
772
+ throw this.log.errorAndThrow(
673
773
  'Full reset requires an app capability, use fastReset if app is not provided'
674
774
  );
675
775
  }
676
776
  this.log.debug('No app capability. Assuming it is already on the device');
677
777
  if (this.opts.fastReset && this.opts.appPackage) {
678
- await helpers.resetApp(this.adb!, this.opts);
778
+ await this.resetAUT();
679
779
  }
680
780
  }
681
781
  }
@@ -738,8 +838,6 @@ class AndroidUiautomator2Driver
738
838
  },
739
839
  ];
740
840
 
741
- await androidHelpers.removeAllSessionWebSocketHandlers(this.server, this.sessionId);
742
-
743
841
  try {
744
842
  await this.stopChromedriverProxies();
745
843
  } catch (err) {
@@ -827,14 +925,13 @@ class AndroidUiautomator2Driver
827
925
  this.log.info('Closing MJPEG stream');
828
926
  this.mjpegStream.stop();
829
927
  }
830
- await BaseDriver.prototype.deleteSession.call(this);
928
+ await super.deleteSession();
831
929
  }
832
930
 
833
931
  async checkAppPresent() {
834
932
  this.log.debug('Checking whether app is actually present');
835
933
  if (!this.opts.app || !(await fs.exists(this.opts.app))) {
836
- this.log.errorAndThrow(`Could not find app apk at '${this.opts.app}'`);
837
- throw new Error(); // unreachable
934
+ throw this.log.errorAndThrow(`Could not find app apk at '${this.opts.app}'`);
838
935
  }
839
936
  }
840
937
 
@@ -887,8 +984,100 @@ class AndroidUiautomator2Driver
887
984
  )) as Partial<Uiautomator2Settings>;
888
985
  return {...driverSettings, ...serverSettings} as any;
889
986
  }
890
- }
891
987
 
892
- import './commands';
988
+ mobileGetActionHistory = mobileGetActionHistory;
989
+ mobileScheduleAction = mobileScheduleAction;
990
+ mobileUnscheduleAction = mobileUnscheduleAction;
991
+
992
+ getAlertText = getAlertText;
993
+ mobileAcceptAlert = mobileAcceptAlert;
994
+ mobileDismissAlert = mobileDismissAlert;
995
+ postAcceptAlert = postAcceptAlert;
996
+ postDismissAlert = postDismissAlert;
997
+
998
+ mobileInstallMultipleApks = mobileInstallMultipleApks;
999
+ mobileBackgroundApp = mobileBackgroundApp;
1000
+
1001
+ mobileGetAppStrings = mobileGetAppStrings;
1002
+
1003
+ mobileGetBatteryInfo = mobileGetBatteryInfo;
1004
+
1005
+ active = active;
1006
+ getAttribute = getAttribute;
1007
+ elementEnabled = elementEnabled;
1008
+ elementDisplayed = elementDisplayed;
1009
+ elementSelected = elementSelected;
1010
+ getName = getName;
1011
+ getLocation = getLocation;
1012
+ getSize = getSize;
1013
+ getElementRect = getElementRect;
1014
+ getElementScreenshot = getElementScreenshot;
1015
+ getText = getText;
1016
+ setValueImmediate = setValueImmediate;
1017
+ doSetElementValue = doSetElementValue;
1018
+ click = click;
1019
+ clear = clear;
1020
+ mobileReplaceElementValue = mobileReplaceElementValue;
1021
+
1022
+ execute = execute;
1023
+ executeMobile = executeMobile;
1024
+
1025
+ doFindElementOrEls = doFindElementOrEls;
1026
+
1027
+ mobileClickGesture = mobileClickGesture;
1028
+ mobileDoubleClickGesture = mobileDoubleClickGesture;
1029
+ mobileDragGesture = mobileDragGesture;
1030
+ mobileFlingGesture = mobileFlingGesture;
1031
+ mobileLongClickGesture = mobileLongClickGesture;
1032
+ mobilePinchCloseGesture = mobilePinchCloseGesture;
1033
+ mobilePinchOpenGesture = mobilePinchOpenGesture;
1034
+ mobileScroll = mobileScroll;
1035
+ mobileScrollBackTo = mobileScrollBackTo;
1036
+ mobileScrollGesture = mobileScrollGesture;
1037
+ mobileSwipeGesture = mobileSwipeGesture;
1038
+
1039
+ pressKeyCode = pressKeyCode;
1040
+ longPressKeyCode = longPressKeyCode;
1041
+ mobilePressKey = mobilePressKey;
1042
+ mobileType = mobileType;
1043
+ doSendKeys = doSendKeys;
1044
+ keyevent = keyevent;
1045
+
1046
+ getPageSource = getPageSource;
1047
+ getOrientation = getOrientation;
1048
+ setOrientation = setOrientation;
1049
+ getClipboard = getClipboard;
1050
+ openNotifications = openNotifications;
1051
+ suspendChromedriverProxy = suspendChromedriverProxy;
1052
+ mobileGetDeviceInfo = mobileGetDeviceInfo;
1053
+
1054
+ setUrl = setUrl;
1055
+ mobileDeepLink = mobileDeepLink;
1056
+ back = back;
1057
+
1058
+ mobileScreenshots = mobileScreenshots;
1059
+ mobileViewportScreenshot = mobileViewportScreenshot;
1060
+ getScreenshot = getScreenshot;
1061
+ getViewportScreenshot = getViewportScreenshot;
1062
+
1063
+ doSwipe = doSwipe;
1064
+ doDrag = doDrag;
1065
+ touchDown = touchDown;
1066
+ touchLongClick = touchLongClick;
1067
+ touchMove = touchMove;
1068
+ touchUp = touchUp;
1069
+ tap = tap;
1070
+ doPerformMultiAction = doPerformMultiAction;
1071
+ performActions = performActions;
1072
+ releaseActions = releaseActions;
1073
+
1074
+ getStatusBarHeight = getStatusBarHeight;
1075
+ getDevicePixelRatio = getDevicePixelRatio;
1076
+ getDisplayDensity = getDisplayDensity;
1077
+ getViewPortRect = getViewPortRect;
1078
+ getWindowRect = getWindowRect;
1079
+ getWindowSize = getWindowSize;
1080
+ mobileViewPortRect = mobileViewPortRect;
1081
+ }
893
1082
 
894
1083
  export {AndroidUiautomator2Driver};
package/lib/helpers.js CHANGED
@@ -1,22 +1,11 @@
1
1
  import path from 'path';
2
2
  import { fs, system } from 'appium/support';
3
3
 
4
-
5
- let helpers = {};
6
-
7
- helpers.ensureInternetPermissionForApp = async function (adb, app) {
8
- let has = await adb.hasInternetPermissionFromManifest(app);
9
- if (has) {
10
- return;
11
- }
12
- let msg = 'Your apk does not have INTERNET permissions. Uiautomator2 needs ' +
13
- 'the internet permission to proceed. Please check if you have ' +
14
- '<uses-permission android:name="android.**permission.INTERNET"/>' +
15
- 'in your AndroidManifest.xml';
16
- throw new Error(msg);
17
- };
18
-
19
- helpers.isWriteable = async function isWriteable (filePath) {
4
+ /**
5
+ * @param {string} filePath
6
+ * @returns {Promise<boolean>}
7
+ */
8
+ export async function isWriteable(filePath) {
20
9
  try {
21
10
  await fs.access(filePath, fs.W_OK);
22
11
  if (system.isWindows()) {
@@ -30,15 +19,19 @@ helpers.isWriteable = async function isWriteable (filePath) {
30
19
  } catch (ign) {
31
20
  return false;
32
21
  }
33
- };
22
+ }
34
23
 
35
- helpers.signApp = async function (adb, appPath) {
36
- if (!await this.isWriteable(appPath)) {
24
+ /**
25
+ *
26
+ * @param {import('appium-adb').ADB} adb
27
+ * @param {string} appPath
28
+ * @returns {Promise<void>}
29
+ */
30
+ export async function signApp(adb, appPath) {
31
+ if (!await isWriteable(appPath)) {
37
32
  throw new Error(`The application at '${appPath}' is not writeable. ` +
38
33
  `Please grant write permissions to this file or to its parent folder '${path.dirname(appPath)}' ` +
39
34
  `for the Appium process, so it could sign the application`);
40
35
  }
41
36
  await adb.sign(appPath);
42
- };
43
-
44
- export default helpers;
37
+ }
@@ -10,7 +10,7 @@ import {
10
10
  util, logger, tempDir, fs, timing
11
11
  } from 'appium/support';
12
12
  import B from 'bluebird';
13
- import helpers from './helpers';
13
+ import {isWriteable, signApp} from './helpers';
14
14
  import axios from 'axios';
15
15
  import path from 'path';
16
16
 
@@ -89,7 +89,7 @@ class UiAutomator2Server {
89
89
  if (await this.adb.checkApkCert(resultInfo.appPath, appId)) {
90
90
  resultInfo.wasSigned = true;
91
91
  } else {
92
- if (!await helpers.isWriteable(appPath)) {
92
+ if (!await isWriteable(appPath)) {
93
93
  this.log.warn(
94
94
  `Server package at '${appPath}' is not writeable. ` +
95
95
  `Will copy it into the temporary location at '${tmpRoot}' as a workaround. ` +
@@ -99,7 +99,7 @@ class UiAutomator2Server {
99
99
  await fs.copyFile(appPath, dstPath);
100
100
  resultInfo.appPath = dstPath;
101
101
  }
102
- await helpers.signApp(this.adb, resultInfo.appPath);
102
+ await signApp(this.adb, resultInfo.appPath);
103
103
  }
104
104
 
105
105
  if (appId === SERVER_TEST_PACKAGE_ID && await this.adb.isAppInstalled(appId)) {