@limrun/appium-xcuitest-driver 10.11.0-lim.4 → 10.14.6-lim.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 +94 -0
- package/build/lib/commands/active-app-info.d.ts +4 -3
- package/build/lib/commands/active-app-info.d.ts.map +1 -1
- package/build/lib/commands/active-app-info.js +2 -3
- package/build/lib/commands/active-app-info.js.map +1 -1
- package/build/lib/commands/alert.d.ts +26 -31
- package/build/lib/commands/alert.d.ts.map +1 -1
- package/build/lib/commands/alert.js +20 -29
- package/build/lib/commands/alert.js.map +1 -1
- package/build/lib/commands/app-management.d.ts +99 -76
- package/build/lib/commands/app-management.d.ts.map +1 -1
- package/build/lib/commands/app-management.js +83 -73
- package/build/lib/commands/app-management.js.map +1 -1
- package/build/lib/commands/app-strings.d.ts +6 -7
- package/build/lib/commands/app-strings.d.ts.map +1 -1
- package/build/lib/commands/app-strings.js +3 -8
- package/build/lib/commands/app-strings.js.map +1 -1
- package/build/lib/commands/appearance.d.ts +7 -9
- package/build/lib/commands/appearance.d.ts.map +1 -1
- package/build/lib/commands/appearance.js +13 -19
- package/build/lib/commands/appearance.js.map +1 -1
- package/build/lib/commands/audit.d.ts +5 -33
- package/build/lib/commands/audit.d.ts.map +1 -1
- package/build/lib/commands/audit.js +3 -16
- package/build/lib/commands/audit.js.map +1 -1
- package/build/lib/commands/battery.d.ts +4 -4
- package/build/lib/commands/battery.d.ts.map +1 -1
- package/build/lib/commands/battery.js +3 -7
- package/build/lib/commands/battery.js.map +1 -1
- package/build/lib/commands/biometric.d.ts +12 -14
- package/build/lib/commands/biometric.d.ts.map +1 -1
- package/build/lib/commands/biometric.js +10 -19
- package/build/lib/commands/biometric.js.map +1 -1
- package/build/lib/commands/certificate.d.ts +14 -19
- package/build/lib/commands/certificate.d.ts.map +1 -1
- package/build/lib/commands/certificate.js +24 -31
- package/build/lib/commands/certificate.js.map +1 -1
- package/build/lib/commands/clipboard.d.ts +9 -11
- package/build/lib/commands/clipboard.d.ts.map +1 -1
- package/build/lib/commands/clipboard.js +8 -13
- package/build/lib/commands/clipboard.js.map +1 -1
- package/build/lib/commands/condition.d.ts +9 -72
- package/build/lib/commands/condition.d.ts.map +1 -1
- package/build/lib/commands/condition.js +5 -66
- package/build/lib/commands/condition.js.map +1 -1
- package/build/lib/commands/content-size.d.ts +16 -19
- package/build/lib/commands/content-size.d.ts.map +1 -1
- package/build/lib/commands/content-size.js +14 -22
- package/build/lib/commands/content-size.js.map +1 -1
- package/build/lib/commands/context.d.ts +130 -161
- package/build/lib/commands/context.d.ts.map +1 -1
- package/build/lib/commands/context.js +123 -108
- package/build/lib/commands/context.js.map +1 -1
- package/build/lib/commands/device-info.d.ts +13 -0
- package/build/lib/commands/device-info.d.ts.map +1 -0
- package/build/lib/commands/device-info.js +20 -0
- package/build/lib/commands/device-info.js.map +1 -0
- package/build/lib/commands/element.d.ts +83 -67
- package/build/lib/commands/element.d.ts.map +1 -1
- package/build/lib/commands/element.js +111 -134
- package/build/lib/commands/element.js.map +1 -1
- package/build/lib/commands/execute.d.ts +10 -22
- package/build/lib/commands/execute.d.ts.map +1 -1
- package/build/lib/commands/execute.js +13 -29
- package/build/lib/commands/execute.js.map +1 -1
- package/build/lib/commands/file-movement.d.ts +31 -42
- package/build/lib/commands/file-movement.d.ts.map +1 -1
- package/build/lib/commands/file-movement.js +146 -205
- package/build/lib/commands/file-movement.js.map +1 -1
- package/build/lib/commands/find.d.ts +20 -12
- package/build/lib/commands/find.d.ts.map +1 -1
- package/build/lib/commands/find.js +27 -65
- package/build/lib/commands/find.js.map +1 -1
- package/build/lib/commands/general.d.ts +84 -80
- package/build/lib/commands/general.d.ts.map +1 -1
- package/build/lib/commands/general.js +67 -54
- package/build/lib/commands/general.js.map +1 -1
- package/build/lib/commands/geolocation.d.ts +16 -36
- package/build/lib/commands/geolocation.d.ts.map +1 -1
- package/build/lib/commands/geolocation.js +8 -25
- package/build/lib/commands/geolocation.js.map +1 -1
- package/build/lib/commands/gesture.d.ts +103 -119
- package/build/lib/commands/gesture.d.ts.map +1 -1
- package/build/lib/commands/gesture.js +98 -138
- package/build/lib/commands/gesture.js.map +1 -1
- package/build/lib/commands/increase-contrast.d.ts +10 -13
- package/build/lib/commands/increase-contrast.d.ts.map +1 -1
- package/build/lib/commands/increase-contrast.js +8 -16
- package/build/lib/commands/increase-contrast.js.map +1 -1
- package/build/lib/commands/iohid.d.ts +6 -1359
- package/build/lib/commands/iohid.d.ts.map +1 -1
- package/build/lib/commands/iohid.js +5 -10
- package/build/lib/commands/iohid.js.map +1 -1
- package/build/lib/commands/keyboard.d.ts +16 -13
- package/build/lib/commands/keyboard.d.ts.map +1 -1
- package/build/lib/commands/keyboard.js +14 -18
- package/build/lib/commands/keyboard.js.map +1 -1
- package/build/lib/commands/keychains.d.ts +2 -2
- package/build/lib/commands/keychains.d.ts.map +1 -1
- package/build/lib/commands/keychains.js +1 -4
- package/build/lib/commands/keychains.js.map +1 -1
- package/build/lib/commands/localization.d.ts +7 -6
- package/build/lib/commands/localization.d.ts.map +1 -1
- package/build/lib/commands/localization.js +7 -8
- package/build/lib/commands/localization.js.map +1 -1
- package/build/lib/commands/location.d.ts +8 -11
- package/build/lib/commands/location.d.ts.map +1 -1
- package/build/lib/commands/location.js +7 -15
- package/build/lib/commands/location.js.map +1 -1
- package/build/lib/commands/lock.d.ts +6 -10
- package/build/lib/commands/lock.d.ts.map +1 -1
- package/build/lib/commands/lock.js +3 -10
- package/build/lib/commands/lock.js.map +1 -1
- package/build/lib/commands/log.d.ts +42 -44
- package/build/lib/commands/log.d.ts.map +1 -1
- package/build/lib/commands/log.js +32 -53
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/memory.d.ts +4 -5
- package/build/lib/commands/memory.d.ts.map +1 -1
- package/build/lib/commands/memory.js +3 -8
- package/build/lib/commands/memory.js.map +1 -1
- package/build/lib/commands/navigation.d.ts +14 -26
- package/build/lib/commands/navigation.d.ts.map +1 -1
- package/build/lib/commands/navigation.js +22 -32
- package/build/lib/commands/navigation.js.map +1 -1
- package/build/lib/commands/notifications.d.ts +10 -10
- package/build/lib/commands/notifications.d.ts.map +1 -1
- package/build/lib/commands/notifications.js +8 -12
- package/build/lib/commands/notifications.js.map +1 -1
- package/build/lib/commands/pasteboard.d.ts +9 -10
- package/build/lib/commands/pasteboard.d.ts.map +1 -1
- package/build/lib/commands/pasteboard.js +8 -13
- package/build/lib/commands/pasteboard.js.map +1 -1
- package/build/lib/commands/pcap.d.ts +18 -38
- package/build/lib/commands/pcap.d.ts.map +1 -1
- package/build/lib/commands/pcap.js +9 -14
- package/build/lib/commands/pcap.js.map +1 -1
- package/build/lib/commands/performance.d.ts +36 -55
- package/build/lib/commands/performance.d.ts.map +1 -1
- package/build/lib/commands/performance.js +93 -86
- package/build/lib/commands/performance.js.map +1 -1
- package/build/lib/commands/permissions.d.ts +15 -17
- package/build/lib/commands/permissions.d.ts.map +1 -1
- package/build/lib/commands/permissions.js +12 -18
- package/build/lib/commands/permissions.js.map +1 -1
- package/build/lib/commands/proxy-helper.d.ts +11 -11
- package/build/lib/commands/proxy-helper.d.ts.map +1 -1
- package/build/lib/commands/proxy-helper.js +15 -24
- package/build/lib/commands/proxy-helper.js.map +1 -1
- package/build/lib/commands/record-audio.d.ts +25 -52
- package/build/lib/commands/record-audio.d.ts.map +1 -1
- package/build/lib/commands/record-audio.js +17 -19
- package/build/lib/commands/record-audio.js.map +1 -1
- package/build/lib/commands/recordscreen.d.ts +31 -62
- package/build/lib/commands/recordscreen.d.ts.map +1 -1
- package/build/lib/commands/recordscreen.js +29 -28
- package/build/lib/commands/recordscreen.js.map +1 -1
- package/build/lib/commands/screenshots.d.ts +15 -9
- package/build/lib/commands/screenshots.d.ts.map +1 -1
- package/build/lib/commands/screenshots.js +16 -16
- package/build/lib/commands/screenshots.js.map +1 -1
- package/build/lib/commands/simctl.d.ts +16 -22
- package/build/lib/commands/simctl.d.ts.map +1 -1
- package/build/lib/commands/simctl.js +13 -17
- package/build/lib/commands/simctl.js.map +1 -1
- package/build/lib/commands/source.d.ts +10 -8
- package/build/lib/commands/source.d.ts.map +1 -1
- package/build/lib/commands/source.js +11 -14
- package/build/lib/commands/source.js.map +1 -1
- package/build/lib/commands/timeouts.d.ts +25 -32
- package/build/lib/commands/timeouts.d.ts.map +1 -1
- package/build/lib/commands/timeouts.js +19 -15
- package/build/lib/commands/timeouts.js.map +1 -1
- package/build/lib/commands/types.d.ts +80 -0
- package/build/lib/commands/types.d.ts.map +1 -1
- package/build/lib/commands/web.d.ts +199 -202
- package/build/lib/commands/web.d.ts.map +1 -1
- package/build/lib/commands/web.js +216 -175
- package/build/lib/commands/web.js.map +1 -1
- package/build/lib/commands/xctest-record-screen.d.ts +17 -47
- package/build/lib/commands/xctest-record-screen.d.ts.map +1 -1
- package/build/lib/commands/xctest-record-screen.js +28 -59
- package/build/lib/commands/xctest-record-screen.js.map +1 -1
- package/build/lib/commands/xctest.d.ts +37 -37
- package/build/lib/commands/xctest.d.ts.map +1 -1
- package/build/lib/commands/xctest.js +38 -50
- package/build/lib/commands/xctest.js.map +1 -1
- package/build/lib/desired-caps.js +1 -1
- package/build/lib/device/log/ios-simulator-log.d.ts.map +1 -1
- package/build/lib/device/log/ios-simulator-log.js +2 -0
- package/build/lib/device/log/ios-simulator-log.js.map +1 -1
- package/build/lib/device/simulator-management.d.ts.map +1 -1
- package/build/lib/device/simulator-management.js +0 -2
- package/build/lib/device/simulator-management.js.map +1 -1
- package/build/lib/doctor/optional-checks.d.ts +0 -9
- package/build/lib/doctor/optional-checks.d.ts.map +1 -1
- package/build/lib/doctor/optional-checks.js +1 -30
- package/build/lib/doctor/optional-checks.js.map +1 -1
- package/build/lib/driver.d.ts +6 -5
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +16 -14
- package/build/lib/driver.js.map +1 -1
- package/build/lib/execute-method-map.d.ts.map +1 -1
- package/build/lib/execute-method-map.js +0 -9
- package/build/lib/execute-method-map.js.map +1 -1
- package/lib/commands/active-app-info.ts +15 -0
- package/lib/commands/alert.ts +98 -0
- package/lib/commands/app-management.ts +414 -0
- package/lib/commands/{app-strings.js → app-strings.ts} +10 -9
- package/lib/commands/appearance.ts +70 -0
- package/lib/commands/audit.ts +25 -0
- package/lib/commands/{battery.js → battery.ts} +10 -12
- package/lib/commands/biometric.ts +52 -0
- package/lib/commands/{certificate.js → certificate.ts} +55 -50
- package/lib/commands/clipboard.ts +37 -0
- package/lib/commands/{condition.js → condition.ts} +21 -77
- package/lib/commands/content-size.ts +67 -0
- package/lib/commands/{context.js → context.ts} +174 -146
- package/lib/commands/device-info.ts +24 -0
- package/lib/commands/element.ts +419 -0
- package/lib/commands/{execute.js → execute.ts} +42 -38
- package/lib/commands/{file-movement.js → file-movement.ts} +212 -235
- package/lib/commands/find.ts +277 -0
- package/lib/commands/{general.js → general.ts} +102 -77
- package/lib/commands/geolocation.ts +55 -0
- package/lib/commands/{gesture.js → gesture.ts} +225 -183
- package/lib/commands/increase-contrast.ts +49 -0
- package/lib/commands/{iohid.js → iohid.ts} +15 -13
- package/lib/commands/keyboard.ts +70 -0
- package/lib/commands/keychains.ts +16 -0
- package/lib/commands/{localization.js → localization.ts} +22 -12
- package/lib/commands/{location.js → location.ts} +19 -22
- package/lib/commands/lock.ts +43 -0
- package/lib/commands/{log.js → log.ts} +68 -68
- package/lib/commands/{memory.js → memory.ts} +9 -9
- package/lib/commands/{navigation.js → navigation.ts} +42 -39
- package/lib/commands/{notifications.js → notifications.ts} +22 -14
- package/lib/commands/pasteboard.ts +44 -0
- package/lib/commands/{pcap.js → pcap.ts} +28 -28
- package/lib/commands/{performance.js → performance.ts} +133 -114
- package/lib/commands/permissions.ts +90 -0
- package/lib/commands/{proxy-helper.js → proxy-helper.ts} +26 -26
- package/lib/commands/{record-audio.js → record-audio.ts} +35 -33
- package/lib/commands/{recordscreen.js → recordscreen.ts} +78 -50
- package/lib/commands/{screenshots.js → screenshots.ts} +27 -21
- package/lib/commands/simctl.ts +82 -0
- package/lib/commands/{source.js → source.ts} +23 -20
- package/lib/commands/timeouts.ts +95 -0
- package/lib/commands/types.ts +86 -0
- package/lib/commands/{web.js → web.ts} +314 -264
- package/lib/commands/{xctest-record-screen.js → xctest-record-screen.ts} +54 -71
- package/lib/commands/{xctest.js → xctest.ts} +78 -71
- package/lib/desired-caps.ts +1 -1
- package/lib/device/log/ios-simulator-log.ts +2 -0
- package/lib/device/simulator-management.ts +0 -2
- package/lib/doctor/optional-checks.ts +0 -33
- package/lib/driver.ts +19 -17
- package/lib/execute-method-map.ts +0 -9
- package/package.json +6 -6
- package/lib/commands/active-app-info.js +0 -12
- package/lib/commands/alert.js +0 -88
- package/lib/commands/app-management.js +0 -346
- package/lib/commands/appearance.js +0 -71
- package/lib/commands/audit.js +0 -31
- package/lib/commands/biometric.js +0 -52
- package/lib/commands/clipboard.js +0 -35
- package/lib/commands/content-size.js +0 -68
- package/lib/commands/deviceInfo.js +0 -27
- package/lib/commands/element.js +0 -423
- package/lib/commands/find.js +0 -205
- package/lib/commands/geolocation.js +0 -56
- package/lib/commands/increase-contrast.js +0 -50
- package/lib/commands/keyboard.js +0 -62
- package/lib/commands/keychains.js +0 -17
- package/lib/commands/lock.js +0 -46
- package/lib/commands/pasteboard.js +0 -43
- package/lib/commands/permissions.js +0 -85
- package/lib/commands/simctl.js +0 -71
- package/lib/commands/timeouts.js +0 -68
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import {CssConverter} from '../css-converter';
|
|
3
|
+
import {errors} from 'appium/driver';
|
|
4
|
+
import {util} from 'appium/support';
|
|
5
|
+
import type {Element, AppiumLogger} from '@appium/types';
|
|
6
|
+
import type {XCUITestDriver} from '../driver';
|
|
7
|
+
import type {AllowedHttpMethod} from './proxy-helper';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Finds elements, delegating to web or native based on context.
|
|
11
|
+
*/
|
|
12
|
+
export async function findElOrEls(
|
|
13
|
+
this: XCUITestDriver,
|
|
14
|
+
strategy: string,
|
|
15
|
+
selector: string,
|
|
16
|
+
mult: true,
|
|
17
|
+
context?: any,
|
|
18
|
+
): Promise<Element[]>;
|
|
19
|
+
export async function findElOrEls(
|
|
20
|
+
this: XCUITestDriver,
|
|
21
|
+
strategy: string,
|
|
22
|
+
selector: string,
|
|
23
|
+
mult: false,
|
|
24
|
+
context?: any,
|
|
25
|
+
): Promise<Element>;
|
|
26
|
+
export async function findElOrEls(
|
|
27
|
+
this: XCUITestDriver,
|
|
28
|
+
strategy: string,
|
|
29
|
+
selector: string,
|
|
30
|
+
mult: boolean,
|
|
31
|
+
context?: any,
|
|
32
|
+
): Promise<Element | Element[]>;
|
|
33
|
+
export async function findElOrEls(
|
|
34
|
+
this: XCUITestDriver,
|
|
35
|
+
strategy: string,
|
|
36
|
+
selector: string,
|
|
37
|
+
mult: boolean,
|
|
38
|
+
context?: any,
|
|
39
|
+
): Promise<Element | Element[]>;
|
|
40
|
+
export async function findElOrEls(
|
|
41
|
+
this: XCUITestDriver,
|
|
42
|
+
strategy: string,
|
|
43
|
+
selector: string,
|
|
44
|
+
mult: boolean,
|
|
45
|
+
context?: any,
|
|
46
|
+
): Promise<Element | Element[]> {
|
|
47
|
+
if (this.isWebview()) {
|
|
48
|
+
return mult
|
|
49
|
+
? await this.findWebElementOrElements(strategy, selector, true, context)
|
|
50
|
+
: await this.findWebElementOrElements(strategy, selector, false, context);
|
|
51
|
+
}
|
|
52
|
+
return mult
|
|
53
|
+
? await this.findNativeElementOrElements(strategy, selector, true, context)
|
|
54
|
+
: await this.findNativeElementOrElements(strategy, selector, false, context);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Finds elements natively with strategy/selector rewriting for WDA.
|
|
59
|
+
*/
|
|
60
|
+
export async function findNativeElementOrElements(
|
|
61
|
+
this: XCUITestDriver,
|
|
62
|
+
strategy: string,
|
|
63
|
+
selector: string,
|
|
64
|
+
mult: true,
|
|
65
|
+
context?: any,
|
|
66
|
+
): Promise<Element[]>;
|
|
67
|
+
export async function findNativeElementOrElements(
|
|
68
|
+
this: XCUITestDriver,
|
|
69
|
+
strategy: string,
|
|
70
|
+
selector: string,
|
|
71
|
+
mult: false,
|
|
72
|
+
context?: any,
|
|
73
|
+
): Promise<Element>;
|
|
74
|
+
export async function findNativeElementOrElements(
|
|
75
|
+
this: XCUITestDriver,
|
|
76
|
+
strategy: string,
|
|
77
|
+
selector: string,
|
|
78
|
+
mult: boolean,
|
|
79
|
+
context?: any,
|
|
80
|
+
): Promise<Element | Element[]>;
|
|
81
|
+
export async function findNativeElementOrElements(
|
|
82
|
+
this: XCUITestDriver,
|
|
83
|
+
strategy: string,
|
|
84
|
+
selector: string,
|
|
85
|
+
mult: boolean,
|
|
86
|
+
context?: any,
|
|
87
|
+
): Promise<Element | Element[]> {
|
|
88
|
+
const initSelector = selector;
|
|
89
|
+
let rewroteSelector = false;
|
|
90
|
+
if (strategy === '-ios predicate string') {
|
|
91
|
+
strategy = 'predicate string';
|
|
92
|
+
} else if (strategy === '-ios class chain') {
|
|
93
|
+
strategy = WDA_CLASS_CHAIN_STRATEGY;
|
|
94
|
+
} else if (strategy === 'css selector') {
|
|
95
|
+
strategy = WDA_CLASS_CHAIN_STRATEGY;
|
|
96
|
+
selector = CssConverter.toIosClassChainSelector(selector);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (strategy === 'class name') {
|
|
100
|
+
if (selector.startsWith('UIA')) {
|
|
101
|
+
selector = selector.substring(3);
|
|
102
|
+
}
|
|
103
|
+
if (!selector.startsWith('XCUIElementType')) {
|
|
104
|
+
selector = stripViewFromSelector(`XCUIElementType${selector}`);
|
|
105
|
+
rewroteSelector = true;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (strategy === 'xpath' && MAGIC_FIRST_VIS_CHILD_SEL.test(selector)) {
|
|
110
|
+
return await this.getFirstVisibleChild(mult, context);
|
|
111
|
+
} else if (strategy === 'xpath' && MAGIC_SCROLLABLE_SEL.test(selector)) {
|
|
112
|
+
[strategy, selector] = rewriteMagicScrollable(mult, this.log);
|
|
113
|
+
} else if (strategy === 'xpath') {
|
|
114
|
+
selector = selector.replace(/(^|\/)(UIA)([^[/]+)/g, (str, g1, _g2, g3) => {
|
|
115
|
+
rewroteSelector = true;
|
|
116
|
+
return g1 + stripViewFromSelector(`XCUIElementType${g3}`);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (rewroteSelector) {
|
|
121
|
+
this.log.info(
|
|
122
|
+
`Rewrote incoming selector from '${initSelector}' to ` +
|
|
123
|
+
`'${selector}' to match XCUI type. You should consider ` +
|
|
124
|
+
`updating your tests to use the new selectors directly`,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return mult
|
|
129
|
+
? await this.doNativeFind(strategy, selector, true, context)
|
|
130
|
+
: await this.doNativeFind(strategy, selector, false, context);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Finds elements natively and returns either a single element or an array depending on `mult`.
|
|
135
|
+
*
|
|
136
|
+
* Returns an array when `mult` is true; otherwise returns a single element.
|
|
137
|
+
*/
|
|
138
|
+
export async function doNativeFind(
|
|
139
|
+
this: XCUITestDriver,
|
|
140
|
+
strategy: string,
|
|
141
|
+
selector: string,
|
|
142
|
+
mult: true,
|
|
143
|
+
context?: any,
|
|
144
|
+
): Promise<Element[]>;
|
|
145
|
+
export async function doNativeFind(
|
|
146
|
+
this: XCUITestDriver,
|
|
147
|
+
strategy: string,
|
|
148
|
+
selector: string,
|
|
149
|
+
mult: false,
|
|
150
|
+
context?: any,
|
|
151
|
+
): Promise<Element>;
|
|
152
|
+
export async function doNativeFind(
|
|
153
|
+
this: XCUITestDriver,
|
|
154
|
+
strategy: string,
|
|
155
|
+
selector: string,
|
|
156
|
+
mult: boolean,
|
|
157
|
+
context?: any,
|
|
158
|
+
): Promise<Element | Element[]>;
|
|
159
|
+
export async function doNativeFind(
|
|
160
|
+
this: XCUITestDriver,
|
|
161
|
+
strategy: string,
|
|
162
|
+
selector: string,
|
|
163
|
+
mult: boolean,
|
|
164
|
+
context?: any,
|
|
165
|
+
): Promise<Element | Element[]>;
|
|
166
|
+
export async function doNativeFind(
|
|
167
|
+
this: XCUITestDriver,
|
|
168
|
+
strategy: string,
|
|
169
|
+
selector: string,
|
|
170
|
+
mult: boolean,
|
|
171
|
+
context?: any,
|
|
172
|
+
): Promise<Element | Element[]> {
|
|
173
|
+
const ctx = util.unwrapElement(context ?? null);
|
|
174
|
+
const endpoint = `/element${ctx ? `/${ctx}/element` : ''}${mult ? 's' : ''}`;
|
|
175
|
+
|
|
176
|
+
const body = {
|
|
177
|
+
using: strategy,
|
|
178
|
+
value: selector,
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const method: AllowedHttpMethod = 'POST';
|
|
182
|
+
|
|
183
|
+
let els: Element[] | Element = [];
|
|
184
|
+
try {
|
|
185
|
+
await this.implicitWaitForCondition(async () => {
|
|
186
|
+
try {
|
|
187
|
+
els = (await this.proxyCommand(endpoint, method, body)) as Element[] | Element;
|
|
188
|
+
} catch {
|
|
189
|
+
els = [] as Element[];
|
|
190
|
+
}
|
|
191
|
+
return !_.isEmpty(els as any[]);
|
|
192
|
+
});
|
|
193
|
+
} catch (err: any) {
|
|
194
|
+
if (err.message?.match(/Condition unmet/)) {
|
|
195
|
+
els = [] as Element[];
|
|
196
|
+
} else {
|
|
197
|
+
throw err;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (mult) {
|
|
201
|
+
return Array.isArray(els) ? els : [els];
|
|
202
|
+
}
|
|
203
|
+
if (Array.isArray(els)) {
|
|
204
|
+
if (_.isEmpty(els)) {
|
|
205
|
+
throw new errors.NoSuchElementError();
|
|
206
|
+
}
|
|
207
|
+
return els[0];
|
|
208
|
+
}
|
|
209
|
+
if (!els) {
|
|
210
|
+
throw new errors.NoSuchElementError();
|
|
211
|
+
}
|
|
212
|
+
return els;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Finds the first visible child element inside a context.
|
|
217
|
+
*/
|
|
218
|
+
export async function getFirstVisibleChild(
|
|
219
|
+
this: XCUITestDriver,
|
|
220
|
+
mult: boolean,
|
|
221
|
+
context: Element | string | null,
|
|
222
|
+
): Promise<Element> {
|
|
223
|
+
this.log.info(`Getting first visible child`);
|
|
224
|
+
if (mult) {
|
|
225
|
+
throw new Error('Cannot get multiple first visible children!');
|
|
226
|
+
}
|
|
227
|
+
if (!context) {
|
|
228
|
+
throw new Error('Cannot get first visible child without a context element');
|
|
229
|
+
}
|
|
230
|
+
let index = 1;
|
|
231
|
+
while (true) {
|
|
232
|
+
const strategy = WDA_CLASS_CHAIN_STRATEGY;
|
|
233
|
+
const selector = `*[${index}]`;
|
|
234
|
+
const nthChild = (await this.doNativeFind(strategy, selector, false, context)) as Element;
|
|
235
|
+
const visible = await this.getAttribute('visible', nthChild);
|
|
236
|
+
if (visible === 'true') {
|
|
237
|
+
this.log.info(`Found first visible child at position ${index}`);
|
|
238
|
+
return nthChild;
|
|
239
|
+
}
|
|
240
|
+
index++;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const MAGIC_FIRST_VIS_CHILD_SEL = /\/\*\[@firstVisible\s*=\s*('|")true\1\]/;
|
|
245
|
+
const MAGIC_SCROLLABLE_SEL = /\/\/\*\[@scrollable\s*=\s*('|")true\1\]/;
|
|
246
|
+
const WDA_CLASS_CHAIN_STRATEGY = 'class chain';
|
|
247
|
+
|
|
248
|
+
function stripViewFromSelector(selector: string): string {
|
|
249
|
+
const keepView = [
|
|
250
|
+
'XCUIElementTypeScrollView',
|
|
251
|
+
'XCUIElementTypeCollectionView',
|
|
252
|
+
'XCUIElementTypeTextView',
|
|
253
|
+
'XCUIElementTypeWebView',
|
|
254
|
+
].includes(selector);
|
|
255
|
+
|
|
256
|
+
if (!keepView && selector.indexOf('View') === selector.length - 4) {
|
|
257
|
+
return selector.substring(0, selector.length - 4);
|
|
258
|
+
}
|
|
259
|
+
return selector;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function rewriteMagicScrollable(mult: boolean, log: AppiumLogger | null = null): [string, string] {
|
|
263
|
+
const pred = ['ScrollView', 'Table', 'CollectionView', 'WebView']
|
|
264
|
+
.map((t) => `type == "XCUIElementType${t}"`)
|
|
265
|
+
.join(' OR ');
|
|
266
|
+
const strategy = WDA_CLASS_CHAIN_STRATEGY;
|
|
267
|
+
let selector = '**/*[`' + pred + '`]';
|
|
268
|
+
if (!mult) {
|
|
269
|
+
selector += '[1]';
|
|
270
|
+
}
|
|
271
|
+
log?.info(
|
|
272
|
+
'Rewrote request for scrollable descendants to class chain ' +
|
|
273
|
+
`format with selector '${selector}'`,
|
|
274
|
+
);
|
|
275
|
+
return [strategy, selector];
|
|
276
|
+
}
|
|
277
|
+
|
|
@@ -3,13 +3,22 @@ import {errors} from 'appium/driver';
|
|
|
3
3
|
import moment from 'moment-timezone';
|
|
4
4
|
import {utilities} from 'appium-ios-device';
|
|
5
5
|
import {exec} from 'teen_process';
|
|
6
|
+
import type {XCUITestDriver} from '../driver';
|
|
7
|
+
import type {Viewport, ScreenInfo, ButtonName} from './types';
|
|
8
|
+
import type {Size, Rect} from '@appium/types';
|
|
9
|
+
import type {Simulator} from 'appium-ios-simulator';
|
|
6
10
|
|
|
7
11
|
const MOMENT_FORMAT_ISO8601 = 'YYYY-MM-DDTHH:mm:ssZ';
|
|
8
12
|
|
|
9
13
|
/**
|
|
10
|
-
*
|
|
14
|
+
* Gets the currently active element.
|
|
15
|
+
*
|
|
16
|
+
* In web context, returns the active element from the DOM.
|
|
17
|
+
* In native context, returns the active element from the current view.
|
|
18
|
+
*
|
|
19
|
+
* @returns The active element
|
|
11
20
|
*/
|
|
12
|
-
export async function active() {
|
|
21
|
+
export async function active(this: XCUITestDriver): Promise<any> {
|
|
13
22
|
if (this.isWebContext()) {
|
|
14
23
|
return this.cacheWebElements(await this.executeAtom('active_element', []));
|
|
15
24
|
}
|
|
@@ -17,31 +26,29 @@ export async function active() {
|
|
|
17
26
|
}
|
|
18
27
|
|
|
19
28
|
/**
|
|
20
|
-
* Trigger a touch/fingerprint match or match failure
|
|
29
|
+
* Trigger a touch/fingerprint match or match failure.
|
|
21
30
|
*
|
|
22
|
-
* @param
|
|
23
|
-
* @this {XCUITestDriver}
|
|
31
|
+
* @param match - Whether the match should be a success or failure
|
|
24
32
|
*/
|
|
25
|
-
export async function touchId(match = true) {
|
|
33
|
+
export async function touchId(this: XCUITestDriver, match = true): Promise<void> {
|
|
26
34
|
await this.mobileSendBiometricMatch('touchId', match);
|
|
27
35
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
export async function toggleEnrollTouchId(isEnabled = true) {
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Toggle whether the device is enrolled in the touch ID program.
|
|
39
|
+
*
|
|
40
|
+
* @param isEnabled - Whether to enable or disable the touch ID program
|
|
41
|
+
*/
|
|
42
|
+
export async function toggleEnrollTouchId(this: XCUITestDriver, isEnabled = true): Promise<void> {
|
|
36
43
|
await this.mobileEnrollBiometric(isEnabled);
|
|
37
44
|
}
|
|
38
45
|
|
|
39
46
|
/**
|
|
40
|
-
* Get the window size
|
|
41
|
-
*
|
|
42
|
-
* @returns
|
|
47
|
+
* Get the window size.
|
|
48
|
+
*
|
|
49
|
+
* @returns The window size (width and height)
|
|
43
50
|
*/
|
|
44
|
-
export async function getWindowSize() {
|
|
51
|
+
export async function getWindowSize(this: XCUITestDriver): Promise<Size> {
|
|
45
52
|
const {width, height} = await this.getWindowRect();
|
|
46
53
|
return {width, height};
|
|
47
54
|
}
|
|
@@ -49,11 +56,13 @@ export async function getWindowSize() {
|
|
|
49
56
|
/**
|
|
50
57
|
* Retrieves the actual device time.
|
|
51
58
|
*
|
|
52
|
-
* @param
|
|
53
|
-
* @returns
|
|
54
|
-
* @this {XCUITestDriver}
|
|
59
|
+
* @param format - The format specifier string. Read the [MomentJS documentation](https://momentjs.com/docs/) to get the full list of supported datetime format specifiers. The default format is `YYYY-MM-DDTHH:mm:ssZ`, which complies to ISO-8601.
|
|
60
|
+
* @returns Formatted datetime string or the raw command output (if formatting fails)
|
|
55
61
|
*/
|
|
56
|
-
export async function getDeviceTime(
|
|
62
|
+
export async function getDeviceTime(
|
|
63
|
+
this: XCUITestDriver,
|
|
64
|
+
format = MOMENT_FORMAT_ISO8601,
|
|
65
|
+
): Promise<string> {
|
|
57
66
|
this.log.info('Attempting to capture iOS device date and time');
|
|
58
67
|
if (!this.isRealDevice()) {
|
|
59
68
|
this.log.info('On simulator. Assuming device time is the same as host time');
|
|
@@ -94,22 +103,29 @@ export async function getDeviceTime(format = MOMENT_FORMAT_ISO8601) {
|
|
|
94
103
|
}
|
|
95
104
|
|
|
96
105
|
/**
|
|
97
|
-
* Retrieves the current device time
|
|
106
|
+
* Retrieves the current device time.
|
|
98
107
|
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* @
|
|
108
|
+
* This is a wrapper around {@linkcode getDeviceTime}.
|
|
109
|
+
*
|
|
110
|
+
* @param format - See {@linkcode getDeviceTime.format}
|
|
111
|
+
* @returns Formatted datetime string or the raw command output if formatting fails
|
|
102
112
|
*/
|
|
103
|
-
export async function mobileGetDeviceTime(
|
|
113
|
+
export async function mobileGetDeviceTime(
|
|
114
|
+
this: XCUITestDriver,
|
|
115
|
+
format = MOMENT_FORMAT_ISO8601,
|
|
116
|
+
): Promise<string> {
|
|
104
117
|
return await this.getDeviceTime(format);
|
|
105
118
|
}
|
|
106
119
|
|
|
107
120
|
/**
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
121
|
+
* Gets the window rectangle (position and size).
|
|
122
|
+
*
|
|
123
|
+
* For W3C compatibility. In web context, returns the browser window dimensions.
|
|
124
|
+
* In native context, returns the device window dimensions.
|
|
125
|
+
*
|
|
126
|
+
* @returns The window rectangle
|
|
111
127
|
*/
|
|
112
|
-
export async function getWindowRect() {
|
|
128
|
+
export async function getWindowRect(this: XCUITestDriver): Promise<Rect> {
|
|
113
129
|
if (this.isWebContext()) {
|
|
114
130
|
const script = 'return {' +
|
|
115
131
|
'x: window.screenX || 0,' +
|
|
@@ -120,22 +136,29 @@ export async function getWindowRect() {
|
|
|
120
136
|
return await this.executeAtom('execute_script', [script]);
|
|
121
137
|
}
|
|
122
138
|
|
|
123
|
-
return
|
|
124
|
-
await this.proxyCommand('/window/rect', 'GET')
|
|
125
|
-
);
|
|
139
|
+
return (await this.proxyCommand('/window/rect', 'GET')) as Rect;
|
|
126
140
|
}
|
|
127
141
|
|
|
128
142
|
/**
|
|
129
|
-
*
|
|
143
|
+
* Removes/uninstalls the given application from the device under test.
|
|
144
|
+
*
|
|
145
|
+
* This is a wrapper around {@linkcode mobileRemoveApp mobile: removeApp}.
|
|
146
|
+
*
|
|
147
|
+
* @param bundleId - The bundle identifier of the application to be removed
|
|
148
|
+
* @returns `true` if the application has been removed successfully; `false` otherwise
|
|
130
149
|
*/
|
|
131
|
-
export async function removeApp(bundleId) {
|
|
150
|
+
export async function removeApp(this: XCUITestDriver, bundleId: string): Promise<boolean> {
|
|
132
151
|
return await this.mobileRemoveApp(bundleId);
|
|
133
152
|
}
|
|
134
153
|
|
|
135
154
|
/**
|
|
136
|
-
*
|
|
155
|
+
* Launches the app.
|
|
156
|
+
*
|
|
157
|
+
* @deprecated This API has been deprecated and is not supported anymore.
|
|
158
|
+
* Consider using corresponding 'mobile:' extensions to manage the state of the app under test.
|
|
159
|
+
* @throws {Error} Always throws an error indicating the API is deprecated
|
|
137
160
|
*/
|
|
138
|
-
export async function launchApp() {
|
|
161
|
+
export async function launchApp(this: XCUITestDriver): Promise<void> {
|
|
139
162
|
throw new Error(
|
|
140
163
|
`The launchApp API has been deprecated and is not supported anymore. ` +
|
|
141
164
|
`Consider using corresponding 'mobile:' extensions to manage the state of the app under test.`,
|
|
@@ -143,9 +166,13 @@ export async function launchApp() {
|
|
|
143
166
|
}
|
|
144
167
|
|
|
145
168
|
/**
|
|
146
|
-
*
|
|
169
|
+
* Closes the app.
|
|
170
|
+
*
|
|
171
|
+
* @deprecated This API has been deprecated and is not supported anymore.
|
|
172
|
+
* Consider using corresponding 'mobile:' extensions to manage the state of the app under test.
|
|
173
|
+
* @throws {Error} Always throws an error indicating the API is deprecated
|
|
147
174
|
*/
|
|
148
|
-
export async function closeApp() {
|
|
175
|
+
export async function closeApp(this: XCUITestDriver): Promise<void> {
|
|
149
176
|
throw new Error(
|
|
150
177
|
`The closeApp API has been deprecated and is not supported anymore. ` +
|
|
151
178
|
`Consider using corresponding 'mobile:' extensions to manage the state of the app under test.`,
|
|
@@ -153,25 +180,29 @@ export async function closeApp() {
|
|
|
153
180
|
}
|
|
154
181
|
|
|
155
182
|
/**
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
183
|
+
* Sets the URL for the current session.
|
|
184
|
+
*
|
|
185
|
+
* In web context, navigates to the URL using the remote debugger.
|
|
186
|
+
* In native context on real devices, uses the proxy command.
|
|
187
|
+
* In native context on simulators, uses simctl to open the URL.
|
|
188
|
+
*
|
|
189
|
+
* @param url - The URL to navigate to
|
|
159
190
|
*/
|
|
160
|
-
export async function setUrl(url) {
|
|
191
|
+
export async function setUrl(this: XCUITestDriver, url: string): Promise<void> {
|
|
161
192
|
this.log.debug(`Attempting to set url '${url}'`);
|
|
162
193
|
|
|
163
194
|
if (this.isWebContext()) {
|
|
164
195
|
this.setCurrentUrl(url);
|
|
165
196
|
// make sure to clear out any leftover web frames
|
|
166
197
|
this.curWebFrames = [];
|
|
167
|
-
await
|
|
198
|
+
await this.remote.navToUrl(url);
|
|
168
199
|
return;
|
|
169
200
|
}
|
|
170
201
|
|
|
171
202
|
if (this.isRealDevice()) {
|
|
172
203
|
await this.proxyCommand('/url', 'POST', {url});
|
|
173
204
|
} else {
|
|
174
|
-
await
|
|
205
|
+
await (this.device as Simulator).simctl.openUrl(url);
|
|
175
206
|
}
|
|
176
207
|
}
|
|
177
208
|
|
|
@@ -179,10 +210,10 @@ export async function setUrl(url) {
|
|
|
179
210
|
* Retrieves the viewport dimensions.
|
|
180
211
|
*
|
|
181
212
|
* The viewport is the device's screen size with status bar size subtracted if the latter is present/visible.
|
|
182
|
-
*
|
|
183
|
-
* @
|
|
213
|
+
*
|
|
214
|
+
* @returns The viewport rectangle
|
|
184
215
|
*/
|
|
185
|
-
export async function getViewportRect() {
|
|
216
|
+
export async function getViewportRect(this: XCUITestDriver): Promise<Viewport> {
|
|
186
217
|
const scale = await this.getDevicePixelRatio();
|
|
187
218
|
// status bar height comes in unscaled, so scale it
|
|
188
219
|
const statusBarHeight = Math.trunc((await this.getStatusBarHeight()) * scale);
|
|
@@ -202,26 +233,29 @@ export async function getViewportRect() {
|
|
|
202
233
|
* Get information about the screen.
|
|
203
234
|
*
|
|
204
235
|
* @privateRemarks memoized in constructor
|
|
205
|
-
* @
|
|
206
|
-
* @returns {Promise<ScreenInfo>}
|
|
236
|
+
* @returns Screen information including dimensions, scale, and status bar size
|
|
207
237
|
*/
|
|
208
|
-
export async function getScreenInfo() {
|
|
209
|
-
return
|
|
238
|
+
export async function getScreenInfo(this: XCUITestDriver): Promise<ScreenInfo> {
|
|
239
|
+
return (await this.proxyCommand('/wda/screen', 'GET')) as ScreenInfo;
|
|
210
240
|
}
|
|
211
241
|
|
|
212
242
|
/**
|
|
213
|
-
*
|
|
243
|
+
* Gets the status bar height.
|
|
244
|
+
*
|
|
245
|
+
* @returns The height of the status bar in logical pixels
|
|
214
246
|
*/
|
|
215
|
-
export async function getStatusBarHeight() {
|
|
247
|
+
export async function getStatusBarHeight(this: XCUITestDriver): Promise<number> {
|
|
216
248
|
const {statusBarSize} = await this.getScreenInfo();
|
|
217
249
|
return statusBarSize.height;
|
|
218
250
|
}
|
|
219
251
|
|
|
220
252
|
/**
|
|
221
|
-
*
|
|
222
|
-
*
|
|
253
|
+
* Gets the device pixel ratio.
|
|
254
|
+
*
|
|
255
|
+
* @privateRemarks memoized in constructor
|
|
256
|
+
* @returns The device pixel ratio (scale factor)
|
|
223
257
|
*/
|
|
224
|
-
export async function getDevicePixelRatio() {
|
|
258
|
+
export async function getDevicePixelRatio(this: XCUITestDriver): Promise<number> {
|
|
225
259
|
const {scale} = await this.getScreenInfo();
|
|
226
260
|
return scale;
|
|
227
261
|
}
|
|
@@ -236,11 +270,14 @@ export async function getDevicePixelRatio() {
|
|
|
236
270
|
*
|
|
237
271
|
* Use {@linkcode mobilePerformIoHidEvent} to call a more universal API to perform a button press with duration on any supported device.
|
|
238
272
|
*
|
|
239
|
-
* @param
|
|
240
|
-
* @param
|
|
241
|
-
* @this {XCUITestDriver}
|
|
273
|
+
* @param name - The name of the button to be pressed
|
|
274
|
+
* @param durationSeconds - The duration of the button press in seconds (float)
|
|
242
275
|
*/
|
|
243
|
-
export async function mobilePressButton(
|
|
276
|
+
export async function mobilePressButton(
|
|
277
|
+
this: XCUITestDriver,
|
|
278
|
+
name: ButtonName,
|
|
279
|
+
durationSeconds?: number,
|
|
280
|
+
): Promise<void> {
|
|
244
281
|
if (!name) {
|
|
245
282
|
throw new errors.InvalidArgumentError('Button name is mandatory');
|
|
246
283
|
}
|
|
@@ -254,25 +291,13 @@ export async function mobilePressButton(name, durationSeconds) {
|
|
|
254
291
|
* Process a string as speech and send it to Siri.
|
|
255
292
|
*
|
|
256
293
|
* Presents the Siri UI, if it is not currently active, and accepts a string which is then processed as if it were recognized speech. See [the documentation of `activateWithVoiceRecognitionText`](https://developer.apple.com/documentation/xctest/xcuisiriservice/2852140-activatewithvoicerecognitiontext?language=objc) for more details.
|
|
257
|
-
|
|
258
|
-
* @param
|
|
259
|
-
* @returns {Promise<void>}
|
|
260
|
-
* @this {XCUITestDriver}
|
|
294
|
+
*
|
|
295
|
+
* @param text - Text to be sent to Siri
|
|
261
296
|
*/
|
|
262
|
-
export async function mobileSiriCommand(text) {
|
|
297
|
+
export async function mobileSiriCommand(this: XCUITestDriver, text: string): Promise<void> {
|
|
263
298
|
if (!text) {
|
|
264
299
|
throw new errors.InvalidArgumentError('"text" argument is mandatory');
|
|
265
300
|
}
|
|
266
301
|
await this.proxyCommand('/wda/siri/activate', 'POST', {text});
|
|
267
302
|
}
|
|
268
303
|
|
|
269
|
-
/**
|
|
270
|
-
* @typedef {Object} PressButtonOptions
|
|
271
|
-
* @property {string} name - The name of the button to be pressed.
|
|
272
|
-
* @property {number} [durationSeconds] - Duration in float seconds.
|
|
273
|
-
*/
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* @typedef {import('../driver').XCUITestDriver} XCUITestDriver
|
|
277
|
-
* @typedef {import('./types').ScreenInfo} ScreenInfo
|
|
278
|
-
*/
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type {XCUITestDriver} from '../driver';
|
|
2
|
+
|
|
3
|
+
export interface GeolocationInfo {
|
|
4
|
+
/** Measurement of distance north or south of the Equator, or `null` if {@linkcode XCUITestDriver.mobileSetSimulatedLocation} has not been called or {@linkcode mobileResetSimulatedLocation} has been called. */
|
|
5
|
+
latitude: number | null;
|
|
6
|
+
/** Measurement of distance east or west of the prime meridian, or `null` if {@linkcode XCUITestDriver.mobileSetSimulatedLocation} has not been called or {@linkcode mobileResetSimulatedLocation} has been called. */
|
|
7
|
+
longitude: number | null;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Retrieves the simulated geolocation value.
|
|
12
|
+
* Only works since Xcode 14.3/iOS 16.4
|
|
13
|
+
*
|
|
14
|
+
* @returns The current simulated geolocation
|
|
15
|
+
* @throws If the device under test does not support geolocation simulation.
|
|
16
|
+
* @since 4.18
|
|
17
|
+
*/
|
|
18
|
+
export async function mobileGetSimulatedLocation(
|
|
19
|
+
this: XCUITestDriver,
|
|
20
|
+
): Promise<GeolocationInfo> {
|
|
21
|
+
return await this.proxyCommand<any, GeolocationInfo>('/wda/simulatedLocation', 'GET');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Sets simulated geolocation value.
|
|
26
|
+
* Only works since Xcode 14.3/iOS 16.4
|
|
27
|
+
*
|
|
28
|
+
* @param latitude - Latitude value
|
|
29
|
+
* @param longitude - Longitude value
|
|
30
|
+
* @throws If the device under test does not support geolocation simulation.
|
|
31
|
+
* @since 4.18
|
|
32
|
+
*/
|
|
33
|
+
export async function mobileSetSimulatedLocation(
|
|
34
|
+
this: XCUITestDriver,
|
|
35
|
+
latitude: number,
|
|
36
|
+
longitude: number,
|
|
37
|
+
): Promise<void> {
|
|
38
|
+
await this.proxyCommand('/wda/simulatedLocation', 'POST', {latitude, longitude});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Resets simulated geolocation value.
|
|
43
|
+
* Only works since Xcode 14.3/iOS 16.4.
|
|
44
|
+
* ! Do not forget to reset the simulated geolocation value after your automated test is finished.
|
|
45
|
+
* ! If the value is not reset explicitly then the simulated one will remain until the next device restart.
|
|
46
|
+
*
|
|
47
|
+
* @throws If the device under test does not support geolocation simulation.
|
|
48
|
+
* @since 4.18
|
|
49
|
+
*/
|
|
50
|
+
export async function mobileResetSimulatedLocation(
|
|
51
|
+
this: XCUITestDriver,
|
|
52
|
+
): Promise<void> {
|
|
53
|
+
await this.proxyCommand('/wda/simulatedLocation', 'DELETE');
|
|
54
|
+
}
|
|
55
|
+
|