@qontinui/ui-bridge-native 0.1.2
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 +244 -0
- package/dist/control/index.d.mts +94 -0
- package/dist/control/index.d.ts +94 -0
- package/dist/control/index.js +448 -0
- package/dist/control/index.js.map +1 -0
- package/dist/control/index.mjs +445 -0
- package/dist/control/index.mjs.map +1 -0
- package/dist/core/index.d.mts +46 -0
- package/dist/core/index.d.ts +46 -0
- package/dist/core/index.js +511 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/index.mjs +500 -0
- package/dist/core/index.mjs.map +1 -0
- package/dist/debug/index.d.mts +47 -0
- package/dist/debug/index.d.ts +47 -0
- package/dist/debug/index.js +408 -0
- package/dist/debug/index.js.map +1 -0
- package/dist/debug/index.mjs +406 -0
- package/dist/debug/index.mjs.map +1 -0
- package/dist/design/index.d.mts +63 -0
- package/dist/design/index.d.ts +63 -0
- package/dist/design/index.js +249 -0
- package/dist/design/index.js.map +1 -0
- package/dist/design/index.mjs +244 -0
- package/dist/design/index.mjs.map +1 -0
- package/dist/design-types-BHr6Q1FX.d.mts +205 -0
- package/dist/design-types-BHr6Q1FX.d.ts +205 -0
- package/dist/index.d.mts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +2882 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2849 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react/index.d.mts +70 -0
- package/dist/react/index.d.ts +70 -0
- package/dist/react/index.js +1446 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/index.mjs +1434 -0
- package/dist/react/index.mjs.map +1 -0
- package/dist/registry-C_35zBrv.d.ts +182 -0
- package/dist/registry-D9J7IVo1.d.mts +182 -0
- package/dist/server/index.d.mts +275 -0
- package/dist/server/index.d.ts +275 -0
- package/dist/server/index.js +1018 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/index.mjs +1012 -0
- package/dist/server/index.mjs.map +1 -0
- package/dist/types-BgZTILOS.d.mts +177 -0
- package/dist/types-D27YUSIk.d.ts +177 -0
- package/dist/types-DM6yMpW8.d.mts +373 -0
- package/dist/types-DM6yMpW8.d.ts +373 -0
- package/dist/useUIBridge-B3cJtaYG.d.mts +455 -0
- package/dist/useUIBridge-DBVW0OSR.d.ts +455 -0
- package/package.json +93 -0
package/README.md
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# ui-bridge-native
|
|
2
|
+
|
|
3
|
+
UI Bridge framework for React Native applications. Enables AI-driven UI automation and testing for mobile apps.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install ui-bridge-native
|
|
9
|
+
# or
|
|
10
|
+
yarn add ui-bridge-native
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### 1. Wrap your app in the provider
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
// app/_layout.tsx or App.tsx
|
|
19
|
+
import { UIBridgeNativeProvider } from 'ui-bridge-native';
|
|
20
|
+
|
|
21
|
+
export default function RootLayout() {
|
|
22
|
+
return (
|
|
23
|
+
<UIBridgeNativeProvider
|
|
24
|
+
features={{ server: __DEV__, debug: __DEV__ }}
|
|
25
|
+
config={{ serverPort: 8087 }}
|
|
26
|
+
>
|
|
27
|
+
<Stack>{/* Your app content */}</Stack>
|
|
28
|
+
</UIBridgeNativeProvider>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. Use hooks in your components
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import { useUIElement } from 'ui-bridge-native';
|
|
37
|
+
|
|
38
|
+
function SubmitButton({ onPress }) {
|
|
39
|
+
const { ref, onLayout, bridgeProps } = useUIElement({
|
|
40
|
+
id: 'submit-button',
|
|
41
|
+
type: 'button',
|
|
42
|
+
label: 'Submit Form',
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<Pressable ref={ref} onLayout={onLayout} {...bridgeProps} onPress={onPress}>
|
|
47
|
+
<Text>Submit</Text>
|
|
48
|
+
</Pressable>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 3. Control from Python (unchanged from web!)
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from ui_bridge import UIBridgeClient
|
|
57
|
+
|
|
58
|
+
# Connect to device (use 10.0.2.2 for Android emulator)
|
|
59
|
+
client = UIBridgeClient("http://10.0.2.2:8087")
|
|
60
|
+
|
|
61
|
+
# Find and interact with elements
|
|
62
|
+
client.press("submit-button")
|
|
63
|
+
client.type("email-input", "test@example.com")
|
|
64
|
+
|
|
65
|
+
# Get element state
|
|
66
|
+
state = client.get_element_state("submit-button")
|
|
67
|
+
print(f"Button visible: {state['visible']}")
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Hooks
|
|
71
|
+
|
|
72
|
+
### useUIElement
|
|
73
|
+
|
|
74
|
+
Register individual elements for control.
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
const { ref, onLayout, bridgeProps, trigger, getState } = useUIElement({
|
|
78
|
+
id: 'my-element',
|
|
79
|
+
type: 'button', // or 'input', 'text', 'view', etc.
|
|
80
|
+
label: 'My Button', // Human-readable label
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Spread onto your component
|
|
84
|
+
<Pressable ref={ref} onLayout={onLayout} {...bridgeProps}>
|
|
85
|
+
<Text>Click Me</Text>
|
|
86
|
+
</Pressable>;
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### useUIElementWithProps
|
|
90
|
+
|
|
91
|
+
Extended version that captures props for action execution.
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
const { ref, onLayout, bridgeProps, captureProps } = useUIElementWithProps({
|
|
95
|
+
id: 'text-input',
|
|
96
|
+
type: 'input',
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Capture props so bridge can call onChangeText
|
|
100
|
+
captureProps({ onChangeText, value });
|
|
101
|
+
|
|
102
|
+
<TextInput
|
|
103
|
+
ref={ref}
|
|
104
|
+
onLayout={onLayout}
|
|
105
|
+
{...bridgeProps}
|
|
106
|
+
value={value}
|
|
107
|
+
onChangeText={onChangeText}
|
|
108
|
+
/>;
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### useUIComponent
|
|
112
|
+
|
|
113
|
+
Register component-level actions.
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
useUIComponent({
|
|
117
|
+
id: 'login-form',
|
|
118
|
+
name: 'Login Form',
|
|
119
|
+
actions: [
|
|
120
|
+
{
|
|
121
|
+
id: 'submit-login',
|
|
122
|
+
label: 'Submit Login',
|
|
123
|
+
handler: async ({ email, password }) => {
|
|
124
|
+
setEmail(email);
|
|
125
|
+
setPassword(password);
|
|
126
|
+
await submitLogin();
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
id: 'clear-form',
|
|
131
|
+
label: 'Clear Form',
|
|
132
|
+
handler: () => {
|
|
133
|
+
setEmail('');
|
|
134
|
+
setPassword('');
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### useUIBridge
|
|
142
|
+
|
|
143
|
+
Access bridge functionality from any component.
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
const { available, elements, components, executeAction, find, createSnapshot } = useUIBridge();
|
|
147
|
+
|
|
148
|
+
// Find all buttons
|
|
149
|
+
const buttons = await find({ types: ['button'] });
|
|
150
|
+
|
|
151
|
+
// Execute action
|
|
152
|
+
await executeAction('submit-button', { action: 'press' });
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Element Types
|
|
156
|
+
|
|
157
|
+
- `button` - Pressable buttons
|
|
158
|
+
- `input` - Text inputs
|
|
159
|
+
- `text` - Text elements
|
|
160
|
+
- `view` - Generic views
|
|
161
|
+
- `scroll` - ScrollViews
|
|
162
|
+
- `list` - FlatList/SectionList
|
|
163
|
+
- `listItem` - List items
|
|
164
|
+
- `switch` - Toggle switches
|
|
165
|
+
- `checkbox` - Checkboxes
|
|
166
|
+
- `radio` - Radio buttons
|
|
167
|
+
- `image` - Images
|
|
168
|
+
- `touchable` - TouchableOpacity/TouchableHighlight
|
|
169
|
+
- `pressable` - Pressable components
|
|
170
|
+
- `modal` - Modals
|
|
171
|
+
- `custom` - Custom elements
|
|
172
|
+
|
|
173
|
+
## Actions
|
|
174
|
+
|
|
175
|
+
- `press` - Single tap
|
|
176
|
+
- `longPress` - Long press
|
|
177
|
+
- `doubleTap` - Double tap
|
|
178
|
+
- `type` - Type text (for inputs)
|
|
179
|
+
- `clear` - Clear text
|
|
180
|
+
- `focus` - Focus element
|
|
181
|
+
- `blur` - Blur element
|
|
182
|
+
- `scroll` - Scroll
|
|
183
|
+
- `swipe` - Swipe gesture
|
|
184
|
+
- `toggle` - Toggle switch/checkbox
|
|
185
|
+
|
|
186
|
+
## HTTP Server
|
|
187
|
+
|
|
188
|
+
The package includes an embedded HTTP server for external control. Configure with:
|
|
189
|
+
|
|
190
|
+
```tsx
|
|
191
|
+
<UIBridgeNativeProvider
|
|
192
|
+
features={{ server: true }}
|
|
193
|
+
config={{ serverPort: 8087 }}
|
|
194
|
+
>
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### API Endpoints
|
|
198
|
+
|
|
199
|
+
| Method | Path | Description |
|
|
200
|
+
| ------ | --------------------------------------------------- | ------------------------ |
|
|
201
|
+
| GET | `/ui-bridge/health` | Health check |
|
|
202
|
+
| GET | `/ui-bridge/control/elements` | List all elements |
|
|
203
|
+
| GET | `/ui-bridge/control/element/:id` | Get element details |
|
|
204
|
+
| POST | `/ui-bridge/control/element/:id/action` | Execute action |
|
|
205
|
+
| GET | `/ui-bridge/control/components` | List all components |
|
|
206
|
+
| POST | `/ui-bridge/control/component/:id/action/:actionId` | Execute component action |
|
|
207
|
+
| POST | `/ui-bridge/control/find` | Find elements |
|
|
208
|
+
| GET | `/ui-bridge/control/snapshot` | Get full snapshot |
|
|
209
|
+
|
|
210
|
+
### Custom Server Adapter
|
|
211
|
+
|
|
212
|
+
The HTTP server requires a platform-specific adapter. See [documentation](./docs/server-adapters.md) for examples with:
|
|
213
|
+
|
|
214
|
+
- `react-native-http-bridge`
|
|
215
|
+
- `@aspect/react-native-http-server`
|
|
216
|
+
|
|
217
|
+
## Debug Inspector
|
|
218
|
+
|
|
219
|
+
Built-in visual inspector for development:
|
|
220
|
+
|
|
221
|
+
```tsx
|
|
222
|
+
import { UIBridgeInspector } from 'ui-bridge-native/debug';
|
|
223
|
+
|
|
224
|
+
function App() {
|
|
225
|
+
return (
|
|
226
|
+
<UIBridgeNativeProvider features={{ debug: __DEV__ }}>
|
|
227
|
+
<MainContent />
|
|
228
|
+
{__DEV__ && <UIBridgeInspector />}
|
|
229
|
+
</UIBridgeNativeProvider>
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## TypeScript
|
|
235
|
+
|
|
236
|
+
Full TypeScript support included. Import types as needed:
|
|
237
|
+
|
|
238
|
+
```tsx
|
|
239
|
+
import type { NativeElementState, NativeElementType, UseUIElementOptions } from 'ui-bridge-native';
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## License
|
|
243
|
+
|
|
244
|
+
MIT
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { N as NativeActionExecutor, C as ControlActionRequest, a as ControlActionResponse, b as ComponentActionRequest, c as ComponentActionResponse, W as WaitResult } from '../types-BgZTILOS.mjs';
|
|
2
|
+
export { A as ActionExecutionOptions, e as PageNavigateRequest, f as PageNavigationResponse, P as PressActionParams, S as ScrollActionParams, d as SwipeActionParams, T as TypeActionParams } from '../types-BgZTILOS.mjs';
|
|
3
|
+
import { a as NativeUIBridgeRegistry } from '../registry-D9J7IVo1.mjs';
|
|
4
|
+
import { l as NativeFindRequest, m as NativeFindResponse, W as WaitOptions } from '../types-DM6yMpW8.mjs';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Native Action Executor
|
|
8
|
+
*
|
|
9
|
+
* Executes actions on registered native elements and components.
|
|
10
|
+
* In React Native, we execute actions by calling prop handlers directly
|
|
11
|
+
* (onPress, onChangeText, etc.) rather than simulating DOM events.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Default native action executor implementation
|
|
16
|
+
*/
|
|
17
|
+
declare class DefaultNativeActionExecutor implements NativeActionExecutor {
|
|
18
|
+
private registry;
|
|
19
|
+
constructor(registry: NativeUIBridgeRegistry);
|
|
20
|
+
/**
|
|
21
|
+
* Execute an action on an element
|
|
22
|
+
*/
|
|
23
|
+
executeAction(elementId: string, request: ControlActionRequest): Promise<ControlActionResponse>;
|
|
24
|
+
/**
|
|
25
|
+
* Perform an action on an element
|
|
26
|
+
*/
|
|
27
|
+
private performAction;
|
|
28
|
+
/**
|
|
29
|
+
* Perform press action
|
|
30
|
+
*/
|
|
31
|
+
private performPress;
|
|
32
|
+
/**
|
|
33
|
+
* Perform long press action
|
|
34
|
+
*/
|
|
35
|
+
private performLongPress;
|
|
36
|
+
/**
|
|
37
|
+
* Perform double tap action
|
|
38
|
+
*/
|
|
39
|
+
private performDoubleTap;
|
|
40
|
+
/**
|
|
41
|
+
* Perform type action
|
|
42
|
+
*/
|
|
43
|
+
private performType;
|
|
44
|
+
/**
|
|
45
|
+
* Perform clear action
|
|
46
|
+
*/
|
|
47
|
+
private performClear;
|
|
48
|
+
/**
|
|
49
|
+
* Perform focus action
|
|
50
|
+
*/
|
|
51
|
+
private performFocus;
|
|
52
|
+
/**
|
|
53
|
+
* Perform blur action
|
|
54
|
+
*/
|
|
55
|
+
private performBlur;
|
|
56
|
+
/**
|
|
57
|
+
* Perform scroll action
|
|
58
|
+
*/
|
|
59
|
+
private performScroll;
|
|
60
|
+
/**
|
|
61
|
+
* Perform swipe action
|
|
62
|
+
*/
|
|
63
|
+
private performSwipe;
|
|
64
|
+
/**
|
|
65
|
+
* Perform toggle action
|
|
66
|
+
*/
|
|
67
|
+
private performToggle;
|
|
68
|
+
/**
|
|
69
|
+
* Create a synthetic press event
|
|
70
|
+
*/
|
|
71
|
+
private createPressEvent;
|
|
72
|
+
/**
|
|
73
|
+
* Execute a component action
|
|
74
|
+
*/
|
|
75
|
+
executeComponentAction(componentId: string, request: ComponentActionRequest): Promise<ComponentActionResponse>;
|
|
76
|
+
/**
|
|
77
|
+
* Find elements
|
|
78
|
+
*/
|
|
79
|
+
find(request: NativeFindRequest): Promise<NativeFindResponse>;
|
|
80
|
+
/**
|
|
81
|
+
* Wait for element conditions
|
|
82
|
+
*/
|
|
83
|
+
waitForElement(elementId: string, options: WaitOptions): Promise<WaitResult>;
|
|
84
|
+
/**
|
|
85
|
+
* Internal wait implementation
|
|
86
|
+
*/
|
|
87
|
+
private waitForElementInternal;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Create a native action executor
|
|
91
|
+
*/
|
|
92
|
+
declare function createNativeActionExecutor(registry: NativeUIBridgeRegistry): NativeActionExecutor;
|
|
93
|
+
|
|
94
|
+
export { ComponentActionRequest, ComponentActionResponse, ControlActionRequest, ControlActionResponse, DefaultNativeActionExecutor, NativeActionExecutor, WaitResult, createNativeActionExecutor };
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { N as NativeActionExecutor, C as ControlActionRequest, a as ControlActionResponse, b as ComponentActionRequest, c as ComponentActionResponse, W as WaitResult } from '../types-D27YUSIk.js';
|
|
2
|
+
export { A as ActionExecutionOptions, e as PageNavigateRequest, f as PageNavigationResponse, P as PressActionParams, S as ScrollActionParams, d as SwipeActionParams, T as TypeActionParams } from '../types-D27YUSIk.js';
|
|
3
|
+
import { a as NativeUIBridgeRegistry } from '../registry-C_35zBrv.js';
|
|
4
|
+
import { l as NativeFindRequest, m as NativeFindResponse, W as WaitOptions } from '../types-DM6yMpW8.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Native Action Executor
|
|
8
|
+
*
|
|
9
|
+
* Executes actions on registered native elements and components.
|
|
10
|
+
* In React Native, we execute actions by calling prop handlers directly
|
|
11
|
+
* (onPress, onChangeText, etc.) rather than simulating DOM events.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Default native action executor implementation
|
|
16
|
+
*/
|
|
17
|
+
declare class DefaultNativeActionExecutor implements NativeActionExecutor {
|
|
18
|
+
private registry;
|
|
19
|
+
constructor(registry: NativeUIBridgeRegistry);
|
|
20
|
+
/**
|
|
21
|
+
* Execute an action on an element
|
|
22
|
+
*/
|
|
23
|
+
executeAction(elementId: string, request: ControlActionRequest): Promise<ControlActionResponse>;
|
|
24
|
+
/**
|
|
25
|
+
* Perform an action on an element
|
|
26
|
+
*/
|
|
27
|
+
private performAction;
|
|
28
|
+
/**
|
|
29
|
+
* Perform press action
|
|
30
|
+
*/
|
|
31
|
+
private performPress;
|
|
32
|
+
/**
|
|
33
|
+
* Perform long press action
|
|
34
|
+
*/
|
|
35
|
+
private performLongPress;
|
|
36
|
+
/**
|
|
37
|
+
* Perform double tap action
|
|
38
|
+
*/
|
|
39
|
+
private performDoubleTap;
|
|
40
|
+
/**
|
|
41
|
+
* Perform type action
|
|
42
|
+
*/
|
|
43
|
+
private performType;
|
|
44
|
+
/**
|
|
45
|
+
* Perform clear action
|
|
46
|
+
*/
|
|
47
|
+
private performClear;
|
|
48
|
+
/**
|
|
49
|
+
* Perform focus action
|
|
50
|
+
*/
|
|
51
|
+
private performFocus;
|
|
52
|
+
/**
|
|
53
|
+
* Perform blur action
|
|
54
|
+
*/
|
|
55
|
+
private performBlur;
|
|
56
|
+
/**
|
|
57
|
+
* Perform scroll action
|
|
58
|
+
*/
|
|
59
|
+
private performScroll;
|
|
60
|
+
/**
|
|
61
|
+
* Perform swipe action
|
|
62
|
+
*/
|
|
63
|
+
private performSwipe;
|
|
64
|
+
/**
|
|
65
|
+
* Perform toggle action
|
|
66
|
+
*/
|
|
67
|
+
private performToggle;
|
|
68
|
+
/**
|
|
69
|
+
* Create a synthetic press event
|
|
70
|
+
*/
|
|
71
|
+
private createPressEvent;
|
|
72
|
+
/**
|
|
73
|
+
* Execute a component action
|
|
74
|
+
*/
|
|
75
|
+
executeComponentAction(componentId: string, request: ComponentActionRequest): Promise<ComponentActionResponse>;
|
|
76
|
+
/**
|
|
77
|
+
* Find elements
|
|
78
|
+
*/
|
|
79
|
+
find(request: NativeFindRequest): Promise<NativeFindResponse>;
|
|
80
|
+
/**
|
|
81
|
+
* Wait for element conditions
|
|
82
|
+
*/
|
|
83
|
+
waitForElement(elementId: string, options: WaitOptions): Promise<WaitResult>;
|
|
84
|
+
/**
|
|
85
|
+
* Internal wait implementation
|
|
86
|
+
*/
|
|
87
|
+
private waitForElementInternal;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Create a native action executor
|
|
91
|
+
*/
|
|
92
|
+
declare function createNativeActionExecutor(registry: NativeUIBridgeRegistry): NativeActionExecutor;
|
|
93
|
+
|
|
94
|
+
export { ComponentActionRequest, ComponentActionResponse, ControlActionRequest, ControlActionResponse, DefaultNativeActionExecutor, NativeActionExecutor, WaitResult, createNativeActionExecutor };
|