codeloop-mcp-server 0.1.88 → 0.1.95
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/README.md +30 -0
- package/dist/evidence/change_coverage.d.ts +41 -0
- package/dist/evidence/change_coverage.d.ts.map +1 -1
- package/dist/evidence/change_coverage.js +69 -2
- package/dist/evidence/change_coverage.js.map +1 -1
- package/dist/evidence/interaction_coverage.d.ts.map +1 -1
- package/dist/evidence/interaction_coverage.js +2 -0
- package/dist/evidence/interaction_coverage.js.map +1 -1
- package/dist/evidence/interaction_evidence.d.ts +38 -0
- package/dist/evidence/interaction_evidence.d.ts.map +1 -1
- package/dist/evidence/interaction_evidence.js +60 -0
- package/dist/evidence/interaction_evidence.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +311 -57
- package/dist/index.js.map +1 -1
- package/dist/runners/active_target.d.ts +31 -0
- package/dist/runners/active_target.d.ts.map +1 -0
- package/dist/runners/active_target.js +65 -0
- package/dist/runners/active_target.js.map +1 -0
- package/dist/runners/android_sdk.d.ts +50 -0
- package/dist/runners/android_sdk.d.ts.map +1 -0
- package/dist/runners/android_sdk.js +123 -0
- package/dist/runners/android_sdk.js.map +1 -0
- package/dist/runners/app_launcher.d.ts +59 -1
- package/dist/runners/app_launcher.d.ts.map +1 -1
- package/dist/runners/app_launcher.js +184 -33
- package/dist/runners/app_launcher.js.map +1 -1
- package/dist/runners/app_logger.d.ts +1 -1
- package/dist/runners/app_logger.d.ts.map +1 -1
- package/dist/runners/app_logger.js +9 -8
- package/dist/runners/app_logger.js.map +1 -1
- package/dist/runners/device_probe.d.ts +18 -0
- package/dist/runners/device_probe.d.ts.map +1 -1
- package/dist/runners/device_probe.js +52 -22
- package/dist/runners/device_probe.js.map +1 -1
- package/dist/runners/interaction_engine.d.ts +6 -0
- package/dist/runners/interaction_engine.d.ts.map +1 -1
- package/dist/runners/interaction_engine.js +71 -21
- package/dist/runners/interaction_engine.js.map +1 -1
- package/dist/runners/ios_sim_input.d.ts +106 -0
- package/dist/runners/ios_sim_input.d.ts.map +1 -0
- package/dist/runners/ios_sim_input.js +453 -0
- package/dist/runners/ios_sim_input.js.map +1 -0
- package/dist/runners/journey_to_maestro.d.ts +27 -0
- package/dist/runners/journey_to_maestro.d.ts.map +1 -1
- package/dist/runners/journey_to_maestro.js +54 -0
- package/dist/runners/journey_to_maestro.js.map +1 -1
- package/dist/runners/logging_readiness.d.ts.map +1 -1
- package/dist/runners/logging_readiness.js +38 -7
- package/dist/runners/logging_readiness.js.map +1 -1
- package/dist/runners/maestro.d.ts +27 -2
- package/dist/runners/maestro.d.ts.map +1 -1
- package/dist/runners/maestro.js +57 -7
- package/dist/runners/maestro.js.map +1 -1
- package/dist/runners/maestro_generator.d.ts +1 -1
- package/dist/runners/maestro_generator.d.ts.map +1 -1
- package/dist/runners/maestro_generator.js +3 -2
- package/dist/runners/maestro_generator.js.map +1 -1
- package/dist/runners/screenshot.d.ts +6 -0
- package/dist/runners/screenshot.d.ts.map +1 -1
- package/dist/runners/screenshot.js +20 -10
- package/dist/runners/screenshot.js.map +1 -1
- package/dist/runners/semantics_audit.d.ts +32 -0
- package/dist/runners/semantics_audit.d.ts.map +1 -0
- package/dist/runners/semantics_audit.js +140 -0
- package/dist/runners/semantics_audit.js.map +1 -0
- package/dist/runners/video_recorder.d.ts +3 -1
- package/dist/runners/video_recorder.d.ts.map +1 -1
- package/dist/runners/video_recorder.js +44 -12
- package/dist/runners/video_recorder.js.map +1 -1
- package/dist/runners/wayland.d.ts +32 -0
- package/dist/runners/wayland.d.ts.map +1 -0
- package/dist/runners/wayland.js +49 -0
- package/dist/runners/wayland.js.map +1 -0
- package/dist/runners/window_manager.d.ts +55 -25
- package/dist/runners/window_manager.d.ts.map +1 -1
- package/dist/runners/window_manager.js +171 -71
- package/dist/runners/window_manager.js.map +1 -1
- package/dist/tools/discover_interactions.d.ts +22 -0
- package/dist/tools/discover_interactions.d.ts.map +1 -1
- package/dist/tools/discover_interactions.js +283 -6
- package/dist/tools/discover_interactions.js.map +1 -1
- package/dist/tools/discover_screens.d.ts +2 -0
- package/dist/tools/discover_screens.d.ts.map +1 -1
- package/dist/tools/discover_screens.js +139 -1
- package/dist/tools/discover_screens.js.map +1 -1
- package/dist/tools/gate_check.d.ts.map +1 -1
- package/dist/tools/gate_check.js +16 -2
- package/dist/tools/gate_check.js.map +1 -1
- package/dist/tools/plan_change_journey.d.ts.map +1 -1
- package/dist/tools/plan_change_journey.js +15 -2
- package/dist/tools/plan_change_journey.js.map +1 -1
- package/dist/tools/plan_user_journey.d.ts.map +1 -1
- package/dist/tools/plan_user_journey.js +5 -2
- package/dist/tools/plan_user_journey.js.map +1 -1
- package/dist/tools/run_journey.d.ts +70 -0
- package/dist/tools/run_journey.d.ts.map +1 -1
- package/dist/tools/run_journey.js +209 -21
- package/dist/tools/run_journey.js.map +1 -1
- package/dist/tools/verify.d.ts.map +1 -1
- package/dist/tools/verify.js +55 -11
- package/dist/tools/verify.js.map +1 -1
- package/package.json +2 -2
|
@@ -122,10 +122,17 @@ export declare function clickAtPosition(x: number, y: number): Promise<boolean>;
|
|
|
122
122
|
* - Linux: X11 keysym name as string via keyName param, or keyCode ignored
|
|
123
123
|
*/
|
|
124
124
|
export declare function sendKeystroke(keyCode: number, keyName?: string): Promise<boolean>;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
/**
|
|
126
|
+
* Prefix adb args with `-s <serial>` when a device id is given, so every
|
|
127
|
+
* helper hits the SAME device the journey booted instead of whatever adb
|
|
128
|
+
* picks when several emulators/phones are attached ("more than one
|
|
129
|
+
* device/emulator" is a hard adb error).
|
|
130
|
+
*/
|
|
131
|
+
export declare function adbArgs(device: string | undefined, ...rest: string[]): string[];
|
|
132
|
+
export declare function adbTap(x: number, y: number, device?: string): Promise<boolean>;
|
|
133
|
+
export declare function adbType(text: string, device?: string): Promise<boolean>;
|
|
134
|
+
export declare function adbKey(keycode: string, device?: string): Promise<boolean>;
|
|
135
|
+
export declare function adbSwipe(x1: number, y1: number, x2: number, y2: number, durationMs?: number, device?: string): Promise<boolean>;
|
|
129
136
|
/**
|
|
130
137
|
* Read back on-screen text from a booted Android emulator/device by dumping
|
|
131
138
|
* the uiautomator view hierarchy and extracting every `text=` / `content-desc=`
|
|
@@ -137,15 +144,15 @@ export declare function adbSwipe(x1: number, y1: number, x2: number, y2: number,
|
|
|
137
144
|
* `filterSubstring` (optional): when given (e.g. a resource-id fragment or
|
|
138
145
|
* expected phrase) only nodes whose text contains it are returned.
|
|
139
146
|
*/
|
|
140
|
-
export declare function adbGetText(filterSubstring?: string): Promise<string | null>;
|
|
147
|
+
export declare function adbGetText(filterSubstring?: string, device?: string): Promise<string | null>;
|
|
141
148
|
/**
|
|
142
149
|
* Pure parser for a uiautomator XML dump: returns the de-duped, in-order text /
|
|
143
150
|
* content-desc values joined by newlines, optionally filtered to nodes whose
|
|
144
151
|
* text contains `filterSubstring` (case-insensitive). Exported for testing.
|
|
145
152
|
*/
|
|
146
153
|
export declare function extractUiAutomatorText(xml: string, filterSubstring?: string): string;
|
|
147
|
-
export declare function simctlLaunch(bundleId: string): Promise<boolean>;
|
|
148
|
-
export declare function simctlTerminate(bundleId: string): Promise<boolean>;
|
|
154
|
+
export declare function simctlLaunch(bundleId: string, udid?: string): Promise<boolean>;
|
|
155
|
+
export declare function simctlTerminate(bundleId: string, udid?: string): Promise<boolean>;
|
|
149
156
|
/**
|
|
150
157
|
* Launch a desktop application by name from a project directory.
|
|
151
158
|
*
|
|
@@ -191,24 +198,47 @@ export declare function hoverAtPosition(x: number, y: number): Promise<boolean>;
|
|
|
191
198
|
export declare function sendHotkey(combo: string): Promise<boolean>;
|
|
192
199
|
export declare function dragDrop(x1: number, y1: number, x2: number, y2: number, durationMs?: number): Promise<boolean>;
|
|
193
200
|
export declare function longPressAtPosition(x: number, y: number, durationMs?: number): Promise<boolean>;
|
|
194
|
-
export declare function
|
|
195
|
-
export declare function
|
|
196
|
-
|
|
197
|
-
export declare function
|
|
198
|
-
|
|
199
|
-
export declare function
|
|
200
|
-
|
|
201
|
-
export declare function
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
export declare function
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
201
|
+
export declare function simctlOpenUrl(url: string, udid?: string): Promise<boolean>;
|
|
202
|
+
export declare function simctlBiometric(accept: boolean, udid?: string): Promise<boolean>;
|
|
203
|
+
/** `simctl privacy <udid> grant|revoke <service> <bundle>` (photos, location, microphone, …). */
|
|
204
|
+
export declare function simctlPermission(bundleId: string, service: string, grant: boolean, udid?: string): Promise<boolean>;
|
|
205
|
+
/** `simctl location <udid> set <lat>,<lon>`. */
|
|
206
|
+
export declare function simctlSetLocation(lat: number, lon: number, udid?: string): Promise<boolean>;
|
|
207
|
+
/** `simctl uninstall <udid> <bundle>` — the iOS equivalent of `pm clear` (wipes data AND binary). */
|
|
208
|
+
export declare function simctlUninstall(bundleId: string, udid?: string): Promise<boolean>;
|
|
209
|
+
/**
|
|
210
|
+
* `simctl push <udid> <bundle> <payload.json>` — simulated remote push.
|
|
211
|
+
* `payload` may be a full APNs JSON string (must contain an `aps` key) or
|
|
212
|
+
* plain alert text which gets wrapped in a minimal aps payload.
|
|
213
|
+
*/
|
|
214
|
+
export declare function simctlPush(bundleId: string, payload: string, udid?: string): Promise<{
|
|
215
|
+
success: boolean;
|
|
216
|
+
detail: string;
|
|
217
|
+
}>;
|
|
218
|
+
/**
|
|
219
|
+
* `simctl status_bar <udid> override --time 9:41 …` for demo-clean
|
|
220
|
+
* screenshots, or `clear` when no overrides are given.
|
|
221
|
+
* `spec` is either JSON (`{"time":"9:41","batteryLevel":100}`) or a
|
|
222
|
+
* comma-separated `key=value` list (`time=9:41,batteryLevel=100`).
|
|
223
|
+
*/
|
|
224
|
+
export declare function simctlStatusBar(spec: string, udid?: string): Promise<{
|
|
225
|
+
success: boolean;
|
|
226
|
+
detail: string;
|
|
227
|
+
}>;
|
|
228
|
+
export declare function adbDeepLink(url: string, device?: string): Promise<boolean>;
|
|
229
|
+
export declare function adbPermission(packageId: string, permission: string, grant: boolean, device?: string): Promise<boolean>;
|
|
230
|
+
export declare function adbHomeButton(device?: string): Promise<boolean>;
|
|
231
|
+
export declare function adbBackButton(device?: string): Promise<boolean>;
|
|
232
|
+
export declare function adbRecentApps(device?: string): Promise<boolean>;
|
|
233
|
+
export declare function adbNotificationShade(expand: boolean, device?: string): Promise<boolean>;
|
|
234
|
+
export declare function adbLongPress(x: number, y: number, durationMs?: number, device?: string): Promise<boolean>;
|
|
235
|
+
export declare function adbClearData(packageId: string, device?: string): Promise<boolean>;
|
|
236
|
+
export declare function adbInstallApk(apkPath: string, device?: string): Promise<boolean>;
|
|
237
|
+
/** True when an adb serial names an emulator (`emulator-5554`) rather than hardware. */
|
|
238
|
+
export declare function isEmulatorSerial(serial: string | undefined): boolean;
|
|
239
|
+
export declare function adbNetworkCondition(mode: string, device?: string): Promise<boolean>;
|
|
240
|
+
export declare function adbMockLocation(lat: number, lng: number, device?: string): Promise<boolean>;
|
|
241
|
+
export declare function adbRotate(landscape: boolean, device?: string): Promise<boolean>;
|
|
212
242
|
export type TargetType = "desktop" | "android_emulator" | "ios_simulator" | "browser";
|
|
213
243
|
/**
|
|
214
244
|
* Check if a required external tool is installed.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"window_manager.d.ts","sourceRoot":"","sources":["../../src/runners/window_manager.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAG1E;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,KAAK,CAAC;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,IAAI,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,mBAAmB,CAAC;AAEnE,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAoBvF;AA+FD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA2BjE;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAgChE;AAiED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKtE;AAkGD;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;GAGG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAMnF;AAkKD;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA+C5E;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA6CvF;AAID,wBAAsB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"window_manager.d.ts","sourceRoot":"","sources":["../../src/runners/window_manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -669,26 +669,30 @@ Start-Sleep -Milliseconds 50
|
|
|
669
669
|
return false;
|
|
670
670
|
}
|
|
671
671
|
// ── Mobile Interaction (Android emulator via ADB) ───────────────
|
|
672
|
-
|
|
673
|
-
|
|
672
|
+
/**
|
|
673
|
+
* Prefix adb args with `-s <serial>` when a device id is given, so every
|
|
674
|
+
* helper hits the SAME device the journey booted instead of whatever adb
|
|
675
|
+
* picks when several emulators/phones are attached ("more than one
|
|
676
|
+
* device/emulator" is a hard adb error).
|
|
677
|
+
*/
|
|
678
|
+
export function adbArgs(device, ...rest) {
|
|
679
|
+
return device ? ["-s", device, ...rest] : rest;
|
|
680
|
+
}
|
|
681
|
+
export async function adbTap(x, y, device) {
|
|
682
|
+
const result = await runCommand("adb", adbArgs(device, "shell", "input", "tap", String(Math.round(x)), String(Math.round(y))), process.cwd());
|
|
674
683
|
return result.exit_code === 0;
|
|
675
684
|
}
|
|
676
|
-
export async function adbType(text) {
|
|
685
|
+
export async function adbType(text, device) {
|
|
677
686
|
const escaped = text.replace(/ /g, "%s").replace(/'/g, "\\'");
|
|
678
|
-
const result = await runCommand("adb",
|
|
687
|
+
const result = await runCommand("adb", adbArgs(device, "shell", "input", "text", escaped), process.cwd());
|
|
679
688
|
return result.exit_code === 0;
|
|
680
689
|
}
|
|
681
|
-
export async function adbKey(keycode) {
|
|
682
|
-
const result = await runCommand("adb",
|
|
690
|
+
export async function adbKey(keycode, device) {
|
|
691
|
+
const result = await runCommand("adb", adbArgs(device, "shell", "input", "keyevent", keycode), process.cwd());
|
|
683
692
|
return result.exit_code === 0;
|
|
684
693
|
}
|
|
685
|
-
export async function adbSwipe(x1, y1, x2, y2, durationMs = 300) {
|
|
686
|
-
const result = await runCommand("adb",
|
|
687
|
-
"shell", "input", "swipe",
|
|
688
|
-
String(Math.round(x1)), String(Math.round(y1)),
|
|
689
|
-
String(Math.round(x2)), String(Math.round(y2)),
|
|
690
|
-
String(durationMs),
|
|
691
|
-
], process.cwd());
|
|
694
|
+
export async function adbSwipe(x1, y1, x2, y2, durationMs = 300, device) {
|
|
695
|
+
const result = await runCommand("adb", adbArgs(device, "shell", "input", "swipe", String(Math.round(x1)), String(Math.round(y1)), String(Math.round(x2)), String(Math.round(y2)), String(durationMs)), process.cwd());
|
|
692
696
|
return result.exit_code === 0;
|
|
693
697
|
}
|
|
694
698
|
/**
|
|
@@ -702,18 +706,18 @@ export async function adbSwipe(x1, y1, x2, y2, durationMs = 300) {
|
|
|
702
706
|
* `filterSubstring` (optional): when given (e.g. a resource-id fragment or
|
|
703
707
|
* expected phrase) only nodes whose text contains it are returned.
|
|
704
708
|
*/
|
|
705
|
-
export async function adbGetText(filterSubstring) {
|
|
709
|
+
export async function adbGetText(filterSubstring, device) {
|
|
706
710
|
// Preferred: stream the dump straight back over exec-out (no device file).
|
|
707
711
|
let xml = "";
|
|
708
|
-
const direct = await runCommand("adb",
|
|
712
|
+
const direct = await runCommand("adb", adbArgs(device, "exec-out", "uiautomator", "dump", "/dev/tty"), process.cwd(), undefined, undefined, 20_000);
|
|
709
713
|
if (direct.exit_code === 0 && direct.stdout.includes("<hierarchy")) {
|
|
710
714
|
xml = direct.stdout;
|
|
711
715
|
}
|
|
712
716
|
else {
|
|
713
717
|
// Fallback: dump to a device file, then read it back. Works on devices
|
|
714
718
|
// whose toolbox build can't write to /dev/tty.
|
|
715
|
-
await runCommand("adb",
|
|
716
|
-
const cat = await runCommand("adb",
|
|
719
|
+
await runCommand("adb", adbArgs(device, "shell", "uiautomator", "dump", "/sdcard/codeloop_ui.xml"), process.cwd(), undefined, undefined, 20_000);
|
|
720
|
+
const cat = await runCommand("adb", adbArgs(device, "exec-out", "cat", "/sdcard/codeloop_ui.xml"), process.cwd(), undefined, undefined, 20_000);
|
|
717
721
|
if (cat.exit_code !== 0 || !cat.stdout.includes("<hierarchy"))
|
|
718
722
|
return null;
|
|
719
723
|
xml = cat.stdout;
|
|
@@ -758,12 +762,12 @@ function decodeXmlEntities(s) {
|
|
|
758
762
|
.replace(/'/g, "'");
|
|
759
763
|
}
|
|
760
764
|
// ── Mobile Interaction (iOS Simulator via simctl) ───────────────
|
|
761
|
-
export async function simctlLaunch(bundleId) {
|
|
762
|
-
const result = await runCommand("xcrun", ["simctl", "launch",
|
|
765
|
+
export async function simctlLaunch(bundleId, udid = "booted") {
|
|
766
|
+
const result = await runCommand("xcrun", ["simctl", "launch", udid, bundleId], process.cwd());
|
|
763
767
|
return result.exit_code === 0;
|
|
764
768
|
}
|
|
765
|
-
export async function simctlTerminate(bundleId) {
|
|
766
|
-
const result = await runCommand("xcrun", ["simctl", "terminate",
|
|
769
|
+
export async function simctlTerminate(bundleId, udid = "booted") {
|
|
770
|
+
const result = await runCommand("xcrun", ["simctl", "terminate", udid, bundleId], process.cwd());
|
|
767
771
|
return result.exit_code === 0;
|
|
768
772
|
}
|
|
769
773
|
// ── Desktop App Launch (cross-OS) ────────────────────────────────
|
|
@@ -1550,88 +1554,184 @@ Start-Sleep -Milliseconds ${durationMs}
|
|
|
1550
1554
|
return false;
|
|
1551
1555
|
}
|
|
1552
1556
|
// ── iOS Simulator Extended Interaction ──────────────────────────
|
|
1553
|
-
|
|
1554
|
-
|
|
1557
|
+
//
|
|
1558
|
+
// NOTE: coordinate input (tap/type/swipe/sendkey) is NOT part of
|
|
1559
|
+
// `simctl io` — those subcommands never existed in any Xcode. Real
|
|
1560
|
+
// iOS simulator input lives in ios_sim_input.ts (CGEvent window
|
|
1561
|
+
// mapping with optional idb backend). Only genuine simctl commands
|
|
1562
|
+
// (openurl / biometric / launch / terminate) remain here.
|
|
1563
|
+
export async function simctlOpenUrl(url, udid = "booted") {
|
|
1564
|
+
const result = await runCommand("xcrun", ["simctl", "openurl", udid, url], process.cwd());
|
|
1555
1565
|
return result.exit_code === 0;
|
|
1556
1566
|
}
|
|
1557
|
-
export async function
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
return false;
|
|
1562
|
-
}
|
|
1563
|
-
return true;
|
|
1564
|
-
}
|
|
1565
|
-
export async function simctlOpenUrl(url) {
|
|
1566
|
-
const result = await runCommand("xcrun", ["simctl", "openurl", "booted", url], process.cwd());
|
|
1567
|
+
export async function simctlBiometric(accept, udid = "booted") {
|
|
1568
|
+
await runCommand("xcrun", ["simctl", "biometric", udid, "--state", "enrolled"], process.cwd());
|
|
1569
|
+
const action = accept ? "--match" : "--no-match";
|
|
1570
|
+
const result = await runCommand("xcrun", ["simctl", "biometric", udid, action], process.cwd());
|
|
1567
1571
|
return result.exit_code === 0;
|
|
1568
1572
|
}
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
+
// ── Extended iOS (simctl) Helpers — P1.2 (0.1.91) ────────────────
|
|
1574
|
+
// Real device-fixture features that previously silently no-opped on iOS
|
|
1575
|
+
// (the interact switch only had Android branches for them).
|
|
1576
|
+
/** `simctl privacy <udid> grant|revoke <service> <bundle>` (photos, location, microphone, …). */
|
|
1577
|
+
export async function simctlPermission(bundleId, service, grant, udid = "booted") {
|
|
1578
|
+
// Accept Android-style names so cross-platform journeys can reuse one
|
|
1579
|
+
// value: "android.permission.ACCESS_FINE_LOCATION" → "location".
|
|
1580
|
+
const normalized = service
|
|
1581
|
+
.replace(/^android\.permission\./, "")
|
|
1582
|
+
.replace(/^ACCESS_(FINE|COARSE)_LOCATION$/, "location")
|
|
1583
|
+
.replace(/^RECORD_AUDIO$/, "microphone")
|
|
1584
|
+
.replace(/^READ_MEDIA_IMAGES$/, "photos")
|
|
1585
|
+
.toLowerCase();
|
|
1586
|
+
const action = grant ? "grant" : "revoke";
|
|
1587
|
+
const result = await runCommand("xcrun", ["simctl", "privacy", udid, action, normalized, bundleId], process.cwd());
|
|
1573
1588
|
return result.exit_code === 0;
|
|
1574
1589
|
}
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
String(Math.round(x1)), String(Math.round(y1)),
|
|
1579
|
-
String(Math.round(x2)), String(Math.round(y2)),
|
|
1580
|
-
"--duration", String(durationMs / 1000),
|
|
1581
|
-
], process.cwd());
|
|
1590
|
+
/** `simctl location <udid> set <lat>,<lon>`. */
|
|
1591
|
+
export async function simctlSetLocation(lat, lon, udid = "booted") {
|
|
1592
|
+
const result = await runCommand("xcrun", ["simctl", "location", udid, "set", `${lat},${lon}`], process.cwd());
|
|
1582
1593
|
return result.exit_code === 0;
|
|
1583
1594
|
}
|
|
1584
|
-
|
|
1585
|
-
|
|
1595
|
+
/** `simctl uninstall <udid> <bundle>` — the iOS equivalent of `pm clear` (wipes data AND binary). */
|
|
1596
|
+
export async function simctlUninstall(bundleId, udid = "booted") {
|
|
1597
|
+
const result = await runCommand("xcrun", ["simctl", "uninstall", udid, bundleId], process.cwd());
|
|
1586
1598
|
return result.exit_code === 0;
|
|
1587
1599
|
}
|
|
1600
|
+
/**
|
|
1601
|
+
* `simctl push <udid> <bundle> <payload.json>` — simulated remote push.
|
|
1602
|
+
* `payload` may be a full APNs JSON string (must contain an `aps` key) or
|
|
1603
|
+
* plain alert text which gets wrapped in a minimal aps payload.
|
|
1604
|
+
*/
|
|
1605
|
+
export async function simctlPush(bundleId, payload, udid = "booted") {
|
|
1606
|
+
let json;
|
|
1607
|
+
try {
|
|
1608
|
+
const parsed = JSON.parse(payload);
|
|
1609
|
+
json = JSON.stringify(typeof parsed === "object" && parsed !== null && "aps" in parsed
|
|
1610
|
+
? parsed
|
|
1611
|
+
: { aps: { alert: parsed } });
|
|
1612
|
+
}
|
|
1613
|
+
catch {
|
|
1614
|
+
json = JSON.stringify({ aps: { alert: payload } });
|
|
1615
|
+
}
|
|
1616
|
+
const file = join(tmpdir(), `codeloop-push-${Date.now()}.json`);
|
|
1617
|
+
try {
|
|
1618
|
+
writeFileSync(file, json, "utf-8");
|
|
1619
|
+
const result = await runCommand("xcrun", ["simctl", "push", udid, bundleId, file], process.cwd());
|
|
1620
|
+
return {
|
|
1621
|
+
success: result.exit_code === 0,
|
|
1622
|
+
detail: result.exit_code === 0 ? `push delivered to ${bundleId}` : (result.stderr || result.stdout || "simctl push failed").trim(),
|
|
1623
|
+
};
|
|
1624
|
+
}
|
|
1625
|
+
finally {
|
|
1626
|
+
try {
|
|
1627
|
+
unlinkSync(file);
|
|
1628
|
+
}
|
|
1629
|
+
catch { /* temp cleanup */ }
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
/** Allowed `simctl status_bar override` flags (value validation stays with simctl). */
|
|
1633
|
+
const STATUS_BAR_KEYS = new Set([
|
|
1634
|
+
"time", "dataNetwork", "wifiMode", "wifiBars", "cellularMode", "cellularBars",
|
|
1635
|
+
"operatorName", "batteryState", "batteryLevel",
|
|
1636
|
+
]);
|
|
1637
|
+
/**
|
|
1638
|
+
* `simctl status_bar <udid> override --time 9:41 …` for demo-clean
|
|
1639
|
+
* screenshots, or `clear` when no overrides are given.
|
|
1640
|
+
* `spec` is either JSON (`{"time":"9:41","batteryLevel":100}`) or a
|
|
1641
|
+
* comma-separated `key=value` list (`time=9:41,batteryLevel=100`).
|
|
1642
|
+
*/
|
|
1643
|
+
export async function simctlStatusBar(spec, udid = "booted") {
|
|
1644
|
+
const trimmed = spec.trim();
|
|
1645
|
+
if (!trimmed || trimmed === "clear") {
|
|
1646
|
+
const result = await runCommand("xcrun", ["simctl", "status_bar", udid, "clear"], process.cwd());
|
|
1647
|
+
return { success: result.exit_code === 0, detail: "status_bar cleared" };
|
|
1648
|
+
}
|
|
1649
|
+
let overrides;
|
|
1650
|
+
try {
|
|
1651
|
+
overrides = JSON.parse(trimmed);
|
|
1652
|
+
}
|
|
1653
|
+
catch {
|
|
1654
|
+
overrides = {};
|
|
1655
|
+
for (const pair of trimmed.split(",")) {
|
|
1656
|
+
const [k, ...rest] = pair.split("=");
|
|
1657
|
+
if (k && rest.length > 0)
|
|
1658
|
+
overrides[k.trim()] = rest.join("=").trim();
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
const args = ["simctl", "status_bar", udid, "override"];
|
|
1662
|
+
const unknown = [];
|
|
1663
|
+
for (const [k, v] of Object.entries(overrides)) {
|
|
1664
|
+
if (!STATUS_BAR_KEYS.has(k)) {
|
|
1665
|
+
unknown.push(k);
|
|
1666
|
+
continue;
|
|
1667
|
+
}
|
|
1668
|
+
args.push(`--${k}`, String(v));
|
|
1669
|
+
}
|
|
1670
|
+
if (args.length === 4) {
|
|
1671
|
+
return {
|
|
1672
|
+
success: false,
|
|
1673
|
+
detail: `status_bar: no valid override keys in "${spec}". Supported: ${[...STATUS_BAR_KEYS].join(", ")}${unknown.length ? ` (unknown: ${unknown.join(", ")})` : ""}.`,
|
|
1674
|
+
};
|
|
1675
|
+
}
|
|
1676
|
+
const result = await runCommand("xcrun", args, process.cwd());
|
|
1677
|
+
return {
|
|
1678
|
+
success: result.exit_code === 0,
|
|
1679
|
+
detail: result.exit_code === 0
|
|
1680
|
+
? `status_bar override applied (${args.slice(4).filter((a) => a.startsWith("--")).map((a) => a.slice(2)).join(", ")})${unknown.length ? `; ignored unknown: ${unknown.join(", ")}` : ""}`
|
|
1681
|
+
: (result.stderr || result.stdout || "simctl status_bar failed").trim(),
|
|
1682
|
+
};
|
|
1683
|
+
}
|
|
1588
1684
|
// ── Extended Android (adb) Helpers ──────────────────────────────
|
|
1589
|
-
export async function adbDeepLink(url) {
|
|
1590
|
-
const result = await runCommand("adb",
|
|
1685
|
+
export async function adbDeepLink(url, device) {
|
|
1686
|
+
const result = await runCommand("adb", adbArgs(device, "shell", "am", "start", "-a", "android.intent.action.VIEW", "-d", url), process.cwd());
|
|
1591
1687
|
return result.exit_code === 0;
|
|
1592
1688
|
}
|
|
1593
|
-
export async function adbPermission(packageId, permission, grant) {
|
|
1689
|
+
export async function adbPermission(packageId, permission, grant, device) {
|
|
1594
1690
|
const action = grant ? "grant" : "revoke";
|
|
1595
|
-
const result = await runCommand("adb",
|
|
1691
|
+
const result = await runCommand("adb", adbArgs(device, "shell", "pm", action, packageId, permission), process.cwd());
|
|
1596
1692
|
return result.exit_code === 0;
|
|
1597
1693
|
}
|
|
1598
|
-
export async function adbHomeButton() {
|
|
1599
|
-
return adbKey("KEYCODE_HOME");
|
|
1694
|
+
export async function adbHomeButton(device) {
|
|
1695
|
+
return adbKey("KEYCODE_HOME", device);
|
|
1600
1696
|
}
|
|
1601
|
-
export async function adbBackButton() {
|
|
1602
|
-
return adbKey("KEYCODE_BACK");
|
|
1697
|
+
export async function adbBackButton(device) {
|
|
1698
|
+
return adbKey("KEYCODE_BACK", device);
|
|
1603
1699
|
}
|
|
1604
|
-
export async function adbRecentApps() {
|
|
1605
|
-
return adbKey("KEYCODE_APP_SWITCH");
|
|
1700
|
+
export async function adbRecentApps(device) {
|
|
1701
|
+
return adbKey("KEYCODE_APP_SWITCH", device);
|
|
1606
1702
|
}
|
|
1607
|
-
export async function adbNotificationShade(expand) {
|
|
1703
|
+
export async function adbNotificationShade(expand, device) {
|
|
1608
1704
|
const action = expand ? "expand-notifications" : "collapse";
|
|
1609
|
-
const result = await runCommand("adb",
|
|
1705
|
+
const result = await runCommand("adb", adbArgs(device, "shell", "cmd", "statusbar", action), process.cwd());
|
|
1610
1706
|
return result.exit_code === 0;
|
|
1611
1707
|
}
|
|
1612
|
-
export async function adbLongPress(x, y, durationMs = 1000) {
|
|
1613
|
-
return adbSwipe(x, y, x, y, durationMs);
|
|
1708
|
+
export async function adbLongPress(x, y, durationMs = 1000, device) {
|
|
1709
|
+
return adbSwipe(x, y, x, y, durationMs, device);
|
|
1614
1710
|
}
|
|
1615
|
-
export async function adbClearData(packageId) {
|
|
1616
|
-
const result = await runCommand("adb",
|
|
1711
|
+
export async function adbClearData(packageId, device) {
|
|
1712
|
+
const result = await runCommand("adb", adbArgs(device, "shell", "pm", "clear", packageId), process.cwd());
|
|
1617
1713
|
return result.exit_code === 0;
|
|
1618
1714
|
}
|
|
1619
|
-
export async function adbInstallApk(apkPath) {
|
|
1620
|
-
const result = await runCommand("adb",
|
|
1715
|
+
export async function adbInstallApk(apkPath, device) {
|
|
1716
|
+
const result = await runCommand("adb", adbArgs(device, "install", "-r", apkPath), process.cwd());
|
|
1621
1717
|
return result.exit_code === 0;
|
|
1622
1718
|
}
|
|
1623
|
-
|
|
1624
|
-
|
|
1719
|
+
/** True when an adb serial names an emulator (`emulator-5554`) rather than hardware. */
|
|
1720
|
+
export function isEmulatorSerial(serial) {
|
|
1721
|
+
return serial == null || serial === "" || serial.startsWith("emulator-");
|
|
1722
|
+
}
|
|
1723
|
+
export async function adbNetworkCondition(mode, device) {
|
|
1724
|
+
const result = await runCommand("adb", adbArgs(device, "emu", "network", "speed", mode), process.cwd());
|
|
1625
1725
|
return result.exit_code === 0;
|
|
1626
1726
|
}
|
|
1627
|
-
export async function adbMockLocation(lat, lng) {
|
|
1628
|
-
const result = await runCommand("adb",
|
|
1727
|
+
export async function adbMockLocation(lat, lng, device) {
|
|
1728
|
+
const result = await runCommand("adb", adbArgs(device, "emu", "geo", "fix", String(lng), String(lat)), process.cwd());
|
|
1629
1729
|
return result.exit_code === 0;
|
|
1630
1730
|
}
|
|
1631
|
-
export async function adbRotate(landscape) {
|
|
1632
|
-
await runCommand("adb",
|
|
1731
|
+
export async function adbRotate(landscape, device) {
|
|
1732
|
+
await runCommand("adb", adbArgs(device, "shell", "settings", "put", "system", "accelerometer_rotation", "0"), process.cwd());
|
|
1633
1733
|
const rotation = landscape ? "1" : "0";
|
|
1634
|
-
const result = await runCommand("adb",
|
|
1734
|
+
const result = await runCommand("adb", adbArgs(device, "shell", "settings", "put", "system", "user_rotation", rotation), process.cwd());
|
|
1635
1735
|
return result.exit_code === 0;
|
|
1636
1736
|
}
|
|
1637
1737
|
const INSTALL_INSTRUCTIONS = {
|