appium-xcuitest-driver 12.21.0 → 12.22.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/CHANGELOG.md +6 -0
- package/build/lib/commands/display.d.ts +4 -4
- package/build/lib/commands/display.d.ts.map +1 -1
- package/build/lib/commands/display.js +11 -5
- package/build/lib/commands/display.js.map +1 -1
- package/build/lib/commands/general.d.ts +2 -1
- package/build/lib/commands/general.d.ts.map +1 -1
- package/build/lib/commands/general.js +18 -1
- package/build/lib/commands/general.js.map +1 -1
- package/build/lib/commands/helpers/duo.d.ts +7 -0
- package/build/lib/commands/helpers/duo.d.ts.map +1 -0
- package/build/lib/commands/helpers/duo.js +28 -0
- package/build/lib/commands/helpers/duo.js.map +1 -0
- package/build/lib/commands/iohid.d.ts +3 -0
- package/build/lib/commands/iohid.d.ts.map +1 -1
- package/build/lib/commands/iohid.js +9 -0
- package/build/lib/commands/iohid.js.map +1 -1
- package/build/lib/commands/lock.d.ts.map +1 -1
- package/build/lib/commands/lock.js +38 -3
- package/build/lib/commands/lock.js.map +1 -1
- package/lib/commands/display.ts +12 -5
- package/lib/commands/general.ts +19 -1
- package/lib/commands/helpers/duo.ts +31 -0
- package/lib/commands/iohid.ts +9 -0
- package/lib/commands/lock.ts +43 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [12.22.0](https://github.com/appium/appium-xcuitest-driver/compare/v12.21.0...v12.22.0) (2026-10-27)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* route Duo simulator HID controls through the host ([#3077](https://github.com/appium/appium-xcuitest-driver/issues/3077)) ([32dae67](https://github.com/appium/appium-xcuitest-driver/commit/32dae673c5b93bdee2fc5c3fe57a45c02a0295b2))
|
|
6
|
+
|
|
1
7
|
## [12.21.0](https://github.com/appium/appium-xcuitest-driver/compare/v12.20.0...v12.21.0) (2026-10-26)
|
|
2
8
|
|
|
3
9
|
### Features
|
|
@@ -36,13 +36,13 @@ export declare function getDevicePixelRatio(this: XCUITestDriver): Promise<numbe
|
|
|
36
36
|
* Reads the current hinge angle in degrees, including changes made outside WDA.
|
|
37
37
|
* Requires a WDA build with GET /wda/device/hingeAngle support.
|
|
38
38
|
* WDA checks platform, hinge and CoreMotion availability and waits up to five seconds for a valid reading.
|
|
39
|
-
*
|
|
39
|
+
* A reading may reflect an intermediate angle during folding.
|
|
40
40
|
*/
|
|
41
41
|
export declare function mobileGetSimulatedHingeAngle(this: XCUITestDriver): Promise<number>;
|
|
42
42
|
/**
|
|
43
|
-
* Requests a simulated hinge angle
|
|
44
|
-
* Requires
|
|
45
|
-
*
|
|
43
|
+
* Requests a simulated hinge angle through the host CoreSimulator HID service.
|
|
44
|
+
* Requires an iPhone Duo Simulator on Xcode 27+; CoreSimulator identifies the device type.
|
|
45
|
+
* WDA supplies hinge angle readings.
|
|
46
46
|
* The transition completes asynchronously. Select currentDisplayId separately.
|
|
47
47
|
*
|
|
48
48
|
* @param angle - Degrees from 0 (closed) to 180 (fully open), inclusive.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../../../lib/commands/display.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../../../lib/commands/display.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,cAAc,CAAC;AAEjD,OAAO,KAAK,EAAC,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAiB,MAAM,YAAY,CAAC;AAElF;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,CAe7E;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAE7E;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAcrF;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAG9E;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAG/E;AAED;;;;;GAKG;AACH,wBAAsB,4BAA4B,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAExF;AAED;;;;;;;GAOG;AACH,wBAAsB,4BAA4B,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMrG"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { errors } from 'appium/driver.js';
|
|
2
|
+
import { getDuoSimulator, withDuoArgumentErrors } from './helpers/duo.js';
|
|
1
3
|
/**
|
|
2
4
|
* Retrieves the viewport dimensions.
|
|
3
5
|
*
|
|
@@ -70,20 +72,24 @@ export async function getDevicePixelRatio() {
|
|
|
70
72
|
* Reads the current hinge angle in degrees, including changes made outside WDA.
|
|
71
73
|
* Requires a WDA build with GET /wda/device/hingeAngle support.
|
|
72
74
|
* WDA checks platform, hinge and CoreMotion availability and waits up to five seconds for a valid reading.
|
|
73
|
-
*
|
|
75
|
+
* A reading may reflect an intermediate angle during folding.
|
|
74
76
|
*/
|
|
75
77
|
export async function mobileGetSimulatedHingeAngle() {
|
|
76
78
|
return await this.proxyCommand('/wda/device/hingeAngle', 'GET');
|
|
77
79
|
}
|
|
78
80
|
/**
|
|
79
|
-
* Requests a simulated hinge angle
|
|
80
|
-
* Requires
|
|
81
|
-
*
|
|
81
|
+
* Requests a simulated hinge angle through the host CoreSimulator HID service.
|
|
82
|
+
* Requires an iPhone Duo Simulator on Xcode 27+; CoreSimulator identifies the device type.
|
|
83
|
+
* WDA supplies hinge angle readings.
|
|
82
84
|
* The transition completes asynchronously. Select currentDisplayId separately.
|
|
83
85
|
*
|
|
84
86
|
* @param angle - Degrees from 0 (closed) to 180 (fully open), inclusive.
|
|
85
87
|
*/
|
|
86
88
|
export async function mobileSetSimulatedHingeAngle(angle) {
|
|
87
|
-
|
|
89
|
+
const simulator = await getDuoSimulator(this);
|
|
90
|
+
if (!simulator) {
|
|
91
|
+
throw new errors.UnsupportedOperationError('Setting the hinge angle requires an iPhone Duo Simulator on Xcode 27+');
|
|
92
|
+
}
|
|
93
|
+
await withDuoArgumentErrors(() => simulator.setSimulatedHingeAngle(angle));
|
|
88
94
|
}
|
|
89
95
|
//# sourceMappingURL=display.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display.js","sourceRoot":"","sources":["../../../lib/commands/display.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"display.js","sourceRoot":"","sources":["../../../lib/commands/display.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAC;AAGxC,OAAO,EAAC,eAAe,EAAE,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AAGxE;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,2EAA2E;IAC3E,0CAA0C;IAC1C,MAAM,EAAC,KAAK,EAAE,aAAa,EAAE,UAAU,EAAC,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;IACtE,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;IACjE,MAAM,IAAI,GAAG,UAAU,IAAI,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;IAExD,2EAA2E;IAC3E,qEAAqE;IACrE,OAAO;QACL,IAAI,EAAE,CAAC;QACP,GAAG,EAAE,eAAe;QACpB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACrC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,eAAe;KAC1D,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,OAAO,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,KAAK,CAAC,CAAe,CAAC;AACvE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,WAAW,GAAG,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,KAAK,CAAC,CAAqB,CAAC;IACzF,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAC,EAAE,EAAE,CAAC,CAAC;QACtE,EAAE,EAAE,SAAS;QACb,OAAO,EAAE;YACP,WAAW,EAAE,MAAM,CAAC,KAAK;YACzB,YAAY,EAAE,MAAM,CAAC,MAAM;YAC3B,MAAM,EAAE,MAAM,CAAC,CAAC;YAChB,MAAM,EAAE,MAAM,CAAC,CAAC;YAChB,OAAO,EAAE,KAAK;YACd,MAAM;SACP;QACD,SAAS,EAAE,MAAM;KAClB,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,EAAC,aAAa,EAAC,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;IACnD,OAAO,aAAa,CAAC,MAAM,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,EAAC,KAAK,EAAC,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;IAC3C,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B;IAChD,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;AAClE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAuB,KAAa;IACpF,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,MAAM,CAAC,yBAAyB,CAAC,uEAAuE,CAAC,CAAC;IACtH,CAAC;IACD,MAAM,qBAAqB,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC;AAC7E,CAAC"}
|
|
@@ -77,7 +77,8 @@ export declare function mobileGetPressableButtons(this: XCUITestDriver): Promise
|
|
|
77
77
|
*
|
|
78
78
|
* This executes different methods based on the platform:
|
|
79
79
|
*
|
|
80
|
-
* -
|
|
80
|
+
* - Duo simulator Home and volume buttons: host CoreSimulator HID.
|
|
81
|
+
* - Other iOS buttons/devices: [`pressButton:`](https://developer.apple.com/documentation/xctest/xcuidevice/1619052-pressbutton)
|
|
81
82
|
* - tvOS: [`pressButton:`](https://developer.apple.com/documentation/xctest/xcuiremote/1627475-pressbutton) or [`pressButton:forDuration:`](https://developer.apple.com/documentation/xctest/xcuiremote/1627476-pressbutton)
|
|
82
83
|
*
|
|
83
84
|
* Use {@linkcode mobilePerformIoHidEvent} to call a more universal API to perform a button press with duration on any supported device.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"general.d.ts","sourceRoot":"","sources":["../../../lib/commands/general.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"general.d.ts","sourceRoot":"","sources":["../../../lib/commands/general.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAC,UAAU,EAAE,oBAAoB,EAAC,MAAM,YAAY,CAAC;AASjE;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,UAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/E;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,UAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/F;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,SAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,CA+B3G;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,SAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,CAEjH;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAExF;AAED;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAKnE;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAKlE;AAED;;;;;;;;GAQG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB7E;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAEnG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,UAAU,EAChB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKzF"}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { errors } from 'appium/driver.js';
|
|
2
2
|
import dayjs from 'dayjs';
|
|
3
3
|
import utc from 'dayjs/plugin/utc.js';
|
|
4
|
+
import { getDuoSimulator, withDuoArgumentErrors } from './helpers/duo.js';
|
|
5
|
+
import { HIDPageEvent, HIDUsageConsumerEvent } from './hid-event.js';
|
|
4
6
|
dayjs.extend(utc);
|
|
5
7
|
import { LockdownClient } from '../device/lockdown-client.js';
|
|
6
8
|
const DATETIME_FORMAT_ISO8601 = 'YYYY-MM-DDTHH:mm:ssZ';
|
|
9
|
+
const DUO_BUTTON_USAGES = new Map([
|
|
10
|
+
['home', HIDUsageConsumerEvent.kHIDUsage_Csmr_Menu],
|
|
11
|
+
['volumeup', HIDUsageConsumerEvent.kHIDUsage_Csmr_VolumeIncrement],
|
|
12
|
+
['volumedown', HIDUsageConsumerEvent.kHIDUsage_Csmr_VolumeDecrement],
|
|
13
|
+
]);
|
|
7
14
|
/**
|
|
8
15
|
* Trigger a touch/fingerprint match or match failure.
|
|
9
16
|
*
|
|
@@ -141,7 +148,8 @@ export async function mobileGetPressableButtons() {
|
|
|
141
148
|
*
|
|
142
149
|
* This executes different methods based on the platform:
|
|
143
150
|
*
|
|
144
|
-
* -
|
|
151
|
+
* - Duo simulator Home and volume buttons: host CoreSimulator HID.
|
|
152
|
+
* - Other iOS buttons/devices: [`pressButton:`](https://developer.apple.com/documentation/xctest/xcuidevice/1619052-pressbutton)
|
|
145
153
|
* - tvOS: [`pressButton:`](https://developer.apple.com/documentation/xctest/xcuiremote/1627475-pressbutton) or [`pressButton:forDuration:`](https://developer.apple.com/documentation/xctest/xcuiremote/1627476-pressbutton)
|
|
146
154
|
*
|
|
147
155
|
* Use {@linkcode mobilePerformIoHidEvent} to call a more universal API to perform a button press with duration on any supported device.
|
|
@@ -156,6 +164,15 @@ export async function mobilePressButton(name, durationSeconds) {
|
|
|
156
164
|
if (durationSeconds != null && typeof durationSeconds !== 'number') {
|
|
157
165
|
throw new errors.InvalidArgumentError('durationSeconds should be a number');
|
|
158
166
|
}
|
|
167
|
+
const simulator = await getDuoSimulator(this);
|
|
168
|
+
if (simulator) {
|
|
169
|
+
const usage = DUO_BUTTON_USAGES.get(name.toLowerCase());
|
|
170
|
+
if (usage === undefined) {
|
|
171
|
+
throw new errors.UnsupportedOperationError(`Button '${name}' has no supported Duo simulator HID mapping`);
|
|
172
|
+
}
|
|
173
|
+
// Preserve iOS pressButton semantics: durationSeconds is a tvOS-only option.
|
|
174
|
+
return await withDuoArgumentErrors(() => simulator.pressHidButton(HIDPageEvent.kHIDPage_Consumer, usage));
|
|
175
|
+
}
|
|
159
176
|
return await this.proxyCommand('/wda/pressButton', 'POST', { name, duration: durationSeconds });
|
|
160
177
|
}
|
|
161
178
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"general.js","sourceRoot":"","sources":["../../../lib/commands/general.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAC;AACxC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,qBAAqB,CAAC;AAEtC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAElB,OAAO,EAAC,cAAc,EAAC,MAAM,8BAA8B,CAAC;AAI5D,MAAM,uBAAuB,GAAG,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"general.js","sourceRoot":"","sources":["../../../lib/commands/general.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Simulator, SupportsDuo } from 'appium-ios-simulator';
|
|
2
|
+
import type { XCUITestDriver } from '../../driver.js';
|
|
3
|
+
/** Select Duo controls by device type, not hinge or multiple-display capability. */
|
|
4
|
+
export declare function getDuoSimulator(driver: XCUITestDriver): Promise<(Simulator & SupportsDuo) | undefined>;
|
|
5
|
+
/** Translate native argument validation at the simulator command boundary. */
|
|
6
|
+
export declare function withDuoArgumentErrors(command: () => Promise<void>): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=duo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duo.d.ts","sourceRoot":"","sources":["../../../../lib/commands/helpers/duo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAE,WAAW,EAAC,MAAM,sBAAsB,CAAC;AAGjE,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAEpD,oFAAoF;AACpF,wBAAsB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,SAAS,CAAC,CAY5G;AAED,8EAA8E;AAC9E,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CASvF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { errors } from 'appium/driver.js';
|
|
2
|
+
/** Select Duo controls by device type, not hinge or multiple-display capability. */
|
|
3
|
+
export async function getDuoSimulator(driver) {
|
|
4
|
+
if (!driver.isSimulator() || ['tvos', 'watchos'].includes(String(driver.opts.platformName).toLowerCase())) {
|
|
5
|
+
return undefined;
|
|
6
|
+
}
|
|
7
|
+
const simulator = driver.device;
|
|
8
|
+
if (typeof simulator.isDuo !== 'function' || !(await simulator.isDuo())) {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
if (typeof simulator.setSimulatedHingeAngle !== 'function') {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
return simulator;
|
|
15
|
+
}
|
|
16
|
+
/** Translate native argument validation at the simulator command boundary. */
|
|
17
|
+
export async function withDuoArgumentErrors(command) {
|
|
18
|
+
try {
|
|
19
|
+
await command();
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
if (err instanceof TypeError) {
|
|
23
|
+
throw new errors.InvalidArgumentError(err.message);
|
|
24
|
+
}
|
|
25
|
+
throw err;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=duo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duo.js","sourceRoot":"","sources":["../../../../lib/commands/helpers/duo.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAC;AAIxC,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAsB;IAC1D,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;QAC1G,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAmB,CAAC;IAC7C,IAAI,OAAO,SAAS,CAAC,KAAK,KAAK,UAAU,IAAI,CAAC,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC;QACxE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,OAAO,SAAS,CAAC,sBAAsB,KAAK,UAAU,EAAE,CAAC;QAC3D,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,SAAoC,CAAC;AAC9C,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAA4B;IACtE,IAAI,CAAC;QACH,MAAM,OAAO,EAAE,CAAC;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,SAAS,EAAE,CAAC;YAC7B,MAAM,IAAI,MAAM,CAAC,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrD,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -4,6 +4,9 @@ import { HIDPageEvent } from './hid-event.js';
|
|
|
4
4
|
/**
|
|
5
5
|
* Emulates triggering of the given low-level IO HID device event.
|
|
6
6
|
*
|
|
7
|
+
* Duo simulators use host CoreSimulator HID with native argument validation.
|
|
8
|
+
* Other devices use WDA/XCTest. Completion does not guarantee that the event was applied.
|
|
9
|
+
*
|
|
7
10
|
* Popular constants:
|
|
8
11
|
* - `kHIDPage_Consumer` = `0x0C`
|
|
9
12
|
* - `kHIDUsage_Csmr_VolumeIncrement` = `0xE9` (Volume Up)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iohid.d.ts","sourceRoot":"","sources":["../../../lib/commands/iohid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AAIxD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"iohid.d.ts","sourceRoot":"","sources":["../../../lib/commands/iohid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AAIxD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,cAAc,CAAC;AAGjD,OAAO,EAAgB,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAE3D;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,MAAM,GAAG,MAAM,GAC/B,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,cAAc,EACpB,IAAI,CAAC,EAAE,aAAa,EACpB,IAAI,CAAC,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,EACd,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,EACjC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAC3B,OAAO,CAAC,IAAI,CAAC,CAyCf"}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { errors } from 'appium/driver.js';
|
|
2
2
|
import { HidIndigoClient } from '../device/hid-indigo-client.js';
|
|
3
|
+
import { getDuoSimulator, withDuoArgumentErrors } from './helpers/duo.js';
|
|
3
4
|
import { requireRealDevice } from './helpers/index.js';
|
|
4
5
|
import { HIDUsageEvent, HIDPageEvent } from './hid-event.js';
|
|
5
6
|
/**
|
|
6
7
|
* Emulates triggering of the given low-level IO HID device event.
|
|
7
8
|
*
|
|
9
|
+
* Duo simulators use host CoreSimulator HID with native argument validation.
|
|
10
|
+
* Other devices use WDA/XCTest. Completion does not guarantee that the event was applied.
|
|
11
|
+
*
|
|
8
12
|
* Popular constants:
|
|
9
13
|
* - `kHIDPage_Consumer` = `0x0C`
|
|
10
14
|
* - `kHIDUsage_Csmr_VolumeIncrement` = `0xE9` (Volume Up)
|
|
@@ -18,6 +22,11 @@ import { HIDUsageEvent, HIDPageEvent } from './hid-event.js';
|
|
|
18
22
|
* @param durationSeconds - The event duration in float seconds (XCTest uses `0.005` for a single press event)
|
|
19
23
|
*/
|
|
20
24
|
export async function mobilePerformIoHidEvent(page, usage, durationSeconds) {
|
|
25
|
+
const simulator = await getDuoSimulator(this);
|
|
26
|
+
if (simulator) {
|
|
27
|
+
const duration = typeof durationSeconds === 'string' ? parseFloat(durationSeconds) : durationSeconds;
|
|
28
|
+
return await withDuoArgumentErrors(() => simulator.pressHidButton(page, usage, duration));
|
|
29
|
+
}
|
|
21
30
|
if (!isHIDPageEvent(page)) {
|
|
22
31
|
throw new errors.InvalidArgumentError(`'page' argument must be a valid HIDPageEvent identifier`);
|
|
23
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iohid.js","sourceRoot":"","sources":["../../../lib/commands/iohid.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAC;AAExC,OAAO,EAAC,eAAe,EAAC,MAAM,gCAAgC,CAAC;AAE/D,OAAO,EAAC,iBAAiB,EAAC,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAC,aAAa,EAAE,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAE3D
|
|
1
|
+
{"version":3,"file":"iohid.js","sourceRoot":"","sources":["../../../lib/commands/iohid.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../../lib/commands/lock.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../../lib/commands/lock.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,cAAc,CAAC;AAIjD;;;;;GAKG;AACH,wBAAsB,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAazF;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhE;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAErE"}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
2
|
+
import { errors } from 'appium/driver.js';
|
|
3
|
+
import { waitForCondition } from 'asyncbox';
|
|
4
|
+
import { getDuoSimulator } from './helpers/duo.js';
|
|
5
|
+
import { HIDPageEvent, HIDUsageConsumerEvent } from './hid-event.js';
|
|
2
6
|
/**
|
|
3
7
|
* Lock the device (and optionally unlock the device after a certain amount of time)
|
|
4
8
|
*
|
|
@@ -6,7 +10,7 @@ import { setTimeout as delay } from 'node:timers/promises';
|
|
|
6
10
|
* @defaultValue 0
|
|
7
11
|
*/
|
|
8
12
|
export async function lock(seconds) {
|
|
9
|
-
await this
|
|
13
|
+
await setLocked(this, true);
|
|
10
14
|
if (isNaN(Number(seconds))) {
|
|
11
15
|
return;
|
|
12
16
|
}
|
|
@@ -15,13 +19,13 @@ export async function lock(seconds) {
|
|
|
15
19
|
return;
|
|
16
20
|
}
|
|
17
21
|
await delay(floatSeconds * 1000);
|
|
18
|
-
await this.
|
|
22
|
+
await this.unlock();
|
|
19
23
|
}
|
|
20
24
|
/**
|
|
21
25
|
* Unlock the device
|
|
22
26
|
*/
|
|
23
27
|
export async function unlock() {
|
|
24
|
-
await this
|
|
28
|
+
await setLocked(this, false);
|
|
25
29
|
}
|
|
26
30
|
/**
|
|
27
31
|
* Determine whether the device is locked
|
|
@@ -31,4 +35,35 @@ export async function unlock() {
|
|
|
31
35
|
export async function isLocked() {
|
|
32
36
|
return await this.proxyCommand('/wda/locked', 'GET');
|
|
33
37
|
}
|
|
38
|
+
async function setLocked(driver, locked) {
|
|
39
|
+
const simulator = await getDuoSimulator(driver);
|
|
40
|
+
if (!simulator) {
|
|
41
|
+
await driver.proxyCommand(locked ? '/wda/lock' : '/wda/unlock', 'POST');
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if ((await driver.isLocked()) === locked) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
await simulator.pressHidButton(HIDPageEvent.kHIDPage_Consumer, locked ? HIDUsageConsumerEvent.kHIDUsage_Csmr_Power : HIDUsageConsumerEvent.kHIDUsage_Csmr_Menu);
|
|
48
|
+
const timeoutError = new errors.UnknownError(`Timed out waiting for the simulator to ${locked ? 'lock' : 'unlock'}`);
|
|
49
|
+
const waitForState = async (waitMs) => await waitForCondition(async () => (await driver.isLocked()) === locked, {
|
|
50
|
+
waitMs,
|
|
51
|
+
intervalMs: 100,
|
|
52
|
+
error: timeoutError,
|
|
53
|
+
});
|
|
54
|
+
if (!locked) {
|
|
55
|
+
try {
|
|
56
|
+
await waitForState(1000);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
if (err !== timeoutError) {
|
|
61
|
+
throw err;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// A sleeping device may need a second Home press after waking.
|
|
65
|
+
await simulator.pressHidButton(HIDPageEvent.kHIDPage_Consumer, HIDUsageConsumerEvent.kHIDUsage_Csmr_Menu);
|
|
66
|
+
}
|
|
67
|
+
await waitForState(locked ? 5000 : 4000);
|
|
68
|
+
}
|
|
34
69
|
//# sourceMappingURL=lock.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../../lib/commands/lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,IAAI,KAAK,EAAC,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../../lib/commands/lock.ts"],"names":[],"mappings":"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"}
|
package/lib/commands/display.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import {errors} from 'appium/driver.js';
|
|
2
|
+
|
|
1
3
|
import type {XCUITestDriver} from '../driver.js';
|
|
4
|
+
import {getDuoSimulator, withDuoArgumentErrors} from './helpers/duo.js';
|
|
2
5
|
import type {Viewport, ScreenInfo, DisplayInfo, WDADisplayInfo} from './types.js';
|
|
3
6
|
|
|
4
7
|
/**
|
|
@@ -79,20 +82,24 @@ export async function getDevicePixelRatio(this: XCUITestDriver): Promise<number>
|
|
|
79
82
|
* Reads the current hinge angle in degrees, including changes made outside WDA.
|
|
80
83
|
* Requires a WDA build with GET /wda/device/hingeAngle support.
|
|
81
84
|
* WDA checks platform, hinge and CoreMotion availability and waits up to five seconds for a valid reading.
|
|
82
|
-
*
|
|
85
|
+
* A reading may reflect an intermediate angle during folding.
|
|
83
86
|
*/
|
|
84
87
|
export async function mobileGetSimulatedHingeAngle(this: XCUITestDriver): Promise<number> {
|
|
85
88
|
return await this.proxyCommand('/wda/device/hingeAngle', 'GET');
|
|
86
89
|
}
|
|
87
90
|
|
|
88
91
|
/**
|
|
89
|
-
* Requests a simulated hinge angle
|
|
90
|
-
* Requires
|
|
91
|
-
*
|
|
92
|
+
* Requests a simulated hinge angle through the host CoreSimulator HID service.
|
|
93
|
+
* Requires an iPhone Duo Simulator on Xcode 27+; CoreSimulator identifies the device type.
|
|
94
|
+
* WDA supplies hinge angle readings.
|
|
92
95
|
* The transition completes asynchronously. Select currentDisplayId separately.
|
|
93
96
|
*
|
|
94
97
|
* @param angle - Degrees from 0 (closed) to 180 (fully open), inclusive.
|
|
95
98
|
*/
|
|
96
99
|
export async function mobileSetSimulatedHingeAngle(this: XCUITestDriver, angle: number): Promise<void> {
|
|
97
|
-
await this
|
|
100
|
+
const simulator = await getDuoSimulator(this);
|
|
101
|
+
if (!simulator) {
|
|
102
|
+
throw new errors.UnsupportedOperationError('Setting the hinge angle requires an iPhone Duo Simulator on Xcode 27+');
|
|
103
|
+
}
|
|
104
|
+
await withDuoArgumentErrors(() => simulator.setSimulatedHingeAngle(angle));
|
|
98
105
|
}
|
package/lib/commands/general.ts
CHANGED
|
@@ -3,6 +3,9 @@ import {errors} from 'appium/driver.js';
|
|
|
3
3
|
import dayjs from 'dayjs';
|
|
4
4
|
import utc from 'dayjs/plugin/utc.js';
|
|
5
5
|
|
|
6
|
+
import {getDuoSimulator, withDuoArgumentErrors} from './helpers/duo.js';
|
|
7
|
+
import {HIDPageEvent, HIDUsageConsumerEvent} from './hid-event.js';
|
|
8
|
+
|
|
6
9
|
dayjs.extend(utc);
|
|
7
10
|
|
|
8
11
|
import {LockdownClient} from '../device/lockdown-client.js';
|
|
@@ -10,6 +13,11 @@ import type {XCUITestDriver} from '../driver.js';
|
|
|
10
13
|
import type {ButtonName, PressableButtonsInfo} from './types.js';
|
|
11
14
|
|
|
12
15
|
const DATETIME_FORMAT_ISO8601 = 'YYYY-MM-DDTHH:mm:ssZ';
|
|
16
|
+
const DUO_BUTTON_USAGES = new Map<string, HIDUsageConsumerEvent>([
|
|
17
|
+
['home', HIDUsageConsumerEvent.kHIDUsage_Csmr_Menu],
|
|
18
|
+
['volumeup', HIDUsageConsumerEvent.kHIDUsage_Csmr_VolumeIncrement],
|
|
19
|
+
['volumedown', HIDUsageConsumerEvent.kHIDUsage_Csmr_VolumeDecrement],
|
|
20
|
+
]);
|
|
13
21
|
|
|
14
22
|
/**
|
|
15
23
|
* Trigger a touch/fingerprint match or match failure.
|
|
@@ -164,7 +172,8 @@ export async function mobileGetPressableButtons(this: XCUITestDriver): Promise<P
|
|
|
164
172
|
*
|
|
165
173
|
* This executes different methods based on the platform:
|
|
166
174
|
*
|
|
167
|
-
* -
|
|
175
|
+
* - Duo simulator Home and volume buttons: host CoreSimulator HID.
|
|
176
|
+
* - Other iOS buttons/devices: [`pressButton:`](https://developer.apple.com/documentation/xctest/xcuidevice/1619052-pressbutton)
|
|
168
177
|
* - tvOS: [`pressButton:`](https://developer.apple.com/documentation/xctest/xcuiremote/1627475-pressbutton) or [`pressButton:forDuration:`](https://developer.apple.com/documentation/xctest/xcuiremote/1627476-pressbutton)
|
|
169
178
|
*
|
|
170
179
|
* Use {@linkcode mobilePerformIoHidEvent} to call a more universal API to perform a button press with duration on any supported device.
|
|
@@ -183,6 +192,15 @@ export async function mobilePressButton(
|
|
|
183
192
|
if (durationSeconds != null && typeof durationSeconds !== 'number') {
|
|
184
193
|
throw new errors.InvalidArgumentError('durationSeconds should be a number');
|
|
185
194
|
}
|
|
195
|
+
const simulator = await getDuoSimulator(this);
|
|
196
|
+
if (simulator) {
|
|
197
|
+
const usage = DUO_BUTTON_USAGES.get(name.toLowerCase());
|
|
198
|
+
if (usage === undefined) {
|
|
199
|
+
throw new errors.UnsupportedOperationError(`Button '${name}' has no supported Duo simulator HID mapping`);
|
|
200
|
+
}
|
|
201
|
+
// Preserve iOS pressButton semantics: durationSeconds is a tvOS-only option.
|
|
202
|
+
return await withDuoArgumentErrors(() => simulator.pressHidButton(HIDPageEvent.kHIDPage_Consumer, usage));
|
|
203
|
+
}
|
|
186
204
|
return await this.proxyCommand('/wda/pressButton', 'POST', {name, duration: durationSeconds});
|
|
187
205
|
}
|
|
188
206
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type {Simulator, SupportsDuo} from 'appium-ios-simulator';
|
|
2
|
+
import {errors} from 'appium/driver.js';
|
|
3
|
+
|
|
4
|
+
import type {XCUITestDriver} from '../../driver.js';
|
|
5
|
+
|
|
6
|
+
/** Select Duo controls by device type, not hinge or multiple-display capability. */
|
|
7
|
+
export async function getDuoSimulator(driver: XCUITestDriver): Promise<(Simulator & SupportsDuo) | undefined> {
|
|
8
|
+
if (!driver.isSimulator() || ['tvos', 'watchos'].includes(String(driver.opts.platformName).toLowerCase())) {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
const simulator = driver.device as Simulator;
|
|
12
|
+
if (typeof simulator.isDuo !== 'function' || !(await simulator.isDuo())) {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
if (typeof simulator.setSimulatedHingeAngle !== 'function') {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
return simulator as Simulator & SupportsDuo;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Translate native argument validation at the simulator command boundary. */
|
|
22
|
+
export async function withDuoArgumentErrors(command: () => Promise<void>): Promise<void> {
|
|
23
|
+
try {
|
|
24
|
+
await command();
|
|
25
|
+
} catch (err) {
|
|
26
|
+
if (err instanceof TypeError) {
|
|
27
|
+
throw new errors.InvalidArgumentError(err.message);
|
|
28
|
+
}
|
|
29
|
+
throw err;
|
|
30
|
+
}
|
|
31
|
+
}
|
package/lib/commands/iohid.ts
CHANGED
|
@@ -3,12 +3,16 @@ import {errors} from 'appium/driver.js';
|
|
|
3
3
|
|
|
4
4
|
import {HidIndigoClient} from '../device/hid-indigo-client.js';
|
|
5
5
|
import type {XCUITestDriver} from '../driver.js';
|
|
6
|
+
import {getDuoSimulator, withDuoArgumentErrors} from './helpers/duo.js';
|
|
6
7
|
import {requireRealDevice} from './helpers/index.js';
|
|
7
8
|
import {HIDUsageEvent, HIDPageEvent} from './hid-event.js';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Emulates triggering of the given low-level IO HID device event.
|
|
11
12
|
*
|
|
13
|
+
* Duo simulators use host CoreSimulator HID with native argument validation.
|
|
14
|
+
* Other devices use WDA/XCTest. Completion does not guarantee that the event was applied.
|
|
15
|
+
*
|
|
12
16
|
* Popular constants:
|
|
13
17
|
* - `kHIDPage_Consumer` = `0x0C`
|
|
14
18
|
* - `kHIDUsage_Csmr_VolumeIncrement` = `0xE9` (Volume Up)
|
|
@@ -27,6 +31,11 @@ export async function mobilePerformIoHidEvent(
|
|
|
27
31
|
usage: number,
|
|
28
32
|
durationSeconds: number | string,
|
|
29
33
|
): Promise<void> {
|
|
34
|
+
const simulator = await getDuoSimulator(this);
|
|
35
|
+
if (simulator) {
|
|
36
|
+
const duration = typeof durationSeconds === 'string' ? parseFloat(durationSeconds) : durationSeconds;
|
|
37
|
+
return await withDuoArgumentErrors(() => simulator.pressHidButton(page, usage, duration));
|
|
38
|
+
}
|
|
30
39
|
if (!isHIDPageEvent(page)) {
|
|
31
40
|
throw new errors.InvalidArgumentError(`'page' argument must be a valid HIDPageEvent identifier`);
|
|
32
41
|
}
|
package/lib/commands/lock.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import {setTimeout as delay} from 'node:timers/promises';
|
|
2
2
|
|
|
3
|
+
import {errors} from 'appium/driver.js';
|
|
4
|
+
import {waitForCondition} from 'asyncbox';
|
|
5
|
+
|
|
3
6
|
import type {XCUITestDriver} from '../driver.js';
|
|
7
|
+
import {getDuoSimulator} from './helpers/duo.js';
|
|
8
|
+
import {HIDPageEvent, HIDUsageConsumerEvent} from './hid-event.js';
|
|
4
9
|
|
|
5
10
|
/**
|
|
6
11
|
* Lock the device (and optionally unlock the device after a certain amount of time)
|
|
@@ -9,7 +14,7 @@ import type {XCUITestDriver} from '../driver.js';
|
|
|
9
14
|
* @defaultValue 0
|
|
10
15
|
*/
|
|
11
16
|
export async function lock(this: XCUITestDriver, seconds?: number | string): Promise<void> {
|
|
12
|
-
await this
|
|
17
|
+
await setLocked(this, true);
|
|
13
18
|
if (isNaN(Number(seconds))) {
|
|
14
19
|
return;
|
|
15
20
|
}
|
|
@@ -20,14 +25,14 @@ export async function lock(this: XCUITestDriver, seconds?: number | string): Pro
|
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
await delay(floatSeconds * 1000);
|
|
23
|
-
await this.
|
|
28
|
+
await this.unlock();
|
|
24
29
|
}
|
|
25
30
|
|
|
26
31
|
/**
|
|
27
32
|
* Unlock the device
|
|
28
33
|
*/
|
|
29
34
|
export async function unlock(this: XCUITestDriver): Promise<void> {
|
|
30
|
-
await this
|
|
35
|
+
await setLocked(this, false);
|
|
31
36
|
}
|
|
32
37
|
|
|
33
38
|
/**
|
|
@@ -38,3 +43,38 @@ export async function unlock(this: XCUITestDriver): Promise<void> {
|
|
|
38
43
|
export async function isLocked(this: XCUITestDriver): Promise<boolean> {
|
|
39
44
|
return await this.proxyCommand<any, boolean>('/wda/locked', 'GET');
|
|
40
45
|
}
|
|
46
|
+
|
|
47
|
+
async function setLocked(driver: XCUITestDriver, locked: boolean): Promise<void> {
|
|
48
|
+
const simulator = await getDuoSimulator(driver);
|
|
49
|
+
if (!simulator) {
|
|
50
|
+
await driver.proxyCommand(locked ? '/wda/lock' : '/wda/unlock', 'POST');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if ((await driver.isLocked()) === locked) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
await simulator.pressHidButton(
|
|
57
|
+
HIDPageEvent.kHIDPage_Consumer,
|
|
58
|
+
locked ? HIDUsageConsumerEvent.kHIDUsage_Csmr_Power : HIDUsageConsumerEvent.kHIDUsage_Csmr_Menu,
|
|
59
|
+
);
|
|
60
|
+
const timeoutError = new errors.UnknownError(`Timed out waiting for the simulator to ${locked ? 'lock' : 'unlock'}`);
|
|
61
|
+
const waitForState = async (waitMs: number) =>
|
|
62
|
+
await waitForCondition(async () => (await driver.isLocked()) === locked, {
|
|
63
|
+
waitMs,
|
|
64
|
+
intervalMs: 100,
|
|
65
|
+
error: timeoutError,
|
|
66
|
+
});
|
|
67
|
+
if (!locked) {
|
|
68
|
+
try {
|
|
69
|
+
await waitForState(1000);
|
|
70
|
+
return;
|
|
71
|
+
} catch (err) {
|
|
72
|
+
if (err !== timeoutError) {
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// A sleeping device may need a second Home press after waking.
|
|
77
|
+
await simulator.pressHidButton(HIDPageEvent.kHIDPage_Consumer, HIDUsageConsumerEvent.kHIDUsage_Csmr_Menu);
|
|
78
|
+
}
|
|
79
|
+
await waitForState(locked ? 5000 : 4000);
|
|
80
|
+
}
|