appium-android-driver 5.14.7 → 6.0.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.
- package/build/index.d.ts +282 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js.map +1 -0
- package/build/lib/commands/actions.d.ts +6 -224
- package/build/lib/commands/actions.d.ts.map +1 -1
- package/build/lib/commands/actions.js +306 -405
- package/build/lib/commands/actions.js.map +1 -1
- package/build/lib/commands/alert.d.ts +7 -9
- package/build/lib/commands/alert.d.ts.map +1 -1
- package/build/lib/commands/alert.js +24 -18
- package/build/lib/commands/alert.js.map +1 -1
- package/build/lib/commands/app-management.d.ts +7 -313
- package/build/lib/commands/app-management.d.ts.map +1 -1
- package/build/lib/commands/app-management.js +135 -293
- package/build/lib/commands/app-management.js.map +1 -1
- package/build/lib/commands/context.d.ts +8 -92
- package/build/lib/commands/context.d.ts.map +1 -1
- package/build/lib/commands/context.js +381 -439
- package/build/lib/commands/context.js.map +1 -1
- package/build/lib/commands/element.d.ts +8 -35
- package/build/lib/commands/element.d.ts.map +1 -1
- package/build/lib/commands/element.js +153 -136
- package/build/lib/commands/element.js.map +1 -1
- package/build/lib/commands/emu-console.d.ts +6 -48
- package/build/lib/commands/emu-console.d.ts.map +1 -1
- package/build/lib/commands/emu-console.js +19 -34
- package/build/lib/commands/emu-console.js.map +1 -1
- package/build/lib/commands/execute.d.ts +6 -5
- package/build/lib/commands/execute.d.ts.map +1 -1
- package/build/lib/commands/execute.js +77 -66
- package/build/lib/commands/execute.js.map +1 -1
- package/build/lib/commands/file-actions.d.ts +7 -128
- package/build/lib/commands/file-actions.d.ts.map +1 -1
- package/build/lib/commands/file-actions.js +183 -219
- package/build/lib/commands/file-actions.js.map +1 -1
- package/build/lib/commands/find.d.ts +8 -12
- package/build/lib/commands/find.d.ts.map +1 -1
- package/build/lib/commands/find.js +19 -23
- package/build/lib/commands/find.js.map +1 -1
- package/build/lib/commands/general.d.ts +9 -132
- package/build/lib/commands/general.d.ts.map +1 -1
- package/build/lib/commands/general.js +281 -312
- package/build/lib/commands/general.js.map +1 -1
- package/build/lib/commands/ime.d.ts +7 -10
- package/build/lib/commands/ime.d.ts.map +1 -1
- package/build/lib/commands/ime.js +47 -35
- package/build/lib/commands/ime.js.map +1 -1
- package/build/lib/commands/index.d.ts +27 -2
- package/build/lib/commands/index.d.ts.map +1 -1
- package/build/lib/commands/index.js +41 -19
- package/build/lib/commands/index.js.map +1 -1
- package/build/lib/commands/intent.d.ts +7 -417
- package/build/lib/commands/intent.d.ts.map +1 -1
- package/build/lib/commands/intent.js +104 -216
- package/build/lib/commands/intent.js.map +1 -1
- package/build/lib/commands/keyboard.d.ts +6 -5
- package/build/lib/commands/keyboard.d.ts.map +1 -1
- package/build/lib/commands/keyboard.js +16 -8
- package/build/lib/commands/keyboard.js.map +1 -1
- package/build/lib/commands/log.d.ts +7 -44
- package/build/lib/commands/log.d.ts.map +1 -1
- package/build/lib/commands/log.js +146 -108
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/media-projection.d.ts +7 -143
- package/build/lib/commands/media-projection.d.ts.map +1 -1
- package/build/lib/commands/media-projection.js +113 -140
- package/build/lib/commands/media-projection.js.map +1 -1
- package/build/lib/commands/mixins.d.ts +740 -0
- package/build/lib/commands/mixins.d.ts.map +1 -0
- package/build/lib/commands/mixins.js +19 -0
- package/build/lib/commands/mixins.js.map +1 -0
- package/build/lib/commands/network.d.ts +7 -138
- package/build/lib/commands/network.d.ts.map +1 -1
- package/build/lib/commands/network.js +212 -254
- package/build/lib/commands/network.js.map +1 -1
- package/build/lib/commands/performance.d.ts +24 -70
- package/build/lib/commands/performance.d.ts.map +1 -1
- package/build/lib/commands/performance.js +144 -100
- package/build/lib/commands/performance.js.map +1 -1
- package/build/lib/commands/permissions.d.ts +8 -92
- package/build/lib/commands/permissions.d.ts.map +1 -1
- package/build/lib/commands/permissions.js +75 -87
- package/build/lib/commands/permissions.js.map +1 -1
- package/build/lib/commands/recordscreen.d.ts +7 -193
- package/build/lib/commands/recordscreen.d.ts.map +1 -1
- package/build/lib/commands/recordscreen.js +151 -182
- package/build/lib/commands/recordscreen.js.map +1 -1
- package/build/lib/commands/shell.d.ts +7 -7
- package/build/lib/commands/shell.d.ts.map +1 -1
- package/build/lib/commands/shell.js +40 -33
- package/build/lib/commands/shell.js.map +1 -1
- package/build/lib/commands/streamscreen.d.ts +9 -103
- package/build/lib/commands/streamscreen.d.ts.map +1 -1
- package/build/lib/commands/streamscreen.js +261 -218
- package/build/lib/commands/streamscreen.js.map +1 -1
- package/build/lib/commands/system-bars.d.ts +22 -90
- package/build/lib/commands/system-bars.d.ts.map +1 -1
- package/build/lib/commands/system-bars.js +76 -74
- package/build/lib/commands/system-bars.js.map +1 -1
- package/build/lib/commands/touch.d.ts +10 -29
- package/build/lib/commands/touch.d.ts.map +1 -1
- package/build/lib/commands/touch.js +301 -285
- package/build/lib/commands/touch.js.map +1 -1
- package/build/lib/commands/types.d.ts +978 -0
- package/build/lib/commands/types.d.ts.map +1 -0
- package/build/lib/commands/types.js +3 -0
- package/build/lib/commands/types.js.map +1 -0
- package/build/lib/constraints.d.ts +291 -0
- package/build/lib/constraints.d.ts.map +1 -0
- package/build/lib/constraints.js +300 -0
- package/build/lib/constraints.js.map +1 -0
- package/build/lib/driver.d.ts +68 -37
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +123 -80
- package/build/lib/driver.js.map +1 -1
- package/build/lib/helpers/android.d.ts +164 -0
- package/build/lib/helpers/android.d.ts.map +1 -0
- package/build/lib/helpers/android.js +819 -0
- package/build/lib/helpers/android.js.map +1 -0
- package/build/lib/helpers/index.d.ts +7 -0
- package/build/lib/helpers/index.d.ts.map +1 -0
- package/build/lib/helpers/index.js +29 -0
- package/build/lib/helpers/index.js.map +1 -0
- package/build/lib/helpers/types.d.ts +121 -0
- package/build/lib/helpers/types.d.ts.map +1 -0
- package/build/lib/helpers/types.js +3 -0
- package/build/lib/helpers/types.js.map +1 -0
- package/build/lib/helpers/unlock.d.ts +32 -0
- package/build/lib/helpers/unlock.d.ts.map +1 -0
- package/build/lib/helpers/unlock.js +273 -0
- package/build/lib/helpers/unlock.js.map +1 -0
- package/build/lib/helpers/webview.d.ts +74 -0
- package/build/lib/helpers/webview.d.ts.map +1 -0
- package/build/lib/helpers/webview.js +421 -0
- package/build/lib/helpers/webview.js.map +1 -0
- package/build/lib/index.d.ts +9 -0
- package/build/lib/index.d.ts.map +1 -0
- package/build/lib/index.js +37 -0
- package/build/lib/index.js.map +1 -0
- package/build/lib/method-map.d.ts +0 -8
- package/build/lib/method-map.d.ts.map +1 -1
- package/build/lib/method-map.js +63 -74
- package/build/lib/method-map.js.map +1 -1
- package/build/lib/stubs.d.ts +0 -1
- package/build/lib/stubs.d.ts.map +1 -1
- package/build/lib/stubs.js +1 -0
- package/build/lib/stubs.js.map +1 -1
- package/build/lib/utils.d.ts +1 -1
- package/build/lib/utils.d.ts.map +1 -1
- package/lib/commands/actions.js +351 -464
- package/lib/commands/alert.js +27 -17
- package/lib/commands/app-management.js +156 -314
- package/lib/commands/context.js +457 -441
- package/lib/commands/element.js +201 -157
- package/lib/commands/emu-console.js +25 -45
- package/lib/commands/execute.js +106 -90
- package/lib/commands/file-actions.js +222 -240
- package/lib/commands/find.ts +103 -0
- package/lib/commands/general.js +327 -339
- package/lib/commands/ime.js +50 -34
- package/lib/commands/{index.js → index.ts} +20 -24
- package/lib/commands/intent.js +108 -249
- package/lib/commands/keyboard.js +20 -8
- package/lib/commands/log.js +172 -116
- package/lib/commands/media-projection.js +134 -161
- package/lib/commands/mixins.ts +966 -0
- package/lib/commands/network.js +252 -281
- package/lib/commands/performance.js +203 -132
- package/lib/commands/permissions.js +108 -109
- package/lib/commands/recordscreen.js +212 -209
- package/lib/commands/shell.js +51 -40
- package/lib/commands/streamscreen.js +355 -289
- package/lib/commands/system-bars.js +92 -83
- package/lib/commands/touch.js +357 -294
- package/lib/commands/types.ts +1097 -0
- package/lib/{desired-caps.js → constraints.ts} +106 -103
- package/lib/{driver.js → driver.ts} +278 -132
- package/lib/helpers/android.ts +1143 -0
- package/lib/helpers/index.ts +6 -0
- package/lib/helpers/types.ts +134 -0
- package/lib/helpers/unlock.ts +329 -0
- package/lib/helpers/webview.ts +582 -0
- package/lib/index.ts +18 -0
- package/lib/method-map.js +87 -98
- package/lib/stubs.ts +0 -1
- package/package.json +27 -20
- package/index.js +0 -24
- package/lib/android-helpers.js +0 -983
- package/lib/commands/coverage.js +0 -18
- package/lib/commands/find.js +0 -82
- package/lib/unlock-helpers.js +0 -278
- package/lib/webview-helpers.js +0 -602
package/lib/commands/element.js
CHANGED
|
@@ -1,168 +1,212 @@
|
|
|
1
|
-
|
|
2
|
-
import { retryInterval } from 'asyncbox';
|
|
3
|
-
import { util } from '@appium/support';
|
|
1
|
+
// @ts-check
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
let p = {attribute, elementId};
|
|
10
|
-
return await this.bootstrap.sendAction('element:getAttribute', p);
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
commands.getName = async function getName (elementId) {
|
|
14
|
-
return await this.getAttribute('className', elementId);
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
commands.elementDisplayed = async function elementDisplayed (elementId) {
|
|
18
|
-
return await this.getAttribute('displayed', elementId) === 'true';
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
commands.elementEnabled = async function elementEnabled (elementId) {
|
|
22
|
-
return await this.getAttribute('enabled', elementId) === 'true';
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
commands.elementSelected = async function elementSelected (elementId) {
|
|
26
|
-
return await this.getAttribute('selected', elementId) === 'true';
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
helpers.setElementValue = async function setElementValue (keys, elementId, replace = false) {
|
|
30
|
-
let text = keys;
|
|
31
|
-
if (keys instanceof Array) {
|
|
32
|
-
text = keys.join('');
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
let params = {
|
|
36
|
-
elementId,
|
|
37
|
-
text,
|
|
38
|
-
replace,
|
|
39
|
-
unicodeKeyboard: this.opts.unicodeKeyboard
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
return await this.doSetElementValue(params);
|
|
43
|
-
};
|
|
3
|
+
import {AndroidHelpers as androidHelpers} from '../helpers';
|
|
4
|
+
import {mixin} from './mixins';
|
|
5
|
+
import {retryInterval} from 'asyncbox';
|
|
6
|
+
import {util} from '@appium/support';
|
|
44
7
|
|
|
45
8
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* Other android-drivers (like appium-uiautomator2-driver) need to override doSetElementValue
|
|
49
|
-
* to facilitate setElementValue.
|
|
9
|
+
* @type {import('./mixins').ElementMixin & ThisType<import('../driver').AndroidDriver>}
|
|
10
|
+
* @satisfies {import('@appium/types').ExternalDriver}
|
|
50
11
|
*/
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
commands.clear = async function clear (elementId) {
|
|
81
|
-
let text = (await this.getText(elementId)) || '';
|
|
82
|
-
let length = text.length;
|
|
83
|
-
if (length === 0) {
|
|
84
|
-
// if length is zero there are two possibilities:
|
|
85
|
-
// 1. there is nothing in the text field
|
|
86
|
-
// 2. it is a password field
|
|
87
|
-
// since there is little overhead to the adb call, delete 100 elements
|
|
88
|
-
// if we get zero, just in case it is #2
|
|
89
|
-
length = 100;
|
|
90
|
-
}
|
|
91
|
-
await this.click(elementId);
|
|
92
|
-
this.log.debug(`Sending up to ${length} clear characters to device`);
|
|
93
|
-
return await retryInterval(5, 500, async () => {
|
|
94
|
-
let remainingLength = length;
|
|
95
|
-
while (remainingLength > 0) {
|
|
96
|
-
let lengthToSend = remainingLength < 50 ? remainingLength : 50;
|
|
97
|
-
this.log.debug(`Sending ${lengthToSend} clear characters to device`);
|
|
98
|
-
await this.adb.clearTextField(lengthToSend);
|
|
99
|
-
remainingLength -= lengthToSend;
|
|
12
|
+
const ElementMixin = {
|
|
13
|
+
async getAttribute(attribute, elementId) {
|
|
14
|
+
let p = {attribute, elementId};
|
|
15
|
+
return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction(
|
|
16
|
+
'element:getAttribute',
|
|
17
|
+
p
|
|
18
|
+
);
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
async getName(elementId) {
|
|
22
|
+
return await this.getAttribute('className', elementId);
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
async elementDisplayed(elementId) {
|
|
26
|
+
return (await this.getAttribute('displayed', elementId)) === 'true';
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
async elementEnabled(elementId) {
|
|
30
|
+
return (await this.getAttribute('enabled', elementId)) === 'true';
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
async elementSelected(elementId) {
|
|
34
|
+
return (await this.getAttribute('selected', elementId)) === 'true';
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
async setElementValue(keys, elementId, replace = false) {
|
|
38
|
+
let text = keys;
|
|
39
|
+
if (keys instanceof Array) {
|
|
40
|
+
text = keys.join('');
|
|
100
41
|
}
|
|
101
|
-
});
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
commands.click = async function click (elementId) {
|
|
105
|
-
return await this.bootstrap.sendAction('element:click', {elementId});
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
commands.getLocation = async function getLocation (elementId) {
|
|
109
|
-
return await this.bootstrap.sendAction('element:getLocation', {elementId});
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
commands.getLocationInView = async function getLocationInView (elementId) {
|
|
113
|
-
return await this.getLocation(elementId);
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
commands.getSize = async function getSize (elementId) {
|
|
117
|
-
return await this.bootstrap.sendAction('element:getSize', {elementId});
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
commands.getElementRect = async function getElementRect (elementId) {
|
|
121
|
-
return await this.bootstrap.sendAction('element:getRect', {elementId});
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
commands.touchLongClick = async function touchLongClick (elementId, x, y, duration) {
|
|
125
|
-
let params = {elementId, x, y, duration};
|
|
126
|
-
androidHelpers.removeNullProperties(params);
|
|
127
|
-
return await this.bootstrap.sendAction('element:touchLongClick', params);
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
commands.touchDown = async function touchDown (elementId, x, y) {
|
|
131
|
-
let params = {elementId, x, y};
|
|
132
|
-
androidHelpers.removeNullProperties(params);
|
|
133
|
-
return await this.bootstrap.sendAction('element:touchDown', params);
|
|
134
|
-
};
|
|
135
42
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
43
|
+
let params = {
|
|
44
|
+
elementId,
|
|
45
|
+
text: String(text),
|
|
46
|
+
replace,
|
|
47
|
+
unicodeKeyboard: this.opts.unicodeKeyboard,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
return await this.doSetElementValue(params);
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Reason for isolating doSetElementValue from setElementValue is for reusing setElementValue
|
|
55
|
+
* across android-drivers (like appium-uiautomator2-driver) and to avoid code duplication.
|
|
56
|
+
* Other android-drivers (like appium-uiautomator2-driver) need to override doSetElementValue
|
|
57
|
+
* to facilitate setElementValue.
|
|
58
|
+
*/
|
|
59
|
+
async doSetElementValue(params) {
|
|
60
|
+
return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction(
|
|
61
|
+
'element:setText',
|
|
62
|
+
params
|
|
63
|
+
);
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
async setValue(keys, elementId) {
|
|
67
|
+
return await this.setElementValue(keys, elementId, false);
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
async replaceValue(keys, elementId) {
|
|
71
|
+
return await this.setElementValue(keys, elementId, true);
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
async setValueImmediate(keys, elementId) {
|
|
75
|
+
let text = keys;
|
|
76
|
+
if (keys instanceof Array) {
|
|
77
|
+
text = keys.join('');
|
|
78
|
+
}
|
|
141
79
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
80
|
+
// first, make sure we are focused on the element
|
|
81
|
+
await this.click(elementId);
|
|
82
|
+
|
|
83
|
+
// then send through adb
|
|
84
|
+
await /** @type {ADB} */ (this.adb).inputText(/** @type {string} */ (text));
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
async getText(elementId) {
|
|
88
|
+
return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction('element:getText', {
|
|
89
|
+
elementId,
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
async clear(elementId) {
|
|
94
|
+
let text = (await this.getText(elementId)) || '';
|
|
95
|
+
let length = text.length;
|
|
96
|
+
if (length === 0) {
|
|
97
|
+
// if length is zero there are two possibilities:
|
|
98
|
+
// 1. there is nothing in the text field
|
|
99
|
+
// 2. it is a password field
|
|
100
|
+
// since there is little overhead to the adb call, delete 100 elements
|
|
101
|
+
// if we get zero, just in case it is #2
|
|
102
|
+
length = 100;
|
|
103
|
+
}
|
|
104
|
+
await this.click(elementId);
|
|
105
|
+
this.log.debug(`Sending up to ${length} clear characters to device`);
|
|
106
|
+
await retryInterval(5, 500, async () => {
|
|
107
|
+
let remainingLength = length;
|
|
108
|
+
while (remainingLength > 0) {
|
|
109
|
+
let lengthToSend = remainingLength < 50 ? remainingLength : 50;
|
|
110
|
+
this.log.debug(`Sending ${lengthToSend} clear characters to device`);
|
|
111
|
+
await /** @type {ADB} */ (this.adb).clearTextField(lengthToSend);
|
|
112
|
+
remainingLength -= lengthToSend;
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
async click(elementId) {
|
|
118
|
+
return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction('element:click', {
|
|
119
|
+
elementId,
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
async getLocation(elementId) {
|
|
124
|
+
return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction(
|
|
125
|
+
'element:getLocation',
|
|
126
|
+
{elementId}
|
|
127
|
+
);
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
async getLocationInView(elementId) {
|
|
131
|
+
return await this.getLocation(elementId);
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
async getSize(elementId) {
|
|
135
|
+
return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction('element:getSize', {
|
|
136
|
+
elementId,
|
|
137
|
+
});
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
async getElementRect(elementId) {
|
|
141
|
+
return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction('element:getRect', {
|
|
142
|
+
elementId,
|
|
143
|
+
});
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
async touchLongClick(elementId, x, y, duration) {
|
|
147
|
+
let params = {elementId, x, y, duration};
|
|
148
|
+
androidHelpers.removeNullProperties(params);
|
|
149
|
+
return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction(
|
|
150
|
+
'element:touchLongClick',
|
|
151
|
+
params
|
|
152
|
+
);
|
|
153
|
+
},
|
|
154
|
+
|
|
155
|
+
async touchDown(elementId, x, y) {
|
|
156
|
+
let params = {elementId, x, y};
|
|
157
|
+
androidHelpers.removeNullProperties(params);
|
|
158
|
+
return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction(
|
|
159
|
+
'element:touchDown',
|
|
160
|
+
params
|
|
161
|
+
);
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
async touchUp(elementId, x, y) {
|
|
165
|
+
let params = {elementId, x, y};
|
|
166
|
+
androidHelpers.removeNullProperties(params);
|
|
167
|
+
return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction(
|
|
168
|
+
'element:touchUp',
|
|
169
|
+
params
|
|
170
|
+
);
|
|
171
|
+
},
|
|
172
|
+
|
|
173
|
+
async touchMove(elementId, x, y) {
|
|
174
|
+
let params = {elementId, x, y};
|
|
175
|
+
androidHelpers.removeNullProperties(params);
|
|
176
|
+
return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction(
|
|
177
|
+
'element:touchMove',
|
|
178
|
+
params
|
|
179
|
+
);
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
async complexTap(tapCount, touchCount, duration, x, y) {
|
|
183
|
+
return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction('click', {x, y});
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
async tap(elementId = null, x = null, y = null, count = 1) {
|
|
187
|
+
if (!util.hasValue(elementId) && !util.hasValue(x) && !util.hasValue(y)) {
|
|
188
|
+
throw new Error(`Either element to tap or both absolute coordinates should be defined`);
|
|
189
|
+
}
|
|
190
|
+
for (let i = 0; i < count; i++) {
|
|
191
|
+
if (util.hasValue(elementId)) {
|
|
192
|
+
// FIXME: bootstrap ignores relative coordinates
|
|
193
|
+
await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction('element:click', {
|
|
194
|
+
elementId,
|
|
195
|
+
x,
|
|
196
|
+
y,
|
|
197
|
+
});
|
|
198
|
+
} else {
|
|
199
|
+
await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction('click', {x, y});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
},
|
|
146
203
|
};
|
|
147
204
|
|
|
148
|
-
|
|
149
|
-
return await this.bootstrap.sendAction('click', {x, y});
|
|
150
|
-
};
|
|
205
|
+
mixin(ElementMixin);
|
|
151
206
|
|
|
152
|
-
|
|
153
|
-
if (!util.hasValue(elementId) && !util.hasValue(x) && !util.hasValue(y)) {
|
|
154
|
-
throw new Error(`Either element to tap or both absolute coordinates should be defined`);
|
|
155
|
-
}
|
|
156
|
-
for (let i = 0; i < count; i++) {
|
|
157
|
-
if (util.hasValue(elementId)) {
|
|
158
|
-
// FIXME: bootstrap ignores relative coordinates
|
|
159
|
-
await this.bootstrap.sendAction('element:click', {elementId, x, y});
|
|
160
|
-
} else {
|
|
161
|
-
await this.bootstrap.sendAction('click', {x, y});
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
};
|
|
207
|
+
export default ElementMixin;
|
|
165
208
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
209
|
+
/**
|
|
210
|
+
* @typedef {import('../bootstrap').AndroidBootstrap} AndroidBootstrap
|
|
211
|
+
* @typedef {import('appium-adb').ADB} ADB
|
|
212
|
+
*/
|
|
@@ -1,51 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
// @ts-check
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const commands = {};
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @typedef {Object} ExecOptions
|
|
9
|
-
* @property {!Array<string>|string} command - The actual command to execute. See
|
|
10
|
-
* https://developer.android.com/studio/run/emulator-console for more details
|
|
11
|
-
* on available commands
|
|
12
|
-
* @property {number} execTimeout [60000] A timeout used to wait for a server
|
|
13
|
-
* reply to the given command in milliseconds
|
|
14
|
-
* @property {number} connTimeout [5000] Console connection timeout in milliseconds
|
|
15
|
-
* @property {number} initTimeout [5000] Telnet console initialization timeout
|
|
16
|
-
* in milliseconds (the time between the connection happens and the command prompt
|
|
17
|
-
* is available)
|
|
18
|
-
*/
|
|
3
|
+
import {mixin} from './mixins';
|
|
4
|
+
import {errors} from 'appium/driver';
|
|
19
5
|
|
|
6
|
+
const EMU_CONSOLE_FEATURE = 'emulator_console';
|
|
20
7
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* @param {ExecOptions} opts
|
|
25
|
-
* @returns {string} The command output
|
|
26
|
-
* @throws {Error} If there was an error while connecting to the Telnet console
|
|
27
|
-
* or if the given command returned non-OK response
|
|
8
|
+
* @type {import('./mixins').EmulatorConsoleMixin & ThisType<import('../driver').AndroidDriver>}
|
|
9
|
+
* @satisfies {import('@appium/types').ExternalDriver}
|
|
28
10
|
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
command,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
connTimeout,
|
|
46
|
-
initTimeout,
|
|
47
|
-
});
|
|
11
|
+
const EmulatorConsoleMixin = {
|
|
12
|
+
async mobileExecEmuConsoleCommand(opts) {
|
|
13
|
+
this.ensureFeatureEnabled(EMU_CONSOLE_FEATURE);
|
|
14
|
+
|
|
15
|
+
const {command, execTimeout, connTimeout, initTimeout} = opts;
|
|
16
|
+
|
|
17
|
+
if (!command) {
|
|
18
|
+
throw new errors.InvalidArgumentError(`The 'command' argument is mandatory`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return await /** @type {import('appium-adb').ADB} */ (this.adb).execEmuConsoleCommand(command, {
|
|
22
|
+
execTimeout,
|
|
23
|
+
connTimeout,
|
|
24
|
+
initTimeout,
|
|
25
|
+
});
|
|
26
|
+
},
|
|
48
27
|
};
|
|
49
28
|
|
|
50
|
-
|
|
51
|
-
|
|
29
|
+
mixin(EmulatorConsoleMixin);
|
|
30
|
+
|
|
31
|
+
export default EmulatorConsoleMixin;
|
package/lib/commands/execute.js
CHANGED
|
@@ -1,95 +1,111 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
1
3
|
import _ from 'lodash';
|
|
2
4
|
import {errors, PROTOCOLS} from 'appium/driver';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
5
|
+
import {mixin} from './mixins';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @type {import('./mixins').ExecuteMixin & ThisType<import('../driver').AndroidDriver>}
|
|
9
|
+
* @satisfies {import('@appium/types').ExternalDriver}
|
|
10
|
+
*/
|
|
11
|
+
const ExecuteMixin = {
|
|
12
|
+
async execute(script, args) {
|
|
13
|
+
if (script.match(/^mobile:/)) {
|
|
14
|
+
this.log.info(`Executing native command '${script}'`);
|
|
15
|
+
script = script.replace(/^mobile:/, '').trim();
|
|
16
|
+
return await this.executeMobile(
|
|
17
|
+
script,
|
|
18
|
+
_.isArray(args) ? /** @type {import('@appium/types').StringRecord} */ (args[0]) : args
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
if (!this.isWebContext()) {
|
|
22
|
+
throw new errors.NotImplementedError();
|
|
23
|
+
}
|
|
24
|
+
const endpoint =
|
|
25
|
+
/** @type {import('appium-chromedriver').Chromedriver} */ (this.chromedriver).jwproxy
|
|
26
|
+
.downstreamProtocol === PROTOCOLS.MJSONWP
|
|
27
|
+
? '/execute'
|
|
28
|
+
: '/execute/sync';
|
|
29
|
+
return await /** @type {import('appium-chromedriver').Chromedriver} */ (
|
|
30
|
+
this.chromedriver
|
|
31
|
+
).jwproxy.command(endpoint, 'POST', {
|
|
32
|
+
script,
|
|
33
|
+
args,
|
|
34
|
+
});
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
async executeMobile(mobileCommand, opts = {}) {
|
|
38
|
+
const mobileCommandsMapping = {
|
|
39
|
+
shell: 'mobileShell',
|
|
40
|
+
|
|
41
|
+
execEmuConsoleCommand: 'mobileExecEmuConsoleCommand',
|
|
42
|
+
|
|
43
|
+
startLogsBroadcast: 'mobileStartLogsBroadcast',
|
|
44
|
+
stopLogsBroadcast: 'mobileStopLogsBroadcast',
|
|
45
|
+
|
|
46
|
+
changePermissions: 'mobileChangePermissions',
|
|
47
|
+
getPermissions: 'mobileGetPermissions',
|
|
48
|
+
|
|
49
|
+
performEditorAction: 'mobilePerformEditorAction',
|
|
50
|
+
|
|
51
|
+
sensorSet: 'sensorSet',
|
|
52
|
+
|
|
53
|
+
getDeviceTime: 'mobileGetDeviceTime',
|
|
54
|
+
|
|
55
|
+
startScreenStreaming: 'mobileStartScreenStreaming',
|
|
56
|
+
stopScreenStreaming: 'mobileStopScreenStreaming',
|
|
57
|
+
|
|
58
|
+
getNotifications: 'mobileGetNotifications',
|
|
59
|
+
|
|
60
|
+
listSms: 'mobileListSms',
|
|
61
|
+
|
|
62
|
+
pushFile: 'mobilePushFile',
|
|
63
|
+
pullFile: 'mobilePullFile',
|
|
64
|
+
pullFolder: 'mobilePullFolder',
|
|
65
|
+
deleteFile: 'mobileDeleteFile',
|
|
66
|
+
|
|
67
|
+
isAppInstalled: 'mobileIsAppInstalled',
|
|
68
|
+
queryAppState: 'mobileQueryAppState',
|
|
69
|
+
activateApp: 'mobileActivateApp',
|
|
70
|
+
removeApp: 'mobileRemoveApp',
|
|
71
|
+
terminateApp: 'mobileTerminateApp',
|
|
72
|
+
installApp: 'mobileInstallApp',
|
|
73
|
+
clearApp: 'mobileClearApp',
|
|
74
|
+
|
|
75
|
+
startService: 'mobileStartService',
|
|
76
|
+
stopService: 'mobileStopService',
|
|
77
|
+
startActivity: 'mobileStartActivity',
|
|
78
|
+
broadcast: 'mobileBroadcast',
|
|
79
|
+
|
|
80
|
+
getContexts: 'mobileGetContexts',
|
|
81
|
+
|
|
82
|
+
lock: 'mobileLock',
|
|
83
|
+
unlock: 'mobileUnlock',
|
|
84
|
+
|
|
85
|
+
refreshGpsCache: 'mobileRefreshGpsCache',
|
|
86
|
+
|
|
87
|
+
startMediaProjectionRecording: 'mobileStartMediaProjectionRecording',
|
|
88
|
+
isMediaProjectionRecordingRunning: 'mobileIsMediaProjectionRecordingRunning',
|
|
89
|
+
stopMediaProjectionRecording: 'mobileStopMediaProjectionRecording',
|
|
90
|
+
|
|
91
|
+
getConnectivity: 'mobileGetConnectivity',
|
|
92
|
+
setConnectivity: 'mobileSetConnectivity',
|
|
93
|
+
|
|
94
|
+
hideKeyboard: 'hideKeyboard',
|
|
95
|
+
isKeyboardShown: 'isKeyboardShown',
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
if (!_.has(mobileCommandsMapping, mobileCommand)) {
|
|
99
|
+
throw new errors.UnknownCommandError(
|
|
100
|
+
`Unknown mobile command "${mobileCommand}". ` +
|
|
101
|
+
`Only ${_.keys(mobileCommandsMapping)} commands are supported.`
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
// @ts-expect-error fine for now until we replace with execute methods
|
|
105
|
+
return await this[mobileCommandsMapping[mobileCommand]](opts);
|
|
106
|
+
},
|
|
23
107
|
};
|
|
24
108
|
|
|
25
|
-
|
|
26
|
-
const mobileCommandsMapping = {
|
|
27
|
-
shell: 'mobileShell',
|
|
28
|
-
|
|
29
|
-
execEmuConsoleCommand: 'mobileExecEmuConsoleCommand',
|
|
30
|
-
|
|
31
|
-
startLogsBroadcast: 'mobileStartLogsBroadcast',
|
|
32
|
-
stopLogsBroadcast: 'mobileStopLogsBroadcast',
|
|
33
|
-
|
|
34
|
-
changePermissions: 'mobileChangePermissions',
|
|
35
|
-
getPermissions: 'mobileGetPermissions',
|
|
36
|
-
|
|
37
|
-
performEditorAction: 'mobilePerformEditorAction',
|
|
38
|
-
|
|
39
|
-
sensorSet: 'sensorSet',
|
|
40
|
-
|
|
41
|
-
getDeviceTime: 'mobileGetDeviceTime',
|
|
42
|
-
|
|
43
|
-
startScreenStreaming: 'mobileStartScreenStreaming',
|
|
44
|
-
stopScreenStreaming: 'mobileStopScreenStreaming',
|
|
45
|
-
|
|
46
|
-
getNotifications: 'mobileGetNotifications',
|
|
47
|
-
|
|
48
|
-
listSms: 'mobileListSms',
|
|
49
|
-
|
|
50
|
-
pushFile: 'mobilePushFile',
|
|
51
|
-
pullFile: 'mobilePullFile',
|
|
52
|
-
pullFolder: 'mobilePullFolder',
|
|
53
|
-
deleteFile: 'mobileDeleteFile',
|
|
54
|
-
|
|
55
|
-
isAppInstalled: 'mobileIsAppInstalled',
|
|
56
|
-
queryAppState: 'mobileQueryAppState',
|
|
57
|
-
activateApp: 'mobileActivateApp',
|
|
58
|
-
removeApp: 'mobileRemoveApp',
|
|
59
|
-
terminateApp: 'mobileTerminateApp',
|
|
60
|
-
installApp: 'mobileInstallApp',
|
|
61
|
-
clearApp: 'mobileClearApp',
|
|
62
|
-
|
|
63
|
-
startService: 'mobileStartService',
|
|
64
|
-
stopService: 'mobileStopService',
|
|
65
|
-
startActivity: 'mobileStartActivity',
|
|
66
|
-
broadcast: 'mobileBroadcast',
|
|
67
|
-
|
|
68
|
-
getContexts: 'mobileGetContexts',
|
|
69
|
-
|
|
70
|
-
lock: 'mobileLock',
|
|
71
|
-
unlock: 'mobileUnlock',
|
|
72
|
-
|
|
73
|
-
refreshGpsCache: 'mobileRefreshGpsCache',
|
|
74
|
-
|
|
75
|
-
startMediaProjectionRecording: 'mobileStartMediaProjectionRecording',
|
|
76
|
-
isMediaProjectionRecordingRunning: 'mobileIsMediaProjectionRecordingRunning',
|
|
77
|
-
stopMediaProjectionRecording: 'mobileStopMediaProjectionRecording',
|
|
78
|
-
|
|
79
|
-
getConnectivity: 'mobileGetConnectivity',
|
|
80
|
-
setConnectivity: 'mobileSetConnectivity',
|
|
81
|
-
|
|
82
|
-
hideKeyboard: 'hideKeyboard',
|
|
83
|
-
isKeyboardShown: 'isKeyboardShown',
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
if (!_.has(mobileCommandsMapping, mobileCommand)) {
|
|
87
|
-
throw new errors.UnknownCommandError(
|
|
88
|
-
`Unknown mobile command "${mobileCommand}". ` +
|
|
89
|
-
`Only ${_.keys(mobileCommandsMapping)} commands are supported.`
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
return await this[mobileCommandsMapping[mobileCommand]](opts);
|
|
93
|
-
};
|
|
109
|
+
mixin(ExecuteMixin);
|
|
94
110
|
|
|
95
|
-
export default
|
|
111
|
+
export default ExecuteMixin;
|