react-native-ai-debugger 1.0.46 → 1.1.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/README.md +61 -89
- package/build/__tests__/unit/tap.test.d.ts +2 -0
- package/build/__tests__/unit/tap.test.d.ts.map +1 -0
- package/build/__tests__/unit/tap.test.js +155 -0
- package/build/__tests__/unit/tap.test.js.map +1 -0
- package/build/core/connection.d.ts +2 -1
- package/build/core/connection.d.ts.map +1 -1
- package/build/core/connection.js +204 -27
- package/build/core/connection.js.map +1 -1
- package/build/core/guides.js +6 -6
- package/build/core/tap.d.ts +90 -0
- package/build/core/tap.d.ts.map +1 -0
- package/build/core/tap.js +485 -0
- package/build/core/tap.js.map +1 -0
- package/build/core/types.d.ts +6 -0
- package/build/core/types.d.ts.map +1 -1
- package/build/index.js +67 -149
- package/build/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,9 +18,9 @@ An MCP (Model Context Protocol) server for AI-powered React Native debugging. En
|
|
|
18
18
|
|
|
19
19
|
- **iOS Simulator** - Screenshots, app management, URL handling, boot/terminate (via simctl)
|
|
20
20
|
- **Android Devices** - Screenshots, app install/launch, package management (via ADB)
|
|
21
|
-
- **
|
|
21
|
+
- **Unified Tap** - Single `tap` tool with automatic fallback chain: fiber tree → accessibility → OCR → coordinates. Auto-detects platform, accepts pixels from screenshots
|
|
22
|
+
- **UI Automation** - Swipe, long press, text input, and key events on both platforms
|
|
22
23
|
- **Accessibility Inspection** - Query UI hierarchy to find elements by text, label, or resource ID
|
|
23
|
-
- **Element-Based Interaction** - Tap/wait for elements by text without screenshots (faster, cheaper)
|
|
24
24
|
- **OCR Text Extraction** - Extract visible text with tap-ready coordinates (works on any screen content)
|
|
25
25
|
|
|
26
26
|
### Under the Hood
|
|
@@ -248,8 +248,8 @@ Style: { borderRadius: 15, overflow: "hidden" }
|
|
|
248
248
|
# 1. Enable the inspector overlay
|
|
249
249
|
toggle_element_inspector()
|
|
250
250
|
|
|
251
|
-
# 2. Tap to select element
|
|
252
|
-
|
|
251
|
+
# 2. Tap to select element
|
|
252
|
+
tap with x=630 y=1200 # pixel coordinates from screenshot
|
|
253
253
|
|
|
254
254
|
# 3. Read the selection
|
|
255
255
|
get_inspector_selection()
|
|
@@ -260,6 +260,22 @@ toggle_element_inspector()
|
|
|
260
260
|
|
|
261
261
|
**Token Efficiency**: Returns ~0.2-0.5KB vs 15-25KB for full component tree. Works on all React Native versions including Fabric/New Architecture.
|
|
262
262
|
|
|
263
|
+
### UI Interaction (Cross-Platform)
|
|
264
|
+
|
|
265
|
+
| Tool | Description |
|
|
266
|
+
| ---------------- | ------------------------------------------------------------------------ |
|
|
267
|
+
| `tap` | **Unified tap** — auto-detects platform, tries fiber tree → accessibility → OCR → coordinates. Accepts text, testID, component name, or pixel coordinates from screenshots |
|
|
268
|
+
| `ocr_screenshot` | Extract all visible text with tap-ready coordinates (works on iOS/Android) |
|
|
269
|
+
|
|
270
|
+
**Examples:**
|
|
271
|
+
```
|
|
272
|
+
tap with text="Submit" # Finds and taps by visible text
|
|
273
|
+
tap with testID="login-btn" # Finds by testID prop
|
|
274
|
+
tap with component="HamburgerIcon" # Finds by React component name
|
|
275
|
+
tap with x=300 y=600 # Taps at pixel coordinates (auto-converts)
|
|
276
|
+
tap with text="Menu" strategy="ocr" # Forces OCR strategy only
|
|
277
|
+
```
|
|
278
|
+
|
|
263
279
|
### Android (ADB)
|
|
264
280
|
|
|
265
281
|
| Tool | Description |
|
|
@@ -269,7 +285,6 @@ toggle_element_inspector()
|
|
|
269
285
|
| `android_install_app` | Install an APK on an Android device/emulator |
|
|
270
286
|
| `android_launch_app` | Launch an app by package name |
|
|
271
287
|
| `android_list_packages` | List installed packages (with optional filter) |
|
|
272
|
-
| `android_tap` | Tap at specific coordinates on screen |
|
|
273
288
|
| `android_long_press` | Long press at specific coordinates |
|
|
274
289
|
| `android_swipe` | Swipe from one point to another |
|
|
275
290
|
| `android_input_text` | Type text at current focus point |
|
|
@@ -277,7 +292,6 @@ toggle_element_inspector()
|
|
|
277
292
|
| `android_get_screen_size` | Get device screen resolution |
|
|
278
293
|
| `android_describe_all` | Get full UI accessibility tree via uiautomator |
|
|
279
294
|
| `android_describe_point` | Get UI element info at specific coordinates |
|
|
280
|
-
| `android_tap_element` | Tap element by text/contentDesc/resourceId |
|
|
281
295
|
| `android_find_element` | Find element by text/contentDesc/resourceId (no screenshot) |
|
|
282
296
|
| `android_wait_for_element` | Wait for element to appear (useful for screen transitions) |
|
|
283
297
|
|
|
@@ -292,8 +306,6 @@ toggle_element_inspector()
|
|
|
292
306
|
| `ios_open_url` | Open a URL (deep links or web URLs) |
|
|
293
307
|
| `ios_terminate_app` | Terminate a running app |
|
|
294
308
|
| `ios_boot_simulator` | Boot a simulator by UDID |
|
|
295
|
-
| `ios_tap` | Tap at coordinates (requires IDB) |
|
|
296
|
-
| `ios_tap_element` | Tap element by accessibility label (requires IDB) |
|
|
297
309
|
| `ios_swipe` | Swipe gesture (requires IDB) |
|
|
298
310
|
| `ios_input_text` | Type text into active field (requires IDB) |
|
|
299
311
|
| `ios_button` | Press hardware button: HOME, LOCK, SIRI (requires IDB) |
|
|
@@ -304,12 +316,6 @@ toggle_element_inspector()
|
|
|
304
316
|
| `ios_find_element` | Find element by label/value (requires IDB, no screenshot) |
|
|
305
317
|
| `ios_wait_for_element` | Wait for element to appear (requires IDB) |
|
|
306
318
|
|
|
307
|
-
### OCR (Cross-Platform)
|
|
308
|
-
|
|
309
|
-
| Tool | Description |
|
|
310
|
-
| ---------------- | ------------------------------------------------------------------------ |
|
|
311
|
-
| `ocr_screenshot` | Extract all visible text with tap-ready coordinates (works on iOS/Android) |
|
|
312
|
-
|
|
313
319
|
## Usage
|
|
314
320
|
|
|
315
321
|
1. Start your React Native app:
|
|
@@ -913,10 +919,10 @@ Take a screenshot:
|
|
|
913
919
|
android_screenshot
|
|
914
920
|
```
|
|
915
921
|
|
|
916
|
-
Tap on screen
|
|
922
|
+
Tap on screen:
|
|
917
923
|
|
|
918
924
|
```
|
|
919
|
-
|
|
925
|
+
tap with x=540 y=960
|
|
920
926
|
```
|
|
921
927
|
|
|
922
928
|
Swipe gesture:
|
|
@@ -928,7 +934,7 @@ android_swipe with startX=540 startY=1500 endX=540 endY=500
|
|
|
928
934
|
Type text (tap input field first):
|
|
929
935
|
|
|
930
936
|
```
|
|
931
|
-
|
|
937
|
+
tap with x=540 y=400
|
|
932
938
|
android_input_text with text="hello@example.com"
|
|
933
939
|
```
|
|
934
940
|
|
|
@@ -972,92 +978,58 @@ Open a deep link:
|
|
|
972
978
|
ios_open_url with url="myapp://settings"
|
|
973
979
|
```
|
|
974
980
|
|
|
975
|
-
##
|
|
976
|
-
|
|
977
|
-
For action triggering without layout debugging, use element-based tools instead of screenshots. This is **2-3x faster** and uses fewer tokens.
|
|
978
|
-
|
|
979
|
-
### Android - Find and Tap by Text
|
|
981
|
+
## UI Interaction
|
|
980
982
|
|
|
981
|
-
|
|
982
|
-
# Wait for screen to load
|
|
983
|
-
android_wait_for_element with text="Login"
|
|
983
|
+
### Unified `tap` Tool (Recommended)
|
|
984
984
|
|
|
985
|
-
|
|
986
|
-
android_find_element with textContains="submit"
|
|
985
|
+
The `tap` tool is the simplest way to interact with UI elements. It automatically tries multiple strategies and handles platform detection and coordinate conversion:
|
|
987
986
|
|
|
988
|
-
# Tap the element (use coordinates from find_element)
|
|
989
|
-
android_tap with x=540 y=960
|
|
990
987
|
```
|
|
988
|
+
# By visible text — tries fiber tree, accessibility, then OCR
|
|
989
|
+
tap with text="Submit"
|
|
991
990
|
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
- `textContains` - partial text (case-insensitive)
|
|
995
|
-
- `contentDesc` - accessibility content description
|
|
996
|
-
- `contentDescContains` - partial content description
|
|
997
|
-
- `resourceId` - resource ID (e.g., "button" or "com.app:id/button")
|
|
991
|
+
# By testID prop
|
|
992
|
+
tap with testID="login-btn"
|
|
998
993
|
|
|
999
|
-
|
|
994
|
+
# By React component name (fiber tree only)
|
|
995
|
+
tap with component="HamburgerIcon"
|
|
1000
996
|
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
brew install idb-companion
|
|
1004
|
-
```
|
|
997
|
+
# By pixel coordinates from screenshot (auto-converts to points on iOS)
|
|
998
|
+
tap with x=300 y=600
|
|
1005
999
|
|
|
1000
|
+
# Force a specific strategy
|
|
1001
|
+
tap with text="Menu" strategy="ocr"
|
|
1006
1002
|
```
|
|
1007
|
-
# Wait for element
|
|
1008
|
-
ios_wait_for_element with label="Sign In"
|
|
1009
1003
|
|
|
1010
|
-
|
|
1011
|
-
ios_find_element with labelContains="welcome"
|
|
1012
|
-
```
|
|
1004
|
+
**Fallback chain:** fiber tree (direct `onPress`) → accessibility tree → OCR → error with suggestion.
|
|
1013
1005
|
|
|
1014
|
-
|
|
1015
|
-
- `label` - exact accessibility label
|
|
1016
|
-
- `labelContains` - partial label (case-insensitive)
|
|
1017
|
-
- `value` - accessibility value
|
|
1018
|
-
- `valueContains` - partial value
|
|
1019
|
-
- `type` - element type (e.g., "Button", "TextField")
|
|
1006
|
+
On failure, the response includes an actionable `suggestion` telling the agent exactly what to try next.
|
|
1020
1007
|
|
|
1021
|
-
###
|
|
1008
|
+
### Platform-Specific Tools
|
|
1022
1009
|
|
|
1023
|
-
|
|
1010
|
+
For gestures beyond tapping, use platform-specific tools:
|
|
1024
1011
|
|
|
1025
1012
|
```
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1013
|
+
# Swipe
|
|
1014
|
+
ios_swipe with startX=200 startY=400 endX=200 endY=100
|
|
1015
|
+
android_swipe with startX=540 startY=1500 endX=540 endY=500
|
|
1029
1016
|
|
|
1030
|
-
|
|
1017
|
+
# Text input (tap input field first)
|
|
1018
|
+
tap with text="Email"
|
|
1019
|
+
ios_input_text with text="hello@example.com"
|
|
1031
1020
|
|
|
1032
|
-
|
|
1021
|
+
# Key events
|
|
1022
|
+
android_key_event with key="BACK"
|
|
1023
|
+
ios_button with button="HOME"
|
|
1024
|
+
```
|
|
1033
1025
|
|
|
1034
|
-
|
|
1035
|
-
2. **Find target** → Use `find_element` to get tap coordinates
|
|
1036
|
-
3. **Tap** → Use `tap` with coordinates from step 2
|
|
1037
|
-
4. **Fallback** → If element not in accessibility tree, use `screenshot`
|
|
1026
|
+
### Wait for Screen Transitions
|
|
1038
1027
|
|
|
1039
1028
|
```
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
android_find_element with text="Submit" # Step 2: Find (returns center coordinates)
|
|
1043
|
-
android_tap with x=540 y=1200 # Step 3: Tap (use returned coordinates)
|
|
1029
|
+
android_wait_for_element with text="Dashboard" timeoutMs=15000
|
|
1030
|
+
ios_wait_for_element with label="Home" timeoutMs=10000
|
|
1044
1031
|
```
|
|
1045
1032
|
|
|
1046
|
-
**Why this order?**
|
|
1047
|
-
- `find_element`: ~100-200 tokens, <100ms
|
|
1048
|
-
- `screenshot`: ~400-500 tokens, 200-500ms
|
|
1049
|
-
|
|
1050
|
-
### When to Use Screenshots vs Element Tools
|
|
1051
|
-
|
|
1052
|
-
| Use Case | Recommended Tool |
|
|
1053
|
-
|----------|------------------|
|
|
1054
|
-
| Trigger button taps | `find_element` + `tap` |
|
|
1055
|
-
| Wait for screen load | `wait_for_element` |
|
|
1056
|
-
| Navigate through flow | `wait_for_element` + `tap` |
|
|
1057
|
-
| Debug layout issues | `screenshot` |
|
|
1058
|
-
| Verify visual appearance | `screenshot` |
|
|
1059
|
-
| Find elements without labels | `screenshot` |
|
|
1060
|
-
|
|
1061
1033
|
## OCR Text Extraction
|
|
1062
1034
|
|
|
1063
1035
|
The `ocr_screenshot` tool extracts all visible text from a screenshot with tap-ready coordinates. This is useful when accessibility labels are missing or when you need to find text that isn't exposed in the accessibility tree.
|
|
@@ -1094,7 +1066,7 @@ Returns all visible text with tap-ready coordinates:
|
|
|
1094
1066
|
Then tap the element:
|
|
1095
1067
|
|
|
1096
1068
|
```
|
|
1097
|
-
|
|
1069
|
+
tap with x=187 y=420
|
|
1098
1070
|
```
|
|
1099
1071
|
|
|
1100
1072
|
### OCR Engine
|
|
@@ -1147,19 +1119,19 @@ See [EasyOCR supported languages](https://www.jaided.ai/easyocr/) for the full l
|
|
|
1147
1119
|
|
|
1148
1120
|
### Recommended Workflow
|
|
1149
1121
|
|
|
1150
|
-
1. **
|
|
1151
|
-
2. **Fall back to OCR** - When
|
|
1122
|
+
1. **Use unified `tap`** - Handles fallback chain automatically
|
|
1123
|
+
2. **Fall back to OCR** - When `tap` suggests using coordinates
|
|
1152
1124
|
3. **Use screenshot** - For visual debugging or layout verification
|
|
1153
1125
|
|
|
1154
1126
|
```
|
|
1155
|
-
#
|
|
1156
|
-
|
|
1127
|
+
# Simplest approach — tap handles everything
|
|
1128
|
+
tap with text="Submit"
|
|
1157
1129
|
|
|
1158
|
-
#
|
|
1130
|
+
# If tap fails, use OCR to find coordinates
|
|
1159
1131
|
ocr_screenshot with platform="android"
|
|
1160
1132
|
|
|
1161
|
-
#
|
|
1162
|
-
|
|
1133
|
+
# Then tap using coordinates from OCR result
|
|
1134
|
+
tap with x=540 y=1200
|
|
1163
1135
|
```
|
|
1164
1136
|
|
|
1165
1137
|
## Supported React Native Versions
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tap.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/unit/tap.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// src/__tests__/unit/tap.test.ts
|
|
2
|
+
import { describe, it, expect } from "@jest/globals";
|
|
3
|
+
import { buildQuery, getAvailableStrategies, isNonAscii, convertPixelsToPoints, formatTapSuccess, formatTapFailure, } from "../../core/tap.js";
|
|
4
|
+
describe("ConnectedApp type", () => {
|
|
5
|
+
it("accepts platform and lastScreenshot fields", () => {
|
|
6
|
+
const app = {
|
|
7
|
+
ws: {},
|
|
8
|
+
deviceInfo: {
|
|
9
|
+
id: "test",
|
|
10
|
+
title: "Hermes React Native",
|
|
11
|
+
description: "",
|
|
12
|
+
appId: "com.test",
|
|
13
|
+
type: "node",
|
|
14
|
+
webSocketDebuggerUrl: "ws://localhost:8081",
|
|
15
|
+
deviceName: "iPhone 16",
|
|
16
|
+
},
|
|
17
|
+
port: 8081,
|
|
18
|
+
platform: "ios",
|
|
19
|
+
lastScreenshot: {
|
|
20
|
+
originalWidth: 1179,
|
|
21
|
+
originalHeight: 2556,
|
|
22
|
+
scaleFactor: 1,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
expect(app.platform).toBe("ios");
|
|
26
|
+
expect(app.lastScreenshot?.originalWidth).toBe(1179);
|
|
27
|
+
});
|
|
28
|
+
it("allows lastScreenshot to be undefined", () => {
|
|
29
|
+
const app = {
|
|
30
|
+
ws: {},
|
|
31
|
+
deviceInfo: {
|
|
32
|
+
id: "test",
|
|
33
|
+
title: "Hermes React Native",
|
|
34
|
+
description: "",
|
|
35
|
+
appId: "com.test",
|
|
36
|
+
type: "node",
|
|
37
|
+
webSocketDebuggerUrl: "ws://localhost:8081",
|
|
38
|
+
deviceName: "iPhone 16",
|
|
39
|
+
},
|
|
40
|
+
port: 8081,
|
|
41
|
+
platform: "ios",
|
|
42
|
+
};
|
|
43
|
+
expect(app.lastScreenshot).toBeUndefined();
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
describe("buildQuery", () => {
|
|
47
|
+
it("builds query from text param", () => {
|
|
48
|
+
const q = buildQuery({ text: "Submit" });
|
|
49
|
+
expect(q).toEqual({ text: "Submit" });
|
|
50
|
+
});
|
|
51
|
+
it("builds query from coordinates", () => {
|
|
52
|
+
const q = buildQuery({ x: 300, y: 600 });
|
|
53
|
+
expect(q).toEqual({ x: 300, y: 600 });
|
|
54
|
+
});
|
|
55
|
+
it("builds query from multiple params", () => {
|
|
56
|
+
const q = buildQuery({ text: "Submit", testID: "btn" });
|
|
57
|
+
expect(q).toEqual({ text: "Submit", testID: "btn" });
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
describe("isNonAscii", () => {
|
|
61
|
+
it("returns false for ASCII text", () => {
|
|
62
|
+
expect(isNonAscii("Submit")).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
it("returns true for Cyrillic", () => {
|
|
65
|
+
expect(isNonAscii("Отправить")).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
it("returns true for emoji", () => {
|
|
68
|
+
expect(isNonAscii("🔥")).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
describe("getAvailableStrategies", () => {
|
|
72
|
+
it("returns all strategies for text query", () => {
|
|
73
|
+
expect(getAvailableStrategies({ text: "Submit" }, "auto")).toEqual(["fiber", "accessibility", "ocr"]);
|
|
74
|
+
});
|
|
75
|
+
it("skips fiber for non-ASCII text", () => {
|
|
76
|
+
expect(getAvailableStrategies({ text: "Отправить" }, "auto")).toEqual(["accessibility", "ocr"]);
|
|
77
|
+
});
|
|
78
|
+
it("returns fiber+accessibility for testID", () => {
|
|
79
|
+
expect(getAvailableStrategies({ testID: "btn" }, "auto")).toEqual(["fiber", "accessibility"]);
|
|
80
|
+
});
|
|
81
|
+
it("returns only fiber for component", () => {
|
|
82
|
+
expect(getAvailableStrategies({ component: "Button" }, "auto")).toEqual(["fiber"]);
|
|
83
|
+
});
|
|
84
|
+
it("returns coordinate for x,y", () => {
|
|
85
|
+
expect(getAvailableStrategies({ x: 100, y: 200 }, "auto")).toEqual(["coordinate"]);
|
|
86
|
+
});
|
|
87
|
+
it("returns single strategy when explicitly set", () => {
|
|
88
|
+
expect(getAvailableStrategies({ text: "Submit" }, "ocr")).toEqual(["ocr"]);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
describe("convertPixelsToPoints", () => {
|
|
92
|
+
it("divides by pixel ratio for iOS", () => {
|
|
93
|
+
expect(convertPixelsToPoints(300, 600, "ios", 3)).toEqual({ x: 100, y: 200 });
|
|
94
|
+
});
|
|
95
|
+
it("passes through for Android", () => {
|
|
96
|
+
expect(convertPixelsToPoints(300, 600, "android", 3)).toEqual({ x: 300, y: 600 });
|
|
97
|
+
});
|
|
98
|
+
it("applies scaleFactor before conversion", () => {
|
|
99
|
+
expect(convertPixelsToPoints(150, 300, "ios", 3, 2)).toEqual({ x: 100, y: 200 });
|
|
100
|
+
});
|
|
101
|
+
it("rounds to integers", () => {
|
|
102
|
+
expect(convertPixelsToPoints(301, 599, "ios", 3)).toEqual({ x: 100, y: 200 });
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
describe("formatTapSuccess", () => {
|
|
106
|
+
it("returns minimal success response", () => {
|
|
107
|
+
const result = formatTapSuccess({
|
|
108
|
+
method: "fiber",
|
|
109
|
+
query: { text: "Submit" },
|
|
110
|
+
pressed: "PrimaryButton",
|
|
111
|
+
text: "Submit",
|
|
112
|
+
screen: "LoginScreen",
|
|
113
|
+
path: "LoginScreen > Form > PrimaryButton",
|
|
114
|
+
});
|
|
115
|
+
expect(result.success).toBe(true);
|
|
116
|
+
expect(result.method).toBe("fiber");
|
|
117
|
+
expect(result.query).toEqual({ text: "Submit" });
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
describe("formatTapFailure", () => {
|
|
121
|
+
it("includes attempted strategies and suggestion", () => {
|
|
122
|
+
const result = formatTapFailure({
|
|
123
|
+
query: { text: "hamburger" },
|
|
124
|
+
screen: "HomeScreen",
|
|
125
|
+
attempted: [{ strategy: "fiber", reason: "No match" }],
|
|
126
|
+
suggestion: "Use screenshot",
|
|
127
|
+
});
|
|
128
|
+
expect(result.success).toBe(false);
|
|
129
|
+
expect(result.attempted).toHaveLength(1);
|
|
130
|
+
expect(result.suggestion).toBe("Use screenshot");
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
describe("tap orchestrator", () => {
|
|
134
|
+
it("returns error when no app is connected", async () => {
|
|
135
|
+
const { tap } = await import("../../core/tap.js");
|
|
136
|
+
const { connectedApps } = await import("../../core/state.js");
|
|
137
|
+
connectedApps.clear();
|
|
138
|
+
const result = await tap({ text: "Submit" });
|
|
139
|
+
expect(result.success).toBe(false);
|
|
140
|
+
expect(result.error).toContain("No connected app");
|
|
141
|
+
});
|
|
142
|
+
it("validates that at least one search param is provided", async () => {
|
|
143
|
+
const { tap } = await import("../../core/tap.js");
|
|
144
|
+
const result = await tap({});
|
|
145
|
+
expect(result.success).toBe(false);
|
|
146
|
+
expect(result.error).toContain("Must provide");
|
|
147
|
+
});
|
|
148
|
+
it("validates x and y are both provided for coordinate tap", async () => {
|
|
149
|
+
const { tap } = await import("../../core/tap.js");
|
|
150
|
+
const result = await tap({ x: 100 });
|
|
151
|
+
expect(result.success).toBe(false);
|
|
152
|
+
expect(result.error).toContain("Both x and y");
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
//# sourceMappingURL=tap.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tap.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/tap.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import WebSocket from "ws";
|
|
1
2
|
import { DeviceInfo, RemoteObject, ConnectedApp, ConnectOptions, EnsureConnectionResult, ConnectionCheckResult } from "./types.js";
|
|
2
3
|
export declare function formatRemoteObject(result: RemoteObject): string;
|
|
3
|
-
export declare function handleCDPMessage(message: Record<string, unknown>, _device: DeviceInfo): void;
|
|
4
|
+
export declare function handleCDPMessage(message: Record<string, unknown>, _device: DeviceInfo, ws?: WebSocket): void;
|
|
4
5
|
export declare function connectToDevice(device: DeviceInfo, port: number, options?: ConnectOptions): Promise<string>;
|
|
5
6
|
export declare function getConnectedApps(): Array<{
|
|
6
7
|
key: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/core/connection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/core/connection.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAoB,YAAY,EAAkB,cAAc,EAAsB,sBAAsB,EAAmB,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAsD1M,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA4B/D;AAiRD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,SAAS,GAAG,IAAI,CAgP5G;AAGD,wBAAsB,eAAe,CACjC,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,cAAmB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAgMjB;AAyED,wBAAgB,gBAAgB,IAAI,KAAK,CAAC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,YAAY,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;CACxB,CAAC,CAMD;AAGD,wBAAgB,oBAAoB,IAAI,YAAY,GAAG,IAAI,CAW1D;AAGD,wBAAgB,eAAe,IAAI,OAAO,CAOzC;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CA4C7E;AAUD;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,GAAE;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;CACrB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CA6IvC;AAED,MAAM,WAAW,uBAAuB;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,IAAI,GAAG,eAAe,GAAG,eAAe,GAAG,aAAa,GAAG,gBAAgB,CAAC;CACvF;AAED,wBAAgB,0BAA0B,IAAI,uBAAuB,CAyBpE;AAED,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAiC/E"}
|