@metamask/device-mcp 0.1.0 → 0.3.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 +29 -14
- package/LICENSE +6 -0
- package/LICENSE.APACHE2 +201 -0
- package/LICENSE.MIT +21 -0
- package/README.md +114 -33
- package/dist/backends/adb-backend.cjs +21 -5
- package/dist/backends/adb-backend.cjs.map +1 -1
- package/dist/backends/adb-backend.d.cts +9 -2
- package/dist/backends/adb-backend.d.cts.map +1 -1
- package/dist/backends/adb-backend.d.mts +9 -2
- package/dist/backends/adb-backend.d.mts.map +1 -1
- package/dist/backends/adb-backend.mjs +21 -5
- package/dist/backends/adb-backend.mjs.map +1 -1
- package/dist/backends/appium-backend.cjs +25 -7
- package/dist/backends/appium-backend.cjs.map +1 -1
- package/dist/backends/appium-backend.d.cts +9 -2
- package/dist/backends/appium-backend.d.cts.map +1 -1
- package/dist/backends/appium-backend.d.mts +9 -2
- package/dist/backends/appium-backend.d.mts.map +1 -1
- package/dist/backends/appium-backend.mjs +25 -7
- package/dist/backends/appium-backend.mjs.map +1 -1
- package/dist/backends/idb-backend.cjs +96 -38
- package/dist/backends/idb-backend.cjs.map +1 -1
- package/dist/backends/idb-backend.d.cts +9 -2
- package/dist/backends/idb-backend.d.cts.map +1 -1
- package/dist/backends/idb-backend.d.mts +9 -2
- package/dist/backends/idb-backend.d.mts.map +1 -1
- package/dist/backends/idb-backend.mjs +97 -39
- package/dist/backends/idb-backend.mjs.map +1 -1
- package/dist/backends/index.cjs +37 -15
- package/dist/backends/index.cjs.map +1 -1
- package/dist/backends/index.d.cts +8 -11
- package/dist/backends/index.d.cts.map +1 -1
- package/dist/backends/index.d.mts +8 -11
- package/dist/backends/index.d.mts.map +1 -1
- package/dist/backends/index.mjs +38 -16
- package/dist/backends/index.mjs.map +1 -1
- package/dist/backends/types.cjs.map +1 -1
- package/dist/backends/types.d.cts +20 -1
- package/dist/backends/types.d.cts.map +1 -1
- package/dist/backends/types.d.mts +20 -1
- package/dist/backends/types.d.mts.map +1 -1
- package/dist/backends/types.mjs.map +1 -1
- package/dist/cli/device-mcp.cjs +11 -2
- package/dist/cli/device-mcp.cjs.map +1 -1
- package/dist/cli/device-mcp.mjs +11 -2
- package/dist/cli/device-mcp.mjs.map +1 -1
- package/dist/hermes/hermes-cdp.cjs +674 -0
- package/dist/hermes/hermes-cdp.cjs.map +1 -0
- package/dist/hermes/hermes-cdp.d.cts +248 -0
- package/dist/hermes/hermes-cdp.d.cts.map +1 -0
- package/dist/hermes/hermes-cdp.d.mts +248 -0
- package/dist/hermes/hermes-cdp.d.mts.map +1 -0
- package/dist/hermes/hermes-cdp.mjs +665 -0
- package/dist/hermes/hermes-cdp.mjs.map +1 -0
- package/dist/hermes/session.cjs +196 -0
- package/dist/hermes/session.cjs.map +1 -0
- package/dist/hermes/session.d.cts +163 -0
- package/dist/hermes/session.d.cts.map +1 -0
- package/dist/hermes/session.d.mts +163 -0
- package/dist/hermes/session.d.mts.map +1 -0
- package/dist/hermes/session.mjs +189 -0
- package/dist/hermes/session.mjs.map +1 -0
- package/dist/index.cjs +19 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +8 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3 -0
- package/dist/index.mjs.map +1 -1
- package/dist/server.cjs +8 -0
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +2 -2
- package/dist/server.d.cts.map +1 -1
- package/dist/server.d.mts +2 -2
- package/dist/server.d.mts.map +1 -1
- package/dist/server.mjs +9 -1
- package/dist/server.mjs.map +1 -1
- package/dist/tools/get-element-text.cjs +46 -0
- package/dist/tools/get-element-text.cjs.map +1 -0
- package/dist/tools/get-element-text.d.cts +4 -0
- package/dist/tools/get-element-text.d.cts.map +1 -0
- package/dist/tools/get-element-text.d.mts +4 -0
- package/dist/tools/get-element-text.d.mts.map +1 -0
- package/dist/tools/get-element-text.mjs +43 -0
- package/dist/tools/get-element-text.mjs.map +1 -0
- package/dist/tools/hermes-cdp.cjs +102 -0
- package/dist/tools/hermes-cdp.cjs.map +1 -0
- package/dist/tools/hermes-cdp.d.cts +18 -0
- package/dist/tools/hermes-cdp.d.cts.map +1 -0
- package/dist/tools/hermes-cdp.d.mts +18 -0
- package/dist/tools/hermes-cdp.d.mts.map +1 -0
- package/dist/tools/hermes-cdp.mjs +99 -0
- package/dist/tools/hermes-cdp.mjs.map +1 -0
- package/dist/tools/hermes-targets.cjs +127 -0
- package/dist/tools/hermes-targets.cjs.map +1 -0
- package/dist/tools/hermes-targets.d.cts +20 -0
- package/dist/tools/hermes-targets.d.cts.map +1 -0
- package/dist/tools/hermes-targets.d.mts +20 -0
- package/dist/tools/hermes-targets.d.mts.map +1 -0
- package/dist/tools/hermes-targets.mjs +124 -0
- package/dist/tools/hermes-targets.mjs.map +1 -0
- package/dist/tools/index.cjs +11 -1
- package/dist/tools/index.cjs.map +1 -1
- package/dist/tools/index.d.cts +5 -0
- package/dist/tools/index.d.cts.map +1 -1
- package/dist/tools/index.d.mts +5 -0
- package/dist/tools/index.d.mts.map +1 -1
- package/dist/tools/index.mjs +5 -0
- package/dist/tools/index.mjs.map +1 -1
- package/dist/tools/list-devices.cjs +36 -0
- package/dist/tools/list-devices.cjs.map +1 -0
- package/dist/tools/list-devices.d.cts +4 -0
- package/dist/tools/list-devices.d.cts.map +1 -0
- package/dist/tools/list-devices.d.mts +4 -0
- package/dist/tools/list-devices.d.mts.map +1 -0
- package/dist/tools/list-devices.mjs +33 -0
- package/dist/tools/list-devices.mjs.map +1 -0
- package/dist/tools/screenshot.cjs +8 -3
- package/dist/tools/screenshot.cjs.map +1 -1
- package/dist/tools/screenshot.d.cts.map +1 -1
- package/dist/tools/screenshot.d.mts.map +1 -1
- package/dist/tools/screenshot.mjs +8 -3
- package/dist/tools/screenshot.mjs.map +1 -1
- package/dist/tools/select-device.cjs +38 -0
- package/dist/tools/select-device.cjs.map +1 -0
- package/dist/tools/select-device.d.cts +4 -0
- package/dist/tools/select-device.d.cts.map +1 -0
- package/dist/tools/select-device.d.mts +4 -0
- package/dist/tools/select-device.d.mts.map +1 -0
- package/dist/tools/select-device.mjs +35 -0
- package/dist/tools/select-device.mjs.map +1 -0
- package/dist/utils/exec.cjs +11 -9
- package/dist/utils/exec.cjs.map +1 -1
- package/dist/utils/exec.d.cts.map +1 -1
- package/dist/utils/exec.d.mts.map +1 -1
- package/dist/utils/exec.mjs +11 -9
- package/dist/utils/exec.mjs.map +1 -1
- package/dist/utils/output-path.cjs +128 -0
- package/dist/utils/output-path.cjs.map +1 -0
- package/dist/utils/output-path.d.cts +41 -0
- package/dist/utils/output-path.d.cts.map +1 -0
- package/dist/utils/output-path.d.mts +41 -0
- package/dist/utils/output-path.d.mts.map +1 -0
- package/dist/utils/output-path.mjs +123 -0
- package/dist/utils/output-path.mjs.map +1 -0
- package/dist/utils/platform.cjs +121 -36
- package/dist/utils/platform.cjs.map +1 -1
- package/dist/utils/platform.d.cts +14 -3
- package/dist/utils/platform.d.cts.map +1 -1
- package/dist/utils/platform.d.mts +14 -3
- package/dist/utils/platform.d.mts.map +1 -1
- package/dist/utils/platform.mjs +117 -36
- package/dist/utils/platform.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -10,20 +10,25 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _IdbBackend_connected, _IdbBackend_udid, _IdbBackend_recordingProcess, _IdbBackend_recordingPath;
|
|
13
|
+
var _IdbBackend_instances, _IdbBackend_connected, _IdbBackend_udid, _IdbBackend_idbPath, _IdbBackend_recordingProcess, _IdbBackend_recordingPath, _IdbBackend_getAppStateViaSimctl;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.IdbBackend = void 0;
|
|
16
16
|
exports.parseIdbHierarchy = parseIdbHierarchy;
|
|
17
17
|
exports.mapIdbElement = mapIdbElement;
|
|
18
18
|
const node_child_process_1 = require("node:child_process");
|
|
19
|
+
const promises_1 = require("node:fs/promises");
|
|
19
20
|
const alert_labels_js_1 = require("../utils/alert-labels.cjs");
|
|
20
21
|
const element_js_1 = require("../utils/element.cjs");
|
|
21
22
|
const exec_js_1 = require("../utils/exec.cjs");
|
|
23
|
+
const output_path_js_1 = require("../utils/output-path.cjs");
|
|
24
|
+
const platform_js_1 = require("../utils/platform.cjs");
|
|
22
25
|
class IdbBackend {
|
|
23
26
|
constructor(udid) {
|
|
27
|
+
_IdbBackend_instances.add(this);
|
|
24
28
|
this.platform = 'ios';
|
|
25
29
|
_IdbBackend_connected.set(this, false);
|
|
26
30
|
_IdbBackend_udid.set(this, void 0);
|
|
31
|
+
_IdbBackend_idbPath.set(this, 'idb');
|
|
27
32
|
_IdbBackend_recordingProcess.set(this, null);
|
|
28
33
|
_IdbBackend_recordingPath.set(this, null);
|
|
29
34
|
__classPrivateFieldSet(this, _IdbBackend_udid, udid, "f");
|
|
@@ -32,16 +37,13 @@ class IdbBackend {
|
|
|
32
37
|
if (__classPrivateFieldGet(this, _IdbBackend_connected, "f")) {
|
|
33
38
|
return;
|
|
34
39
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
'Install: brew tap facebook/fb && brew install idb-companion && pip3 install fb-idb');
|
|
38
|
-
}
|
|
39
|
-
await (0, exec_js_1.exec)('idb', ['connect', __classPrivateFieldGet(this, _IdbBackend_udid, "f")]);
|
|
40
|
+
__classPrivateFieldSet(this, _IdbBackend_idbPath, await (0, platform_js_1.resolveIdbPath)(), "f");
|
|
41
|
+
await (0, exec_js_1.exec)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), ['connect', __classPrivateFieldGet(this, _IdbBackend_udid, "f")]);
|
|
40
42
|
__classPrivateFieldSet(this, _IdbBackend_connected, true, "f");
|
|
41
43
|
}
|
|
42
44
|
async getDeviceInfo() {
|
|
43
45
|
await this.ensureConnected();
|
|
44
|
-
const raw = await (0, exec_js_1.execStrict)(
|
|
46
|
+
const raw = await (0, exec_js_1.execStrict)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), [
|
|
45
47
|
'describe',
|
|
46
48
|
'--udid',
|
|
47
49
|
__classPrivateFieldGet(this, _IdbBackend_udid, "f"),
|
|
@@ -64,7 +66,7 @@ class IdbBackend {
|
|
|
64
66
|
}
|
|
65
67
|
async snapshot() {
|
|
66
68
|
await this.ensureConnected();
|
|
67
|
-
const raw = await (0, exec_js_1.execStrict)(
|
|
69
|
+
const raw = await (0, exec_js_1.execStrict)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), [
|
|
68
70
|
'ui',
|
|
69
71
|
'describe-all',
|
|
70
72
|
'--udid',
|
|
@@ -96,9 +98,19 @@ class IdbBackend {
|
|
|
96
98
|
targetDescription: (0, element_js_1.describeElement)(element),
|
|
97
99
|
};
|
|
98
100
|
}
|
|
101
|
+
async getElementText(query) {
|
|
102
|
+
await this.ensureConnected();
|
|
103
|
+
const snapshot = await this.snapshot();
|
|
104
|
+
const element = (0, element_js_1.findElement)(snapshot.hierarchy, query);
|
|
105
|
+
if (!element) {
|
|
106
|
+
throw new Error(`Element not found: ${JSON.stringify(query)}\n` +
|
|
107
|
+
'Use device_snapshot to inspect the current UI hierarchy.');
|
|
108
|
+
}
|
|
109
|
+
return element.label ?? element.value ?? '';
|
|
110
|
+
}
|
|
99
111
|
async tapCoordinates(x, y) {
|
|
100
112
|
await this.ensureConnected();
|
|
101
|
-
await (0, exec_js_1.execStrict)(
|
|
113
|
+
await (0, exec_js_1.execStrict)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), [
|
|
102
114
|
'ui',
|
|
103
115
|
'tap',
|
|
104
116
|
String(x),
|
|
@@ -109,7 +121,7 @@ class IdbBackend {
|
|
|
109
121
|
}
|
|
110
122
|
async typeText(text) {
|
|
111
123
|
await this.ensureConnected();
|
|
112
|
-
await (0, exec_js_1.exec)(
|
|
124
|
+
await (0, exec_js_1.exec)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), [
|
|
113
125
|
'ui',
|
|
114
126
|
'key-sequence',
|
|
115
127
|
'--',
|
|
@@ -117,8 +129,8 @@ class IdbBackend {
|
|
|
117
129
|
'--udid',
|
|
118
130
|
__classPrivateFieldGet(this, _IdbBackend_udid, "f"),
|
|
119
131
|
]);
|
|
120
|
-
await (0, exec_js_1.exec)(
|
|
121
|
-
await (0, exec_js_1.execStrict)(
|
|
132
|
+
await (0, exec_js_1.exec)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), ['ui', 'key', 'DELETE', '--udid', __classPrivateFieldGet(this, _IdbBackend_udid, "f")]);
|
|
133
|
+
await (0, exec_js_1.execStrict)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), ['ui', 'text', text, '--udid', __classPrivateFieldGet(this, _IdbBackend_udid, "f")]);
|
|
122
134
|
}
|
|
123
135
|
async swipe(direction, startX, startY, distance) {
|
|
124
136
|
await this.ensureConnected();
|
|
@@ -126,7 +138,7 @@ class IdbBackend {
|
|
|
126
138
|
const sx = startX ?? 200;
|
|
127
139
|
const sy = startY ?? 400;
|
|
128
140
|
const [endX, endY] = (0, element_js_1.computeSwipeEnd)(sx, sy, direction, d);
|
|
129
|
-
await (0, exec_js_1.execStrict)(
|
|
141
|
+
await (0, exec_js_1.execStrict)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), [
|
|
130
142
|
'ui',
|
|
131
143
|
'swipe',
|
|
132
144
|
String(sx),
|
|
@@ -151,33 +163,66 @@ class IdbBackend {
|
|
|
151
163
|
}
|
|
152
164
|
async getAppState(bundleId) {
|
|
153
165
|
await this.ensureConnected();
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
166
|
+
try {
|
|
167
|
+
const raw = await (0, exec_js_1.execStrict)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), [
|
|
168
|
+
'list-apps',
|
|
169
|
+
'--udid',
|
|
170
|
+
__classPrivateFieldGet(this, _IdbBackend_udid, "f"),
|
|
171
|
+
]);
|
|
172
|
+
for (const line of raw.trim().split('\n')) {
|
|
173
|
+
if (line.includes(bundleId)) {
|
|
174
|
+
const parts = line.split('|').map((s) => s.trim());
|
|
175
|
+
return {
|
|
176
|
+
bundleId,
|
|
177
|
+
state: parts[2] ?? 'Unknown',
|
|
178
|
+
pid: parts[3] ? parseInt(parts[3], 10) : undefined,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
163
181
|
}
|
|
182
|
+
return { bundleId, state: 'Not Installed' };
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
return __classPrivateFieldGet(this, _IdbBackend_instances, "m", _IdbBackend_getAppStateViaSimctl).call(this, bundleId);
|
|
164
186
|
}
|
|
165
|
-
return { bundleId, state: 'Not Installed' };
|
|
166
187
|
}
|
|
167
|
-
async screenshot(outputPath) {
|
|
188
|
+
async screenshot(outputPath, options) {
|
|
168
189
|
await this.ensureConnected();
|
|
169
|
-
const path = outputPath
|
|
170
|
-
await (0, exec_js_1.execStrict)(
|
|
171
|
-
|
|
172
|
-
|
|
190
|
+
const path = (0, output_path_js_1.resolveArtifactPath)(outputPath, 'screenshot');
|
|
191
|
+
await (0, exec_js_1.execStrict)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), ['screenshot', path, '--udid', __classPrivateFieldGet(this, _IdbBackend_udid, "f")]);
|
|
192
|
+
(0, output_path_js_1.hardenArtifactFile)(path);
|
|
193
|
+
if (options?.encode === false) {
|
|
194
|
+
return { data: undefined, format: 'png', path };
|
|
195
|
+
}
|
|
196
|
+
const data = await (0, promises_1.readFile)(path, 'base64');
|
|
197
|
+
return { data, format: 'png', path };
|
|
173
198
|
}
|
|
174
199
|
async openApp(bundleId) {
|
|
175
200
|
await this.ensureConnected();
|
|
176
|
-
|
|
201
|
+
try {
|
|
202
|
+
await (0, exec_js_1.execStrict)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), [
|
|
203
|
+
'launch',
|
|
204
|
+
bundleId,
|
|
205
|
+
'--udid',
|
|
206
|
+
__classPrivateFieldGet(this, _IdbBackend_udid, "f"),
|
|
207
|
+
]);
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
await (0, exec_js_1.execStrict)('xcrun', ['simctl', 'launch', __classPrivateFieldGet(this, _IdbBackend_udid, "f"), bundleId]);
|
|
211
|
+
}
|
|
177
212
|
}
|
|
178
213
|
async closeApp(bundleId) {
|
|
179
214
|
await this.ensureConnected();
|
|
180
|
-
|
|
215
|
+
try {
|
|
216
|
+
await (0, exec_js_1.execStrict)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), [
|
|
217
|
+
'terminate',
|
|
218
|
+
bundleId,
|
|
219
|
+
'--udid',
|
|
220
|
+
__classPrivateFieldGet(this, _IdbBackend_udid, "f"),
|
|
221
|
+
]);
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
await (0, exec_js_1.execStrict)('xcrun', ['simctl', 'terminate', __classPrivateFieldGet(this, _IdbBackend_udid, "f"), bundleId]);
|
|
225
|
+
}
|
|
181
226
|
}
|
|
182
227
|
async pressButton(button) {
|
|
183
228
|
await this.ensureConnected();
|
|
@@ -187,7 +232,7 @@ class IdbBackend {
|
|
|
187
232
|
back: 'HOME',
|
|
188
233
|
enter: 'RETURN',
|
|
189
234
|
};
|
|
190
|
-
await (0, exec_js_1.execStrict)(
|
|
235
|
+
await (0, exec_js_1.execStrict)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), [
|
|
191
236
|
'ui',
|
|
192
237
|
'key',
|
|
193
238
|
keyMap[button],
|
|
@@ -197,7 +242,13 @@ class IdbBackend {
|
|
|
197
242
|
}
|
|
198
243
|
async dismissKeyboard() {
|
|
199
244
|
await this.ensureConnected();
|
|
200
|
-
await (0, exec_js_1.execStrict)(
|
|
245
|
+
await (0, exec_js_1.execStrict)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), [
|
|
246
|
+
'ui',
|
|
247
|
+
'key',
|
|
248
|
+
'RETURN',
|
|
249
|
+
'--udid',
|
|
250
|
+
__classPrivateFieldGet(this, _IdbBackend_udid, "f"),
|
|
251
|
+
]);
|
|
201
252
|
}
|
|
202
253
|
async dismissAlert(accept) {
|
|
203
254
|
await this.ensureConnected();
|
|
@@ -227,7 +278,7 @@ class IdbBackend {
|
|
|
227
278
|
if (filter) {
|
|
228
279
|
args.push('--predicate', `eventMessage CONTAINS "${filter}"`);
|
|
229
280
|
}
|
|
230
|
-
const raw = await (0, exec_js_1.execStrict)(
|
|
281
|
+
const raw = await (0, exec_js_1.execStrict)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), args);
|
|
231
282
|
const entries = raw
|
|
232
283
|
.trim()
|
|
233
284
|
.split('\n')
|
|
@@ -249,7 +300,7 @@ class IdbBackend {
|
|
|
249
300
|
}
|
|
250
301
|
const cx = Math.round(element.frame.x + element.frame.width / 2);
|
|
251
302
|
const cy = Math.round(element.frame.y + element.frame.height / 2);
|
|
252
|
-
await (0, exec_js_1.execStrict)(
|
|
303
|
+
await (0, exec_js_1.execStrict)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), [
|
|
253
304
|
'ui',
|
|
254
305
|
'tap',
|
|
255
306
|
String(cx),
|
|
@@ -296,7 +347,7 @@ class IdbBackend {
|
|
|
296
347
|
}
|
|
297
348
|
async getWindowSize() {
|
|
298
349
|
await this.ensureConnected();
|
|
299
|
-
const raw = await (0, exec_js_1.execStrict)(
|
|
350
|
+
const raw = await (0, exec_js_1.execStrict)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), [
|
|
300
351
|
'describe',
|
|
301
352
|
'--udid',
|
|
302
353
|
__classPrivateFieldGet(this, _IdbBackend_udid, "f"),
|
|
@@ -346,9 +397,9 @@ class IdbBackend {
|
|
|
346
397
|
if (__classPrivateFieldGet(this, _IdbBackend_recordingProcess, "f")) {
|
|
347
398
|
throw new Error('Screen recording is already in progress');
|
|
348
399
|
}
|
|
349
|
-
const path = outputPath
|
|
400
|
+
const path = (0, output_path_js_1.resolveArtifactPath)(outputPath, 'recording');
|
|
350
401
|
__classPrivateFieldSet(this, _IdbBackend_recordingPath, path, "f");
|
|
351
|
-
__classPrivateFieldSet(this, _IdbBackend_recordingProcess, (0, node_child_process_1.spawn)(
|
|
402
|
+
__classPrivateFieldSet(this, _IdbBackend_recordingProcess, (0, node_child_process_1.spawn)(__classPrivateFieldGet(this, _IdbBackend_idbPath, "f"), [
|
|
352
403
|
'record-video',
|
|
353
404
|
path,
|
|
354
405
|
'--udid',
|
|
@@ -368,11 +419,18 @@ class IdbBackend {
|
|
|
368
419
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
369
420
|
__classPrivateFieldSet(this, _IdbBackend_recordingProcess, null, "f");
|
|
370
421
|
__classPrivateFieldSet(this, _IdbBackend_recordingPath, null, "f");
|
|
422
|
+
(0, output_path_js_1.hardenArtifactFile)(path);
|
|
371
423
|
return path;
|
|
372
424
|
}
|
|
373
425
|
}
|
|
374
426
|
exports.IdbBackend = IdbBackend;
|
|
375
|
-
_IdbBackend_connected = new WeakMap(), _IdbBackend_udid = new WeakMap(), _IdbBackend_recordingProcess = new WeakMap(), _IdbBackend_recordingPath = new WeakMap()
|
|
427
|
+
_IdbBackend_connected = new WeakMap(), _IdbBackend_udid = new WeakMap(), _IdbBackend_idbPath = new WeakMap(), _IdbBackend_recordingProcess = new WeakMap(), _IdbBackend_recordingPath = new WeakMap(), _IdbBackend_instances = new WeakSet(), _IdbBackend_getAppStateViaSimctl = async function _IdbBackend_getAppStateViaSimctl(bundleId) {
|
|
428
|
+
const result = await (0, exec_js_1.exec)('xcrun', ['simctl', 'listapps', __classPrivateFieldGet(this, _IdbBackend_udid, "f")]);
|
|
429
|
+
if (result.exitCode === 0 && result.stdout.includes(bundleId)) {
|
|
430
|
+
return { bundleId, state: 'Running' };
|
|
431
|
+
}
|
|
432
|
+
return { bundleId, state: 'Not Installed' };
|
|
433
|
+
};
|
|
376
434
|
function collectAlertTexts(elements) {
|
|
377
435
|
const texts = [];
|
|
378
436
|
for (const el of elements) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idb-backend.cjs","sourceRoot":"","sources":["../../src/backends/idb-backend.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile as execFileCb, spawn } from 'node:child_process';\nimport type { ChildProcess } from 'node:child_process';\n\nimport type {\n DeviceBackend,\n DeviceButton,\n DeviceInfo,\n SnapshotResult,\n ScreenshotResult,\n LogsResult,\n TapResult,\n AppStateResult,\n ElementQuery,\n UIElement,\n WindowSize,\n} from './types.js';\nimport { ACCEPT_LABELS, DENY_LABELS } from '../utils/alert-labels.js';\nimport {\n findElement,\n describeElement,\n computeSwipeEnd,\n} from '../utils/element.js';\nimport { execStrict, exec, isCommandAvailable } from '../utils/exec.js';\n\nexport class IdbBackend implements DeviceBackend {\n readonly platform = 'ios' as const;\n\n #connected = false;\n\n readonly #udid: string;\n\n #recordingProcess: ChildProcess | null = null;\n\n #recordingPath: string | null = null;\n\n constructor(udid: string) {\n this.#udid = udid;\n }\n\n async ensureConnected(): Promise<void> {\n if (this.#connected) {\n return;\n }\n\n if (!(await isCommandAvailable('idb'))) {\n throw new Error(\n 'idb is not installed.\\n' +\n 'Install: brew tap facebook/fb && brew install idb-companion && pip3 install fb-idb',\n );\n }\n\n await exec('idb', ['connect', this.#udid]);\n this.#connected = true;\n }\n\n async getDeviceInfo(): Promise<DeviceInfo> {\n await this.ensureConnected();\n const raw = await execStrict('idb', [\n 'describe',\n '--udid',\n this.#udid,\n '--json',\n ]);\n let info: Record<string, unknown>;\n try {\n info = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n throw new Error(\n `idb describe returned invalid JSON for device ${this.#udid}: ${raw.slice(0, 200)}`,\n );\n }\n return {\n platform: 'ios',\n deviceId: this.#udid,\n name: (info.name as string) ?? 'Unknown',\n osVersion: (info.os_version as string) ?? 'Unknown',\n state: (info.state as string) ?? 'Unknown',\n };\n }\n\n async snapshot(): Promise<SnapshotResult> {\n await this.ensureConnected();\n const raw = await execStrict('idb', [\n 'ui',\n 'describe-all',\n '--udid',\n this.#udid,\n ]);\n const hierarchy = parseIdbHierarchy(raw);\n return {\n platform: 'ios',\n hierarchy,\n raw,\n timestamp: Date.now(),\n };\n }\n\n async tapElement(query: ElementQuery): Promise<TapResult> {\n await this.ensureConnected();\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n const x = Math.round(element.frame.x + element.frame.width / 2);\n const y = Math.round(element.frame.y + element.frame.height / 2);\n await this.tapCoordinates(x, y);\n\n return {\n success: true,\n x,\n y,\n targetDescription: describeElement(element),\n };\n }\n\n async tapCoordinates(x: number, y: number): Promise<void> {\n await this.ensureConnected();\n await execStrict('idb', [\n 'ui',\n 'tap',\n String(x),\n String(y),\n '--udid',\n this.#udid,\n ]);\n }\n\n async typeText(text: string): Promise<void> {\n await this.ensureConnected();\n await exec('idb', [\n 'ui',\n 'key-sequence',\n '--',\n 'cmd+a',\n '--udid',\n this.#udid,\n ]);\n await exec('idb', ['ui', 'key', 'DELETE', '--udid', this.#udid]);\n await execStrict('idb', ['ui', 'text', text, '--udid', this.#udid]);\n }\n\n async swipe(\n direction: 'up' | 'down' | 'left' | 'right',\n startX?: number,\n startY?: number,\n distance?: number,\n ): Promise<void> {\n await this.ensureConnected();\n const d = distance ?? 500;\n const sx = startX ?? 200;\n const sy = startY ?? 400;\n const [endX, endY] = computeSwipeEnd(sx, sy, direction, d);\n\n await execStrict('idb', [\n 'ui',\n 'swipe',\n String(sx),\n String(sy),\n String(endX),\n String(endY),\n '--udid',\n this.#udid,\n ]);\n }\n\n async waitForElement(\n query: ElementQuery,\n timeoutMs = 10_000,\n intervalMs = 500,\n ): Promise<UIElement> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (element) {\n return element;\n }\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n throw new Error(\n `Timed out waiting for element: ${JSON.stringify(query)} (${timeoutMs}ms)`,\n );\n }\n\n async getAppState(bundleId: string): Promise<AppStateResult> {\n await this.ensureConnected();\n const raw = await execStrict('idb', ['list-apps', '--udid', this.#udid]);\n\n for (const line of raw.trim().split('\\n')) {\n if (line.includes(bundleId)) {\n const parts = line.split('|').map((s) => s.trim());\n return {\n bundleId,\n state: parts[2] ?? 'Unknown',\n pid: parts[3] ? parseInt(parts[3], 10) : undefined,\n };\n }\n }\n\n return { bundleId, state: 'Not Installed' };\n }\n\n async screenshot(outputPath?: string): Promise<ScreenshotResult> {\n await this.ensureConnected();\n const path = outputPath ?? `/tmp/device-mcp-screenshot-${Date.now()}.png`;\n await execStrict('idb', ['screenshot', path, '--udid', this.#udid]);\n const data = await execStrict('base64', [path]);\n return { data: data.trim(), format: 'png', path };\n }\n\n async openApp(bundleId: string): Promise<void> {\n await this.ensureConnected();\n await execStrict('idb', ['launch', bundleId, '--udid', this.#udid]);\n }\n\n async closeApp(bundleId: string): Promise<void> {\n await this.ensureConnected();\n await execStrict('idb', ['terminate', bundleId, '--udid', this.#udid]);\n }\n\n async pressButton(button: DeviceButton): Promise<void> {\n await this.ensureConnected();\n const keyMap: Record<DeviceButton, string> = {\n home: 'HOME',\n lock: 'LOCK',\n back: 'HOME',\n enter: 'RETURN',\n };\n await execStrict('idb', [\n 'ui',\n 'key',\n keyMap[button],\n '--udid',\n this.#udid,\n ]);\n }\n\n async dismissKeyboard(): Promise<void> {\n await this.ensureConnected();\n await execStrict('idb', ['ui', 'key', 'RETURN', '--udid', this.#udid]);\n }\n\n async dismissAlert(accept: boolean): Promise<void> {\n await this.ensureConnected();\n const snap = await this.snapshot();\n const candidates = accept ? ACCEPT_LABELS : DENY_LABELS;\n\n for (const label of candidates) {\n const element = findElement(snap.hierarchy, { label });\n if (element) {\n const cx = Math.round(element.frame.x + element.frame.width / 2);\n const cy = Math.round(element.frame.y + element.frame.height / 2);\n await this.tapCoordinates(cx, cy);\n return;\n }\n }\n\n throw new Error(`No alert button found. Tried: ${candidates.join(', ')}`);\n }\n\n async getLogs(durationSeconds = 30, filter?: string): Promise<LogsResult> {\n await this.ensureConnected();\n const args = [\n 'log',\n '--udid',\n this.#udid,\n '--',\n '--last',\n `${durationSeconds}s`,\n ];\n if (filter) {\n args.push('--predicate', `eventMessage CONTAINS \"${filter}\"`);\n }\n const raw = await execStrict('idb', args);\n const entries = raw\n .trim()\n .split('\\n')\n .filter(Boolean)\n .map((line) => ({\n timestamp: line.substring(0, 31).trim(),\n level: 'info',\n message: line.substring(31).trim(),\n }));\n return { entries, source: 'idb log' };\n }\n\n async longPress(query: ElementQuery, durationMs = 1000): Promise<TapResult> {\n await this.ensureConnected();\n const snap = await this.snapshot();\n const element = findElement(snap.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n const cx = Math.round(element.frame.x + element.frame.width / 2);\n const cy = Math.round(element.frame.y + element.frame.height / 2);\n await execStrict('idb', [\n 'ui',\n 'tap',\n String(cx),\n String(cy),\n '--duration',\n String(durationMs / 1000),\n '--udid',\n this.#udid,\n ]);\n\n return {\n success: true,\n x: cx,\n y: cy,\n targetDescription: describeElement(element),\n };\n }\n\n async scrollToElement(\n query: ElementQuery,\n direction: 'up' | 'down' = 'down',\n maxAttempts = 10,\n ): Promise<UIElement> {\n await this.ensureConnected();\n let previousRaw = '';\n\n for (let i = 0; i < maxAttempts; i++) {\n const snap = await this.snapshot();\n const element = findElement(snap.hierarchy, query);\n if (element) {\n return element;\n }\n if (snap.raw === previousRaw) {\n break;\n }\n previousRaw = snap.raw;\n await this.swipe(direction);\n }\n throw new Error(\n `Element not found after scrolling: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n async getAlertText(): Promise<string> {\n await this.ensureConnected();\n const snap = await this.snapshot();\n const texts = collectAlertTexts(snap.hierarchy);\n if (texts.length === 0) {\n throw new Error(\n 'No alert is currently displayed.\\n' +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n return texts.join('\\n');\n }\n\n async getWindowSize(): Promise<WindowSize> {\n await this.ensureConnected();\n const raw = await execStrict('idb', [\n 'describe',\n '--udid',\n this.#udid,\n '--json',\n ]);\n try {\n const info = JSON.parse(raw) as Record<string, unknown>;\n const dims = info.screen_dimensions as\n | { width: number; height: number }\n | undefined;\n if (dims?.width && dims?.height) {\n return { width: dims.width, height: dims.height };\n }\n } catch {\n // fall through to snapshot-based approach\n }\n const snap = await this.snapshot();\n if (snap.hierarchy.length > 0) {\n const root = snap.hierarchy[0];\n if (root.frame.width > 0 && root.frame.height > 0) {\n return { width: root.frame.width, height: root.frame.height };\n }\n }\n throw new Error('Unable to determine window size from device');\n }\n\n async getContexts(): Promise<string[]> {\n return ['NATIVE_APP'];\n }\n\n async setContext(context: string): Promise<void> {\n if (context === 'NATIVE_APP') {\n return;\n }\n throw new Error(\n 'Context switching requires Appium backend. IDB only supports NATIVE_APP.',\n );\n }\n\n async getClipboard(): Promise<string> {\n await this.ensureConnected();\n return execStrict('xcrun', ['simctl', 'pbpaste', this.#udid]);\n }\n\n async setClipboard(text: string): Promise<void> {\n await this.ensureConnected();\n await new Promise<void>((resolve, reject) => {\n const proc = execFileCb(\n 'xcrun',\n ['simctl', 'pbcopy', this.#udid],\n { timeout: 30_000 },\n (error) => (error ? reject(new Error(error.message)) : resolve()),\n );\n proc.stdin?.end(text);\n });\n }\n\n async startScreenRecording(outputPath?: string): Promise<void> {\n await this.ensureConnected();\n if (this.#recordingProcess) {\n throw new Error('Screen recording is already in progress');\n }\n const path = outputPath ?? `/tmp/device-mcp-recording-${Date.now()}.mp4`;\n this.#recordingPath = path;\n this.#recordingProcess = spawn('idb', [\n 'record-video',\n path,\n '--udid',\n this.#udid,\n ]);\n this.#recordingProcess.on('error', () => {\n this.#recordingProcess = null;\n this.#recordingPath = null;\n });\n }\n\n async stopScreenRecording(): Promise<string> {\n if (!this.#recordingProcess || !this.#recordingPath) {\n throw new Error('No screen recording in progress');\n }\n const path = this.#recordingPath;\n this.#recordingProcess.kill('SIGINT');\n await new Promise((resolve) => setTimeout(resolve, 1000));\n this.#recordingProcess = null;\n this.#recordingPath = null;\n return path;\n }\n}\n\nfunction collectAlertTexts(elements: UIElement[]): string[] {\n const texts: string[] = [];\n for (const el of elements) {\n const isAlertContainer =\n el.type === 'Alert' || el.type === 'Sheet' || el.type.includes('Alert');\n if (isAlertContainer) {\n collectTextsFromChildren(el.children ?? [], texts);\n return texts;\n }\n if (el.children) {\n const found = collectAlertTexts(el.children);\n if (found.length > 0) {\n return found;\n }\n }\n }\n return texts;\n}\n\nfunction collectTextsFromChildren(\n elements: UIElement[],\n texts: string[],\n): void {\n for (const el of elements) {\n if (el.type === 'StaticText' || el.type === 'TextView') {\n const text = el.value ?? el.label;\n if (text) {\n texts.push(text);\n }\n }\n if (el.children) {\n collectTextsFromChildren(el.children, texts);\n }\n }\n}\n\nexport function parseIdbHierarchy(raw: string): UIElement[] {\n try {\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed)) {\n return parsed.map(mapIdbElement);\n }\n if (parsed.children) {\n return parsed.children.map(mapIdbElement);\n }\n return [mapIdbElement(parsed)];\n } catch {\n return [\n {\n type: 'raw',\n label: raw.slice(0, 200),\n frame: { x: 0, y: 0, width: 0, height: 0 },\n enabled: true,\n },\n ];\n }\n}\n\nexport function mapIdbElement(node: Record<string, unknown>): UIElement {\n const frame = node.frame as\n | { x: number; y: number; width: number; height: number }\n | undefined;\n\n return {\n type: (node.type as string) ?? (node.AXType as string) ?? 'Unknown',\n label: (node.AXLabel as string) ?? (node.label as string) ?? undefined,\n value: (node.AXValue as string) ?? (node.value as string) ?? undefined,\n identifier:\n (node.AXUniqueId as string) ?? (node.identifier as string) ?? undefined,\n frame: frame ?? { x: 0, y: 0, width: 0, height: 0 },\n enabled: (node.enabled as boolean) ?? true,\n children: Array.isArray(node.children)\n ? node.children.map(mapIdbElement)\n : undefined,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"idb-backend.cjs","sourceRoot":"","sources":["../../src/backends/idb-backend.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile as execFileCb, spawn } from 'node:child_process';\nimport type { ChildProcess } from 'node:child_process';\nimport { readFile } from 'node:fs/promises';\n\nimport type {\n DeviceBackend,\n DeviceButton,\n DeviceInfo,\n SnapshotResult,\n ScreenshotResult,\n ScreenshotFileResult,\n ScreenshotOptions,\n LogsResult,\n TapResult,\n AppStateResult,\n ElementQuery,\n UIElement,\n WindowSize,\n} from './types.js';\nimport { ACCEPT_LABELS, DENY_LABELS } from '../utils/alert-labels.js';\nimport {\n findElement,\n describeElement,\n computeSwipeEnd,\n} from '../utils/element.js';\nimport { execStrict, exec } from '../utils/exec.js';\nimport {\n hardenArtifactFile,\n resolveArtifactPath,\n} from '../utils/output-path.js';\nimport { resolveIdbPath } from '../utils/platform.js';\n\nexport class IdbBackend implements DeviceBackend {\n readonly platform = 'ios' as const;\n\n #connected = false;\n\n readonly #udid: string;\n\n #idbPath = 'idb';\n\n #recordingProcess: ChildProcess | null = null;\n\n #recordingPath: string | null = null;\n\n constructor(udid: string) {\n this.#udid = udid;\n }\n\n async ensureConnected(): Promise<void> {\n if (this.#connected) {\n return;\n }\n\n this.#idbPath = await resolveIdbPath();\n await exec(this.#idbPath, ['connect', this.#udid]);\n this.#connected = true;\n }\n\n async getDeviceInfo(): Promise<DeviceInfo> {\n await this.ensureConnected();\n const raw = await execStrict(this.#idbPath, [\n 'describe',\n '--udid',\n this.#udid,\n '--json',\n ]);\n let info: Record<string, unknown>;\n try {\n info = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n throw new Error(\n `idb describe returned invalid JSON for device ${this.#udid}: ${raw.slice(0, 200)}`,\n );\n }\n return {\n platform: 'ios',\n deviceId: this.#udid,\n name: (info.name as string) ?? 'Unknown',\n osVersion: (info.os_version as string) ?? 'Unknown',\n state: (info.state as string) ?? 'Unknown',\n };\n }\n\n async snapshot(): Promise<SnapshotResult> {\n await this.ensureConnected();\n const raw = await execStrict(this.#idbPath, [\n 'ui',\n 'describe-all',\n '--udid',\n this.#udid,\n ]);\n const hierarchy = parseIdbHierarchy(raw);\n return {\n platform: 'ios',\n hierarchy,\n raw,\n timestamp: Date.now(),\n };\n }\n\n async tapElement(query: ElementQuery): Promise<TapResult> {\n await this.ensureConnected();\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n const x = Math.round(element.frame.x + element.frame.width / 2);\n const y = Math.round(element.frame.y + element.frame.height / 2);\n await this.tapCoordinates(x, y);\n\n return {\n success: true,\n x,\n y,\n targetDescription: describeElement(element),\n };\n }\n\n async getElementText(query: ElementQuery): Promise<string> {\n await this.ensureConnected();\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n return element.label ?? element.value ?? '';\n }\n\n async tapCoordinates(x: number, y: number): Promise<void> {\n await this.ensureConnected();\n await execStrict(this.#idbPath, [\n 'ui',\n 'tap',\n String(x),\n String(y),\n '--udid',\n this.#udid,\n ]);\n }\n\n async typeText(text: string): Promise<void> {\n await this.ensureConnected();\n await exec(this.#idbPath, [\n 'ui',\n 'key-sequence',\n '--',\n 'cmd+a',\n '--udid',\n this.#udid,\n ]);\n await exec(this.#idbPath, ['ui', 'key', 'DELETE', '--udid', this.#udid]);\n await execStrict(this.#idbPath, ['ui', 'text', text, '--udid', this.#udid]);\n }\n\n async swipe(\n direction: 'up' | 'down' | 'left' | 'right',\n startX?: number,\n startY?: number,\n distance?: number,\n ): Promise<void> {\n await this.ensureConnected();\n const d = distance ?? 500;\n const sx = startX ?? 200;\n const sy = startY ?? 400;\n const [endX, endY] = computeSwipeEnd(sx, sy, direction, d);\n\n await execStrict(this.#idbPath, [\n 'ui',\n 'swipe',\n String(sx),\n String(sy),\n String(endX),\n String(endY),\n '--udid',\n this.#udid,\n ]);\n }\n\n async waitForElement(\n query: ElementQuery,\n timeoutMs = 10_000,\n intervalMs = 500,\n ): Promise<UIElement> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n const snapshot = await this.snapshot();\n const element = findElement(snapshot.hierarchy, query);\n if (element) {\n return element;\n }\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n throw new Error(\n `Timed out waiting for element: ${JSON.stringify(query)} (${timeoutMs}ms)`,\n );\n }\n\n async getAppState(bundleId: string): Promise<AppStateResult> {\n await this.ensureConnected();\n try {\n const raw = await execStrict(this.#idbPath, [\n 'list-apps',\n '--udid',\n this.#udid,\n ]);\n\n for (const line of raw.trim().split('\\n')) {\n if (line.includes(bundleId)) {\n const parts = line.split('|').map((s) => s.trim());\n return {\n bundleId,\n state: parts[2] ?? 'Unknown',\n pid: parts[3] ? parseInt(parts[3], 10) : undefined,\n };\n }\n }\n\n return { bundleId, state: 'Not Installed' };\n } catch {\n return this.#getAppStateViaSimctl(bundleId);\n }\n }\n\n async #getAppStateViaSimctl(bundleId: string): Promise<AppStateResult> {\n const result = await exec('xcrun', ['simctl', 'listapps', this.#udid]);\n if (result.exitCode === 0 && result.stdout.includes(bundleId)) {\n return { bundleId, state: 'Running' };\n }\n return { bundleId, state: 'Not Installed' };\n }\n\n screenshot(\n outputPath?: string,\n options?: { encode?: true },\n ): Promise<ScreenshotResult>;\n\n screenshot(\n outputPath: string | undefined,\n options: { encode: false },\n ): Promise<ScreenshotFileResult>;\n\n screenshot(\n outputPath?: string,\n options?: ScreenshotOptions,\n ): Promise<ScreenshotResult | ScreenshotFileResult>;\n\n async screenshot(\n outputPath?: string,\n options?: ScreenshotOptions,\n ): Promise<ScreenshotResult | ScreenshotFileResult> {\n await this.ensureConnected();\n const path = resolveArtifactPath(outputPath, 'screenshot');\n await execStrict(this.#idbPath, ['screenshot', path, '--udid', this.#udid]);\n hardenArtifactFile(path);\n if (options?.encode === false) {\n return { data: undefined, format: 'png', path };\n }\n const data = await readFile(path, 'base64');\n return { data, format: 'png', path };\n }\n\n async openApp(bundleId: string): Promise<void> {\n await this.ensureConnected();\n try {\n await execStrict(this.#idbPath, [\n 'launch',\n bundleId,\n '--udid',\n this.#udid,\n ]);\n } catch {\n await execStrict('xcrun', ['simctl', 'launch', this.#udid, bundleId]);\n }\n }\n\n async closeApp(bundleId: string): Promise<void> {\n await this.ensureConnected();\n try {\n await execStrict(this.#idbPath, [\n 'terminate',\n bundleId,\n '--udid',\n this.#udid,\n ]);\n } catch {\n await execStrict('xcrun', ['simctl', 'terminate', this.#udid, bundleId]);\n }\n }\n\n async pressButton(button: DeviceButton): Promise<void> {\n await this.ensureConnected();\n const keyMap: Record<DeviceButton, string> = {\n home: 'HOME',\n lock: 'LOCK',\n back: 'HOME',\n enter: 'RETURN',\n };\n await execStrict(this.#idbPath, [\n 'ui',\n 'key',\n keyMap[button],\n '--udid',\n this.#udid,\n ]);\n }\n\n async dismissKeyboard(): Promise<void> {\n await this.ensureConnected();\n await execStrict(this.#idbPath, [\n 'ui',\n 'key',\n 'RETURN',\n '--udid',\n this.#udid,\n ]);\n }\n\n async dismissAlert(accept: boolean): Promise<void> {\n await this.ensureConnected();\n const snap = await this.snapshot();\n const candidates = accept ? ACCEPT_LABELS : DENY_LABELS;\n\n for (const label of candidates) {\n const element = findElement(snap.hierarchy, { label });\n if (element) {\n const cx = Math.round(element.frame.x + element.frame.width / 2);\n const cy = Math.round(element.frame.y + element.frame.height / 2);\n await this.tapCoordinates(cx, cy);\n return;\n }\n }\n\n throw new Error(`No alert button found. Tried: ${candidates.join(', ')}`);\n }\n\n async getLogs(durationSeconds = 30, filter?: string): Promise<LogsResult> {\n await this.ensureConnected();\n const args = [\n 'log',\n '--udid',\n this.#udid,\n '--',\n '--last',\n `${durationSeconds}s`,\n ];\n if (filter) {\n args.push('--predicate', `eventMessage CONTAINS \"${filter}\"`);\n }\n const raw = await execStrict(this.#idbPath, args);\n const entries = raw\n .trim()\n .split('\\n')\n .filter(Boolean)\n .map((line) => ({\n timestamp: line.substring(0, 31).trim(),\n level: 'info',\n message: line.substring(31).trim(),\n }));\n return { entries, source: 'idb log' };\n }\n\n async longPress(query: ElementQuery, durationMs = 1000): Promise<TapResult> {\n await this.ensureConnected();\n const snap = await this.snapshot();\n const element = findElement(snap.hierarchy, query);\n if (!element) {\n throw new Error(\n `Element not found: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n const cx = Math.round(element.frame.x + element.frame.width / 2);\n const cy = Math.round(element.frame.y + element.frame.height / 2);\n await execStrict(this.#idbPath, [\n 'ui',\n 'tap',\n String(cx),\n String(cy),\n '--duration',\n String(durationMs / 1000),\n '--udid',\n this.#udid,\n ]);\n\n return {\n success: true,\n x: cx,\n y: cy,\n targetDescription: describeElement(element),\n };\n }\n\n async scrollToElement(\n query: ElementQuery,\n direction: 'up' | 'down' = 'down',\n maxAttempts = 10,\n ): Promise<UIElement> {\n await this.ensureConnected();\n let previousRaw = '';\n\n for (let i = 0; i < maxAttempts; i++) {\n const snap = await this.snapshot();\n const element = findElement(snap.hierarchy, query);\n if (element) {\n return element;\n }\n if (snap.raw === previousRaw) {\n break;\n }\n previousRaw = snap.raw;\n await this.swipe(direction);\n }\n throw new Error(\n `Element not found after scrolling: ${JSON.stringify(query)}\\n` +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n\n async getAlertText(): Promise<string> {\n await this.ensureConnected();\n const snap = await this.snapshot();\n const texts = collectAlertTexts(snap.hierarchy);\n if (texts.length === 0) {\n throw new Error(\n 'No alert is currently displayed.\\n' +\n 'Use device_snapshot to inspect the current UI hierarchy.',\n );\n }\n return texts.join('\\n');\n }\n\n async getWindowSize(): Promise<WindowSize> {\n await this.ensureConnected();\n const raw = await execStrict(this.#idbPath, [\n 'describe',\n '--udid',\n this.#udid,\n '--json',\n ]);\n try {\n const info = JSON.parse(raw) as Record<string, unknown>;\n const dims = info.screen_dimensions as\n | { width: number; height: number }\n | undefined;\n if (dims?.width && dims?.height) {\n return { width: dims.width, height: dims.height };\n }\n } catch {\n // fall through to snapshot-based approach\n }\n const snap = await this.snapshot();\n if (snap.hierarchy.length > 0) {\n const root = snap.hierarchy[0];\n if (root.frame.width > 0 && root.frame.height > 0) {\n return { width: root.frame.width, height: root.frame.height };\n }\n }\n throw new Error('Unable to determine window size from device');\n }\n\n async getContexts(): Promise<string[]> {\n return ['NATIVE_APP'];\n }\n\n async setContext(context: string): Promise<void> {\n if (context === 'NATIVE_APP') {\n return;\n }\n throw new Error(\n 'Context switching requires Appium backend. IDB only supports NATIVE_APP.',\n );\n }\n\n async getClipboard(): Promise<string> {\n await this.ensureConnected();\n return execStrict('xcrun', ['simctl', 'pbpaste', this.#udid]);\n }\n\n async setClipboard(text: string): Promise<void> {\n await this.ensureConnected();\n await new Promise<void>((resolve, reject) => {\n const proc = execFileCb(\n 'xcrun',\n ['simctl', 'pbcopy', this.#udid],\n { timeout: 30_000 },\n (error) => (error ? reject(new Error(error.message)) : resolve()),\n );\n proc.stdin?.end(text);\n });\n }\n\n async startScreenRecording(outputPath?: string): Promise<void> {\n await this.ensureConnected();\n if (this.#recordingProcess) {\n throw new Error('Screen recording is already in progress');\n }\n const path = resolveArtifactPath(outputPath, 'recording');\n this.#recordingPath = path;\n this.#recordingProcess = spawn(this.#idbPath, [\n 'record-video',\n path,\n '--udid',\n this.#udid,\n ]);\n this.#recordingProcess.on('error', () => {\n this.#recordingProcess = null;\n this.#recordingPath = null;\n });\n }\n\n async stopScreenRecording(): Promise<string> {\n if (!this.#recordingProcess || !this.#recordingPath) {\n throw new Error('No screen recording in progress');\n }\n const path = this.#recordingPath;\n this.#recordingProcess.kill('SIGINT');\n await new Promise((resolve) => setTimeout(resolve, 1000));\n this.#recordingProcess = null;\n this.#recordingPath = null;\n hardenArtifactFile(path);\n return path;\n }\n}\n\nfunction collectAlertTexts(elements: UIElement[]): string[] {\n const texts: string[] = [];\n for (const el of elements) {\n const isAlertContainer =\n el.type === 'Alert' || el.type === 'Sheet' || el.type.includes('Alert');\n if (isAlertContainer) {\n collectTextsFromChildren(el.children ?? [], texts);\n return texts;\n }\n if (el.children) {\n const found = collectAlertTexts(el.children);\n if (found.length > 0) {\n return found;\n }\n }\n }\n return texts;\n}\n\nfunction collectTextsFromChildren(\n elements: UIElement[],\n texts: string[],\n): void {\n for (const el of elements) {\n if (el.type === 'StaticText' || el.type === 'TextView') {\n const text = el.value ?? el.label;\n if (text) {\n texts.push(text);\n }\n }\n if (el.children) {\n collectTextsFromChildren(el.children, texts);\n }\n }\n}\n\nexport function parseIdbHierarchy(raw: string): UIElement[] {\n try {\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed)) {\n return parsed.map(mapIdbElement);\n }\n if (parsed.children) {\n return parsed.children.map(mapIdbElement);\n }\n return [mapIdbElement(parsed)];\n } catch {\n return [\n {\n type: 'raw',\n label: raw.slice(0, 200),\n frame: { x: 0, y: 0, width: 0, height: 0 },\n enabled: true,\n },\n ];\n }\n}\n\nexport function mapIdbElement(node: Record<string, unknown>): UIElement {\n const frame = node.frame as\n | { x: number; y: number; width: number; height: number }\n | undefined;\n\n return {\n type: (node.type as string) ?? (node.AXType as string) ?? 'Unknown',\n label: (node.AXLabel as string) ?? (node.label as string) ?? undefined,\n value: (node.AXValue as string) ?? (node.value as string) ?? undefined,\n identifier:\n (node.AXUniqueId as string) ?? (node.identifier as string) ?? undefined,\n frame: frame ?? { x: 0, y: 0, width: 0, height: 0 },\n enabled: (node.enabled as boolean) ?? true,\n children: Array.isArray(node.children)\n ? node.children.map(mapIdbElement)\n : undefined,\n };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DeviceBackend, DeviceButton, DeviceInfo, SnapshotResult, ScreenshotResult, LogsResult, TapResult, AppStateResult, ElementQuery, UIElement, WindowSize } from "./types.cjs";
|
|
1
|
+
import type { DeviceBackend, DeviceButton, DeviceInfo, SnapshotResult, ScreenshotResult, ScreenshotFileResult, ScreenshotOptions, LogsResult, TapResult, AppStateResult, ElementQuery, UIElement, WindowSize } from "./types.cjs";
|
|
2
2
|
export declare class IdbBackend implements DeviceBackend {
|
|
3
3
|
#private;
|
|
4
4
|
readonly platform: "ios";
|
|
@@ -7,12 +7,19 @@ export declare class IdbBackend implements DeviceBackend {
|
|
|
7
7
|
getDeviceInfo(): Promise<DeviceInfo>;
|
|
8
8
|
snapshot(): Promise<SnapshotResult>;
|
|
9
9
|
tapElement(query: ElementQuery): Promise<TapResult>;
|
|
10
|
+
getElementText(query: ElementQuery): Promise<string>;
|
|
10
11
|
tapCoordinates(x: number, y: number): Promise<void>;
|
|
11
12
|
typeText(text: string): Promise<void>;
|
|
12
13
|
swipe(direction: 'up' | 'down' | 'left' | 'right', startX?: number, startY?: number, distance?: number): Promise<void>;
|
|
13
14
|
waitForElement(query: ElementQuery, timeoutMs?: number, intervalMs?: number): Promise<UIElement>;
|
|
14
15
|
getAppState(bundleId: string): Promise<AppStateResult>;
|
|
15
|
-
screenshot(outputPath?: string
|
|
16
|
+
screenshot(outputPath?: string, options?: {
|
|
17
|
+
encode?: true;
|
|
18
|
+
}): Promise<ScreenshotResult>;
|
|
19
|
+
screenshot(outputPath: string | undefined, options: {
|
|
20
|
+
encode: false;
|
|
21
|
+
}): Promise<ScreenshotFileResult>;
|
|
22
|
+
screenshot(outputPath?: string, options?: ScreenshotOptions): Promise<ScreenshotResult | ScreenshotFileResult>;
|
|
16
23
|
openApp(bundleId: string): Promise<void>;
|
|
17
24
|
closeApp(bundleId: string): Promise<void>;
|
|
18
25
|
pressButton(button: DeviceButton): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idb-backend.d.cts","sourceRoot":"","sources":["../../src/backends/idb-backend.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"idb-backend.d.cts","sourceRoot":"","sources":["../../src/backends/idb-backend.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,UAAU,EACV,SAAS,EACT,cAAc,EACd,YAAY,EACZ,SAAS,EACT,UAAU,EACX,oBAAmB;AAcpB,qBAAa,UAAW,YAAW,aAAa;;IAC9C,QAAQ,CAAC,QAAQ,EAAG,KAAK,CAAU;gBAYvB,IAAI,EAAE,MAAM;IAIlB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAUhC,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC;IAyBpC,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC;IAiBnC,UAAU,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC;IAuBnD,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAapD,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYnD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcrC,KAAK,CACT,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,EAC3C,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IAmBV,cAAc,CAClB,KAAK,EAAE,YAAY,EACnB,SAAS,SAAS,EAClB,UAAU,SAAM,GACf,OAAO,CAAC,SAAS,CAAC;IAef,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAkC5D,UAAU,CACR,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,IAAI,CAAA;KAAE,GAC1B,OAAO,CAAC,gBAAgB,CAAC;IAE5B,UAAU,CACR,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,OAAO,EAAE;QAAE,MAAM,EAAE,KAAK,CAAA;KAAE,GACzB,OAAO,CAAC,oBAAoB,CAAC;IAEhC,UAAU,CACR,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,gBAAgB,GAAG,oBAAoB,CAAC;IAiB7C,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAczC,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBhD,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAWhC,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB5C,OAAO,CAAC,eAAe,SAAK,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IA0BnE,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,SAAO,GAAG,OAAO,CAAC,SAAS,CAAC;IAgCrE,eAAe,CACnB,KAAK,EAAE,YAAY,EACnB,SAAS,GAAE,IAAI,GAAG,MAAe,EACjC,WAAW,SAAK,GACf,OAAO,CAAC,SAAS,CAAC;IAsBf,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAa/B,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC;IA6BpC,WAAW,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIhC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1C,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAK/B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAazC,oBAAoB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBxD,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;CAY7C;AAsCD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,CAoB1D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAiBtE"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DeviceBackend, DeviceButton, DeviceInfo, SnapshotResult, ScreenshotResult, LogsResult, TapResult, AppStateResult, ElementQuery, UIElement, WindowSize } from "./types.mjs";
|
|
1
|
+
import type { DeviceBackend, DeviceButton, DeviceInfo, SnapshotResult, ScreenshotResult, ScreenshotFileResult, ScreenshotOptions, LogsResult, TapResult, AppStateResult, ElementQuery, UIElement, WindowSize } from "./types.mjs";
|
|
2
2
|
export declare class IdbBackend implements DeviceBackend {
|
|
3
3
|
#private;
|
|
4
4
|
readonly platform: "ios";
|
|
@@ -7,12 +7,19 @@ export declare class IdbBackend implements DeviceBackend {
|
|
|
7
7
|
getDeviceInfo(): Promise<DeviceInfo>;
|
|
8
8
|
snapshot(): Promise<SnapshotResult>;
|
|
9
9
|
tapElement(query: ElementQuery): Promise<TapResult>;
|
|
10
|
+
getElementText(query: ElementQuery): Promise<string>;
|
|
10
11
|
tapCoordinates(x: number, y: number): Promise<void>;
|
|
11
12
|
typeText(text: string): Promise<void>;
|
|
12
13
|
swipe(direction: 'up' | 'down' | 'left' | 'right', startX?: number, startY?: number, distance?: number): Promise<void>;
|
|
13
14
|
waitForElement(query: ElementQuery, timeoutMs?: number, intervalMs?: number): Promise<UIElement>;
|
|
14
15
|
getAppState(bundleId: string): Promise<AppStateResult>;
|
|
15
|
-
screenshot(outputPath?: string
|
|
16
|
+
screenshot(outputPath?: string, options?: {
|
|
17
|
+
encode?: true;
|
|
18
|
+
}): Promise<ScreenshotResult>;
|
|
19
|
+
screenshot(outputPath: string | undefined, options: {
|
|
20
|
+
encode: false;
|
|
21
|
+
}): Promise<ScreenshotFileResult>;
|
|
22
|
+
screenshot(outputPath?: string, options?: ScreenshotOptions): Promise<ScreenshotResult | ScreenshotFileResult>;
|
|
16
23
|
openApp(bundleId: string): Promise<void>;
|
|
17
24
|
closeApp(bundleId: string): Promise<void>;
|
|
18
25
|
pressButton(button: DeviceButton): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idb-backend.d.mts","sourceRoot":"","sources":["../../src/backends/idb-backend.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"idb-backend.d.mts","sourceRoot":"","sources":["../../src/backends/idb-backend.ts"],"names":[],"mappings":"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"}
|