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,110 +1,124 @@
1
+ // @ts-check
1
2
 
2
-
3
- let commands = {}, helpers = {}, extensions = {};
4
-
5
- commands.pressKeyCode = async function (keycode, metastate = null, flags = null) {
6
- return await this.uiautomator2.jwproxy.command('/appium/device/press_keycode', 'POST', {
7
- keycode,
8
- metastate,
9
- flags,
10
- });
11
- };
12
-
13
- commands.longPressKeyCode = async function (keycode, metastate = null, flags = null) {
14
- return await this.uiautomator2.jwproxy.command('/appium/device/long_press_keycode', 'POST', {
15
- keycode,
16
- metastate,
17
- flags
18
- });
19
- };
20
-
21
- commands.doSwipe = async function (swipeOpts) {
22
- return await this.uiautomator2.jwproxy.command(`/touch/perform`, 'POST', swipeOpts);
23
- };
24
-
25
- commands.doDrag = async function (dragOpts) {
26
- return await this.uiautomator2.jwproxy.command(`/touch/drag`, 'POST', dragOpts);
27
- };
28
-
29
- commands.getOrientation = async function () {
30
- return await this.uiautomator2.jwproxy.command(`/orientation`, 'GET', {});
31
- };
32
-
33
- commands.setOrientation = async function (orientation) {
34
- orientation = orientation.toUpperCase();
35
- return await this.uiautomator2.jwproxy.command(`/orientation`, 'POST', {orientation});
36
- };
37
-
38
- /**
39
- * @typedef {Object} PressKeyOptions
40
- * @property {number} keycode A valid Android key code. See https://developer.android.com/reference/android/view/KeyEvent
41
- * for the list of available key codes
42
- * @property {number?} metastate An integer in which each bit set to 1 represents a pressed meta key. See
43
- * https://developer.android.com/reference/android/view/KeyEvent for more details.
44
- * @property {string?} flags Flags for the particular key event. See
45
- * https://developer.android.com/reference/android/view/KeyEvent for more details.
46
- * @property {boolean} isLongPress [false] Whether to emulate long key press
47
- */
3
+ import {mixin} from './mixins';
48
4
 
49
5
  /**
50
- * Emulates single key press of the key with the given code.
51
- *
52
- * @param {PressKeyOptions} opts
6
+ * @type {import('./mixins').UIA2ActionsMixin}
7
+ * @satisfies {import('@appium/types').ExternalDriver}
53
8
  */
54
- commands.mobilePressKey = async function mobilePressKey(opts = {}) {
55
- const {
56
- keycode,
57
- metastate,
58
- flags,
59
- isLongPress = false,
60
- } = opts;
61
-
62
- return await this.uiautomator2.jwproxy.command(
63
- `/appium/device/${isLongPress ? 'long_' : ''}press_keycode`,
64
- 'POST', {
65
- keycode,
66
- metastate,
67
- flags
68
- }
69
- );
9
+ const ActionsMixin = {
10
+ async pressKeyCode(keycode, metastate, flags) {
11
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
12
+ '/appium/device/press_keycode',
13
+ 'POST',
14
+ {
15
+ keycode,
16
+ metastate,
17
+ flags,
18
+ }
19
+ );
20
+ },
21
+
22
+ async longPressKeyCode(keycode, metastate, flags) {
23
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
24
+ '/appium/device/long_press_keycode',
25
+ 'POST',
26
+ {
27
+ keycode,
28
+ metastate,
29
+ flags,
30
+ }
31
+ );
32
+ },
33
+
34
+ async doSwipe(swipeOpts) {
35
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
36
+ `/touch/perform`,
37
+ 'POST',
38
+ swipeOpts
39
+ );
40
+ },
41
+
42
+ async doDrag(dragOpts) {
43
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
44
+ `/touch/drag`,
45
+ 'POST',
46
+ dragOpts
47
+ );
48
+ },
49
+
50
+ async getOrientation() {
51
+ return /** @type {import('@appium/types').Orientation} */ (
52
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
53
+ `/orientation`,
54
+ 'GET',
55
+ {}
56
+ )
57
+ );
58
+ },
59
+
60
+ async setOrientation(orientation) {
61
+ orientation = /** @type {import('@appium/types').Orientation} */ (orientation.toUpperCase());
62
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
63
+ `/orientation`,
64
+ 'POST',
65
+ {orientation}
66
+ );
67
+ },
68
+
69
+ async mobilePressKey(opts) {
70
+ const {keycode, metastate, flags, isLongPress = false} = opts;
71
+
72
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
73
+ `/appium/device/${isLongPress ? 'long_' : ''}press_keycode`,
74
+ 'POST',
75
+ {
76
+ keycode,
77
+ metastate,
78
+ flags,
79
+ }
80
+ );
81
+ },
82
+
83
+ /**
84
+ * See https://github.com/appium/appium-uiautomator2-driver/blob/master/docs/scheduled-actions.md#mobile-scheduleaction
85
+ * @param {Record<string, any>} opts
86
+ */
87
+ async mobileScheduleAction(opts = {}) {
88
+ return await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
89
+ '/appium/schedule_action',
90
+ 'POST',
91
+ opts
92
+ );
93
+ },
94
+
95
+ /**
96
+ * @see https://github.com/appium/appium-uiautomator2-driver/blob/master/docs/scheduled-actions.md#mobile-getactionhistory
97
+ */
98
+ async mobileGetActionHistory(opts) {
99
+ return /** @type {import('./types').ActionResult} */ (
100
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
101
+ '/appium/action_history',
102
+ 'POST',
103
+ opts ?? {}
104
+ )
105
+ );
106
+ },
107
+
108
+ /**
109
+ * @see https://github.com/appium/appium-uiautomator2-driver/blob/master/docs/scheduled-actions.md#mobile-unscheduleaction
110
+ */
111
+ async mobileUnscheduleAction(opts) {
112
+ return await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
113
+ '/appium/unschedule_action',
114
+ 'POST',
115
+ opts ?? {}
116
+ );
117
+ },
70
118
  };
71
119
 
72
- /**
73
- * See https://github.com/appium/appium-uiautomator2-driver/blob/master/docs/scheduled-actions.md#mobile-scheduleaction
74
- * @param {Record<string, any>} opts
75
- */
76
- commands.mobileScheduleAction = async function mobileScheduleAction (opts = {}) {
77
- return await this.uiautomator2.jwproxy.command('/appium/schedule_action', 'POST', opts);
78
- };
79
-
80
- /**
81
- * @typedef {Object} ActionResult
82
- * @property {number} repeats
83
- * @property {Record<string, any>[][]}
84
- */
120
+ mixin(ActionsMixin);
85
121
 
86
122
  /**
87
- * @typedef {Object} ActionArgs
88
- * @property {string} name
123
+ * @typedef {import('../uiautomator2').UiAutomator2Server} UiAutomator2Server
89
124
  */
90
-
91
- /**
92
- * See https://github.com/appium/appium-uiautomator2-driver/blob/master/docs/scheduled-actions.md#mobile-getactionhistory
93
- * @param {ActionArgs} opts
94
- * @returns {Promise<ActionResult>}
95
- */
96
- commands.mobileGetActionHistory = async function mobileGetActionHistory (opts) {
97
- return await this.uiautomator2.jwproxy.command('/appium/action_history', 'POST', opts ?? {});
98
- };
99
-
100
- /**
101
- * See https://github.com/appium/appium-uiautomator2-driver/blob/master/docs/scheduled-actions.md#mobile-unscheduleaction
102
- * @param {ActionArgs} opts
103
- */
104
- commands.mobileUnscheduleAction = async function mobileUnscheduleAction (opts) {
105
- return await this.uiautomator2.jwproxy.command('/appium/unschedule_action', 'POST', opts ?? {});
106
- };
107
-
108
- Object.assign(extensions, commands, helpers);
109
- export { commands, helpers };
110
- export default extensions;
@@ -1,53 +1,45 @@
1
- let commands = {}, helpers = {}, extensions = {};
1
+ // @ts-check
2
2
 
3
- commands.getAlertText = async function () {
4
- return await this.uiautomator2.jwproxy.command('/alert/text', 'GET', {});
5
- };
6
-
7
- /**
8
- * @typedef {Object} AcceptAlertOptions
9
- * @property {?string} buttonLabel - The name of the button to click in order to
10
- * accept the alert. If the name is not provided
11
- * then the script will try to detect the button
12
- * automatically.
13
- */
3
+ import {mixin} from './mixins';
14
4
 
15
5
  /**
16
- * @param {AcceptAlertOptions} opts
17
- * @throws {InvalidElementStateError} If no matching button, that can accept the alert,
18
- * can be found
19
- * @throws {NoAlertOpenError} If no alert is present
6
+ * @type {import('./mixins').UIA2AlertMixin}
7
+ * @satisfies {import('@appium/types').ExternalDriver}
20
8
  */
21
- commands.mobileAcceptAlert = async function (opts = {}) {
22
- return await this.uiautomator2.jwproxy.command('/alert/accept', 'POST', opts);
23
- };
24
-
25
- commands.postAcceptAlert = async function () {
26
- return await this.mobileAcceptAlert();
9
+ const AlertMixin = {
10
+ async getAlertText() {
11
+ return String(
12
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
13
+ '/alert/text',
14
+ 'GET',
15
+ {}
16
+ )
17
+ );
18
+ },
19
+ async mobileAcceptAlert(opts = {}) {
20
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
21
+ '/alert/accept',
22
+ 'POST',
23
+ opts
24
+ );
25
+ },
26
+ async postAcceptAlert() {
27
+ await this.mobileAcceptAlert();
28
+ },
29
+ async mobileDismissAlert(opts = {}) {
30
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
31
+ '/alert/dismiss',
32
+ 'POST',
33
+ opts
34
+ );
35
+ },
36
+ async postDismissAlert() {
37
+ await this.mobileDismissAlert();
38
+ },
27
39
  };
28
40
 
29
- /**
30
- * @typedef {Object} DismissAlertOptions
31
- * @property {?string} buttonLabel - The name of the button to click in order to
32
- * dismiss the alert. If the name is not provided
33
- * then the script will try to detect the button
34
- * automatically.
35
- */
41
+ mixin(AlertMixin);
36
42
 
37
43
  /**
38
- * @param {DismissAlertOptions} opts
39
- * @throws {InvalidElementStateError} If no matching button, that can dismiss the alert,
40
- * can be found
41
- * @throws {NoAlertOpenError} If no alert is present
44
+ * @typedef {import('../uiautomator2').UiAutomator2Server} UiAutomator2Server
42
45
  */
43
- commands.mobileDismissAlert = async function (opts = {}) {
44
- return await this.uiautomator2.jwproxy.command('/alert/dismiss', 'POST', opts);
45
- };
46
-
47
- commands.postDismissAlert = async function () {
48
- return await this.mobileDismissAlert();
49
- };
50
-
51
- Object.assign(extensions, commands, helpers);
52
- export { commands, helpers };
53
- export default extensions;
@@ -1,76 +1,97 @@
1
+ // @ts-check
2
+
3
+ import {mixin} from './mixins';
1
4
  import _ from 'lodash';
2
- import { fs, tempDir } from 'appium/support';
5
+ import {fs, tempDir} from 'appium/support';
3
6
 
4
- const commands = {};
7
+ /**
8
+ * @type {import('./mixins').UIA2AppStringsMixin}
9
+ * @satisfies {import('@appium/types').ExternalDriver}
10
+ */
11
+ const AppStringsMixin = {
12
+ async getStrings(language) {
13
+ const adb = /** @type {ADB} */ (this.adb);
14
+ if (!language) {
15
+ language = await adb.getDeviceLanguage();
16
+ this.log.info(`No language specified, returning strings for: ${language}`);
17
+ }
5
18
 
6
- commands.getStrings = async function (language) {
7
- if (!language) {
8
- language = await this.adb.getDeviceLanguage();
9
- this.log.info(`No language specified, returning strings for: ${language}`);
10
- }
19
+ /**
20
+ * Clients require the resulting mapping to have both keys
21
+ * and values of type string
22
+ * @param {StringRecord} mapping
23
+ */
24
+ const preprocessStringsMap = function (mapping) {
25
+ /** @type {StringRecord} */
26
+ const result = {};
27
+ for (const [key, value] of _.toPairs(mapping)) {
28
+ result[key] = _.isString(value) ? value : JSON.stringify(value);
29
+ }
30
+ return result;
31
+ };
11
32
 
12
- // Clients require the resulting mapping to have both keys
13
- // and values of type string
14
- const preprocessStringsMap = function (mapping) {
15
- const result = {};
16
- for (const [key, value] of _.toPairs(mapping)) {
17
- result[key] = _.isString(value) ? value : JSON.stringify(value);
33
+ if (this.apkStrings[language]) {
34
+ // Return cached strings
35
+ return preprocessStringsMap(this.apkStrings[language]);
18
36
  }
19
- return result;
20
- };
21
37
 
22
- if (this.apkStrings[language]) {
23
- // Return cached strings
24
- return preprocessStringsMap(this.apkStrings[language]);
25
- }
38
+ if (!this.opts.app && !this.opts.appPackage) {
39
+ this.log.errorAndThrow("One of 'app' or 'appPackage' capabilities should must be specified");
40
+ throw new Error(); // unreachable
41
+ }
42
+
43
+ let app = this.opts.app;
44
+ const tmpRoot = await tempDir.openDir();
45
+ try {
46
+ if (!app) {
47
+ try {
48
+ app = await adb.pullApk(/** @type {string} */ (this.opts.appPackage), tmpRoot);
49
+ } catch (err) {
50
+ this.log.errorAndThrow(
51
+ `Failed to pull an apk from '${this.opts.appPackage}'. Original error: ${
52
+ /** @type {Error} */ (err).message
53
+ }`
54
+ );
55
+ throw new Error(); // unreachable
56
+ }
57
+ }
26
58
 
27
- if (!this.opts.app && !this.opts.appPackage) {
28
- this.log.errorAndThrow("One of 'app' or 'appPackage' capabilities should must be specified");
29
- }
59
+ if (!(await fs.exists(app))) {
60
+ this.log.errorAndThrow(`The app at '${app}' does not exist`);
61
+ throw new Error(); // unreachable
62
+ }
30
63
 
31
- let app = this.opts.app;
32
- const tmpRoot = await tempDir.openDir();
33
- try {
34
- if (!app) {
35
64
  try {
36
- app = await this.adb.pullApk(this.opts.appPackage, tmpRoot);
65
+ const {apkStrings} = await adb.extractStringsFromApk(app, language, tmpRoot);
66
+ this.apkStrings[language] = apkStrings;
67
+ return preprocessStringsMap(apkStrings);
37
68
  } catch (err) {
38
- this.log.errorAndThrow(`Failed to pull an apk from '${this.opts.appPackage}'. Original error: ${err.message}`);
69
+ this.log.errorAndThrow(
70
+ `Cannot extract strings from '${app}'. Original error: ${
71
+ /** @type {Error} */ (err).message
72
+ }`
73
+ );
74
+ throw new Error(); // unreachable
39
75
  }
76
+ } finally {
77
+ await fs.rimraf(tmpRoot);
40
78
  }
79
+ },
41
80
 
42
- if (!await fs.exists(app)) {
43
- this.log.errorAndThrow(`The app at '${app}' does not exist`);
44
- }
45
-
46
- try {
47
- const {apkStrings} = await this.adb.extractStringsFromApk(app, language, tmpRoot);
48
- this.apkStrings[language] = apkStrings;
49
- return preprocessStringsMap(apkStrings);
50
- } catch (err) {
51
- this.log.errorAndThrow(`Cannot extract strings from '${app}'. Original error: ${err.message}`);
52
- }
53
- } finally {
54
- await fs.rimraf(tmpRoot);
55
- }
81
+ /**
82
+ * Retrives app strings from its resources for the given language
83
+ * or the default device language.
84
+ *
85
+ * @returns App strings map
86
+ */
87
+ async mobileGetAppStrings(opts) {
88
+ return await this.getStrings(opts?.language);
89
+ },
56
90
  };
57
91
 
58
- /**
59
- * @typedef {Object} GetAppStringsOptions
60
- * @property {string?} language The language abbreviation to fetch app strings mapping for. If no
61
- * language is provided then strings for the default language on the device under test
62
- * would be returned. Examples: en, fr
63
- */
92
+ mixin(AppStringsMixin);
64
93
 
65
94
  /**
66
- * Retrives app strings from its resources for the given language
67
- * or the default device language.
68
- *
69
- * @param {GetAppStringsOptions} opts
70
- * @returns {Promise<object>} App strings map
95
+ * @typedef {import('appium-adb').ADB} ADB
96
+ * @typedef {import('@appium/types').StringRecord} StringRecord
71
97
  */
72
- commands.mobileGetAppStrings = async function mobileGetAppStrings (opts = {}) {
73
- return await this.getStrings(opts.language);
74
- };
75
-
76
- export default commands;
@@ -1,34 +1,33 @@
1
- let extensions = {}, commands = {};
1
+ // @ts-check
2
2
 
3
- /**
4
- * @typedef {Object} BatteryInfo
5
- *
6
- * @property {number} level - Battery level in range [0.0, 1.0], where
7
- * 1.0 means 100% charge.
8
- * -1 is returned if the actual value cannot be
9
- * retrieved from the system.
10
- * @property {number} state - Battery state. The following values are possible:
11
- * BATTERY_STATUS_UNKNOWN = 1
12
- * BATTERY_STATUS_CHARGING = 2
13
- * BATTERY_STATUS_DISCHARGING = 3
14
- * BATTERY_STATUS_NOT_CHARGING = 4
15
- * BATTERY_STATUS_FULL = 5
16
- * -1 is returned if the actual value cannot be retrieved from the system.
17
- */
3
+ import {mixin} from './mixins';
18
4
 
19
5
  /**
20
- * Reads the battery information from the device under test.
21
- *
22
- * @returns {BatteryInfo} The actual battery info
6
+ * @type {import('./mixins').UIA2BatteryMixin}
7
+ * @satisfies {import('@appium/types').ExternalDriver}
23
8
  */
24
- commands.mobileGetBatteryInfo = async function () {
25
- const result = await this.uiautomator2.jwproxy.command('/appium/device/battery_info', 'GET', {});
26
- // Give it the same name as in iOS
27
- result.state = result.status;
28
- delete result.status;
29
- return result;
9
+ const BatteryMixin = {
10
+ /**
11
+ * Reads the battery information from the device under test.
12
+ *
13
+ * @returns The actual battery info
14
+ */
15
+ async mobileGetBatteryInfo() {
16
+ const result = /** @type {import('./types').MapKey<BatteryInfo, 'state', 'status'>} */ (
17
+ await /** @type {import('../uiautomator2').UiAutomator2Server} */ (
18
+ this.uiautomator2
19
+ ).jwproxy.command('/appium/device/battery_info', 'GET', {})
20
+ );
21
+ const batteryInfo = /** @type {any} */ (result);
22
+ // Give it the same name as in iOS
23
+ batteryInfo.state = result.status;
24
+ delete batteryInfo.status;
25
+ return /** @type {BatteryInfo} */ (batteryInfo);
26
+ },
30
27
  };
31
28
 
32
- Object.assign(extensions, commands);
33
- export { commands };
34
- export default extensions;
29
+ mixin(BatteryMixin);
30
+
31
+ /**
32
+ * @typedef {import('./types').BatteryInfo} BatteryInfo
33
+ */