react-native-ai-debugger 1.8.1 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -66
- package/build/__tests__/integration/auto-reconnect.test.d.ts +2 -0
- package/build/__tests__/integration/auto-reconnect.test.d.ts.map +1 -0
- package/build/__tests__/integration/auto-reconnect.test.js +118 -0
- package/build/__tests__/integration/auto-reconnect.test.js.map +1 -0
- package/build/__tests__/integration/execute-in-app.test.js +11 -3
- package/build/__tests__/integration/execute-in-app.test.js.map +1 -1
- package/build/__tests__/integration/per-call-timeout.test.d.ts +2 -0
- package/build/__tests__/integration/per-call-timeout.test.d.ts.map +1 -0
- package/build/__tests__/integration/per-call-timeout.test.js +103 -0
- package/build/__tests__/integration/per-call-timeout.test.js.map +1 -0
- package/build/__tests__/setup.js +3 -5
- package/build/__tests__/setup.js.map +1 -1
- package/build/__tests__/unit/debugGlobals.test.d.ts +2 -0
- package/build/__tests__/unit/debugGlobals.test.d.ts.map +1 -0
- package/build/__tests__/unit/debugGlobals.test.js +14 -0
- package/build/__tests__/unit/debugGlobals.test.js.map +1 -0
- package/build/__tests__/unit/escapeNonAscii.test.d.ts +2 -0
- package/build/__tests__/unit/escapeNonAscii.test.d.ts.map +1 -0
- package/build/__tests__/unit/escapeNonAscii.test.js +76 -0
- package/build/__tests__/unit/escapeNonAscii.test.js.map +1 -0
- package/build/__tests__/unit/executor.test.js +59 -7
- package/build/__tests__/unit/executor.test.js.map +1 -1
- package/build/__tests__/unit/failureArtifact.test.js +3 -3
- package/build/__tests__/unit/failureArtifact.test.js.map +1 -1
- package/build/__tests__/unit/fastRefreshRecorder.test.d.ts +2 -0
- package/build/__tests__/unit/fastRefreshRecorder.test.d.ts.map +1 -0
- package/build/__tests__/unit/fastRefreshRecorder.test.js +68 -0
- package/build/__tests__/unit/fastRefreshRecorder.test.js.map +1 -0
- package/build/__tests__/unit/fastRefreshTools.test.d.ts +2 -0
- package/build/__tests__/unit/fastRefreshTools.test.d.ts.map +1 -0
- package/build/__tests__/unit/fastRefreshTools.test.js +112 -0
- package/build/__tests__/unit/fastRefreshTools.test.js.map +1 -0
- package/build/__tests__/unit/fingerprint.test.js +10 -0
- package/build/__tests__/unit/fingerprint.test.js.map +1 -1
- package/build/__tests__/unit/measureComponent.test.d.ts +2 -0
- package/build/__tests__/unit/measureComponent.test.d.ts.map +1 -0
- package/build/__tests__/unit/measureComponent.test.js +66 -0
- package/build/__tests__/unit/measureComponent.test.js.map +1 -0
- package/build/__tests__/unit/measureComponentTools.test.d.ts +2 -0
- package/build/__tests__/unit/measureComponentTools.test.d.ts.map +1 -0
- package/build/__tests__/unit/measureComponentTools.test.js +94 -0
- package/build/__tests__/unit/measureComponentTools.test.js.map +1 -0
- package/build/__tests__/unit/rnGlobalsBootstrap.test.d.ts +2 -0
- package/build/__tests__/unit/rnGlobalsBootstrap.test.d.ts.map +1 -0
- package/build/__tests__/unit/rnGlobalsBootstrap.test.js +29 -0
- package/build/__tests__/unit/rnGlobalsBootstrap.test.js.map +1 -0
- package/build/__tests__/unit/timeoutClamp.test.d.ts +2 -0
- package/build/__tests__/unit/timeoutClamp.test.d.ts.map +1 -0
- package/build/__tests__/unit/timeoutClamp.test.js +17 -0
- package/build/__tests__/unit/timeoutClamp.test.js.map +1 -0
- package/build/__tests__/unit/transportClassify.test.d.ts +2 -0
- package/build/__tests__/unit/transportClassify.test.d.ts.map +1 -0
- package/build/__tests__/unit/transportClassify.test.js +60 -0
- package/build/__tests__/unit/transportClassify.test.js.map +1 -0
- package/build/core/bundle.d.ts +1 -1
- package/build/core/bundle.d.ts.map +1 -1
- package/build/core/bundle.js +6 -10
- package/build/core/bundle.js.map +1 -1
- package/build/core/componentSearch.d.ts +3 -0
- package/build/core/componentSearch.d.ts.map +1 -1
- package/build/core/componentSearch.js +73 -8
- package/build/core/componentSearch.js.map +1 -1
- package/build/core/componentTree.d.ts +1 -0
- package/build/core/componentTree.d.ts.map +1 -1
- package/build/core/componentTree.js +2 -2
- package/build/core/componentTree.js.map +1 -1
- package/build/core/debugGlobals.d.ts +1 -0
- package/build/core/debugGlobals.d.ts.map +1 -1
- package/build/core/debugGlobals.js +45 -9
- package/build/core/debugGlobals.js.map +1 -1
- package/build/core/escapeNonAscii.d.ts +18 -0
- package/build/core/escapeNonAscii.d.ts.map +1 -0
- package/build/core/escapeNonAscii.js +352 -0
- package/build/core/escapeNonAscii.js.map +1 -0
- package/build/core/failureArtifact.d.ts +0 -2
- package/build/core/failureArtifact.d.ts.map +1 -1
- package/build/core/failureArtifact.js +0 -4
- package/build/core/failureArtifact.js.map +1 -1
- package/build/core/fastRefreshRecorder.d.ts +23 -0
- package/build/core/fastRefreshRecorder.d.ts.map +1 -0
- package/build/core/fastRefreshRecorder.js +83 -0
- package/build/core/fastRefreshRecorder.js.map +1 -0
- package/build/core/fastRefreshTools.d.ts +19 -0
- package/build/core/fastRefreshTools.d.ts.map +1 -0
- package/build/core/fastRefreshTools.js +71 -0
- package/build/core/fastRefreshTools.js.map +1 -0
- package/build/core/guides.d.ts.map +1 -1
- package/build/core/guides.js +2 -1
- package/build/core/guides.js.map +1 -1
- package/build/core/index.d.ts +2 -0
- package/build/core/index.d.ts.map +1 -1
- package/build/core/index.js +2 -0
- package/build/core/index.js.map +1 -1
- package/build/core/jsExecute.d.ts +34 -0
- package/build/core/jsExecute.d.ts.map +1 -1
- package/build/core/jsExecute.js +249 -23
- package/build/core/jsExecute.js.map +1 -1
- package/build/core/measureComponent.d.ts +19 -0
- package/build/core/measureComponent.d.ts.map +1 -0
- package/build/core/measureComponent.js +94 -0
- package/build/core/measureComponent.js.map +1 -0
- package/build/core/measureComponentTools.d.ts +6 -0
- package/build/core/measureComponentTools.d.ts.map +1 -0
- package/build/core/measureComponentTools.js +43 -0
- package/build/core/measureComponentTools.js.map +1 -0
- package/build/core/pressables.d.ts.map +1 -1
- package/build/core/pressables.js +43 -8
- package/build/core/pressables.js.map +1 -1
- package/build/core/rnGlobalsBootstrap.d.ts +16 -0
- package/build/core/rnGlobalsBootstrap.d.ts.map +1 -0
- package/build/core/rnGlobalsBootstrap.js +116 -0
- package/build/core/rnGlobalsBootstrap.js.map +1 -0
- package/build/core/screenLayout.d.ts +1 -0
- package/build/core/screenLayout.d.ts.map +1 -1
- package/build/core/screenLayout.js +4 -4
- package/build/core/screenLayout.js.map +1 -1
- package/build/core/state.d.ts +2 -2
- package/build/core/state.d.ts.map +1 -1
- package/build/core/state.js +10 -5
- package/build/core/state.js.map +1 -1
- package/build/core/telemetry.d.ts +23 -0
- package/build/core/telemetry.d.ts.map +1 -1
- package/build/core/telemetry.js +67 -0
- package/build/core/telemetry.js.map +1 -1
- package/build/core/types.d.ts +7 -0
- package/build/core/types.d.ts.map +1 -1
- package/build/pro/screenshot-diff.js +1 -1
- package/build/pro/screenshot-diff.js.map +1 -1
- package/build/pro/tap.d.ts +3 -0
- package/build/pro/tap.d.ts.map +1 -1
- package/build/pro/tap.js +97 -35
- package/build/pro/tap.js.map +1 -1
- package/build/tools/componentTools.d.ts.map +1 -1
- package/build/tools/componentTools.js +148 -87
- package/build/tools/componentTools.js.map +1 -1
- package/build/tools/connectionTools.d.ts.map +1 -1
- package/build/tools/connectionTools.js +5 -3
- package/build/tools/connectionTools.js.map +1 -1
- package/build/tools/executionTools.d.ts.map +1 -1
- package/build/tools/executionTools.js +85 -15
- package/build/tools/executionTools.js.map +1 -1
- package/build/tools/interactionTools.d.ts.map +1 -1
- package/build/tools/interactionTools.js +146 -2
- package/build/tools/interactionTools.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,6 +22,12 @@ ExecBro is the runtime bridge that gives your AI coding assistant live access to
|
|
|
22
22
|
|
|
23
23
|
Have an idea or found something that could be better? Head over to [GitHub Discussions](https://github.com/igorzheludkov/react-native-ai-devtools/discussions) to share feedback, request features, and vote on what gets built next.
|
|
24
24
|
|
|
25
|
+
## Pricing
|
|
26
|
+
|
|
27
|
+
ExecBro is and will remain free for typical workflows. A paid tier launches in summer 2026 with a single $9/month plan covering unlimited tool calls; the free tier will be capped at 300 tool calls / 30 days at that point. Everyone already using ExecBro before the announcement gets 3 months free of the paid tier — auto-applied via your installation ID, no action required.
|
|
28
|
+
|
|
29
|
+
Full details and exact dates will be published at [execbro.com/pricing](https://execbro.com/pricing) closer to launch. Until then, nothing changes for current users.
|
|
30
|
+
|
|
25
31
|
## Features
|
|
26
32
|
|
|
27
33
|
### Runtime Interaction
|
|
@@ -37,6 +43,7 @@ Have an idea or found something that could be better? Head over to [GitHub Discu
|
|
|
37
43
|
- **iOS Simulator** - Screenshots, app management, URL handling, boot/terminate (via simctl)
|
|
38
44
|
- **Android Devices** - Screenshots, app install/launch, package management (via ADB)
|
|
39
45
|
- **Unified Tap** - Single `tap` tool with automatic fallback chain: fiber tree → accessibility → OCR → coordinates. Auto-detects platform, accepts pixels from screenshots. Returns post-tap screenshot and verifies visual change by default
|
|
46
|
+
- **Unified Swipe** - Single `swipe` tool that auto-routes to iOS or Android based on the connected device. Accepts screenshot pixel coordinates and handles per-platform conversion. Essential for scrolling virtualized lists (FlatList/SectionList) where off-screen items aren't in the fiber tree. Platform-specific `ios_swipe` / `android_swipe` remain available as fallbacks
|
|
40
47
|
- **UI Automation** - Swipe, long press, key events, and text input on both platforms. On Bridgeless/Fabric apps, `clear_focused_input` and `dismiss_keyboard` operate on whatever has focus, and `ios_input_text` / `android_input_text` accept `replace:true` to overwrite pre-filled values — all three update React state through `onChangeText` so controlled components (Formik, react-hook-form, useState) stay consistent
|
|
41
48
|
- **Accessibility Inspection** - Query UI hierarchy to find elements by text, label, or resource ID
|
|
42
49
|
- **OCR Text Extraction** - Extract visible text with tap-ready coordinates via Google Cloud Vision (works on any screen content)
|
|
@@ -58,7 +65,7 @@ Have an idea or found something that could be better? Head over to [GitHub Discu
|
|
|
58
65
|
|
|
59
66
|
### Related
|
|
60
67
|
|
|
61
|
-
- **[execbro-runner](https://github.com/igorzheludkov/execbro-runner)**
|
|
68
|
+
- **[execbro-runner](https://github.com/igorzheludkov/execbro-runner)** _(early alpha, in active development)_ — queue-based autonomous task runner built on top of ExecBro. Drop in a markdown prompt and a background daemon spins up an isolated sandbox (git worktree + simulator/emulator + Metro), runs Claude Code headlessly, has the agent verify the change live on the device via ExecBro, and optionally pushes a branch with a PR URL. Fire-and-forget Claude Code runs for your React Native app.
|
|
62
69
|
|
|
63
70
|
## Setup
|
|
64
71
|
|
|
@@ -82,13 +89,13 @@ Or edit `~/.claude.json` (user) / `.mcp.json` (project) manually:
|
|
|
82
89
|
|
|
83
90
|
```json
|
|
84
91
|
{
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
92
|
+
"mcpServers": {
|
|
93
|
+
"execbro": {
|
|
94
|
+
"type": "stdio",
|
|
95
|
+
"command": "npx",
|
|
96
|
+
"args": ["-y", "react-native-ai-devtools@latest"]
|
|
97
|
+
}
|
|
90
98
|
}
|
|
91
|
-
}
|
|
92
99
|
}
|
|
93
100
|
```
|
|
94
101
|
|
|
@@ -101,12 +108,12 @@ Edit the config at:
|
|
|
101
108
|
|
|
102
109
|
```json
|
|
103
110
|
{
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
111
|
+
"mcpServers": {
|
|
112
|
+
"execbro": {
|
|
113
|
+
"command": "npx",
|
|
114
|
+
"args": ["-y", "react-native-ai-devtools@latest"]
|
|
115
|
+
}
|
|
108
116
|
}
|
|
109
|
-
}
|
|
110
117
|
}
|
|
111
118
|
```
|
|
112
119
|
|
|
@@ -132,12 +139,12 @@ args = ["-y", "react-native-ai-devtools@latest"]
|
|
|
132
139
|
|
|
133
140
|
```json
|
|
134
141
|
{
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
142
|
+
"mcpServers": {
|
|
143
|
+
"execbro": {
|
|
144
|
+
"command": "npx",
|
|
145
|
+
"args": ["-y", "react-native-ai-devtools@latest"]
|
|
146
|
+
}
|
|
139
147
|
}
|
|
140
|
-
}
|
|
141
148
|
}
|
|
142
149
|
```
|
|
143
150
|
|
|
@@ -147,13 +154,13 @@ Requires VS Code 1.102+ with Copilot ([docs](https://code.visualstudio.com/docs/
|
|
|
147
154
|
|
|
148
155
|
```json
|
|
149
156
|
{
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
157
|
+
"servers": {
|
|
158
|
+
"execbro": {
|
|
159
|
+
"type": "stdio",
|
|
160
|
+
"command": "npx",
|
|
161
|
+
"args": ["-y", "react-native-ai-devtools@latest"]
|
|
162
|
+
}
|
|
155
163
|
}
|
|
156
|
-
}
|
|
157
164
|
}
|
|
158
165
|
```
|
|
159
166
|
|
|
@@ -163,12 +170,12 @@ Requires VS Code 1.102+ with Copilot ([docs](https://code.visualstudio.com/docs/
|
|
|
163
170
|
|
|
164
171
|
```json
|
|
165
172
|
{
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
173
|
+
"mcpServers": {
|
|
174
|
+
"execbro": {
|
|
175
|
+
"command": "npx",
|
|
176
|
+
"args": ["-y", "react-native-ai-devtools@latest"]
|
|
177
|
+
}
|
|
170
178
|
}
|
|
171
|
-
}
|
|
172
179
|
}
|
|
173
180
|
```
|
|
174
181
|
|
|
@@ -178,13 +185,13 @@ Requires VS Code 1.102+ with Copilot ([docs](https://code.visualstudio.com/docs/
|
|
|
178
185
|
|
|
179
186
|
```json
|
|
180
187
|
{
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
188
|
+
"context_servers": {
|
|
189
|
+
"execbro": {
|
|
190
|
+
"command": "npx",
|
|
191
|
+
"args": ["-y", "react-native-ai-devtools@latest"],
|
|
192
|
+
"env": {}
|
|
193
|
+
}
|
|
186
194
|
}
|
|
187
|
-
}
|
|
188
195
|
}
|
|
189
196
|
```
|
|
190
197
|
|
|
@@ -194,12 +201,12 @@ Edit `~/.gemini/settings.json` (user) or `.gemini/settings.json` (project):
|
|
|
194
201
|
|
|
195
202
|
```json
|
|
196
203
|
{
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
204
|
+
"mcpServers": {
|
|
205
|
+
"execbro": {
|
|
206
|
+
"command": "npx",
|
|
207
|
+
"args": ["-y", "react-native-ai-devtools@latest"]
|
|
208
|
+
}
|
|
201
209
|
}
|
|
202
|
-
}
|
|
203
210
|
}
|
|
204
211
|
```
|
|
205
212
|
|
|
@@ -241,14 +248,14 @@ Opt in by setting `IOS_DRIVER=idb` in your MCP server configuration:
|
|
|
241
248
|
|
|
242
249
|
```json
|
|
243
250
|
{
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
251
|
+
"mcpServers": {
|
|
252
|
+
"execbro": {
|
|
253
|
+
"type": "stdio",
|
|
254
|
+
"command": "npx",
|
|
255
|
+
"args": ["-y", "react-native-ai-devtools@latest"],
|
|
256
|
+
"env": { "IOS_DRIVER": "idb" }
|
|
257
|
+
}
|
|
250
258
|
}
|
|
251
|
-
}
|
|
252
259
|
}
|
|
253
260
|
```
|
|
254
261
|
|
|
@@ -300,22 +307,22 @@ See the [full tool reference](docs/tools.md) for all tools with descriptions. Ke
|
|
|
300
307
|
|
|
301
308
|
1. Start your React Native app:
|
|
302
309
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
310
|
+
```bash
|
|
311
|
+
npm start
|
|
312
|
+
# or
|
|
313
|
+
expo start
|
|
314
|
+
```
|
|
308
315
|
|
|
309
316
|
2. In Claude Code, scan for Metro:
|
|
310
317
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
318
|
+
```
|
|
319
|
+
Use scan_metro to find and connect to Metro
|
|
320
|
+
```
|
|
314
321
|
|
|
315
322
|
3. Get logs:
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
323
|
+
```
|
|
324
|
+
Use get_logs to see recent console output
|
|
325
|
+
```
|
|
319
326
|
|
|
320
327
|
## Detailed Guides
|
|
321
328
|
|
|
@@ -346,8 +353,8 @@ See the [full tool reference](docs/tools.md) for all tools with descriptions. Ke
|
|
|
346
353
|
2. Connects to the main JS runtime via CDP (Chrome DevTools Protocol) WebSocket
|
|
347
354
|
3. Enables `Runtime.enable` to receive `Runtime.consoleAPICalled` events
|
|
348
355
|
4. Network capture via two paths:
|
|
349
|
-
|
|
350
|
-
|
|
356
|
+
- **With SDK**: Reads from the SDK's in-app buffer via `Runtime.evaluate` — captures all requests from startup with full headers and bodies, including cold-start events that CDP would miss
|
|
357
|
+
- **Without SDK**: Enables CDP `Network.enable` (on supported targets) or injects a JS fetch interceptor as fallback. On cold start, events emitted before the CDP connection is established are lost; subsequent reloads capture everything
|
|
351
358
|
5. Stores logs and network requests in circular buffers for retrieval
|
|
352
359
|
|
|
353
360
|
## Connection Management
|
|
@@ -453,14 +460,14 @@ To disable telemetry and auto-registration, add `RN_DEBUGGER_TELEMETRY` to the `
|
|
|
453
460
|
|
|
454
461
|
```json
|
|
455
462
|
{
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
463
|
+
"mcpServers": {
|
|
464
|
+
"execbro": {
|
|
465
|
+
"type": "stdio",
|
|
466
|
+
"command": "npx",
|
|
467
|
+
"args": ["-y", "react-native-ai-devtools@latest"],
|
|
468
|
+
"env": { "RN_DEBUGGER_TELEMETRY": "false" }
|
|
469
|
+
}
|
|
462
470
|
}
|
|
463
|
-
}
|
|
464
471
|
}
|
|
465
472
|
```
|
|
466
473
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-reconnect.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/integration/auto-reconnect.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { jest, describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from "@jest/globals";
|
|
2
|
+
import { connectToDevice } from "../../core/connection.js";
|
|
3
|
+
import { executeInApp } from "../../core/jsExecute.js";
|
|
4
|
+
import { connectedApps, pendingExecutions } from "../../core/state.js";
|
|
5
|
+
import { FakeCDPServer } from "../helpers/fake-cdp-server.js";
|
|
6
|
+
describe("auto-reconnect via CDP wrapper", () => {
|
|
7
|
+
let server;
|
|
8
|
+
let device;
|
|
9
|
+
beforeAll(() => {
|
|
10
|
+
jest.spyOn(console, "error").mockImplementation(() => { });
|
|
11
|
+
});
|
|
12
|
+
afterAll(() => {
|
|
13
|
+
jest.restoreAllMocks();
|
|
14
|
+
});
|
|
15
|
+
beforeEach(async () => {
|
|
16
|
+
for (const [key, app] of connectedApps.entries()) {
|
|
17
|
+
try {
|
|
18
|
+
app.ws.close();
|
|
19
|
+
}
|
|
20
|
+
catch { /* ignore */ }
|
|
21
|
+
connectedApps.delete(key);
|
|
22
|
+
}
|
|
23
|
+
pendingExecutions.clear();
|
|
24
|
+
server = new FakeCDPServer();
|
|
25
|
+
const port = await server.start();
|
|
26
|
+
device = {
|
|
27
|
+
id: "test-device",
|
|
28
|
+
title: "Hermes React Native",
|
|
29
|
+
description: "Test Device",
|
|
30
|
+
appId: "com.test.app",
|
|
31
|
+
type: "node",
|
|
32
|
+
webSocketDebuggerUrl: `${server.wsUrl}/inspector/device?page=1`,
|
|
33
|
+
deviceName: "Test",
|
|
34
|
+
};
|
|
35
|
+
await connectToDevice(device, port, {
|
|
36
|
+
reconnectionConfig: { enabled: false, maxAttempts: 0, initialDelayMs: 0, maxDelayMs: 0, backoffMultiplier: 1 },
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
afterEach(async () => {
|
|
40
|
+
const closePromises = [];
|
|
41
|
+
for (const [key, app] of connectedApps.entries()) {
|
|
42
|
+
closePromises.push(new Promise((resolve) => {
|
|
43
|
+
if (app.ws.readyState === app.ws.CLOSED) {
|
|
44
|
+
resolve();
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
app.ws.on("close", () => resolve());
|
|
48
|
+
try {
|
|
49
|
+
app.ws.close();
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
resolve();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}));
|
|
56
|
+
connectedApps.delete(key);
|
|
57
|
+
}
|
|
58
|
+
await Promise.all(closePromises);
|
|
59
|
+
pendingExecutions.clear();
|
|
60
|
+
await server.stop();
|
|
61
|
+
});
|
|
62
|
+
it("does NOT auto-retry on logical failure (ReferenceError)", async () => {
|
|
63
|
+
server.respondWithError("ReferenceError", "__FOO__ is not defined");
|
|
64
|
+
const result = await executeInApp("__FOO__", false, {
|
|
65
|
+
maxRetries: 0,
|
|
66
|
+
originatingToolName: "execute_in_app",
|
|
67
|
+
});
|
|
68
|
+
expect(result.success).toBe(false);
|
|
69
|
+
// Logical CDP exception — outer wrapper must NOT mark _meta.reconnected.
|
|
70
|
+
expect(result._meta?.reconnected).toBeFalsy();
|
|
71
|
+
expect(result.error).not.toMatch(/^reconnect/);
|
|
72
|
+
expect(result.error).toMatch(/ReferenceError/);
|
|
73
|
+
});
|
|
74
|
+
it("does NOT auto-retry on server-side timeoutMs (logical, not transport)", async () => {
|
|
75
|
+
server.respondWithTimeout(); // never replies
|
|
76
|
+
const result = await executeInApp("blockForever()", false, {
|
|
77
|
+
maxRetries: 0,
|
|
78
|
+
timeoutMs: 300,
|
|
79
|
+
originatingToolName: "execute_in_app",
|
|
80
|
+
});
|
|
81
|
+
expect(result.success).toBe(false);
|
|
82
|
+
expect(result.error).toMatch(/Timeout: Expression took too long/);
|
|
83
|
+
// Critical: a server-side timer hit is logical — no reconnect.
|
|
84
|
+
expect(result._meta?.reconnected).toBeFalsy();
|
|
85
|
+
expect(result.error).not.toMatch(/^reconnect/);
|
|
86
|
+
});
|
|
87
|
+
it("attempts reconnect on transport failure and surfaces _meta on the result", async () => {
|
|
88
|
+
// Force a transport-classified failure by closing the WebSocket before the call.
|
|
89
|
+
// executeInAppInner will return "WebSocket connection is not open." → classified as ws_closed.
|
|
90
|
+
const app = [...connectedApps.values()][0];
|
|
91
|
+
try {
|
|
92
|
+
app.ws.close();
|
|
93
|
+
}
|
|
94
|
+
catch { /* ignore */ }
|
|
95
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
96
|
+
const result = await executeInApp("doSomething()", false, {
|
|
97
|
+
maxRetries: 0,
|
|
98
|
+
autoReconnect: false, // disable inner reconnect so outer wrapper's path is exercised
|
|
99
|
+
originatingToolName: "execute_in_app",
|
|
100
|
+
});
|
|
101
|
+
expect(result.success).toBe(false);
|
|
102
|
+
// The outer wrapper triggered reconnect path — Metro discovery from the test process
|
|
103
|
+
// probes real ports (8081, 8082, 19000-19002). Either outcome is acceptable:
|
|
104
|
+
// - scan_failed → error starts "reconnect_attempted:"
|
|
105
|
+
// - retry_failed → error starts "reconnected_but_still_failed:"
|
|
106
|
+
// - success → result.success === true, _meta.reconnected === true
|
|
107
|
+
// What MUST hold: _meta exists and transportError captures the original message.
|
|
108
|
+
if (result.success) {
|
|
109
|
+
expect(result._meta?.reconnected).toBe(true);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
expect(result.error).toMatch(/^(reconnect_attempted:|reconnected_but_still_failed:)/);
|
|
113
|
+
expect(result._meta).toBeDefined();
|
|
114
|
+
expect(result._meta?.transportError).toMatch(/WebSocket connection is not open|No apps connected/);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
//# sourceMappingURL=auto-reconnect.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-reconnect.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/auto-reconnect.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACvG,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEvE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAE9D,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC5C,IAAI,MAAqB,CAAC;IAC1B,IAAI,MAAkB,CAAC;IAEvB,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,GAAG,EAAE;QACV,IAAI,CAAC,eAAe,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,KAAK,IAAI,EAAE;QAClB,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC;YAC/C,IAAI,CAAC;gBAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;YAC9C,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC;QACD,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAE1B,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QAElC,MAAM,GAAG;YACL,EAAE,EAAE,aAAa;YACjB,KAAK,EAAE,qBAAqB;YAC5B,WAAW,EAAE,aAAa;YAC1B,KAAK,EAAE,cAAc;YACrB,IAAI,EAAE,MAAM;YACZ,oBAAoB,EAAE,GAAG,MAAM,CAAC,KAAK,0BAA0B;YAC/D,UAAU,EAAE,MAAM;SACrB,CAAC;QAEF,MAAM,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE;YAChC,kBAAkB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE;SACjH,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,aAAa,GAAoB,EAAE,CAAC;QAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC;YAC/C,aAAa,CAAC,IAAI,CACd,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBAC1B,IAAI,GAAG,CAAC,EAAE,CAAC,UAAU,KAAK,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC;oBACtC,OAAO,EAAE,CAAC;gBACd,CAAC;qBAAM,CAAC;oBACJ,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;oBACpC,IAAI,CAAC;wBAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;oBAAC,CAAC;oBAAC,MAAM,CAAC;wBAAC,OAAO,EAAE,CAAC;oBAAC,CAAC;gBAChD,CAAC;YACL,CAAC,CAAC,CACL,CAAC;YACF,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC;QACD,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACjC,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAC1B,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,wBAAwB,CAAC,CAAC;QAEpE,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE;YAChD,UAAU,EAAE,CAAC;YACb,mBAAmB,EAAE,gBAAgB;SACxC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,yEAAyE;QACzE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,SAAS,EAAE,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACnF,MAAM,CAAC,kBAAkB,EAAE,CAAC,CAAC,gBAAgB;QAE7C,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,gBAAgB,EAAE,KAAK,EAAE;YACvD,UAAU,EAAE,CAAC;YACb,SAAS,EAAE,GAAG;YACd,mBAAmB,EAAE,gBAAgB;SACxC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;QAClE,+DAA+D;QAC/D,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,SAAS,EAAE,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;QACtF,iFAAiF;QACjF,+FAA+F;QAC/F,MAAM,GAAG,GAAG,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC;QAC5C,IAAI,CAAC;YAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAC9C,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAE5C,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,eAAe,EAAE,KAAK,EAAE;YACtD,UAAU,EAAE,CAAC;YACb,aAAa,EAAE,KAAK,EAAE,+DAA+D;YACrF,mBAAmB,EAAE,gBAAgB;SACxC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,qFAAqF;QACrF,6EAA6E;QAC7E,wDAAwD;QACxD,kEAAkE;QAClE,wEAAwE;QACxE,iFAAiF;QACjF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACJ,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,uDAAuD,CAAC,CAAC;YACtF,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;YACnC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,OAAO,CAAC,oDAAoD,CAAC,CAAC;QACvG,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -100,10 +100,18 @@ describe("executeInApp (integration)", () => {
|
|
|
100
100
|
expect(expr).toContain("var global");
|
|
101
101
|
expect(expr).toContain("__DEV__");
|
|
102
102
|
});
|
|
103
|
-
it("
|
|
103
|
+
it("auto-escapes emoji inside string literals before sending", async () => {
|
|
104
|
+
server.respondWithValue("\\u{1F600}", "string");
|
|
104
105
|
const result = await executeInApp("'\ud83d\ude00'", false, { timeoutMs: 5000 });
|
|
105
|
-
expect(result.success).toBe(
|
|
106
|
-
|
|
106
|
+
expect(result.success).toBe(true);
|
|
107
|
+
// The wire expression must be pure ASCII \u2014 emoji is rewritten to \u{...}
|
|
108
|
+
// escape sequences inside the string literal so Hermes can compile it.
|
|
109
|
+
const evalMsg = server.receivedMessages.find((m) => m.method === "Runtime.evaluate" &&
|
|
110
|
+
m.params.expression.includes("\\u{1F600}"));
|
|
111
|
+
expect(evalMsg).toBeDefined();
|
|
112
|
+
const expr = evalMsg.params.expression;
|
|
113
|
+
// The raw surrogate code units must NOT appear on the wire
|
|
114
|
+
expect(/[\uD800-\uDFFF]/.test(expr)).toBe(false);
|
|
107
115
|
});
|
|
108
116
|
it("handles timeout gracefully", async () => {
|
|
109
117
|
// Don't respond — causes timeout
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-in-app.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/execute-in-app.test.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"execute-in-app.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/execute-in-app.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACvG,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEvE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAE9D,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IACxC,IAAI,MAAqB,CAAC;IAC1B,IAAI,MAAkB,CAAC;IAEvB,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,GAAG,EAAE;QACV,IAAI,CAAC,eAAe,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,KAAK,IAAI,EAAE;QAClB,8BAA8B;QAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC;YAC/C,IAAI,CAAC;gBAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;YAC9C,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC;QACD,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAE1B,wBAAwB;QACxB,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QAElC,6CAA6C;QAC7C,MAAM,GAAG;YACL,EAAE,EAAE,aAAa;YACjB,KAAK,EAAE,qBAAqB;YAC5B,WAAW,EAAE,aAAa;YAC1B,KAAK,EAAE,cAAc;YACrB,IAAI,EAAE,MAAM;YACZ,oBAAoB,EAAE,GAAG,MAAM,CAAC,KAAK,0BAA0B;YAC/D,UAAU,EAAE,MAAM;SACrB,CAAC;QAEF,wDAAwD;QACxD,2DAA2D;QAC3D,MAAM,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE;YAChC,kBAAkB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE;SACjH,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACjB,kEAAkE;QAClE,MAAM,aAAa,GAAoB,EAAE,CAAC;QAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC;YAC/C,aAAa,CAAC,IAAI,CACd,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBAC1B,IAAI,GAAG,CAAC,EAAE,CAAC,UAAU,KAAK,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC;oBACtC,OAAO,EAAE,CAAC;gBACd,CAAC;qBAAM,CAAC;oBACJ,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;oBACpC,IAAI,CAAC;wBAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;oBAAC,CAAC;oBAAC,MAAM,CAAC;wBAAC,OAAO,EAAE,CAAC;oBAAC,CAAC;gBAChD,CAAC;YACL,CAAC,CAAC,CACL,CAAC;YACF,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC;QACD,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACjC,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAC1B,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,CAAC,gBAAgB,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QAClC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,CAAC,gBAAgB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,kBAAkB,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAO,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;QAC9D,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACzC,MAAM,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAC/C,CAAC,CAAC,MAAM,KAAK,kBAAkB;YAC9B,CAAC,CAAC,MAAiC,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CACtE,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAI,OAAQ,CAAC,MAAiC,CAAC,UAAU,CAAC;QACpE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,gBAAgB,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,8EAA8E;QAC9E,uEAAuE;QACvE,MAAM,OAAO,GAAG,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAC/C,CAAC,CAAC,MAAM,KAAK,kBAAkB;YAC9B,CAAC,CAAC,MAAiC,CAAC,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,CACzE,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAI,OAAQ,CAAC,MAAiC,CAAC,UAAU,CAAC;QACpE,2DAA2D;QAC3D,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QACxC,iCAAiC;QACjC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;QACtF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9C,CAAC,EAAE,KAAK,CAAC,CAAC;AACd,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"per-call-timeout.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/integration/per-call-timeout.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { jest, describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from "@jest/globals";
|
|
2
|
+
import { connectToDevice } from "../../core/connection.js";
|
|
3
|
+
import { executeInApp } from "../../core/jsExecute.js";
|
|
4
|
+
import { connectedApps, pendingExecutions } from "../../core/state.js";
|
|
5
|
+
import { FakeCDPServer } from "../helpers/fake-cdp-server.js";
|
|
6
|
+
describe("per-call timeoutMs", () => {
|
|
7
|
+
let server;
|
|
8
|
+
let device;
|
|
9
|
+
beforeAll(() => {
|
|
10
|
+
jest.spyOn(console, "error").mockImplementation(() => { });
|
|
11
|
+
});
|
|
12
|
+
afterAll(() => {
|
|
13
|
+
jest.restoreAllMocks();
|
|
14
|
+
});
|
|
15
|
+
beforeEach(async () => {
|
|
16
|
+
for (const [key, app] of connectedApps.entries()) {
|
|
17
|
+
try {
|
|
18
|
+
app.ws.close();
|
|
19
|
+
}
|
|
20
|
+
catch { /* ignore */ }
|
|
21
|
+
connectedApps.delete(key);
|
|
22
|
+
}
|
|
23
|
+
pendingExecutions.clear();
|
|
24
|
+
server = new FakeCDPServer();
|
|
25
|
+
const port = await server.start();
|
|
26
|
+
device = {
|
|
27
|
+
id: "test-device",
|
|
28
|
+
title: "Hermes React Native",
|
|
29
|
+
description: "Test Device",
|
|
30
|
+
appId: "com.test.app",
|
|
31
|
+
type: "node",
|
|
32
|
+
webSocketDebuggerUrl: `${server.wsUrl}/inspector/device?page=1`,
|
|
33
|
+
deviceName: "Test",
|
|
34
|
+
};
|
|
35
|
+
await connectToDevice(device, port, {
|
|
36
|
+
reconnectionConfig: { enabled: false, maxAttempts: 0, initialDelayMs: 0, maxDelayMs: 0, backoffMultiplier: 1 },
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
afterEach(async () => {
|
|
40
|
+
const closePromises = [];
|
|
41
|
+
for (const [key, app] of connectedApps.entries()) {
|
|
42
|
+
closePromises.push(new Promise((resolve) => {
|
|
43
|
+
if (app.ws.readyState === app.ws.CLOSED) {
|
|
44
|
+
resolve();
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
app.ws.on("close", () => resolve());
|
|
48
|
+
try {
|
|
49
|
+
app.ws.close();
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
resolve();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}));
|
|
56
|
+
connectedApps.delete(key);
|
|
57
|
+
}
|
|
58
|
+
await Promise.all(closePromises);
|
|
59
|
+
pendingExecutions.clear();
|
|
60
|
+
await server.stop();
|
|
61
|
+
});
|
|
62
|
+
it("forwards timeoutMs to Runtime.evaluate as the 'timeout' field", async () => {
|
|
63
|
+
server.respondWithValue(1, "number");
|
|
64
|
+
await executeInApp("doSomething()", false, { timeoutMs: 7777, originatingToolName: "execute_in_app" });
|
|
65
|
+
// Find the non-probe Runtime.evaluate call. The probe sends "1+1"; we sent "doSomething()" which
|
|
66
|
+
// becomes wrapped with the GLOBAL_POLYFILL.
|
|
67
|
+
const evalMsg = server.receivedMessages.find((m) => m.method === "Runtime.evaluate" && typeof m.params.expression === "string"
|
|
68
|
+
&& m.params.expression.includes("doSomething()"));
|
|
69
|
+
expect(evalMsg).toBeDefined();
|
|
70
|
+
expect(evalMsg.params.timeout).toBe(7777);
|
|
71
|
+
});
|
|
72
|
+
it("Promise.race fires the server-side timer at the configured timeout", async () => {
|
|
73
|
+
server.respondWithTimeout();
|
|
74
|
+
const start = Date.now();
|
|
75
|
+
const result = await executeInApp("blockForever()", false, {
|
|
76
|
+
maxRetries: 0,
|
|
77
|
+
timeoutMs: 500,
|
|
78
|
+
originatingToolName: "execute_in_app",
|
|
79
|
+
});
|
|
80
|
+
const elapsed = Date.now() - start;
|
|
81
|
+
expect(result.success).toBe(false);
|
|
82
|
+
expect(result.error).toMatch(/Timeout: Expression took too long/);
|
|
83
|
+
expect(elapsed).toBeGreaterThanOrEqual(450);
|
|
84
|
+
expect(elapsed).toBeLessThan(2500);
|
|
85
|
+
// Critical: a timeoutMs hit is logical, NOT transport — no reconnect marker.
|
|
86
|
+
expect(result._meta?.reconnected).toBeFalsy();
|
|
87
|
+
});
|
|
88
|
+
it("clamps timeoutMs > 120000 and reports the original in _meta", async () => {
|
|
89
|
+
server.respondWithValue(42, "number");
|
|
90
|
+
const result = await executeInApp("getAnswer()", false, {
|
|
91
|
+
timeoutMs: 3_000_000,
|
|
92
|
+
originatingToolName: "execute_in_app",
|
|
93
|
+
});
|
|
94
|
+
expect(result.success).toBe(true);
|
|
95
|
+
expect(result._meta?.timeoutClampedFrom).toBe(3_000_000);
|
|
96
|
+
// And the forwarded Hermes-side timeout must be the clamped value, not the raw input.
|
|
97
|
+
const evalMsg = server.receivedMessages.find((m) => m.method === "Runtime.evaluate" && typeof m.params.expression === "string"
|
|
98
|
+
&& m.params.expression.includes("getAnswer()"));
|
|
99
|
+
expect(evalMsg).toBeDefined();
|
|
100
|
+
expect(evalMsg.params.timeout).toBe(120000);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
//# sourceMappingURL=per-call-timeout.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"per-call-timeout.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/per-call-timeout.test.ts"],"names":[],"mappings":"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"}
|
package/build/__tests__/setup.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { afterEach } from "@jest/globals";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// even when a real Metro server is running during test execution.
|
|
6
|
-
afterEach(() => {
|
|
2
|
+
afterEach(async () => {
|
|
3
|
+
const { cancelAllReconnectionTimers, clearAllConnectionState } = await import("../core/connectionState.js");
|
|
4
|
+
const { pendingExecutions } = await import("../core/state.js");
|
|
7
5
|
cancelAllReconnectionTimers();
|
|
8
6
|
clearAllConnectionState();
|
|
9
7
|
pendingExecutions.clear();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/__tests__/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/__tests__/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,SAAS,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,GAAG,MAAM,MAAM,CACzE,4BAA4B,CAC/B,CAAC;IACF,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC/D,2BAA2B,EAAE,CAAC;IAC9B,uBAAuB,EAAE,CAAC;IAC1B,iBAAiB,CAAC,KAAK,EAAE,CAAC;AAC9B,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debugGlobals.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/unit/debugGlobals.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { describe, it, expect } from "@jest/globals";
|
|
2
|
+
import { buildListDebugGlobalsExpression } from "../../core/debugGlobals.js";
|
|
3
|
+
describe("buildListDebugGlobalsExpression", () => {
|
|
4
|
+
it("probes globalThis.__rn__ and surfaces its keys", () => {
|
|
5
|
+
const expr = buildListDebugGlobalsExpression();
|
|
6
|
+
expect(expr).toContain("__rn__");
|
|
7
|
+
expect(expr).toMatch(/rn\s*:/);
|
|
8
|
+
});
|
|
9
|
+
it("emits a hint that mentions globalThis.__rn__", () => {
|
|
10
|
+
const expr = buildListDebugGlobalsExpression();
|
|
11
|
+
expect(expr).toContain("globalThis.__rn__");
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=debugGlobals.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debugGlobals.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/debugGlobals.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AAE7E,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;IAC7C,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACtD,MAAM,IAAI,GAAG,+BAA+B,EAAE,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACpD,MAAM,IAAI,GAAG,+BAA+B,EAAE,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escapeNonAscii.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/unit/escapeNonAscii.test.ts"],"names":[],"mappings":""}
|