@sqaitech/ios 0.5.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.
Files changed (76) hide show
  1. package/README.md +336 -0
  2. package/bin/sqai-ios-playground +3 -0
  3. package/dist/es/bin.mjs +12872 -0
  4. package/dist/es/bin.mjs.LICENSE.txt +256 -0
  5. package/dist/es/index.mjs +923 -0
  6. package/dist/lib/bin.js +13017 -0
  7. package/dist/lib/bin.js.LICENSE.txt +256 -0
  8. package/dist/lib/index.js +982 -0
  9. package/dist/types/bin.d.ts +1 -0
  10. package/dist/types/index.d.ts +132 -0
  11. package/package.json +65 -0
  12. package/static/favicon.ico +0 -0
  13. package/static/index.html +1 -0
  14. package/static/static/css/index.60c69390.css +2 -0
  15. package/static/static/css/index.60c69390.css.map +1 -0
  16. package/static/static/image/sqai-logo.b7f781cd.png +0 -0
  17. package/static/static/js/931.dc961e99.js +620 -0
  18. package/static/static/js/931.dc961e99.js.LICENSE.txt +146 -0
  19. package/static/static/js/931.dc961e99.js.map +1 -0
  20. package/static/static/js/async/173.9cf6b074.js +3 -0
  21. package/static/static/js/async/173.9cf6b074.js.map +1 -0
  22. package/static/static/js/async/212.e243c338.js +158 -0
  23. package/static/static/js/async/212.e243c338.js.map +1 -0
  24. package/static/static/js/async/329.f888b505.js +26 -0
  25. package/static/static/js/async/329.f888b505.js.map +1 -0
  26. package/static/static/js/async/364.1821e74b.js +30 -0
  27. package/static/static/js/async/364.1821e74b.js.map +1 -0
  28. package/static/static/js/async/544.b73fa603.js +2 -0
  29. package/static/static/js/async/544.b73fa603.js.map +1 -0
  30. package/static/static/js/async/582.5dccae2d.js +21 -0
  31. package/static/static/js/async/582.5dccae2d.js.map +1 -0
  32. package/static/static/js/async/624.45ee2b2c.js +3 -0
  33. package/static/static/js/async/624.45ee2b2c.js.map +1 -0
  34. package/static/static/js/async/644.6bdc4065.js +1 -0
  35. package/static/static/js/async/659.9afd03db.js +21 -0
  36. package/static/static/js/async/659.9afd03db.js.map +1 -0
  37. package/static/static/js/async/702.60261735.js +231 -0
  38. package/static/static/js/async/702.60261735.js.map +1 -0
  39. package/static/static/js/async/920.7d9a9aa8.js +2 -0
  40. package/static/static/js/async/920.7d9a9aa8.js.map +1 -0
  41. package/static/static/js/async/983.8b91303f.js +1 -0
  42. package/static/static/js/index.0c5d4f3b.js +10 -0
  43. package/static/static/js/index.0c5d4f3b.js.LICENSE.txt +7 -0
  44. package/static/static/js/index.0c5d4f3b.js.map +1 -0
  45. package/static/static/js/index.3890f2de.js +10 -0
  46. package/static/static/js/index.3890f2de.js.LICENSE.txt +7 -0
  47. package/static/static/js/index.3890f2de.js.map +1 -0
  48. package/static/static/js/index.39b0d1ea.js +10 -0
  49. package/static/static/js/index.39b0d1ea.js.LICENSE.txt +7 -0
  50. package/static/static/js/index.39b0d1ea.js.map +1 -0
  51. package/static/static/js/index.3f24d218.js +10 -0
  52. package/static/static/js/index.3f24d218.js.LICENSE.txt +7 -0
  53. package/static/static/js/index.3f24d218.js.map +1 -0
  54. package/static/static/js/index.5cccbdaf.js +10 -0
  55. package/static/static/js/index.5cccbdaf.js.LICENSE.txt +7 -0
  56. package/static/static/js/index.5cccbdaf.js.map +1 -0
  57. package/static/static/js/index.8a10896b.js +10 -0
  58. package/static/static/js/index.8a10896b.js.LICENSE.txt +7 -0
  59. package/static/static/js/index.8a10896b.js.map +1 -0
  60. package/static/static/js/index.afc8ef37.js +10 -0
  61. package/static/static/js/index.afc8ef37.js.LICENSE.txt +7 -0
  62. package/static/static/js/index.afc8ef37.js.map +1 -0
  63. package/static/static/js/index.b8a17a87.js +10 -0
  64. package/static/static/js/index.b8a17a87.js.LICENSE.txt +7 -0
  65. package/static/static/js/index.b8a17a87.js.map +1 -0
  66. package/static/static/js/index.d0dcab60.js +10 -0
  67. package/static/static/js/index.d0dcab60.js.LICENSE.txt +7 -0
  68. package/static/static/js/index.d0dcab60.js.map +1 -0
  69. package/static/static/js/index.f21bb1df.js +10 -0
  70. package/static/static/js/index.f21bb1df.js.LICENSE.txt +7 -0
  71. package/static/static/js/index.f21bb1df.js.map +1 -0
  72. package/static/static/js/lib-react.f566a9ed.js +3 -0
  73. package/static/static/js/lib-react.f566a9ed.js.LICENSE.txt +39 -0
  74. package/static/static/js/lib-react.f566a9ed.js.map +1 -0
  75. package/static/static/svg/server-offline-foreground.3113df3c.svg +36 -0
  76. package/static/static/wasm/9e906fbf55e08f98.module.wasm +0 -0
package/README.md ADDED
@@ -0,0 +1,336 @@
1
+ # @SQAI/ios
2
+
3
+ iOS automation library for SQAI, providing AI-powered testing and automation capabilities for iOS simulators and devices.
4
+
5
+ ## Features
6
+
7
+ - 🎯 **iOS Simulator Support** - Full automation support for iOS simulators
8
+ - 🤖 **AI-Powered Actions** - Intelligent element detection and interaction
9
+ - 📱 **Native iOS Actions** - Home button, app switcher, and iOS-specific gestures
10
+ - 🔧 **Simple API** - Easy-to-use interface similar to @SQAI/android
11
+ - 📸 **Screenshot Capture** - Built-in screenshot functionality
12
+ - ⌨️ **Text Input** - Support for text input including non-ASCII characters
13
+ - 🎮 **Gesture Support** - Tap, swipe, long press, and custom gestures
14
+
15
+ ## Prerequisites
16
+
17
+ - **macOS** (required for iOS development)
18
+ - **Xcode** and Xcode Command Line Tools
19
+ - **iOS Simulator** or physical iOS device
20
+ - **WebDriverAgent** (required for automation)
21
+
22
+ ### Environment Setup
23
+
24
+ ```bash
25
+ # Install Xcode Command Line Tools
26
+ xcode-select --install
27
+
28
+ # Verify simctl is available
29
+ xcrun simctl list devices
30
+
31
+ # Install WebDriverAgent dependency
32
+ npm install appium-webdriveragent
33
+ ```
34
+
35
+ ### WebDriverAgent Setup
36
+
37
+ SQAI iOS uses WebDriverAgent for device automation. You need to prepare WebDriverAgent before using the library:
38
+
39
+ #### For iOS Simulators
40
+
41
+ 1. **Install WebDriverAgent dependency:**
42
+ ```bash
43
+ npm install appium-webdriveragent
44
+ ```
45
+
46
+ 2. **Build and start WebDriverAgent:**
47
+ ```bash
48
+ # Navigate to WebDriverAgent project
49
+ cd node_modules/appium-webdriveragent
50
+
51
+ # Build and run for simulator
52
+ xcodebuild -project WebDriverAgent.xcodeproj \
53
+ -scheme WebDriverAgentRunner \
54
+ -destination 'platform=iOS Simulator,name=iPhone 15' \
55
+ test
56
+ ```
57
+
58
+ #### For Physical iOS Devices
59
+
60
+ 1. **Configure Development Team:**
61
+ - Open `node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj` in Xcode
62
+ - Select your Development Team for both `WebDriverAgentLib` and `WebDriverAgentRunner` targets
63
+ - Ensure proper code signing is configured
64
+
65
+ 2. **Build and deploy to device:**
66
+ ```bash
67
+ # Replace DEVICE_UDID with your device's UDID
68
+ xcodebuild -project WebDriverAgent.xcodeproj \
69
+ -scheme WebDriverAgentRunner \
70
+ -destination 'id=YOUR_DEVICE_UDID' \
71
+ test
72
+ ```
73
+
74
+ 3. **Trust Developer Certificate:**
75
+ - On your iOS device, go to Settings > General > VPN & Device Management
76
+ - Trust your developer certificate
77
+
78
+ 4. **Set up port forwarding (for real devices):**
79
+ ```bash
80
+ # Install iproxy (if needed)
81
+ brew install libimobiledevice
82
+
83
+ # Forward local port 8100 to device port 8100
84
+ iproxy -u YOUR_DEVICE_ID 8100:8100
85
+ ```
86
+
87
+ #### Alternative Setup Methods
88
+
89
+ For more advanced setup options and troubleshooting, refer to the official WebDriverAgent documentation:
90
+ **📖 [WebDriverAgent Setup Guide](https://appium.github.io/appium-xcuitest-driver/4.25/wda-custom-server/)**
91
+
92
+ > **⚠️ Important:** WebDriverAgent must be running on port 8100 (default) before using SQAI iOS. If WebDriverAgent is not detected, you'll receive setup instructions.
93
+
94
+ ## Installation
95
+
96
+ ```bash
97
+ npm install @SQAI/ios
98
+ # or
99
+ pnpm add @SQAI/ios
100
+ ```
101
+
102
+ ## Quick Start
103
+
104
+ ### Basic Usage (Recommended)
105
+
106
+ ```typescript
107
+ import { agentFromWebDriverAgent } from '@SQAI/ios';
108
+
109
+ // Connect to WebDriverAgent (auto-detects device)
110
+ const agent = await agentFromWebDriverAgent();
111
+
112
+ // Launch an app
113
+ await agent.launch('com.apple.MobileSafari');
114
+
115
+ // Perform AI-powered actions
116
+ await agent.aiAction('tap on the address bar');
117
+ await agent.aiAction('type "https://example.com"');
118
+ await agent.aiAction('tap the go button');
119
+ ```
120
+
121
+ ### Using Custom WebDriverAgent Configuration
122
+
123
+ ```typescript
124
+ import { agentFromWebDriverAgent } from '@SQAI/ios';
125
+
126
+ // Connect to WebDriverAgent on custom host/port
127
+ const agent = await agentFromWebDriverAgent({
128
+ wdaHost: 'localhost',
129
+ wdaPort: 8100, // Custom port
130
+ aiActionContext: 'If any popup appears, click agree',
131
+ });
132
+
133
+ // Launch app and interact
134
+ await agent.launch('com.yourapp.bundleid');
135
+ await agent.aiAction('tap the login button');
136
+ ```
137
+
138
+ ## API Reference
139
+
140
+ ### IOSDevice
141
+
142
+ Core device automation class implementing the AbstractInterface.
143
+
144
+ ```typescript
145
+ import { IOSDevice } from '@SQAI/ios';
146
+
147
+ // Create device (deviceId is auto-detected from WebDriverAgent)
148
+ const device = new IOSDevice({
149
+ wdaHost: 'localhost',
150
+ wdaPort: 8100,
151
+ });
152
+ await device.connect();
153
+
154
+ // Basic interactions
155
+ await device.tap(100, 200);
156
+ await device.swipe(100, 200, 300, 400);
157
+ await device.typeText('Hello World');
158
+ await device.pressKey('Enter');
159
+
160
+ // iOS-specific actions
161
+ await device.home();
162
+ await device.appSwitcher();
163
+ await device.longPress(150, 300, 1000);
164
+
165
+ // Screenshots
166
+ const screenshot = await device.screenshotBase64();
167
+
168
+ // Cleanup
169
+ await device.destroy();
170
+ ```
171
+
172
+ ### IOSAgent
173
+
174
+ High-level agent for AI-powered automation.
175
+
176
+ ```typescript
177
+ import { IOSAgent, agentFromWebDriverAgent } from '@SQAI/ios';
178
+
179
+ // Recommended approach
180
+ const agent = await agentFromWebDriverAgent();
181
+
182
+ // AI actions
183
+ await agent.aiAction('tap the settings icon');
184
+ await agent.aiQuery('what is the current battery level?');
185
+ await agent.aiWaitFor('the page is loaded');
186
+
187
+ // App management
188
+ await agent.launch('com.apple.Preferences');
189
+ ```
190
+
191
+ ### Utility Functions
192
+
193
+ ```typescript
194
+ import {
195
+ checkIOSEnvironment,
196
+ ensureSimulatorBooted,
197
+ // Note: getConnectedDevices and getDefaultDevice are deprecated
198
+ // Use agentFromWebDriverAgent() instead
199
+ } from '@SQAI/ios';
200
+
201
+ // Environment check
202
+ const envStatus = await checkIOSEnvironment();
203
+ console.log('iOS environment available:', envStatus.available);
204
+
205
+ // Simulator management (if needed)
206
+ await ensureSimulatorBooted('simulator-udid');
207
+
208
+ // Simulator management
209
+ await ensureSimulatorBooted('device-udid');
210
+ ```
211
+
212
+ ## Configuration
213
+
214
+ Set environment variables for default behavior:
215
+
216
+ ```bash
217
+ # Default device UDID
218
+ export SQAI_IOS_DEVICE_UDID=your-device-udid
219
+
220
+ # Default simulator UDID
221
+ export SQAI_IOS_SIMULATOR_UDID=your-simulator-udid
222
+ ```
223
+
224
+ ## Supported iOS Actions
225
+
226
+ ### Basic Gestures
227
+ - `tap(x, y)` - Single tap at coordinates
228
+ - `doubleTap(x, y)` - Double tap at coordinates
229
+ - `longPress(x, y, duration)` - Long press with duration
230
+ - `swipe(fromX, fromY, toX, toY)` - Swipe gesture
231
+
232
+ ### Text Input
233
+ - `typeText(text)` - Type text using iOS keyboard
234
+ - `pressKey(key)` - Press specific keys (Enter, Backspace, etc.)
235
+ - `clearInput(element)` - Clear input field
236
+
237
+ ### Scrolling
238
+ - `scrollUp/Down/Left/Right(distance?, startPoint?)` - Directional scrolling
239
+ - `scrollUntilTop/Bottom/Left/Right(startPoint?)` - Scroll to extremes
240
+
241
+ ### iOS System Actions
242
+ - `home()` - Press home button
243
+ - `appSwitcher()` - Open app switcher
244
+ - `hideKeyboard()` - Dismiss keyboard
245
+
246
+ ### AI-Powered Actions
247
+ - `aiAction(instruction)` - Perform action based on natural language
248
+ - `aiQuery(question)` - Query UI state with natural language
249
+ - `aiWaitFor(condition)` - Wait for condition to be met
250
+
251
+ ## Device Requirements
252
+
253
+ ### iOS Simulators
254
+ - Managed through Xcode
255
+ - No additional setup required
256
+ - Supports all iOS versions available in Xcode
257
+
258
+ ### Physical iOS Devices
259
+ - Requires iOS 9.0 or later
260
+ - Device must be in Developer Mode
261
+ - Requires valid provisioning profile for your apps
262
+
263
+ ## Examples
264
+
265
+ ### Complete Test Example
266
+
267
+ ```typescript
268
+ import { describe, it } from 'vitest';
269
+ import { agentFromWebDriverAgent } from '@SQAI/ios';
270
+
271
+ describe('iOS App Test', () => {
272
+ it('should login to app', async () => {
273
+ // WebDriverAgent auto-detects the connected device
274
+ const agent = await agentFromWebDriverAgent();
275
+
276
+ // Launch your app
277
+ await agent.launch('com.yourcompany.yourapp');
278
+
279
+ // AI-powered login flow
280
+ await agent.aiAction('tap on email field');
281
+ await agent.aiAction('type "user@example.com"');
282
+ await agent.aiAction('tap on password field');
283
+ await agent.aiAction('type "password123"');
284
+ await agent.aiAction('tap the login button');
285
+
286
+ // Verify successful login
287
+ await agent.aiWaitFor('dashboard is visible');
288
+
289
+ const isLoggedIn = await agent.aiQuery('is the user logged in?');
290
+ expect(isLoggedIn).toBe(true);
291
+ });
292
+ });
293
+ ```
294
+
295
+ ## Troubleshooting
296
+
297
+ ### Common Issues
298
+
299
+ 1. **"No iOS devices available"**
300
+ - Ensure Xcode is installed
301
+ - Check `xcrun simctl list devices` shows available simulators
302
+ - Try booting a simulator manually in Xcode
303
+
304
+ 2. **"Command failed: xcrun simctl"**
305
+ - Verify Xcode Command Line Tools are installed
306
+ - Run `xcode-select --install` if needed
307
+ - Check `which xcrun` returns a valid path
308
+
309
+ 3. **Simulator not responding**
310
+ - Restart the simulator
311
+ - Try `xcrun simctl shutdown all && xcrun simctl boot <udid>`
312
+
313
+ 4. **App launch fails**
314
+ - Verify the bundle ID is correct
315
+ - Ensure the app is installed on the simulator
316
+ - Check app permissions and entitlements
317
+
318
+ ### Debug Mode
319
+
320
+ Enable debug logging:
321
+
322
+ ```typescript
323
+ process.env.DEBUG = 'ios:*';
324
+ ```
325
+
326
+ ## Contributing
327
+
328
+ 1. Fork the repository
329
+ 2. Create your feature branch
330
+ 3. Add tests for new functionality
331
+ 4. Ensure all tests pass
332
+ 5. Submit a pull request
333
+
334
+ ## License
335
+
336
+ MIT License - see LICENSE file for details.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ require('../dist/lib/bin.js');