@roopesh.yadava/qa-pack 1.4.0 → 1.5.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.
@@ -0,0 +1,234 @@
1
+ # Mobile MCP + MobileWright — Command & Tool Reference
2
+
3
+ > Load this file once at Phase 0 (Environment + Device Discovery). Do not reload later in
4
+ > the run — reference tools/commands by name from context, same discipline as the web
5
+ > `automation` skill applies to `LOCATOR_PATTERNS.md`.
6
+
7
+ ## Two tool surfaces — know which one to reach for
8
+
9
+ | Surface | Role | When to use |
10
+ |---|---|---|
11
+ | **Mobile MCP** (`mobile-next/mobile-mcp`) | Live device control — the mobile equivalent of Playwright MCP. Drives the actual simulator/emulator/real device during authoring and self-heal. | Discovering devices/apps, inspecting the current screen, tapping/typing/swiping to explore a flow before writing a locator, re-inspecting on self-heal |
12
+ | **MobileWright** (`mobilewright` CLI + `@mobilewright/test`) | The authored test framework — what the generated Gherkin/step-defs/POM actually run against. | Writing the real test code, running the real suite, generating reports |
13
+
14
+ Generated tests never call Mobile MCP tools directly. Mobile MCP is this skill's
15
+ authoring/inspection tool — exactly how Playwright MCP is used by the web `automation`
16
+ skill, never referenced from inside the `.feature`/step-def/POM files it produces.
17
+
18
+ ## Mobile MCP — Tool Catalog
19
+
20
+ From `mobile-next/mobile-mcp`. Verify exact names **and parameters** against whatever server
21
+ is actually connected before relying on them — MCP servers version-drift like anything else;
22
+ if a tool listed here doesn't exist, or takes different arguments than assumed, treat the
23
+ connected server as the current truth, not this table. In particular: when Phase 0c resolves
24
+ more than one connected device, check whether each tool call below needs an explicit device
25
+ identifier passed alongside it — don't assume every call implicitly targets "the" device
26
+ once more than one is available.
27
+
28
+ ### Device Management
29
+ | Tool | Purpose |
30
+ |---|---|
31
+ | `mobile_list_available_devices` | Lists simulators, emulators, and connected real devices |
32
+ | `mobile_get_screen_size` | Screen dimensions in pixels — needed before any coordinate-based tap |
33
+ | `mobile_get_orientation` / `mobile_set_orientation` | Read / change portrait ↔ landscape |
34
+
35
+ ### App Management
36
+ | Tool | Purpose |
37
+ |---|---|
38
+ | `mobile_list_apps` | Installed apps on the device |
39
+ | `mobile_launch_app` | Start an app by package/bundle ID |
40
+ | `mobile_terminate_app` | Stop a running app — cold-start on next launch (distinct from HOME — see `LOCATOR_PATTERNS.md` §10) |
41
+ | `mobile_install_app` | Deploy `.apk` / `.ipa` / `.app` / `.zip` |
42
+ | `mobile_uninstall_app` | Remove by bundle ID / package name |
43
+
44
+ ### Screen Interaction & UI Inspection
45
+ | Tool | Purpose | Token cost |
46
+ |---|---|---|
47
+ | `mobile_list_elements_on_screen` | Reads the real accessibility tree — coordinates + properties **including `resource-id` and accessibility-id fields**. Mobile equivalent of `browser_snapshot()` / DOM inspection. | Expensive — full tree. Once per new/changed screen, never per interaction |
48
+ | `mobile_take_screenshot` | Captures current screen, returned inline | Expensive if not saved |
49
+ | `mobile_save_screenshot` | Persists screenshot straight to a file | Cheap — zero response tokens, use for all evidence capture |
50
+ | `mobile_click_on_screen_at_coordinates` | Tap at x,y | Last-resort locator method only |
51
+ | `mobile_double_tap_on_screen` | Double-tap at x,y | — |
52
+ | `mobile_long_press_on_screen_at_coordinates` | Long-press at x,y | — |
53
+ | `mobile_swipe_on_screen` | Directional swipe (up/down/left/right) | — |
54
+
55
+ ### Input & Navigation
56
+ | Tool | Purpose |
57
+ |---|---|
58
+ | `mobile_type_keys` | Enter text, optional submit |
59
+ | `mobile_press_button` | `HOME` / `BACK` (Android only) / `VOLUME_UP` / `VOLUME_DOWN` / `ENTER` |
60
+ | `mobile_open_url` | Open a URL in the device browser — deep-link entry points |
61
+
62
+ ### Recording & Diagnostics
63
+ | Tool | Purpose |
64
+ |---|---|
65
+ | `mobile_start_screen_recording` / `mobile_stop_screen_recording` | Video capture across a multi-step flow |
66
+ | `mobile_list_crashes` / `mobile_get_crash` | Retrieve crash reports — pull the crash report into a bug candidate's Description when a self-heal assertion failure coincides with a crash |
67
+
68
+ ## Token Discipline
69
+
70
+ Mirrors the web `automation`/`manual-testing` skills' Playwright rules — same principle, different tool names:
71
+
72
+ | Operation | Use | Avoid | Why |
73
+ |---|---|---|---|
74
+ | Screen inspection | `mobile_list_elements_on_screen` once per new/changed screen | Calling it after every single tap | Full accessibility tree — same cost profile as `browser_snapshot()` |
75
+ | Evidence capture | `mobile_save_screenshot` | `mobile_take_screenshot` without saving | Inline image return burns response tokens |
76
+ | Repeated screens | Fingerprint check (below) before re-inspecting | Re-dumping a screen whose resource-ids haven't moved | Same principle as the web skill's DOM fingerprint cache |
77
+
78
+ ## Resource-ID / Accessibility-ID Detection ("is there a testid on this screen")
79
+
80
+ Before writing any locator, dump the current screen and check whether the target element
81
+ carries a stable identifier:
82
+
83
+ ```
84
+ mobile_list_elements_on_screen()
85
+ ```
86
+
87
+ For each element in the result, check in this order:
88
+ 1. **`resource-id`** (Android) or **`accessibility-id`** (iOS) — if present, this is the
89
+ mobile equivalent of a web `data-testid` and maps directly to MobileWright's
90
+ `screen.getByTestId(...)`. Check both field names — they aren't interchangeable across
91
+ platforms (see `LOCATOR_PATTERNS.md` §1).
92
+ 2. If absent, check for an accessibility label/role (`getByLabel` / `getByRole`).
93
+ 3. If neither, fall through to the Locator Priority table in `LOCATOR_PATTERNS.md`.
94
+
95
+ If `npx mobilewright --help` (checked once at Phase 0) reveals a dedicated UI-dump command in
96
+ the installed version, prefer it for authoring convenience — but `mobile_list_elements_on_screen`
97
+ stays the source of truth during self-heal since it reflects the live device, not a static
98
+ dump. Don't assume a specific dump subcommand name beyond what `--help`/`doctor` actually shows
99
+ for the installed version.
100
+
101
+ ## MobileWright — Setup & Environment Commands
102
+
103
+ ```bash
104
+ npx mobilewright doctor # environment health check (Xcode, ADB, simulators)
105
+ npx mobilewright doctor --json # machine-readable, for logging without narrating to chat
106
+ npx mobilewright doctor --category ios|android|system
107
+ npx mobilewright devices # list connected devices/simulators/emulators
108
+ npm init mobilewright@latest # scaffold config + example test (skips existing files)
109
+ ```
110
+
111
+ `mobilecli` (the device server) must already be running in a separate terminal —
112
+ `mobilecli start`. If any MCP tool call or `doctor` reports no device / connection refused,
113
+ stop and ask the user to confirm `mobilecli` is running before proceeding — same pattern as
114
+ the web skill's Playwright MCP pre-flight check.
115
+
116
+ ## MobileWright — Config Reference
117
+
118
+ `mobilewright.config.ts` (or `.js`) at the project root. Config values are defaults —
119
+ options passed directly to a launch call always win.
120
+
121
+ ```typescript
122
+ import { defineConfig } from 'mobilewright';
123
+
124
+ export default defineConfig({
125
+ platform: 'android', // 'ios' | 'android'
126
+ bundleId: 'com.example.app',
127
+ deviceName: /Pixel 7/,
128
+ installApps: './builds/app.apk',
129
+ timeout: 10_000,
130
+ retries: 1,
131
+ reporter: 'html',
132
+ });
133
+ ```
134
+
135
+ Multi-platform matrix:
136
+ ```typescript
137
+ export default defineConfig({
138
+ projects: [
139
+ { name: 'iOS', platform: 'ios', bundleId: 'com.app.ios' },
140
+ { name: 'Android', platform: 'android', bundleId: 'com.app.android' },
141
+ ],
142
+ });
143
+ ```
144
+
145
+ ## MobileWright — Test-Writing API (what generated POM/step defs call)
146
+
147
+ ```typescript
148
+ import { test, expect } from '@mobilewright/test';
149
+
150
+ // Finding elements — priority order matches LOCATOR_PATTERNS.md
151
+ screen.getByTestId('submit-button'); // 1st — maps to resource-id/accessibility-id
152
+ screen.getByRole('button', { name: 'Submit' }); // 2nd
153
+ screen.getByLabel('Username'); // 2nd (accessibility label)
154
+ screen.getByText('Sign In'); // 3rd — fragile across locales
155
+ screen.getByType('TextField'); // 4th — broad, last resort before coordinates
156
+
157
+ // Actions
158
+ await screen.getByText('Sign In').tap();
159
+ await screen.getByRole('button', { name: 'Submit' }).doubleTap();
160
+ await screen.getByText('Options').longPress();
161
+ await screen.getByLabel('Email').fill('user@example.com');
162
+ await screen.swipe('up');
163
+ await screen.swipe('down', { distance: 300 });
164
+ await screen.pressButton('HOME');
165
+ await screen.pressButton('BACK'); // Android only
166
+
167
+ // Assertions
168
+ await expect(screen.getByText('Welcome')).toBeVisible();
169
+ await expect(screen.getByRole('button', { name: 'Submit' })).toBeEnabled();
170
+ await expect(screen.getByTestId('greeting')).toHaveText('Hello, World');
171
+ await expect(screen.getByText('Error')).not.toBeVisible();
172
+ ```
173
+
174
+ ## MobileWright — Running Tests
175
+
176
+ Native runner:
177
+ ```bash
178
+ npx mobilewright test # all tests
179
+ npx mobilewright test tests/login.test.ts # one file
180
+ npx mobilewright test --grep "sign in"
181
+ npx mobilewright test --project=ios
182
+ npx mobilewright test --list # list without running
183
+ ```
184
+
185
+ BDD/Cucumber profile — this skill's default output shape, matching the pack's existing
186
+ reuse-first Gherkin approach:
187
+ ```bash
188
+ npm test # all features, default profile
189
+ npm run test:android # PLATFORM=android
190
+ npm run test:ios # PLATFORM=ios
191
+ npm run test:dry # validate steps without touching a device — mobile
192
+ # equivalent of `cucumber-js --dry-run`
193
+ npx cucumber-js test/features/Auth/login.feature
194
+ npx cucumber-js --tags @smoke
195
+ ```
196
+
197
+ Reports:
198
+ ```bash
199
+ npx mobilewright show-report
200
+ npx mobilewright show-report --host 0.0.0.0 --port 8080
201
+ npm run report:open # BDD profile's cucumber-report.html
202
+ ```
203
+
204
+ ## MobileWright — Project Structure (BDD/Cucumber profile)
205
+
206
+ Discover this at Phase 0 — never impose it if the repo already has its own layout, same rule
207
+ the web `automation` skill follows for its tree (including preserving any existing typos):
208
+
209
+ ```
210
+ test/
211
+ app/ # .apk / .ipa binaries
212
+ features/ # Gherkin .feature files
213
+ Pages/ # Page Object Model classes
214
+ step_definitions/ # Cucumber step implementations (Driver.js = World + hooks)
215
+ TestData/ # Faker-based test data generators
216
+ Utils/BasePage.js # Base class for all page objects
217
+ cucumber.js # Cucumber profile config
218
+ mobilewright.config.js
219
+ .env.example / .env
220
+ ```
221
+
222
+ ## Debugging
223
+
224
+ ```bash
225
+ DEBUG=mw:* npx mobilewright test # verbose logging
226
+ MWDEBUGIMPL=1 npx mobilewright test # verbose driver output
227
+ ```
228
+
229
+ | Issue | Fix |
230
+ |---|---|
231
+ | `mobilecli: command not found` | `npm install -g mobilecli@latest` |
232
+ | No devices found / connection refused | `adb kill-server && adb start-server && adb devices`, or confirm `mobilecli start` is running |
233
+ | Tests time out immediately | Confirm `mobilecli` running, device ID matches `mobilewright devices`, raise timeout |
234
+ | iOS not running on Linux/Windows | iOS requires macOS + Xcode — use `platform: 'android'` elsewhere |