agentic-qe 2.0.0 → 2.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/.claude/agents/qx-partner.md +17 -4
- package/.claude/skills/accessibility-testing/SKILL.md +144 -692
- package/.claude/skills/agentic-quality-engineering/SKILL.md +176 -529
- package/.claude/skills/api-testing-patterns/SKILL.md +180 -560
- package/.claude/skills/brutal-honesty-review/SKILL.md +113 -603
- package/.claude/skills/bug-reporting-excellence/SKILL.md +116 -517
- package/.claude/skills/chaos-engineering-resilience/SKILL.md +127 -72
- package/.claude/skills/cicd-pipeline-qe-orchestrator/SKILL.md +209 -404
- package/.claude/skills/code-review-quality/SKILL.md +158 -608
- package/.claude/skills/compatibility-testing/SKILL.md +148 -38
- package/.claude/skills/compliance-testing/SKILL.md +132 -63
- package/.claude/skills/consultancy-practices/SKILL.md +114 -446
- package/.claude/skills/context-driven-testing/SKILL.md +117 -381
- package/.claude/skills/contract-testing/SKILL.md +176 -141
- package/.claude/skills/database-testing/SKILL.md +137 -130
- package/.claude/skills/exploratory-testing-advanced/SKILL.md +160 -629
- package/.claude/skills/holistic-testing-pact/SKILL.md +140 -188
- package/.claude/skills/localization-testing/SKILL.md +145 -33
- package/.claude/skills/mobile-testing/SKILL.md +132 -448
- package/.claude/skills/mutation-testing/SKILL.md +147 -41
- package/.claude/skills/performance-testing/SKILL.md +200 -546
- package/.claude/skills/quality-metrics/SKILL.md +164 -519
- package/.claude/skills/refactoring-patterns/SKILL.md +132 -699
- package/.claude/skills/regression-testing/SKILL.md +120 -926
- package/.claude/skills/risk-based-testing/SKILL.md +157 -660
- package/.claude/skills/security-testing/SKILL.md +199 -538
- package/.claude/skills/sherlock-review/SKILL.md +163 -699
- package/.claude/skills/shift-left-testing/SKILL.md +161 -465
- package/.claude/skills/shift-right-testing/SKILL.md +161 -519
- package/.claude/skills/six-thinking-hats/SKILL.md +175 -1110
- package/.claude/skills/skills-manifest.json +71 -20
- package/.claude/skills/tdd-london-chicago/SKILL.md +131 -448
- package/.claude/skills/technical-writing/SKILL.md +103 -154
- package/.claude/skills/test-automation-strategy/SKILL.md +166 -772
- package/.claude/skills/test-data-management/SKILL.md +126 -910
- package/.claude/skills/test-design-techniques/SKILL.md +179 -89
- package/.claude/skills/test-environment-management/SKILL.md +136 -91
- package/.claude/skills/test-reporting-analytics/SKILL.md +169 -92
- package/.claude/skills/testability-scoring/SKILL.md +172 -538
- package/.claude/skills/testability-scoring/scripts/generate-html-report.js +0 -0
- package/.claude/skills/visual-testing-advanced/SKILL.md +155 -78
- package/.claude/skills/xp-practices/SKILL.md +151 -587
- package/CHANGELOG.md +48 -0
- package/README.md +23 -16
- package/dist/agents/QXPartnerAgent.d.ts +8 -1
- package/dist/agents/QXPartnerAgent.d.ts.map +1 -1
- package/dist/agents/QXPartnerAgent.js +1174 -112
- package/dist/agents/QXPartnerAgent.js.map +1 -1
- package/dist/agents/lifecycle/AgentLifecycleManager.d.ts.map +1 -1
- package/dist/agents/lifecycle/AgentLifecycleManager.js +34 -31
- package/dist/agents/lifecycle/AgentLifecycleManager.js.map +1 -1
- package/dist/cli/commands/init-claude-md-template.d.ts.map +1 -1
- package/dist/cli/commands/init-claude-md-template.js +14 -0
- package/dist/cli/commands/init-claude-md-template.js.map +1 -1
- package/dist/core/SwarmCoordinator.d.ts +180 -0
- package/dist/core/SwarmCoordinator.d.ts.map +1 -0
- package/dist/core/SwarmCoordinator.js +473 -0
- package/dist/core/SwarmCoordinator.js.map +1 -0
- package/dist/core/metrics/MetricsAggregator.d.ts +228 -0
- package/dist/core/metrics/MetricsAggregator.d.ts.map +1 -0
- package/dist/core/metrics/MetricsAggregator.js +482 -0
- package/dist/core/metrics/MetricsAggregator.js.map +1 -0
- package/dist/core/metrics/index.d.ts +5 -0
- package/dist/core/metrics/index.d.ts.map +1 -0
- package/dist/core/metrics/index.js +11 -0
- package/dist/core/metrics/index.js.map +1 -0
- package/dist/core/optimization/SwarmOptimizer.d.ts +5 -0
- package/dist/core/optimization/SwarmOptimizer.d.ts.map +1 -1
- package/dist/core/optimization/SwarmOptimizer.js +17 -0
- package/dist/core/optimization/SwarmOptimizer.js.map +1 -1
- package/dist/core/orchestration/AdaptiveScheduler.d.ts +190 -0
- package/dist/core/orchestration/AdaptiveScheduler.d.ts.map +1 -0
- package/dist/core/orchestration/AdaptiveScheduler.js +460 -0
- package/dist/core/orchestration/AdaptiveScheduler.js.map +1 -0
- package/dist/core/orchestration/WorkflowOrchestrator.d.ts +13 -0
- package/dist/core/orchestration/WorkflowOrchestrator.d.ts.map +1 -1
- package/dist/core/orchestration/WorkflowOrchestrator.js +32 -0
- package/dist/core/orchestration/WorkflowOrchestrator.js.map +1 -1
- package/dist/core/recovery/CircuitBreaker.d.ts +176 -0
- package/dist/core/recovery/CircuitBreaker.d.ts.map +1 -0
- package/dist/core/recovery/CircuitBreaker.js +382 -0
- package/dist/core/recovery/CircuitBreaker.js.map +1 -0
- package/dist/core/recovery/RecoveryOrchestrator.d.ts +186 -0
- package/dist/core/recovery/RecoveryOrchestrator.d.ts.map +1 -0
- package/dist/core/recovery/RecoveryOrchestrator.js +476 -0
- package/dist/core/recovery/RecoveryOrchestrator.js.map +1 -0
- package/dist/core/recovery/RetryStrategy.d.ts +127 -0
- package/dist/core/recovery/RetryStrategy.d.ts.map +1 -0
- package/dist/core/recovery/RetryStrategy.js +314 -0
- package/dist/core/recovery/RetryStrategy.js.map +1 -0
- package/dist/core/recovery/index.d.ts +8 -0
- package/dist/core/recovery/index.d.ts.map +1 -0
- package/dist/core/recovery/index.js +27 -0
- package/dist/core/recovery/index.js.map +1 -0
- package/dist/core/skills/DependencyResolver.d.ts +99 -0
- package/dist/core/skills/DependencyResolver.d.ts.map +1 -0
- package/dist/core/skills/DependencyResolver.js +260 -0
- package/dist/core/skills/DependencyResolver.js.map +1 -0
- package/dist/core/skills/ManifestGenerator.d.ts +114 -0
- package/dist/core/skills/ManifestGenerator.d.ts.map +1 -0
- package/dist/core/skills/ManifestGenerator.js +449 -0
- package/dist/core/skills/ManifestGenerator.js.map +1 -0
- package/dist/core/skills/index.d.ts +9 -0
- package/dist/core/skills/index.d.ts.map +1 -0
- package/dist/core/skills/index.js +24 -0
- package/dist/core/skills/index.js.map +1 -0
- package/dist/mcp/server.d.ts +9 -9
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +1 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/types/qx.d.ts +39 -7
- package/dist/types/qx.d.ts.map +1 -1
- package/dist/types/qx.js.map +1 -1
- package/dist/visualization/api/RestEndpoints.js +1 -1
- package/dist/visualization/api/RestEndpoints.js.map +1 -1
- package/package.json +13 -55
|
@@ -1,124 +1,81 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mobile-testing
|
|
3
|
-
description: Comprehensive mobile testing for iOS and Android platforms including gestures, sensors, permissions, device fragmentation, and performance. Use when testing native apps, hybrid apps, or mobile web, ensuring quality across 1000+ device variants.
|
|
3
|
+
description: "Comprehensive mobile testing for iOS and Android platforms including gestures, sensors, permissions, device fragmentation, and performance. Use when testing native apps, hybrid apps, or mobile web, ensuring quality across 1000+ device variants."
|
|
4
|
+
category: specialized-testing
|
|
5
|
+
priority: high
|
|
6
|
+
tokenEstimate: 1000
|
|
7
|
+
agents: [qe-test-executor, qe-performance-tester, qe-visual-tester]
|
|
8
|
+
implementation_status: optimized
|
|
9
|
+
optimization_version: 1.0
|
|
10
|
+
last_optimized: 2025-12-02
|
|
11
|
+
dependencies: []
|
|
12
|
+
quick_reference_card: true
|
|
13
|
+
tags: [mobile, ios, android, appium, gestures, device-fragmentation, sensors]
|
|
4
14
|
---
|
|
5
15
|
|
|
6
16
|
# Mobile Testing
|
|
7
17
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
**Mobile
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
- Platform-specific UI (UIKit vs Material Design)
|
|
39
|
-
- Separate codebase per platform
|
|
40
|
-
|
|
41
|
-
**Testing Tools:**
|
|
42
|
-
- **iOS:** XCTest, XCUITest, EarlGrey
|
|
43
|
-
- **Android:** Espresso, UI Automator, Robolectric
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
### 2. Hybrid Apps
|
|
48
|
-
|
|
49
|
-
**Technologies:** React Native, Flutter, Ionic, Cordova
|
|
50
|
-
|
|
51
|
-
**Characteristics:**
|
|
52
|
-
- Single codebase for both platforms
|
|
53
|
-
- JavaScript/Dart + native bridges
|
|
54
|
-
- Good performance (near-native)
|
|
55
|
-
- Shared business logic, platform-specific UI
|
|
56
|
-
|
|
57
|
-
**Testing Tools:**
|
|
58
|
-
- Appium (cross-platform)
|
|
59
|
-
- Detox (React Native)
|
|
60
|
-
- Flutter Driver (Flutter)
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
### 3. Mobile Web
|
|
65
|
-
|
|
66
|
-
**PWAs, responsive websites in mobile browsers**
|
|
67
|
-
|
|
68
|
-
**Characteristics:**
|
|
69
|
-
- No app store submission
|
|
70
|
-
- Universal access via URL
|
|
71
|
-
- Limited device feature access
|
|
72
|
-
- Responsive design critical
|
|
73
|
-
|
|
74
|
-
**Testing Tools:**
|
|
75
|
-
- Playwright Mobile
|
|
76
|
-
- BrowserStack, Sauce Labs
|
|
77
|
-
- Chrome DevTools (mobile emulation)
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
## iOS vs Android Differences
|
|
82
|
-
|
|
83
|
-
### Key Differences
|
|
84
|
-
|
|
18
|
+
<default_to_action>
|
|
19
|
+
When testing mobile applications:
|
|
20
|
+
1. DEFINE device coverage matrix (Tier 1: 60%, Tier 2: 30%, Tier 3: 10%)
|
|
21
|
+
2. TEST platform differences (iOS ≠ Android: back button, permissions, UI)
|
|
22
|
+
3. VALIDATE touch gestures (tap, swipe, pinch, long-press)
|
|
23
|
+
4. TEST mobile-specific scenarios (offline, low battery, interruptions)
|
|
24
|
+
5. USE real devices for critical paths, emulators for fast feedback
|
|
25
|
+
|
|
26
|
+
**Quick Mobile Checklist:**
|
|
27
|
+
- Test on latest iOS + Android flagship devices
|
|
28
|
+
- Test offline mode and network transitions
|
|
29
|
+
- Verify push notifications work
|
|
30
|
+
- Test gesture interactions (swipe, pinch)
|
|
31
|
+
- Check permissions flow (camera, location, notifications)
|
|
32
|
+
|
|
33
|
+
**Critical Success Factors:**
|
|
34
|
+
- Emulators for 80% of testing, real devices for 20% critical paths
|
|
35
|
+
- Test on devices your users actually use (analytics)
|
|
36
|
+
- Device fragmentation is Android's biggest challenge
|
|
37
|
+
</default_to_action>
|
|
38
|
+
|
|
39
|
+
## Quick Reference Card
|
|
40
|
+
|
|
41
|
+
### When to Use
|
|
42
|
+
- Native app development (iOS/Android)
|
|
43
|
+
- Hybrid apps (React Native, Flutter)
|
|
44
|
+
- Mobile web / PWAs
|
|
45
|
+
- App store submission preparation
|
|
46
|
+
|
|
47
|
+
### iOS vs Android Differences
|
|
85
48
|
| Aspect | iOS | Android |
|
|
86
49
|
|--------|-----|---------|
|
|
87
|
-
|
|
|
88
|
-
|
|
|
89
|
-
|
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
| **Back Button** | Swipe/nav button | Hardware/software back button |
|
|
93
|
-
| **App Distribution** | App Store (strict review) | Google Play + sideloading |
|
|
94
|
-
| **Testing Tools** | XCUITest (native) | Espresso (native) |
|
|
50
|
+
| OS Versions | 2-3 supported | 10+ in use |
|
|
51
|
+
| Devices | ~40 models | 1000+ variants |
|
|
52
|
+
| Back Button | Gesture/nav | Hardware/software |
|
|
53
|
+
| Permissions | Single prompt | Runtime granular |
|
|
54
|
+
| App Store | Strict review | Google Play + sideload |
|
|
95
55
|
|
|
96
|
-
|
|
56
|
+
### Device Coverage Tiers
|
|
57
|
+
| Tier | Coverage | Devices |
|
|
58
|
+
|------|----------|---------|
|
|
59
|
+
| **Tier 1** | 60% users | iPhone 15, Galaxy S24, iPad |
|
|
60
|
+
| **Tier 2** | 30% users | iPhone 14/13, Pixel 8 |
|
|
61
|
+
| **Tier 3** | 10% users | Older devices, other manufacturers |
|
|
97
62
|
|
|
98
|
-
|
|
63
|
+
### Mobile Performance Goals
|
|
64
|
+
| Metric | Target |
|
|
65
|
+
|--------|--------|
|
|
66
|
+
| App launch | < 2 seconds |
|
|
67
|
+
| Screen transition | < 300ms |
|
|
68
|
+
| Frame rate | 60 FPS |
|
|
69
|
+
| Battery drain | < 5%/hour background |
|
|
99
70
|
|
|
100
|
-
|
|
71
|
+
---
|
|
101
72
|
|
|
102
|
-
|
|
103
|
-
```
|
|
104
|
-
Tap → Single touch
|
|
105
|
-
Double Tap → Quick two taps
|
|
106
|
-
Long Press → Touch and hold (context menu)
|
|
107
|
-
Swipe → Slide finger (scroll, swipe between screens)
|
|
108
|
-
Pinch → Two fingers move apart (zoom in)
|
|
109
|
-
Zoom Out → Two fingers move together (zoom out)
|
|
110
|
-
Rotate → Two fingers rotate
|
|
111
|
-
Multi-Touch → Multiple simultaneous touches
|
|
112
|
-
```
|
|
73
|
+
## Touch Gesture Testing
|
|
113
74
|
|
|
114
|
-
**Testing with Appium:**
|
|
115
75
|
```javascript
|
|
76
|
+
// Appium gesture examples
|
|
116
77
|
// Tap
|
|
117
|
-
await driver.touchAction({
|
|
118
|
-
action: 'tap',
|
|
119
|
-
x: 100,
|
|
120
|
-
y: 200
|
|
121
|
-
});
|
|
78
|
+
await driver.touchAction({ action: 'tap', x: 100, y: 200 });
|
|
122
79
|
|
|
123
80
|
// Swipe (scroll down)
|
|
124
81
|
await driver.touchAction([
|
|
@@ -143,393 +100,120 @@ await driver.multiTouchAction([finger1, finger2]);
|
|
|
143
100
|
// Long press
|
|
144
101
|
await driver.touchAction({
|
|
145
102
|
action: 'longPress',
|
|
146
|
-
x: 100,
|
|
147
|
-
|
|
148
|
-
duration: 2000 // 2 seconds
|
|
103
|
+
x: 100, y: 200,
|
|
104
|
+
duration: 2000
|
|
149
105
|
});
|
|
150
106
|
```
|
|
151
107
|
|
|
152
108
|
---
|
|
153
109
|
|
|
154
|
-
|
|
110
|
+
## Mobile-Specific Scenarios
|
|
155
111
|
|
|
156
|
-
**Device Sensors:**
|
|
157
|
-
- **GPS/Location:** Location services
|
|
158
|
-
- **Camera:** Photo/video capture
|
|
159
|
-
- **Microphone:** Audio recording
|
|
160
|
-
- **Accelerometer:** Device tilt/shake
|
|
161
|
-
- **Gyroscope:** Rotation detection
|
|
162
|
-
- **Proximity:** Screen off when near face
|
|
163
|
-
- **Ambient Light:** Brightness auto-adjust
|
|
164
|
-
|
|
165
|
-
**Testing Location:**
|
|
166
112
|
```javascript
|
|
167
|
-
//
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
longitude: -122.4194,
|
|
171
|
-
altitude: 0
|
|
172
|
-
});
|
|
113
|
+
// Offline mode testing
|
|
114
|
+
test('app works offline', async () => {
|
|
115
|
+
await driver.toggleAirplaneMode();
|
|
173
116
|
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
expect(
|
|
177
|
-
```
|
|
117
|
+
await driver.findElement('view-saved-items').click();
|
|
118
|
+
const items = await driver.findElements('saved-item');
|
|
119
|
+
expect(items.length).toBeGreaterThan(0);
|
|
178
120
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
// iOS: Push image to simulator
|
|
182
|
-
await driver.pushFile('/path/on/device/image.jpg', imageBase64);
|
|
121
|
+
const banner = await driver.findElement('offline-banner');
|
|
122
|
+
expect(banner.getText()).toContain('No internet');
|
|
183
123
|
|
|
184
|
-
|
|
185
|
-
await driver.execute('mobile: shell', {
|
|
186
|
-
command: 'am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///path'
|
|
124
|
+
await driver.toggleAirplaneMode(); // Restore
|
|
187
125
|
});
|
|
188
126
|
|
|
189
|
-
//
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
---
|
|
197
|
-
|
|
198
|
-
### 3. Permissions Testing
|
|
127
|
+
// Location testing
|
|
128
|
+
test('location-based features', async () => {
|
|
129
|
+
await driver.setGeoLocation({
|
|
130
|
+
latitude: 37.7749,
|
|
131
|
+
longitude: -122.4194,
|
|
132
|
+
altitude: 0
|
|
133
|
+
});
|
|
199
134
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
// Request permission (iOS shows system alert)
|
|
203
|
-
await driver.findElement('enable-location').click();
|
|
204
|
-
|
|
205
|
-
// Handle iOS permission alert
|
|
206
|
-
const alert = await driver.getAlert();
|
|
207
|
-
expect(alert.getText()).toContain('allow location');
|
|
208
|
-
await alert.accept(); // or alert.dismiss()
|
|
209
|
-
|
|
210
|
-
// Verify permission granted
|
|
211
|
-
const locationEnabled = await driver.findElement('location-status');
|
|
212
|
-
expect(locationEnabled.getText()).toBe('Enabled');
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
**Android Runtime Permissions:**
|
|
216
|
-
```javascript
|
|
217
|
-
// Grant permission before test (Android)
|
|
218
|
-
await driver.execute('mobile: shell', {
|
|
219
|
-
command: 'pm grant com.example.app android.permission.CAMERA'
|
|
135
|
+
const stores = await driver.findElement('stores-list');
|
|
136
|
+
expect(stores.getText()).toContain('San Francisco');
|
|
220
137
|
});
|
|
221
138
|
|
|
222
|
-
//
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
// Wait for permission dialog
|
|
226
|
-
const permissionDialog = await driver.waitForElement('com.android.packageinstaller:id/permission_message');
|
|
227
|
-
await driver.findElement('com.android.packageinstaller:id/permission_allow_button').click();
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
---
|
|
231
|
-
|
|
232
|
-
### 4. Network Conditions
|
|
233
|
-
|
|
234
|
-
**Test on Poor Networks:**
|
|
235
|
-
```javascript
|
|
236
|
-
// Simulate 3G network
|
|
237
|
-
await driver.setNetworkConnection(4); // 3G
|
|
238
|
-
|
|
239
|
-
// Test app behavior
|
|
240
|
-
await driver.findElement('load-content').click();
|
|
241
|
-
|
|
242
|
-
const loadingIndicator = await driver.waitForElement('spinner', 5000);
|
|
243
|
-
expect(loadingIndicator).toBeDefined();
|
|
244
|
-
|
|
245
|
-
// Restore full network
|
|
246
|
-
await driver.setNetworkConnection(6); // WiFi + Data
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
**Offline Mode Testing:**
|
|
250
|
-
```javascript
|
|
251
|
-
// Disable network
|
|
252
|
-
await driver.toggleAirplaneMode();
|
|
253
|
-
|
|
254
|
-
// Test offline functionality
|
|
255
|
-
await driver.findElement('view-saved-items').click();
|
|
256
|
-
const items = await driver.findElements('saved-item');
|
|
257
|
-
expect(items.length).toBeGreaterThan(0);
|
|
258
|
-
|
|
259
|
-
// Verify offline banner
|
|
260
|
-
const banner = await driver.findElement('offline-banner');
|
|
261
|
-
expect(banner.getText()).toContain('No internet connection');
|
|
262
|
-
|
|
263
|
-
// Re-enable network
|
|
264
|
-
await driver.toggleAirplaneMode();
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
---
|
|
139
|
+
// Permission testing (Android)
|
|
140
|
+
test('camera permission flow', async () => {
|
|
141
|
+
await driver.findElement('take-photo').click();
|
|
268
142
|
|
|
269
|
-
|
|
143
|
+
// Handle permission dialog
|
|
144
|
+
await driver.findElement(
|
|
145
|
+
'com.android.packageinstaller:id/permission_allow_button'
|
|
146
|
+
).click();
|
|
270
147
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
**Emulators/Simulators:**
|
|
274
|
-
- **Pros:** Fast, free, easy to automate, unlimited devices
|
|
275
|
-
- **Cons:** Not 100% accurate, no real sensors, different performance
|
|
276
|
-
|
|
277
|
-
**Real Devices:**
|
|
278
|
-
- **Pros:** Accurate, real sensors, actual performance, real network
|
|
279
|
-
- **Cons:** Expensive, harder to maintain, slower
|
|
280
|
-
|
|
281
|
-
**Strategy:** Use emulators for fast feedback, real devices for critical paths
|
|
282
|
-
|
|
283
|
-
---
|
|
284
|
-
|
|
285
|
-
### Device Coverage Matrix
|
|
286
|
-
|
|
287
|
-
**Priority Tiers:**
|
|
288
|
-
|
|
289
|
-
**Tier 1 (Must Test):**
|
|
290
|
-
- Latest iPhone (iOS current version)
|
|
291
|
-
- Latest Samsung Galaxy (Android current version)
|
|
292
|
-
- iPad (latest)
|
|
293
|
-
- ~60% of user base
|
|
294
|
-
|
|
295
|
-
**Tier 2 (Should Test):**
|
|
296
|
-
- iPhone N-1, N-2 (previous 2 generations)
|
|
297
|
-
- Samsung Galaxy N-1, N-2
|
|
298
|
-
- Google Pixel (latest)
|
|
299
|
-
- One popular low-end Android
|
|
300
|
-
- ~30% of user base
|
|
301
|
-
|
|
302
|
-
**Tier 3 (Nice to Test):**
|
|
303
|
-
- Older devices (N-3, N-4)
|
|
304
|
-
- Various manufacturers (Xiaomi, OnePlus, etc.)
|
|
305
|
-
- Tablets
|
|
306
|
-
- ~10% of user base
|
|
307
|
-
|
|
308
|
-
**Example Matrix:**
|
|
309
|
-
```
|
|
310
|
-
Device | OS Version | Screen Size | Priority
|
|
311
|
-
-----------------------|------------|-------------|----------
|
|
312
|
-
iPhone 15 Pro | iOS 17 | 6.1" | Tier 1
|
|
313
|
-
iPhone 14 | iOS 16 | 6.1" | Tier 2
|
|
314
|
-
iPhone 13 | iOS 15 | 6.1" | Tier 2
|
|
315
|
-
iPad Pro | iOS 17 | 12.9" | Tier 1
|
|
316
|
-
Samsung Galaxy S24 | Android 14 | 6.2" | Tier 1
|
|
317
|
-
Samsung Galaxy S23 | Android 13 | 6.1" | Tier 2
|
|
318
|
-
Google Pixel 8 | Android 14 | 6.2" | Tier 2
|
|
319
|
-
Xiaomi Redmi Note 12 | Android 13 | 6.67" | Tier 3
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
---
|
|
323
|
-
|
|
324
|
-
## Mobile Automation with Appium
|
|
325
|
-
|
|
326
|
-
### Setup
|
|
327
|
-
|
|
328
|
-
**Install Appium:**
|
|
329
|
-
```bash
|
|
330
|
-
npm install -g appium
|
|
331
|
-
appium driver install xcuitest # iOS
|
|
332
|
-
appium driver install uiautomator2 # Android
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
**Capabilities (iOS):**
|
|
336
|
-
```javascript
|
|
337
|
-
const caps = {
|
|
338
|
-
platformName: 'iOS',
|
|
339
|
-
'appium:platformVersion': '17.0',
|
|
340
|
-
'appium:deviceName': 'iPhone 15',
|
|
341
|
-
'appium:automationName': 'XCUITest',
|
|
342
|
-
'appium:app': '/path/to/app.ipa',
|
|
343
|
-
'appium:noReset': true,
|
|
344
|
-
'appium:fullReset': false
|
|
345
|
-
};
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
**Capabilities (Android):**
|
|
349
|
-
```javascript
|
|
350
|
-
const caps = {
|
|
351
|
-
platformName: 'Android',
|
|
352
|
-
'appium:platformVersion': '14',
|
|
353
|
-
'appium:deviceName': 'Pixel 8',
|
|
354
|
-
'appium:automationName': 'UiAutomator2',
|
|
355
|
-
'appium:app': '/path/to/app.apk',
|
|
356
|
-
'appium:appPackage': 'com.example.app',
|
|
357
|
-
'appium:appActivity': '.MainActivity'
|
|
358
|
-
};
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
---
|
|
362
|
-
|
|
363
|
-
### Cross-Platform Tests
|
|
364
|
-
|
|
365
|
-
**Page Object Pattern:**
|
|
366
|
-
```javascript
|
|
367
|
-
class LoginPage {
|
|
368
|
-
get emailInput() {
|
|
369
|
-
return platform === 'iOS'
|
|
370
|
-
? $('~email-input') // accessibility id
|
|
371
|
-
: $('android=new UiSelector().resourceId("email")');
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
get passwordInput() {
|
|
375
|
-
return platform === 'iOS'
|
|
376
|
-
? $('~password-input')
|
|
377
|
-
: $('android=new UiSelector().resourceId("password")');
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
get loginButton() {
|
|
381
|
-
return platform === 'iOS'
|
|
382
|
-
? $('~login-button')
|
|
383
|
-
: $('android=new UiSelector().text("Login")');
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
async login(email, password) {
|
|
387
|
-
await this.emailInput.setValue(email);
|
|
388
|
-
await this.passwordInput.setValue(password);
|
|
389
|
-
await this.loginButton.click();
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
// Use in tests
|
|
394
|
-
test('user can login', async () => {
|
|
395
|
-
const loginPage = new LoginPage();
|
|
396
|
-
await loginPage.login('test@example.com', 'password123');
|
|
397
|
-
|
|
398
|
-
expect(await dashboardPage.isDisplayed()).toBe(true);
|
|
148
|
+
expect(await driver.findElement('camera-view')).toBeDefined();
|
|
399
149
|
});
|
|
400
150
|
```
|
|
401
151
|
|
|
402
152
|
---
|
|
403
153
|
|
|
404
|
-
## Mobile
|
|
405
|
-
|
|
406
|
-
### Key Metrics
|
|
407
|
-
|
|
408
|
-
**Performance Goals:**
|
|
409
|
-
- **App Launch:** < 2 seconds
|
|
410
|
-
- **Screen Transition:** < 300ms
|
|
411
|
-
- **Network Request:** < 1 second
|
|
412
|
-
- **Frame Rate:** 60 FPS (no jank)
|
|
413
|
-
- **Battery Drain:** < 5%/hour (background)
|
|
414
|
-
- **Memory Usage:** < 150MB (typical app)
|
|
415
|
-
|
|
416
|
-
**Measuring with Appium:**
|
|
417
|
-
```javascript
|
|
418
|
-
// Get performance data
|
|
419
|
-
const perfData = await driver.getPerformanceData('com.example.app', 'cpuinfo', 5);
|
|
420
|
-
console.log('CPU Usage:', perfData);
|
|
421
|
-
|
|
422
|
-
const memData = await driver.getPerformanceData('com.example.app', 'memoryinfo', 5);
|
|
423
|
-
console.log('Memory Usage:', memData);
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
**iOS Instruments:**
|
|
427
|
-
```bash
|
|
428
|
-
# Measure launch time
|
|
429
|
-
instruments -t "Time Profiler" -D trace.trace -w "iPhone 15" MyApp.app
|
|
430
|
-
|
|
431
|
-
# Measure memory
|
|
432
|
-
instruments -t "Allocations" -D memory.trace -w "iPhone 15" MyApp.app
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
**Android Profiler:**
|
|
436
|
-
```bash
|
|
437
|
-
# Measure CPU
|
|
438
|
-
adb shell dumpsys cpuinfo | grep com.example.app
|
|
439
|
-
|
|
440
|
-
# Measure memory
|
|
441
|
-
adb shell dumpsys meminfo com.example.app
|
|
442
|
-
|
|
443
|
-
# Measure battery
|
|
444
|
-
adb shell dumpsys batterystats --reset
|
|
445
|
-
# Use app for 1 hour
|
|
446
|
-
adb shell dumpsys batterystats com.example.app
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
---
|
|
450
|
-
|
|
451
|
-
## Using with QE Agents
|
|
452
|
-
|
|
453
|
-
### qe-mobile-tester: Intelligent Cross-Platform Testing
|
|
154
|
+
## Agent-Driven Mobile Testing
|
|
454
155
|
|
|
455
156
|
```typescript
|
|
456
|
-
//
|
|
457
|
-
|
|
157
|
+
// Cross-platform mobile testing
|
|
158
|
+
await Task("Mobile Test Suite", {
|
|
458
159
|
platforms: ['iOS', 'Android'],
|
|
459
|
-
deviceTiers: [1, 2],
|
|
160
|
+
deviceTiers: [1, 2],
|
|
460
161
|
tests: 'regression-suite',
|
|
461
|
-
parallelDevices: 5
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
// Returns:
|
|
465
|
-
// {
|
|
466
|
-
// iOS: {
|
|
467
|
-
// iPhone15: { passed: 47, failed: 0 },
|
|
468
|
-
// iPhone14: { passed: 46, failed: 1 }
|
|
469
|
-
// },
|
|
470
|
-
// Android: {
|
|
471
|
-
// GalaxyS24: { passed: 45, failed: 2 },
|
|
472
|
-
// Pixel8: { passed: 47, failed: 0 }
|
|
473
|
-
// },
|
|
474
|
-
// totalTime: '15 minutes',
|
|
475
|
-
// deviceFarmCost: '$8.50'
|
|
476
|
-
// }
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
### Device Farm Integration
|
|
162
|
+
parallelDevices: 5,
|
|
163
|
+
deviceFarm: 'browserstack'
|
|
164
|
+
}, "qe-test-executor");
|
|
480
165
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
await agent.runOnDeviceFarm({
|
|
166
|
+
// Device farm integration
|
|
167
|
+
await Task("Device Farm Execution", {
|
|
484
168
|
service: 'browserstack',
|
|
485
169
|
devices: [
|
|
486
170
|
'iPhone 15 - iOS 17',
|
|
487
|
-
'Samsung Galaxy S24 - Android 14'
|
|
488
|
-
'iPad Pro - iOS 17'
|
|
171
|
+
'Samsung Galaxy S24 - Android 14'
|
|
489
172
|
],
|
|
490
|
-
tests: 'smoke-suite',
|
|
491
173
|
recordVideo: true,
|
|
492
174
|
captureNetworkLogs: true
|
|
493
|
-
});
|
|
175
|
+
}, "qe-test-executor");
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Agent Coordination Hints
|
|
181
|
+
|
|
182
|
+
### Memory Namespace
|
|
183
|
+
```
|
|
184
|
+
aqe/mobile-testing/
|
|
185
|
+
├── device-matrix/* - Device coverage strategy
|
|
186
|
+
├── platform-tests/* - iOS/Android specific tests
|
|
187
|
+
├── gesture-library/* - Reusable gesture patterns
|
|
188
|
+
└── performance/* - Mobile performance metrics
|
|
189
|
+
```
|
|
494
190
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
191
|
+
### Fleet Coordination
|
|
192
|
+
```typescript
|
|
193
|
+
const mobileFleet = await FleetManager.coordinate({
|
|
194
|
+
strategy: 'mobile-testing',
|
|
195
|
+
agents: [
|
|
196
|
+
'qe-test-executor', // Cross-platform execution
|
|
197
|
+
'qe-performance-tester', // Mobile performance
|
|
198
|
+
'qe-visual-tester' // Screen size validation
|
|
199
|
+
],
|
|
200
|
+
topology: 'parallel'
|
|
201
|
+
});
|
|
498
202
|
```
|
|
499
203
|
|
|
500
204
|
---
|
|
501
205
|
|
|
502
206
|
## Related Skills
|
|
503
|
-
|
|
504
|
-
**Core Testing:**
|
|
505
|
-
- [agentic-quality-engineering](../agentic-quality-engineering/) - Mobile testing agents
|
|
506
|
-
- [regression-testing](../regression-testing/) - Mobile regression
|
|
207
|
+
- [accessibility-testing](../accessibility-testing/) - VoiceOver, TalkBack
|
|
507
208
|
- [performance-testing](../performance-testing/) - Mobile performance
|
|
508
|
-
|
|
509
|
-
**Specialized:**
|
|
510
|
-
- [accessibility-testing](../accessibility-testing/) - Mobile a11y (VoiceOver, TalkBack)
|
|
511
|
-
- [security-testing](../security-testing/) - Mobile security
|
|
512
209
|
- [compatibility-testing](../compatibility-testing/) - Device compatibility
|
|
513
210
|
|
|
514
211
|
---
|
|
515
212
|
|
|
516
213
|
## Remember
|
|
517
214
|
|
|
518
|
-
**Mobile is not a smaller desktop - it's a different platform.**
|
|
519
|
-
|
|
520
|
-
Unique challenges:
|
|
521
|
-
- Device fragmentation (1000+ devices)
|
|
522
|
-
- Touch gestures, not mouse clicks
|
|
523
|
-
- Sensors, permissions, offline scenarios
|
|
524
|
-
- Intermittent networks, battery constraints
|
|
525
|
-
- Platform differences (iOS ≠ Android)
|
|
526
|
-
|
|
527
|
-
**Test on real devices for critical flows.**
|
|
215
|
+
**Mobile is not a smaller desktop - it's a different platform.** 60%+ of web traffic is mobile. Device fragmentation (1000+ Android devices), touch gestures, sensors, permissions, offline scenarios - all require specific testing.
|
|
528
216
|
|
|
529
|
-
Emulators catch 80% of bugs
|
|
530
|
-
- Actual performance
|
|
531
|
-
- Real sensor behavior
|
|
532
|
-
- Network reliability
|
|
533
|
-
- Platform-specific quirks
|
|
217
|
+
**Test on real devices for critical flows.** Emulators catch 80% of bugs but real devices needed for actual performance, sensor behavior, and platform quirks.
|
|
534
218
|
|
|
535
|
-
**With Agents:** `qe-
|
|
219
|
+
**With Agents:** `qe-test-executor` orchestrates testing across device farms, manages platform differences, and tests 10+ devices in parallel. Reduces mobile testing from days to hours.
|