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.
- package/CHANGELOG.md +14 -0
- package/build/lib/commands/actions.d.ts +22 -1
- package/build/lib/commands/actions.d.ts.map +1 -1
- package/build/lib/commands/actions.js +30 -62
- package/build/lib/commands/actions.js.map +1 -1
- package/build/lib/commands/alert.d.ts +28 -1
- package/build/lib/commands/alert.d.ts.map +1 -1
- package/build/lib/commands/alert.js +42 -23
- package/build/lib/commands/alert.js.map +1 -1
- package/build/lib/commands/app-management.d.ts +19 -0
- package/build/lib/commands/app-management.d.ts.map +1 -0
- package/build/lib/commands/app-management.js +45 -0
- package/build/lib/commands/app-management.js.map +1 -0
- package/build/lib/commands/app-strings.d.ts +9 -0
- package/build/lib/commands/app-strings.d.ts.map +1 -1
- package/build/lib/commands/app-strings.js +11 -79
- package/build/lib/commands/app-strings.js.map +1 -1
- package/build/lib/commands/battery.d.ts +7 -0
- package/build/lib/commands/battery.d.ts.map +1 -1
- package/build/lib/commands/battery.js +14 -20
- package/build/lib/commands/battery.js.map +1 -1
- package/build/lib/commands/element.d.ts +100 -1
- package/build/lib/commands/element.d.ts.map +1 -1
- package/build/lib/commands/element.js +175 -125
- package/build/lib/commands/element.js.map +1 -1
- package/build/lib/commands/execute.d.ts +25 -0
- package/build/lib/commands/execute.d.ts.map +1 -0
- package/build/lib/commands/execute.js +109 -0
- package/build/lib/commands/execute.js.map +1 -0
- package/build/lib/commands/find.d.ts +10 -0
- package/build/lib/commands/find.d.ts.map +1 -1
- package/build/lib/commands/find.js +25 -27
- package/build/lib/commands/find.js.map +1 -1
- package/build/lib/commands/gestures.d.ts +103 -1
- package/build/lib/commands/gestures.d.ts.map +1 -1
- package/build/lib/commands/gestures.js +202 -173
- package/build/lib/commands/gestures.js.map +1 -1
- package/build/lib/commands/keyboard.d.ts +47 -0
- package/build/lib/commands/keyboard.d.ts.map +1 -0
- package/build/lib/commands/keyboard.js +92 -0
- package/build/lib/commands/keyboard.js.map +1 -0
- package/build/lib/commands/misc.d.ts +48 -0
- package/build/lib/commands/misc.d.ts.map +1 -0
- package/build/lib/commands/misc.js +75 -0
- package/build/lib/commands/misc.js.map +1 -0
- package/build/lib/commands/navigation.d.ts +20 -0
- package/build/lib/commands/navigation.d.ts.map +1 -0
- package/build/lib/commands/navigation.js +35 -0
- package/build/lib/commands/navigation.js.map +1 -0
- package/build/lib/commands/screenshot.d.ts +24 -1
- package/build/lib/commands/screenshot.d.ts.map +1 -1
- package/build/lib/commands/screenshot.js +87 -64
- package/build/lib/commands/screenshot.js.map +1 -1
- package/build/lib/commands/touch.d.ts +81 -0
- package/build/lib/commands/touch.d.ts.map +1 -1
- package/build/lib/commands/touch.js +158 -41
- package/build/lib/commands/touch.js.map +1 -1
- package/build/lib/commands/viewport.d.ts +37 -1
- package/build/lib/commands/viewport.d.ts.map +1 -1
- package/build/lib/commands/viewport.js +80 -36
- package/build/lib/commands/viewport.js.map +1 -1
- package/build/lib/driver.d.ts +94 -24
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +114 -28
- package/build/lib/driver.js.map +1 -1
- package/build/lib/helpers.d.ts +12 -6
- package/build/lib/helpers.d.ts.map +1 -1
- package/build/lib/helpers.js +18 -18
- package/build/lib/helpers.js.map +1 -1
- package/build/lib/method-map.d.ts +0 -23
- package/build/lib/method-map.d.ts.map +1 -1
- package/build/lib/uiautomator2.js +3 -3
- package/build/lib/uiautomator2.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/lib/commands/actions.js +37 -114
- package/lib/commands/alert.js +51 -37
- package/lib/commands/app-management.js +42 -0
- package/lib/commands/app-strings.js +9 -89
- package/lib/commands/battery.js +16 -26
- package/lib/commands/element.js +235 -214
- package/lib/commands/execute.js +120 -0
- package/lib/commands/find.js +31 -37
- package/lib/commands/gestures.js +252 -234
- package/lib/commands/keyboard.js +103 -0
- package/lib/commands/misc.js +106 -0
- package/lib/commands/navigation.js +31 -0
- package/lib/commands/screenshot.js +96 -77
- package/lib/commands/touch.js +190 -48
- package/lib/commands/viewport.js +100 -50
- package/lib/driver.ts +225 -36
- package/lib/helpers.js +15 -22
- package/lib/uiautomator2.js +3 -3
- package/npm-shrinkwrap.json +34 -34
- package/package.json +2 -2
- package/build/lib/commands/general.d.ts +0 -4
- package/build/lib/commands/general.d.ts.map +0 -1
- package/build/lib/commands/general.js +0 -214
- package/build/lib/commands/general.js.map +0 -1
- package/build/lib/commands/index.d.ts +0 -2
- package/build/lib/commands/index.d.ts.map +0 -1
- package/build/lib/commands/index.js +0 -14
- package/build/lib/commands/index.js.map +0 -1
- package/build/lib/commands/mixins.d.ts +0 -87
- package/build/lib/commands/mixins.d.ts.map +0 -1
- package/build/lib/commands/mixins.js +0 -26
- package/build/lib/commands/mixins.js.map +0 -1
- package/build/lib/utils.d.ts +0 -10
- package/build/lib/utils.d.ts.map +0 -1
- package/build/lib/utils.js +0 -26
- package/build/lib/utils.js.map +0 -1
- package/lib/commands/general.js +0 -289
- package/lib/commands/index.js +0 -11
- package/lib/commands/mixins.ts +0 -169
- package/lib/utils.js +0 -19
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @this {AndroidUiautomator2Driver}
|
|
3
|
+
* @returns {Promise<string>}
|
|
4
|
+
*/
|
|
5
|
+
export async function getPageSource() {
|
|
6
|
+
return String(
|
|
7
|
+
await this.uiautomator2.jwproxy.command(
|
|
8
|
+
'/source',
|
|
9
|
+
'GET',
|
|
10
|
+
{}
|
|
11
|
+
)
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @this {AndroidUiautomator2Driver}
|
|
17
|
+
* @returns {Promise<import('@appium/types').Orientation>}
|
|
18
|
+
*/
|
|
19
|
+
export async function getOrientation() {
|
|
20
|
+
return /** @type {import('@appium/types').Orientation} */ (
|
|
21
|
+
await this.uiautomator2.jwproxy.command(
|
|
22
|
+
`/orientation`,
|
|
23
|
+
'GET',
|
|
24
|
+
{}
|
|
25
|
+
)
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @this {AndroidUiautomator2Driver}
|
|
31
|
+
* @param {import('@appium/types').Orientation} orientation
|
|
32
|
+
* @returns {Promise<void>}
|
|
33
|
+
*/
|
|
34
|
+
export async function setOrientation(orientation) {
|
|
35
|
+
orientation = /** @type {import('@appium/types').Orientation} */ (orientation.toUpperCase());
|
|
36
|
+
await this.uiautomator2.jwproxy.command(
|
|
37
|
+
`/orientation`,
|
|
38
|
+
'POST',
|
|
39
|
+
{orientation}
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @this {AndroidUiautomator2Driver}
|
|
45
|
+
* @returns {Promise<string>}
|
|
46
|
+
*/
|
|
47
|
+
export async function getClipboard() {
|
|
48
|
+
return String(
|
|
49
|
+
(await this.adb.getApiLevel()) < 29
|
|
50
|
+
? await this.uiautomator2.jwproxy.command(
|
|
51
|
+
'/appium/device/get_clipboard',
|
|
52
|
+
'POST',
|
|
53
|
+
{}
|
|
54
|
+
)
|
|
55
|
+
: await this.settingsApp.getClipboard()
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @this {AndroidUiautomator2Driver}
|
|
61
|
+
* @returns {Promise<void>}
|
|
62
|
+
*/
|
|
63
|
+
export async function openNotifications() {
|
|
64
|
+
await this.uiautomator2.jwproxy.command(
|
|
65
|
+
'/appium/device/open_notifications',
|
|
66
|
+
'POST',
|
|
67
|
+
{}
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Stop proxying to any Chromedriver and redirect to uiautomator2
|
|
73
|
+
* @this {AndroidUiautomator2Driver}
|
|
74
|
+
* @returns {void}
|
|
75
|
+
*/
|
|
76
|
+
export function suspendChromedriverProxy() {
|
|
77
|
+
this.chromedriver = undefined;
|
|
78
|
+
this.proxyReqRes = this.uiautomator2.proxyReqRes.bind(
|
|
79
|
+
this.uiautomator2
|
|
80
|
+
);
|
|
81
|
+
this.proxyCommand = /** @type {typeof this.proxyCommand} */ (
|
|
82
|
+
this.uiautomator2.proxyCommand.bind(this.uiautomator2)
|
|
83
|
+
);
|
|
84
|
+
this.jwpProxyActive = true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The list of available info entries can be found at
|
|
89
|
+
* https://github.com/appium/appium-uiautomator2-server/blob/master/app/src/main/java/io/appium/uiautomator2/handler/GetDeviceInfo.java
|
|
90
|
+
* @this {AndroidUiautomator2Driver}
|
|
91
|
+
* @returns {Promise<StringRecord>}
|
|
92
|
+
*/
|
|
93
|
+
export async function mobileGetDeviceInfo() {
|
|
94
|
+
return /** @type {StringRecord} */ (
|
|
95
|
+
await this.uiautomator2.jwproxy.command(
|
|
96
|
+
'/appium/device/info',
|
|
97
|
+
'GET'
|
|
98
|
+
)
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @template [T=any]
|
|
104
|
+
* @typedef {import('@appium/types').StringRecord<T>} StringRecord
|
|
105
|
+
* @typedef {import('../driver').AndroidUiautomator2Driver} AndroidUiautomator2Driver
|
|
106
|
+
*/
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @this {AndroidUiautomator2Driver}
|
|
3
|
+
* @param {string} url
|
|
4
|
+
* @returns {Promise<void>}
|
|
5
|
+
*/
|
|
6
|
+
export async function setUrl(url) {
|
|
7
|
+
await this.adb.startUri(url, /** @type {string} */ (this.opts.appPackage));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Start URL that take users directly to specific content in the app
|
|
12
|
+
* @this {AndroidUiautomator2Driver}
|
|
13
|
+
* @param {import('./types').DeepLinkOpts} opts
|
|
14
|
+
* @returns {Promise<void>}
|
|
15
|
+
*/
|
|
16
|
+
export async function mobileDeepLink(opts) {
|
|
17
|
+
const {url, package: pkg, waitForLaunch} = opts;
|
|
18
|
+
return await this.adb.startUri(url, pkg, {waitForLaunch});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @this {AndroidUiautomator2Driver}
|
|
23
|
+
* @returns {Promise<void>}
|
|
24
|
+
*/
|
|
25
|
+
export async function back() {
|
|
26
|
+
await this.adb.keyevent(4);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @typedef {import('../driver').AndroidUiautomator2Driver} AndroidUiautomator2Driver
|
|
31
|
+
*/
|
|
@@ -1,95 +1,114 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
import {mixin} from './mixins';
|
|
4
1
|
import _ from 'lodash';
|
|
5
2
|
import B from 'bluebird';
|
|
3
|
+
import {imageUtil} from 'appium/support';
|
|
6
4
|
|
|
7
5
|
// Display 4619827259835644672 (HWC display 0): port=0 pnpId=GGL displayName="EMU_display_0"
|
|
8
6
|
const DISPLAY_PATTERN = /^Display\s+(\d+)\s+\(.+display\s+(\d+)\).+displayName="([^"]*)/gm;
|
|
9
7
|
|
|
10
8
|
/**
|
|
11
|
-
* @
|
|
12
|
-
* @
|
|
9
|
+
* @this {AndroidUiautomator2Driver}
|
|
10
|
+
* @returns {Promise<string>}
|
|
13
11
|
*/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
12
|
+
export async function mobileViewportScreenshot() {
|
|
13
|
+
return await this.getViewportScreenshot();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @this {AndroidUiautomator2Driver}
|
|
18
|
+
* @returns {Promise<string>}
|
|
19
|
+
*/
|
|
20
|
+
export async function getViewportScreenshot() {
|
|
21
|
+
const screenshot = await this.getScreenshot();
|
|
22
|
+
const rect = await this.getViewPortRect();
|
|
23
|
+
return await imageUtil.cropBase64Image(screenshot, rect);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @this {AndroidUiautomator2Driver}
|
|
28
|
+
* @returns {Promise<string>}
|
|
29
|
+
*/
|
|
30
|
+
export async function getScreenshot() {
|
|
31
|
+
if (this.mjpegStream) {
|
|
32
|
+
const data = await this.mjpegStream.lastChunkPNGBase64();
|
|
33
|
+
if (data) {
|
|
34
|
+
return data;
|
|
25
35
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
).jwproxy.command('/screenshot', 'GET')
|
|
36
|
+
this.log.warn(
|
|
37
|
+
'Tried to get screenshot from active MJPEG stream, but there ' +
|
|
38
|
+
'was no data yet. Falling back to regular screenshot methods.'
|
|
30
39
|
);
|
|
31
|
-
}
|
|
40
|
+
}
|
|
41
|
+
return String(
|
|
42
|
+
await /** @type {import('../uiautomator2').UiAutomator2Server} */ (
|
|
43
|
+
this.uiautomator2
|
|
44
|
+
).jwproxy.command('/screenshot', 'GET')
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Retrieves screenshots of each display available to Android.
|
|
50
|
+
* This functionality is only supported since Android 10.
|
|
51
|
+
* @this {AndroidUiautomator2Driver}
|
|
52
|
+
* @param {import('./types').ScreenshotsOpts} [opts={}]
|
|
53
|
+
* @returns {Promise<import('@appium/types').StringRecord<import('./types').Screenshot>>}
|
|
54
|
+
*/
|
|
55
|
+
export async function mobileScreenshots(opts = {}) {
|
|
56
|
+
const displaysInfo = await /** @type {import('appium-adb').ADB} */ (this.adb).shell([
|
|
57
|
+
'dumpsys',
|
|
58
|
+
'SurfaceFlinger',
|
|
59
|
+
'--display-id',
|
|
60
|
+
]);
|
|
61
|
+
/** @type {import('@appium/types').StringRecord<import('./types').Screenshot>} */
|
|
62
|
+
const infos = {};
|
|
63
|
+
let match;
|
|
64
|
+
while ((match = DISPLAY_PATTERN.exec(displaysInfo))) {
|
|
65
|
+
infos[match[1]] = /** @type {any} */ ({
|
|
66
|
+
id: match[1],
|
|
67
|
+
isDefault: match[2] === '0',
|
|
68
|
+
name: match[3],
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
if (_.isEmpty(infos)) {
|
|
72
|
+
this.log.debug(displaysInfo);
|
|
73
|
+
throw new Error('Cannot determine the information about connected Android displays');
|
|
74
|
+
}
|
|
75
|
+
this.log.info(`Parsed Android display infos: ${JSON.stringify(infos)}`);
|
|
32
76
|
|
|
33
77
|
/**
|
|
34
|
-
*
|
|
35
|
-
* This functionality is only supported since Android 10.
|
|
78
|
+
* @param {string} dispId
|
|
36
79
|
*/
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
'
|
|
40
|
-
|
|
41
|
-
'--display-id',
|
|
42
|
-
]);
|
|
43
|
-
/** @type {import('@appium/types').StringRecord<import('./types').Screenshot>} */
|
|
44
|
-
const infos = {};
|
|
45
|
-
let match;
|
|
46
|
-
while ((match = DISPLAY_PATTERN.exec(displaysInfo))) {
|
|
47
|
-
infos[match[1]] = /** @type {any} */ ({
|
|
48
|
-
id: match[1],
|
|
49
|
-
isDefault: match[2] === '0',
|
|
50
|
-
name: match[3],
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
if (_.isEmpty(infos)) {
|
|
54
|
-
this.log.debug(displaysInfo);
|
|
55
|
-
throw new Error('Cannot determine the information about connected Android displays');
|
|
56
|
-
}
|
|
57
|
-
this.log.info(`Parsed Android display infos: ${JSON.stringify(infos)}`);
|
|
80
|
+
const toB64Screenshot = async (dispId) =>
|
|
81
|
+
(await /** @type {import('appium-adb').ADB} */ (this.adb).takeScreenshot(dispId)).toString(
|
|
82
|
+
'base64'
|
|
83
|
+
);
|
|
58
84
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
'
|
|
85
|
+
const {displayId} = opts;
|
|
86
|
+
const displayIdStr = _.isNaN(displayId) ? null : `${displayId}`;
|
|
87
|
+
if (displayIdStr) {
|
|
88
|
+
if (!infos[displayIdStr]) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
`The provided display identifier '${displayId}' is not known. ` +
|
|
91
|
+
`Only the following displays have been detected: ${JSON.stringify(infos)}`
|
|
65
92
|
);
|
|
66
|
-
|
|
67
|
-
const {displayId} = opts;
|
|
68
|
-
const displayIdStr = _.isNaN(displayId) ? null : `${displayId}`;
|
|
69
|
-
if (displayIdStr) {
|
|
70
|
-
if (!infos[displayIdStr]) {
|
|
71
|
-
throw new Error(
|
|
72
|
-
`The provided display identifier '${displayId}' is not known. ` +
|
|
73
|
-
`Only the following displays have been detected: ${JSON.stringify(infos)}`
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
return {
|
|
77
|
-
[displayIdStr]: {
|
|
78
|
-
...infos[displayIdStr],
|
|
79
|
-
payload: await toB64Screenshot(displayIdStr),
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
93
|
}
|
|
94
|
+
return {
|
|
95
|
+
[displayIdStr]: {
|
|
96
|
+
...infos[displayIdStr],
|
|
97
|
+
payload: await toB64Screenshot(displayIdStr),
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
83
101
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
};
|
|
102
|
+
const allInfos = _.values(infos);
|
|
103
|
+
const screenshots = await B.all(allInfos.map(({id}) => toB64Screenshot(id)));
|
|
104
|
+
for (const [info, payload] of /** @type {[import('./types').Screenshot, string][]} */ (
|
|
105
|
+
_.zip(allInfos, screenshots)
|
|
106
|
+
)) {
|
|
107
|
+
info.payload = payload;
|
|
108
|
+
}
|
|
109
|
+
return infos;
|
|
110
|
+
}
|
|
94
111
|
|
|
95
|
-
|
|
112
|
+
/**
|
|
113
|
+
* @typedef {import('../driver').AndroidUiautomator2Driver} AndroidUiautomator2Driver
|
|
114
|
+
*/
|
package/lib/commands/touch.js
CHANGED
|
@@ -1,71 +1,213 @@
|
|
|
1
|
-
|
|
1
|
+
import { util } from 'appium/support';
|
|
2
|
+
import { W3C_ELEMENT_KEY } from 'appium/driver';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
/**
|
|
5
|
+
* @deprecated
|
|
6
|
+
* @this {AndroidUiautomator2Driver}
|
|
7
|
+
* @param {import('appium-android-driver').SwipeOpts} swipeOpts
|
|
8
|
+
* @returns {Promise<void>}
|
|
9
|
+
*/
|
|
10
|
+
export async function doSwipe(swipeOpts) {
|
|
11
|
+
await this.uiautomator2.jwproxy.command(
|
|
12
|
+
`/touch/perform`,
|
|
13
|
+
'POST',
|
|
14
|
+
swipeOpts
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @deprecated
|
|
20
|
+
* @this {AndroidUiautomator2Driver}
|
|
21
|
+
* @param {import('appium-android-driver').DragOpts} dragOpts
|
|
22
|
+
* @returns {Promise<void>}
|
|
23
|
+
*/
|
|
24
|
+
export async function doDrag(dragOpts) {
|
|
25
|
+
await this.uiautomator2.jwproxy.command(
|
|
26
|
+
`/touch/drag`,
|
|
27
|
+
'POST',
|
|
28
|
+
dragOpts
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @deprecated
|
|
34
|
+
* @this {AndroidUiautomator2Driver}
|
|
35
|
+
* @param {string} element
|
|
36
|
+
* @param {number} x
|
|
37
|
+
* @param {number} y
|
|
38
|
+
* @param {number} duration
|
|
39
|
+
* @returns {Promise<void>}
|
|
40
|
+
*/
|
|
41
|
+
export async function touchLongClick(element, x, y, duration) {
|
|
42
|
+
let params = {element, x, y, duration};
|
|
43
|
+
await this.uiautomator2.jwproxy.command(
|
|
44
|
+
`/touch/longclick`,
|
|
45
|
+
'POST',
|
|
46
|
+
{params}
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @deprecated
|
|
52
|
+
* @this {AndroidUiautomator2Driver}
|
|
53
|
+
* @param {string} element
|
|
54
|
+
* @param {number} x
|
|
55
|
+
* @param {number} y
|
|
56
|
+
* @returns {Promise<void>}
|
|
57
|
+
*/
|
|
58
|
+
export async function touchDown(element, x, y) {
|
|
59
|
+
let params = {element, x, y};
|
|
60
|
+
await this.uiautomator2.jwproxy.command(
|
|
61
|
+
`/touch/down`,
|
|
62
|
+
'POST',
|
|
63
|
+
{params}
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @deprecated
|
|
69
|
+
* @this {AndroidUiautomator2Driver}
|
|
70
|
+
* @param {string} element
|
|
71
|
+
* @param {number} x
|
|
72
|
+
* @param {number} y
|
|
73
|
+
* @returns {Promise<void>}
|
|
74
|
+
*/
|
|
75
|
+
export async function touchUp(element, x, y) {
|
|
76
|
+
let params = {element, x, y};
|
|
77
|
+
await this.uiautomator2.jwproxy.command(
|
|
78
|
+
`/touch/up`,
|
|
79
|
+
'POST',
|
|
80
|
+
{params}
|
|
81
|
+
);
|
|
82
|
+
}
|
|
4
83
|
|
|
5
84
|
/**
|
|
6
|
-
* @
|
|
7
|
-
* @
|
|
85
|
+
* @deprecated
|
|
86
|
+
* @this {AndroidUiautomator2Driver}
|
|
87
|
+
* @param {string} element
|
|
88
|
+
* @param {number} x
|
|
89
|
+
* @param {number} y
|
|
90
|
+
* @returns {Promise<void>}
|
|
8
91
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
92
|
+
export async function touchMove(element, x, y) {
|
|
93
|
+
let params = {element, x, y};
|
|
94
|
+
await this.uiautomator2.jwproxy.command(
|
|
95
|
+
`/touch/move`,
|
|
96
|
+
'POST',
|
|
97
|
+
{params}
|
|
98
|
+
);
|
|
99
|
+
}
|
|
17
100
|
|
|
101
|
+
/**
|
|
102
|
+
* @deprecated
|
|
103
|
+
* @this {AndroidUiautomator2Driver}
|
|
104
|
+
* @param {string?} [elementId=null]
|
|
105
|
+
* @param {number?} [x=null]
|
|
106
|
+
* @param {number?} [y=null]
|
|
107
|
+
* @param {number} [count=1]
|
|
108
|
+
* @returns {Promise<void>}
|
|
109
|
+
*/
|
|
110
|
+
export async function tap(elementId = null, x = null, y = null, count = 1) {
|
|
111
|
+
const areCoordinatesDefined = util.hasValue(x) && util.hasValue(y);
|
|
112
|
+
if (!util.hasValue(elementId) && !areCoordinatesDefined) {
|
|
113
|
+
throw new Error(`Either element id to tap or both absolute coordinates should be defined`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
for (let i = 0; i < count; i++) {
|
|
117
|
+
if (util.hasValue(elementId) && !areCoordinatesDefined) {
|
|
118
|
+
// we are either tapping on the default location of the element
|
|
119
|
+
// or an offset from the top left corner
|
|
18
120
|
await this.uiautomator2.jwproxy.command(
|
|
19
|
-
|
|
20
|
-
'POST'
|
|
21
|
-
opts
|
|
121
|
+
`/element/${elementId}/click`,
|
|
122
|
+
'POST'
|
|
22
123
|
);
|
|
23
124
|
} else {
|
|
24
|
-
opts = {
|
|
25
|
-
actions: states,
|
|
26
|
-
};
|
|
27
125
|
await this.uiautomator2.jwproxy.command(
|
|
28
|
-
|
|
126
|
+
`/appium/tap`,
|
|
29
127
|
'POST',
|
|
30
|
-
|
|
128
|
+
{
|
|
129
|
+
x,
|
|
130
|
+
y,
|
|
131
|
+
[W3C_ELEMENT_KEY]: elementId,
|
|
132
|
+
}
|
|
31
133
|
);
|
|
32
134
|
}
|
|
33
|
-
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @deprecated
|
|
140
|
+
* @this {AndroidUiautomator2Driver}
|
|
141
|
+
* @param {string} elementId
|
|
142
|
+
* @param {import('appium-android-driver').TouchState[]} states
|
|
143
|
+
* @returns {Promise<void>}
|
|
144
|
+
*/
|
|
145
|
+
export async function doPerformMultiAction(elementId, states) {
|
|
146
|
+
let opts;
|
|
147
|
+
if (elementId) {
|
|
148
|
+
opts = {
|
|
149
|
+
elementId,
|
|
150
|
+
actions: states,
|
|
151
|
+
};
|
|
34
152
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
Object.assign(
|
|
40
|
-
{},
|
|
41
|
-
action,
|
|
42
|
-
action.type === 'pointer'
|
|
43
|
-
? {
|
|
44
|
-
parameters: {
|
|
45
|
-
pointerType: 'touch',
|
|
46
|
-
},
|
|
47
|
-
}
|
|
48
|
-
: {}
|
|
49
|
-
)
|
|
153
|
+
await this.uiautomator2.jwproxy.command(
|
|
154
|
+
'/touch/multi/perform',
|
|
155
|
+
'POST',
|
|
156
|
+
opts
|
|
50
157
|
);
|
|
51
|
-
|
|
158
|
+
} else {
|
|
159
|
+
opts = {
|
|
160
|
+
actions: states,
|
|
161
|
+
};
|
|
52
162
|
await this.uiautomator2.jwproxy.command(
|
|
53
|
-
'/
|
|
163
|
+
'/touch/multi/perform',
|
|
54
164
|
'POST',
|
|
55
|
-
|
|
56
|
-
actions: preprocessedActions,
|
|
57
|
-
}
|
|
165
|
+
opts
|
|
58
166
|
);
|
|
59
|
-
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
60
169
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
170
|
+
/**
|
|
171
|
+
* @this {AndroidUiautomator2Driver}
|
|
172
|
+
* @param {import('@appium/types').StringRecord} actions
|
|
173
|
+
* @returns {Promise<void>}
|
|
174
|
+
*/
|
|
175
|
+
export async function performActions(actions) {
|
|
176
|
+
this.log.debug(`Received the following W3C actions: ${JSON.stringify(actions, null, ' ')}`);
|
|
177
|
+
// This is mandatory, since Selenium API uses MOUSE as the default pointer type
|
|
178
|
+
const preprocessedActions = actions.map((action) =>
|
|
179
|
+
Object.assign(
|
|
180
|
+
{},
|
|
181
|
+
action,
|
|
182
|
+
action.type === 'pointer'
|
|
183
|
+
? {
|
|
184
|
+
parameters: {
|
|
185
|
+
pointerType: 'touch',
|
|
186
|
+
},
|
|
187
|
+
}
|
|
188
|
+
: {}
|
|
189
|
+
)
|
|
190
|
+
);
|
|
191
|
+
this.log.debug(`Preprocessed actions: ${JSON.stringify(preprocessedActions, null, ' ')}`);
|
|
192
|
+
await this.uiautomator2.jwproxy.command(
|
|
193
|
+
'/actions',
|
|
194
|
+
'POST',
|
|
195
|
+
{
|
|
196
|
+
actions: preprocessedActions,
|
|
197
|
+
}
|
|
198
|
+
);
|
|
199
|
+
}
|
|
66
200
|
|
|
67
|
-
|
|
201
|
+
/**
|
|
202
|
+
* @this {AndroidUiautomator2Driver}
|
|
203
|
+
* @returns {Promise<void>}
|
|
204
|
+
*/
|
|
205
|
+
// eslint-disable-next-line require-await
|
|
206
|
+
export async function releaseActions() {
|
|
207
|
+
this.log.info('On this platform, releaseActions is a no-op');
|
|
208
|
+
}
|
|
68
209
|
|
|
69
210
|
/**
|
|
70
211
|
* @typedef {import('../uiautomator2').UiAutomator2Server} UiAutomator2Server
|
|
212
|
+
* @typedef {import('../driver').AndroidUiautomator2Driver} AndroidUiautomator2Driver
|
|
71
213
|
*/
|