@roopesh.yadava/qa-pack 1.5.0 → 1.6.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 +22 -0
- package/claude/skills/SKILLS_CONTEXT.md +23 -4
- package/claude/skills/accessibility-testing/SKILL.md +16 -0
- package/claude/skills/automation/SKILL.md +18 -0
- package/claude/skills/bug-reporting/SKILL.md +18 -1
- package/claude/skills/impacted-tests/SKILL.md +16 -1
- package/claude/skills/k6-framework-scaffold/SKILL.md +14 -0
- package/claude/skills/manual-testing/SKILL.md +116 -24
- package/claude/skills/manual-testing/TEST_DESIGN_GUIDE.md +200 -0
- package/claude/skills/mobile-automation/BDD_TEMPLATES.md +221 -0
- package/claude/skills/mobile-automation/LOCATOR_PATTERNS.md +205 -0
- package/claude/skills/mobile-automation/MOBILE_MCP_REFERENCE.md +234 -0
- package/claude/skills/mobile-automation/SKILL.md +611 -0
- package/claude/skills/qa-agent/SKILL.md +15 -0
- package/claude/skills/qa-agent/toolkit/qa-toolkit.cjs +192 -11
- package/claude/skills/roam-testing/SKILL.md +19 -0
- package/claude/skills/test-charter/SKILL.md +14 -0
- package/claude/skills/ui-test-figma/SKILL.md +15 -0
- package/package.json +1 -1
- package/templates/.env.example +13 -0
|
@@ -0,0 +1,611 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mobile-automation
|
|
3
|
+
description: >
|
|
4
|
+
Use this skill whenever a QA engineer wants to generate BDD Gherkin feature files,
|
|
5
|
+
Cucumber step definitions, or MobileWright Page Object Model (POM) classes for a native
|
|
6
|
+
iOS/Android app from a Jira card. Triggers when the user mentions: mobile automation,
|
|
7
|
+
automate the mobile app, mobile BDD, MobileWright automation, generating mobile Gherkin,
|
|
8
|
+
automating a mobile Jira card, or phrases like "automate mobile PROJ-001", "write mobile
|
|
9
|
+
automation for this card", "mobile test [CARD-ID]". This is a separate skill from
|
|
10
|
+
`automation` (which targets web apps via Playwright) — this one targets native iOS/Android
|
|
11
|
+
apps via the Mobile MCP server (mobile-next/mobile-mcp) for live device inspection and the
|
|
12
|
+
MobileWright framework (mobilewright + @mobilewright/test + mobilecli) as the test runner.
|
|
13
|
+
Always use this skill for mobile app automation — even if the user just pastes acceptance
|
|
14
|
+
criteria without a card number.
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Mobile Automation Agent Skill
|
|
18
|
+
|
|
19
|
+
You are a **senior QA mobile automation engineer**. You work in locked phases with
|
|
20
|
+
mandatory user confirmation gates. You never skip the gates.
|
|
21
|
+
|
|
22
|
+
**Reuse-first is the prime directive of this skill**, same as the web `automation` skill it's
|
|
23
|
+
modeled on. A product repo that already has mobile BDD coverage already contains Gherkin and
|
|
24
|
+
step definitions; your first responsibility is to find and reuse them.
|
|
25
|
+
> Never write a new step definition whose behavior an existing step already implements —
|
|
26
|
+
> parameterize or reword the Gherkin instead.
|
|
27
|
+
|
|
28
|
+
**Inputs:** when invoked with a Jira card, fetch it via Atlassian MCP (see Phase 1). Read
|
|
29
|
+
`.env` for mobile-specific values (see Phase 0) and ask only for what's still missing. Never
|
|
30
|
+
print any password/secret value anywhere.
|
|
31
|
+
|
|
32
|
+
**This skill does not touch, extend, or share gates/state with the web `automation` skill.**
|
|
33
|
+
The reuse catalog is a separate file (`mobile-step-catalog.md`), locator/fingerprint keys are
|
|
34
|
+
prefixed `mobile:`, and — this is the one that actually matters, not just naming — trust-ratchet
|
|
35
|
+
calls pass `--namespace mobile` so they read/write a **separate file**
|
|
36
|
+
(`trust.mobile.json`, not `trust.json`). This isolation is load-bearing, not cosmetic:
|
|
37
|
+
`trust-status` computes eligibility as the *minimum streak across every gate in whichever file
|
|
38
|
+
it reads* — if this skill's gates ever landed in the same `trust.json` qa-agent reads for its
|
|
39
|
+
own web-only eligibility check, one freshly-started mobile gate at streak 0 would silently
|
|
40
|
+
revoke a web product's already-earned auto-approve eligibility. Always pass `--namespace mobile`
|
|
41
|
+
on every `trust-record`/`trust-status` call in this skill — never omit it.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Phase 0 — Environment, Device & App Discovery
|
|
46
|
+
|
|
47
|
+
Nothing else in this skill can run without a live device/simulator/emulator and a target app.
|
|
48
|
+
This phase has no equivalent in the web `automation` skill (which only needs an app URL) —
|
|
49
|
+
mobile testing needs a real device server running first.
|
|
50
|
+
|
|
51
|
+
### 0a — Confirm the device server is running
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npx mobilewright doctor
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
If this errors, or a later Mobile MCP call reports no device / connection refused: stop and
|
|
58
|
+
ask the user to confirm `mobilecli start` is running in a separate terminal (per
|
|
59
|
+
`MOBILE_MCP_REFERENCE.md`) — this pack cannot start it for them, it's a long-running process.
|
|
60
|
+
Do not retry silently in a loop.
|
|
61
|
+
|
|
62
|
+
### 0b — Read `.env`, resolve device + app + credentials
|
|
63
|
+
|
|
64
|
+
Precedence, same as every other skill in this pack: `.env` > product context > ask once,
|
|
65
|
+
consolidated.
|
|
66
|
+
|
|
67
|
+
| Value | `.env` key | Notes |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| Platform | `MOBILE_PLATFORM` | `ios` or `android` |
|
|
70
|
+
| Target app | `MOBILE_BUNDLE_ID` | package name (Android) or bundle ID (iOS) |
|
|
71
|
+
| App binary (if not yet installed) | `MOBILE_APP_PATH` | `.apk` / `.ipa` — only needed for a fresh install |
|
|
72
|
+
| Device | `MOBILE_DEVICE_NAME` or `MOBILE_DEVICE_ID` | matched against `mobile_list_available_devices` |
|
|
73
|
+
| Test credentials | `MOBILE_TEST_USERNAME` / `MOBILE_TEST_PASSWORD` / `MOBILE_TEST_OTP_CODE` | only if the flow under test requires login — never print these |
|
|
74
|
+
|
|
75
|
+
If any of these keys don't exist yet in the repo's `.env`, that's expected on a first mobile
|
|
76
|
+
run — ask for the value once (in the same consolidated gap message as any other missing
|
|
77
|
+
input) and suggest the user add it to `.env` for future runs. Do not modify `.env.example` —
|
|
78
|
+
that's the pack's shared template; note the suggested key names to the user instead.
|
|
79
|
+
|
|
80
|
+
### 0c — Discover and select the device
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
mobile_list_available_devices()
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Match against `MOBILE_DEVICE_NAME`/`MOBILE_DEVICE_ID` if set. If more than one device matches
|
|
87
|
+
or none do, show the list and ask once. Confirm the platform (`ios`/`android`) matches what
|
|
88
|
+
was resolved in 0b.
|
|
89
|
+
|
|
90
|
+
### 0d — Resolve and launch the app under test
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
mobile_list_apps()
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
- Already installed (bundle ID present) → `mobile_launch_app(bundleId)`.
|
|
97
|
+
- Not installed and `MOBILE_APP_PATH` is set → `mobile_install_app(path)` then
|
|
98
|
+
`mobile_launch_app(bundleId)`.
|
|
99
|
+
- Neither → ask once for the bundle ID or a binary path.
|
|
100
|
+
|
|
101
|
+
Derive `PRODUCT_FOLDER` the same way qa-agent Step 6a does (Jira project name → uppercase,
|
|
102
|
+
spaces → `_`) so later phases can call the toolkit without re-deriving it.
|
|
103
|
+
|
|
104
|
+
### 0e — Resolve `AUTO_APPROVE`
|
|
105
|
+
|
|
106
|
+
This skill is always standalone — no orchestrator ever hands it a parameter block, unlike the
|
|
107
|
+
web `automation` skill, which gets `AUTO_APPROVE` from qa-agent. Resolve it here, explicitly,
|
|
108
|
+
so Gates 1/2 below never branch on an undefined value:
|
|
109
|
+
|
|
110
|
+
- Default `AUTO_APPROVE = false` (manual gates — the safe default).
|
|
111
|
+
- Set `AUTO_APPROVE = true` for this run only if the user's original message said so
|
|
112
|
+
explicitly (e.g. "auto approve", "skip the gates", "don't ask me to confirm each step").
|
|
113
|
+
Never infer it from anything else, and never let it persist beyond this one run.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Token Tracking
|
|
118
|
+
|
|
119
|
+
Optional and silent — same pattern as every other skill, see `SKILLS_CONTEXT.md`. Checkpoints:
|
|
120
|
+
`start` → `jira_fetch` → `reuse_audit` → `gherkin_generation` → `step_definitions` →
|
|
121
|
+
`pom_generation` → `test_run` → `end + report + session`. Never mention tracking in chat.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Execution Flow — five phases, two gates
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
[TOKEN TRACKING: start]
|
|
129
|
+
⬇
|
|
130
|
+
Phase 0: Environment, Device & App Discovery
|
|
131
|
+
⬇
|
|
132
|
+
Phase 1: Repo Discovery + Reuse Audit (mobile step catalog)
|
|
133
|
+
[TOKEN TRACKING: jira_fetch → reuse_audit]
|
|
134
|
+
⬇
|
|
135
|
+
Phase 2: Read COS / Business Rules → Write Gherkin (reuse-matched)
|
|
136
|
+
[TOKEN TRACKING: gherkin_generation after Gate 1]
|
|
137
|
+
⬇
|
|
138
|
+
── GATE 1: Present Gherkin + REUSE REPORT. STOP. Wait for confirmation. ──
|
|
139
|
+
⬇
|
|
140
|
+
Phase 3: Write Step Definitions — ONLY for approved new steps
|
|
141
|
+
[TOKEN TRACKING: step_definitions after Gate 2]
|
|
142
|
+
⬇
|
|
143
|
+
── GATE 2: Present step defs. STOP. Wait for user confirmation. ──
|
|
144
|
+
⬇
|
|
145
|
+
Phase 4: Write POM (screen classes) → Dry run
|
|
146
|
+
[TOKEN TRACKING: pom_generation]
|
|
147
|
+
⬇
|
|
148
|
+
Phase 5: REAL test run on device → self-heal loop (max 3) → Hand-off
|
|
149
|
+
[TOKEN TRACKING: test_run → end + report + session]
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Hard rule:** No step-definition code until Gate 1 is confirmed. No POM until Gate 2 is
|
|
153
|
+
confirmed. No Gherkin until the Phase 1 reuse audit is complete.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Tech Stack Defaults
|
|
158
|
+
|
|
159
|
+
Used only where Phase 1 discovery finds no existing convention (empty repo, first mobile
|
|
160
|
+
feature):
|
|
161
|
+
|
|
162
|
+
- **Framework**: MobileWright + `@mobilewright/test`, driven via Cucumber (BDD profile)
|
|
163
|
+
- **Language**: JavaScript (CommonJS — `.cjs`)
|
|
164
|
+
- **Pattern**: BDD with `Rule` / `Example` / `Scenario Outline`, platform tags `@android`/`@ios`
|
|
165
|
+
- **Fake data**: `faker.js`
|
|
166
|
+
- **Default paths** (only when the repo has none): `test/features/`, `test/step_definitions/`,
|
|
167
|
+
`test/Pages/` — per `MOBILE_MCP_REFERENCE.md`'s documented MobileWright BDD project layout
|
|
168
|
+
|
|
169
|
+
**Whatever Phase 1 discovers in the repo overrides these defaults** — match the existing
|
|
170
|
+
tree's layout, naming style, and idioms exactly, same rule the web `automation` skill follows.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## PHASE 1 — Repo Discovery + Reuse Audit
|
|
175
|
+
|
|
176
|
+
Runs before any Gherkin is drafted.
|
|
177
|
+
|
|
178
|
+
**Card + product first:** fetch the card via Atlassian MCP now (this is the `jira_fetch`
|
|
179
|
+
checkpoint). `PRODUCT_FOLDER` was already derived in Phase 0d — reuse it.
|
|
180
|
+
|
|
181
|
+
Produces/refreshes the **mobile step catalog** — deliberately a separate file from the web
|
|
182
|
+
`automation` skill's `step-catalog.md`, since mobile Gherkin vocabulary (tap/swipe/screen)
|
|
183
|
+
and web vocabulary (click/fill/page) shouldn't reuse-match against each other:
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
CATALOG = .claude/skills/qa-agent/product_context/{PRODUCT_FOLDER}/mobile-step-catalog.md
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### 1a — Check catalog freshness
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
ls "$CATALOG" 2>/dev/null && \
|
|
193
|
+
find . -path ./node_modules -prune -o \( -name '*.feature' -o -name '*.steps.cjs' -o -name '*.steps.js' \) -newer "$CATALOG" -print | head -5
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Catalog exists and nothing newer → load it, skip to 1d. Otherwise build/refresh below.
|
|
197
|
+
|
|
198
|
+
### 1b — Discover the repo layout
|
|
199
|
+
|
|
200
|
+
MobileWright ships **two** distinct project shapes (per `MOBILE_MCP_REFERENCE.md`) — check
|
|
201
|
+
which one this repo actually has before assuming either:
|
|
202
|
+
|
|
203
|
+
0. Glob for `**/*.feature` and `cucumber.js`/`.cjs`/`.json` (BDD/Cucumber shape) **and**
|
|
204
|
+
separately for `**/*.test.ts` under a plain `tests/`/`test/` root with no `features/`
|
|
205
|
+
directory (the native shape `npm init mobilewright@latest` scaffolds). If only the native
|
|
206
|
+
shape is present, this product has no Gherkin/reuse-audit surface for this skill to plug
|
|
207
|
+
into yet — say so and ask once: "This repo uses MobileWright's native test format
|
|
208
|
+
(`.test.ts`, no Cucumber) — set up the BDD/Cucumber profile for this feature, or add a
|
|
209
|
+
plain `.test.ts` instead?" Proceed on whichever the user picks; do not silently impose BDD
|
|
210
|
+
on a repo that has deliberately not adopted it.
|
|
211
|
+
1. Read `cucumber.js` (or `.cjs`/`.json`) and `mobilewright.config.ts`/`.js` — their globs
|
|
212
|
+
and `platform`/`projects` settings tell you where features/steps/screens actually live and
|
|
213
|
+
which platform(s) this product targets. A `projects` array means the real run (Phase 5)
|
|
214
|
+
needs to loop once per listed platform, not assume a single device covers all of them.
|
|
215
|
+
2. Glob the tree for `**/*.feature`, the matched step-definition files, and Page-Object
|
|
216
|
+
directories (`Pages/`, `screens/`...), excluding `node_modules`.
|
|
217
|
+
3. Record the observed conventions: feature path pattern, step file path pattern, screen POM
|
|
218
|
+
path pattern, naming style.
|
|
219
|
+
4. **No test tree at all (neither shape):** tell the user, propose the BDD defaults above,
|
|
220
|
+
record what they confirm.
|
|
221
|
+
|
|
222
|
+
### 1c — Build the mobile step catalog
|
|
223
|
+
|
|
224
|
+
Extract every `Given/When/Then(...)` pattern with its cucumber-expression parameters, and
|
|
225
|
+
every screen-POM class name + public methods.
|
|
226
|
+
|
|
227
|
+
```markdown
|
|
228
|
+
# Mobile Step Catalog — {PRODUCT}
|
|
229
|
+
Generated: {date} · Features: {n} · Step files: {n} · Steps: {n} · Screen classes: {n}
|
|
230
|
+
Platform(s) discovered: {ios | android | both}
|
|
231
|
+
|
|
232
|
+
## Repo Layout (discovered)
|
|
233
|
+
| Artifact | Path pattern | Example |
|
|
234
|
+
|----------|--------------|---------|
|
|
235
|
+
|
|
236
|
+
## Steps
|
|
237
|
+
| Pattern | Params | File | Platform tag |
|
|
238
|
+
|---------|--------|------|---------------|
|
|
239
|
+
|
|
240
|
+
## Screen Classes
|
|
241
|
+
| Class | File | Key methods |
|
|
242
|
+
|-------|------|-------------|
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### 1d — Announce (one line)
|
|
246
|
+
|
|
247
|
+
> "Mobile reuse audit ready — {n} existing steps, {n} screen classes catalogued for {PRODUCT}."
|
|
248
|
+
|
|
249
|
+
Run `reuse_audit` token checkpoint.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## PHASE 2 — Read COS / Business Rules → Write Gherkin
|
|
254
|
+
|
|
255
|
+
**Static file load — once only, right now:** read `MOBILE_MCP_REFERENCE.md`,
|
|
256
|
+
`BDD_TEMPLATES.md`, and `LOCATOR_PATTERNS.md` (all in this skill's own directory). Do NOT
|
|
257
|
+
re-read any of them in Phase 3 or 4 — reference their rules by name only (e.g. "per Locator
|
|
258
|
+
Priority 1", "per the app-lifecycle step catalog").
|
|
259
|
+
|
|
260
|
+
### Step 0 — Card data check
|
|
261
|
+
|
|
262
|
+
Read `issuetype.name`:
|
|
263
|
+
|
|
264
|
+
| Card type | Action |
|
|
265
|
+
|-----------|--------|
|
|
266
|
+
| `Story` | Run full pipeline |
|
|
267
|
+
| `Bug` | Ask: "Do you want automation coverage, or just manual retest?" |
|
|
268
|
+
| `Task` | Ask: "Does this need automation or is it a config/infra task?" |
|
|
269
|
+
|
|
270
|
+
Extract: **Title**, **Description**, **Acceptance Criteria / COS**, **Comments**.
|
|
271
|
+
|
|
272
|
+
Run `jira_fetch` token checkpoint after fetch (if not already run in Phase 1).
|
|
273
|
+
|
|
274
|
+
### Step 1 — Think like a senior mobile QA engineer (internal)
|
|
275
|
+
|
|
276
|
+
Before writing any Gherkin, answer:
|
|
277
|
+
1. What is the **core user journey**, and does it differ meaningfully between iOS and Android?
|
|
278
|
+
2. What are the **happy paths**? (AC-driven)
|
|
279
|
+
3. What **permission dialogs, OTP screens, or deep links** does this flow touch?
|
|
280
|
+
4. What are the **negative scenarios**? (invalid input, denied permission, offline, backgrounded mid-flow)
|
|
281
|
+
5. Are there **role-based variations**?
|
|
282
|
+
6. Is there **dynamic data** repeating the same flow? → `Scenario Outline` candidate
|
|
283
|
+
7. Can any **Gherkin steps be reused** from the Phase 1 catalog (including the app-lifecycle
|
|
284
|
+
step catalog in `BDD_TEMPLATES.md`)?
|
|
285
|
+
8. Which **screen elements** will need a `resource-id`/`accessibility-id` added?
|
|
286
|
+
9. Does any step need a **platform-conditional branch** (`@android`/`@ios`) per
|
|
287
|
+
`LOCATOR_PATTERNS.md` §7?
|
|
288
|
+
|
|
289
|
+
Write a brief internal test plan (3–8 bullets) before generating the feature file.
|
|
290
|
+
|
|
291
|
+
### Step 2 — Generate the Feature File (reuse-matched)
|
|
292
|
+
|
|
293
|
+
Use the Gherkin format from `BDD_TEMPLATES.md`.
|
|
294
|
+
|
|
295
|
+
**Reuse matching — apply to EVERY drafted step, in strict priority order, against the
|
|
296
|
+
Phase 1 mobile step catalog** (identical priority logic to the web skill, applied to the
|
|
297
|
+
mobile-specific catalog):
|
|
298
|
+
|
|
299
|
+
| Priority | Match type | Action |
|
|
300
|
+
|----------|-----------|--------|
|
|
301
|
+
| 1 | **Exact** | Reuse verbatim. Tag internally `[reused]` |
|
|
302
|
+
| 2 | **Parameterized** | Reuse the existing pattern with new arguments. Tag `[reused-param]` |
|
|
303
|
+
| 3 | **Semantic duplicate** | Rewrite your draft to the existing wording — never a parallel step. Tag `[reused-reworded]` |
|
|
304
|
+
| 4 | **Genuine gap** | New step allowed. Tag `[new]` — requires approval at Gate 1 |
|
|
305
|
+
|
|
306
|
+
**Gherkin writing rules:**
|
|
307
|
+
- One `Rule:` per business rule / AC from the Jira card; rule text = the AC verbatim
|
|
308
|
+
- Use real persona names + role in `Example:` titles
|
|
309
|
+
- Tag `@android`/`@ios` on any Example whose interaction differs by platform (hardware BACK,
|
|
310
|
+
swipe-back, permission dialog wording)
|
|
311
|
+
- Describe **intent and outcome**, never mechanics (`When Maria confirms the delivery address` ✅)
|
|
312
|
+
- Use `Scenario Outline` when 2+ scenarios share identical steps but differ only in data
|
|
313
|
+
|
|
314
|
+
### ══ GATE 1 — Gherkin + Reuse Report ══
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
Reuse report — [CARD-ID] (mobile)
|
|
318
|
+
Steps total: {N} | Reused exact: {N} | Reused parameterized: {N} | New: {N} ({X}% reuse)
|
|
319
|
+
New steps requiring definitions:
|
|
320
|
+
- ...
|
|
321
|
+
(or: "No new step definitions needed — full reuse.")
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**If AUTO_APPROVE = false (default):**
|
|
325
|
+
|
|
326
|
+
Present Gherkin + reuse report and ask:
|
|
327
|
+
|
|
328
|
+
> **Here is the mobile Gherkin for [CARD-ID]. Please review each Rule, Example, and the reuse report.**
|
|
329
|
+
>
|
|
330
|
+
> - Does the Rule text match the business rule / COS exactly?
|
|
331
|
+
> - Are platform-specific Examples (`@android`/`@ios`) tagged correctly?
|
|
332
|
+
> - Are the **new steps** genuinely new, or should any map to an existing step?
|
|
333
|
+
>
|
|
334
|
+
> **Type "looks good" or "confirmed" to proceed to step definitions.**
|
|
335
|
+
|
|
336
|
+
Do not write any code until confirmed. Iterate until approved. Then record the trust ratchet
|
|
337
|
+
— **always with `--namespace mobile`**, so this never lands in the same file the web
|
|
338
|
+
`automation` skill and qa-agent read (see the note at the top of this file for why that
|
|
339
|
+
matters):
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs trust-record --product {PRODUCT_FOLDER} --namespace mobile --gate gate1 --result clean|edited
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
**If AUTO_APPROVE = true:** display the reuse report + a compact summary, proceed immediately
|
|
346
|
+
without waiting. Do not call `trust-record` — no human review to score.
|
|
347
|
+
|
|
348
|
+
Run `gherkin_generation` token checkpoint, then move to Phase 3.
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## PHASE 3 — Write Step Definitions (after Gate 1)
|
|
353
|
+
|
|
354
|
+
**Do NOT reload any Phase 2 file.** Recall the rules from context.
|
|
355
|
+
|
|
356
|
+
### Step 3 — Generate Step Definitions using Mobile MCP
|
|
357
|
+
|
|
358
|
+
**Write definitions ONLY for steps tagged `[new]` at Gate 1.** Reused steps already work —
|
|
359
|
+
duplicating one causes cucumber-js `Ambiguous`. If every step was reused, skip to Phase 4.
|
|
360
|
+
|
|
361
|
+
For every new step that interacts with the screen, use **Mobile MCP** to:
|
|
362
|
+
1. Ensure the app is on the relevant screen (navigate via existing steps if needed)
|
|
363
|
+
2. Dump the screen via `mobile_list_elements_on_screen`
|
|
364
|
+
3. Check for a `resource-id`/`accessibility-id` on the target element (per
|
|
365
|
+
`MOBILE_MCP_REFERENCE.md`'s detection procedure) — or note one needs to be added
|
|
366
|
+
4. Use the real element info to write accurate step → screen-POM method calls
|
|
367
|
+
|
|
368
|
+
**Do not guess locators.** Dump the real screen first.
|
|
369
|
+
|
|
370
|
+
Use the step definition template from `BDD_TEMPLATES.md`, including the platform-conditional
|
|
371
|
+
and app-lifecycle patterns where relevant.
|
|
372
|
+
|
|
373
|
+
**Step definition rules:**
|
|
374
|
+
- CommonJS only — `require()`/`module.exports`
|
|
375
|
+
- Use `{word}` for persona capture, `{string}` for quoted data values
|
|
376
|
+
- No business logic in step files — all logic lives in the screen POM
|
|
377
|
+
- No direct `screen.getByX()` calls in step files — always go through POM methods
|
|
378
|
+
- Step pattern must match the `.feature` file exactly, character for character
|
|
379
|
+
- Any step whose behavior differs by platform must branch on `this.platform`, resolved once
|
|
380
|
+
in a `Before` hook (see template) — never re-detect platform mid-step
|
|
381
|
+
|
|
382
|
+
### ══ GATE 2 ══
|
|
383
|
+
|
|
384
|
+
**If AUTO_APPROVE = false:**
|
|
385
|
+
|
|
386
|
+
> **Here are the step definitions for [CARD-ID]. Please review.**
|
|
387
|
+
>
|
|
388
|
+
> - Do the step patterns match the Gherkin exactly?
|
|
389
|
+
> - Are platform-conditional branches correct for both `@android` and `@ios`?
|
|
390
|
+
> - Any lifecycle/permission-dialog steps to add or remove?
|
|
391
|
+
>
|
|
392
|
+
> **Type "looks good" or "confirmed" to proceed to the screen POM.**
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs trust-record --product {PRODUCT_FOLDER} --namespace mobile --gate gate2 --result clean|edited
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
**If AUTO_APPROVE = true:** display a compact summary, proceed immediately. No `trust-record`.
|
|
399
|
+
|
|
400
|
+
Run `step_definitions` token checkpoint, then move to Phase 4.
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## PHASE 4 — Write Screen POM → Dry Run
|
|
405
|
+
|
|
406
|
+
**Do NOT reload any file.** Recall `BDD_TEMPLATES.md`/`LOCATOR_PATTERNS.md` rules from context.
|
|
407
|
+
|
|
408
|
+
### Step 4 — Generate the Screen POM using Mobile MCP
|
|
409
|
+
|
|
410
|
+
**Reuse check first:** consult the catalog's Screen Classes table. Extend an existing class
|
|
411
|
+
rather than creating a parallel one.
|
|
412
|
+
|
|
413
|
+
**Locator memory check — once per screen, before opening Mobile MCP for it.** Prefix the
|
|
414
|
+
`--page` key with `mobile:` so it never collides with a web page URL recorded for the same
|
|
415
|
+
product folder:
|
|
416
|
+
```bash
|
|
417
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs locator-query --product {PRODUCT_FOLDER} --page "mobile:{ScreenName}"
|
|
418
|
+
```
|
|
419
|
+
`NONE` → nothing learned yet, proceed as usual. Rows returned → avoid the recorded **Failed
|
|
420
|
+
Locator** even if it looks obvious; prefer the recorded **Working Locator** if the element matches.
|
|
421
|
+
|
|
422
|
+
**Screen fingerprint check — once per distinct screen this run.** Reuses the generic
|
|
423
|
+
`fingerprint`/`get-selectors` toolkit commands (they only take opaque strings — no change
|
|
424
|
+
needed to the toolkit itself) with a synthetic mobile identifier as the `--url`:
|
|
425
|
+
```
|
|
426
|
+
mobile_list_elements_on_screen() # extract resource-id/accessibility-id values, comma-join
|
|
427
|
+
```
|
|
428
|
+
```bash
|
|
429
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs fingerprint --product {PRODUCT_FOLDER} --url "mobile:{bundleId}/{ScreenName}" --testids "RESULT_FROM_ABOVE"
|
|
430
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs get-selectors --product {PRODUCT_FOLDER} --url "mobile:{bundleId}/{ScreenName}"
|
|
431
|
+
```
|
|
432
|
+
`UNCHANGED` + `get-selectors` covers the needed elements → write POM locators straight from
|
|
433
|
+
those rows, skip the per-element dump below. Otherwise fall through to full inspection.
|
|
434
|
+
|
|
435
|
+
For every locator not already resolved above:
|
|
436
|
+
1. Ensure the app is on the target screen
|
|
437
|
+
2. `mobile_list_elements_on_screen()` and inspect the target element
|
|
438
|
+
3. Check for `resource-id`/`accessibility-id` (check both fields — see `LOCATOR_PATTERNS.md` §1)
|
|
439
|
+
- Present → `screen.getByTestId('...')` with the real value
|
|
440
|
+
- Absent → ask for one to be added to source if feasible, then fall through the Locator
|
|
441
|
+
Priority table in `LOCATOR_PATTERNS.md`
|
|
442
|
+
4. Never write a coordinate fallback and move on without documenting why no better locator existed
|
|
443
|
+
|
|
444
|
+
**POM rules:**
|
|
445
|
+
- All locators defined in `constructor`, never inside methods
|
|
446
|
+
- All actions `async`, single-purpose
|
|
447
|
+
- Assertions in separate methods prefixed `verify`
|
|
448
|
+
- No hardcoded waits — use `expect(...).toBeVisible()`/`toBeEnabled()`
|
|
449
|
+
|
|
450
|
+
Run `pom_generation` token checkpoint after the POM is written.
|
|
451
|
+
|
|
452
|
+
### Step 5 — Dry Run Validation
|
|
453
|
+
|
|
454
|
+
```bash
|
|
455
|
+
npm run test:dry
|
|
456
|
+
```
|
|
457
|
+
(or `npx cucumber-js --dry-run` if the repo's discovered config uses plain Cucumber rather
|
|
458
|
+
than MobileWright's BDD wrapper script)
|
|
459
|
+
|
|
460
|
+
- ✅ All steps defined → proceed
|
|
461
|
+
- ❌ `Undefined` → fix step pattern to match Gherkin exactly, re-run
|
|
462
|
+
- ❌ `Ambiguous` → reuse-audit miss — reuse the existing step, don't rename
|
|
463
|
+
- ❌ `require` errors → fix paths, re-run
|
|
464
|
+
|
|
465
|
+
Fix and re-run automatically. Do not proceed until clean.
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
## PHASE 5 — Real Test Run on Device + Self-Heal → Hand-off
|
|
470
|
+
|
|
471
|
+
A dry run only proves patterns match. QA means the test actually passes against a real
|
|
472
|
+
device/simulator/emulator.
|
|
473
|
+
|
|
474
|
+
### Step 6 — Execute the new feature
|
|
475
|
+
|
|
476
|
+
Requires the device + app resolved in Phase 0. If unavailable, skip with an explicit warning
|
|
477
|
+
in the hand-off: "Real run SKIPPED — no device available."
|
|
478
|
+
|
|
479
|
+
**Platform targeting and scenario tag filtering are two different things — don't conflate
|
|
480
|
+
them.** The device/platform is already fixed by whichever one Phase 0 connected to (or by the
|
|
481
|
+
`PLATFORM` env var the repo's own `test:android`/`test:ios` npm scripts set, if those are
|
|
482
|
+
what Phase 1b discovered). `--tags` only selects *which scenarios* cucumber picks up within
|
|
483
|
+
that run — it does not target a device.
|
|
484
|
+
|
|
485
|
+
```bash
|
|
486
|
+
# Single platform (the common case — one device was resolved in Phase 0):
|
|
487
|
+
npx cucumber-js <new feature file> --tags "@android or not @ios" # drop platform-exclusive
|
|
488
|
+
# tags for the platform NOT running
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
**If Phase 1b found a `projects` matrix covering multiple platforms**, run the suite once per
|
|
492
|
+
listed platform (looping, not a single command) — each with its own device from Phase 0 and
|
|
493
|
+
its own tag filter for that platform's Examples:
|
|
494
|
+
|
|
495
|
+
```bash
|
|
496
|
+
PLATFORM=android npm run test:android -- <new feature file>
|
|
497
|
+
PLATFORM=ios npm run test:ios -- <new feature file>
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
Report each platform's result separately in the hand-off (Step 8) — do not average or merge
|
|
501
|
+
a pass on one platform with a fail on the other into a single PASSED/FAILED line.
|
|
502
|
+
|
|
503
|
+
### Step 6b — Self-heal loop (max 3 attempts)
|
|
504
|
+
|
|
505
|
+
1. Read the failure: locator timeout? permission dialog blocking? assertion mismatch?
|
|
506
|
+
platform-conditional branch missing? crash?
|
|
507
|
+
2. **Locator failures** → re-inspect via `mobile_list_elements_on_screen`, fix the POM
|
|
508
|
+
locator (respect Locator Priority). Once fixed, persist it so no future run repeats the
|
|
509
|
+
same wrong guess — locator strings can contain quotes; write a JSON file first:
|
|
510
|
+
```
|
|
511
|
+
Write outputs/.mobile-locator-tmp.json containing:
|
|
512
|
+
{"product": "{PRODUCT_FOLDER}", "page": "mobile:{ScreenName}", "element": "ELEMENT_LABEL",
|
|
513
|
+
"failed": "OLD_LOCATOR", "fixed": "NEW_LOCATOR", "reason": "ONE_LINE_WHY", "card": "{CARD_ID}"}
|
|
514
|
+
```
|
|
515
|
+
```bash
|
|
516
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs locator-record --file outputs/.mobile-locator-tmp.json
|
|
517
|
+
```
|
|
518
|
+
3. **Permission dialog / OS interruption** → not a locator bug (per `LOCATOR_PATTERNS.md` §3)
|
|
519
|
+
— add the dialog-handling step from `BDD_TEMPLATES.md` before the step that triggers it,
|
|
520
|
+
don't touch the target element's locator.
|
|
521
|
+
4. **Assertion failures where the app itself looks wrong** → check whether an app crash
|
|
522
|
+
coincided with the failure:
|
|
523
|
+
```
|
|
524
|
+
mobile_list_crashes()
|
|
525
|
+
mobile_get_crash(crashId) # if one matches the failure's timestamp
|
|
526
|
+
```
|
|
527
|
+
If the app appears genuinely wrong (or crashed), this is a **bug, not a test fix** — stop
|
|
528
|
+
healing that scenario, mark it failing, note it (with the crash report if found) as a bug
|
|
529
|
+
candidate in the hand-off.
|
|
530
|
+
5. Re-run. After 3 failed attempts, stop and report the failure honestly.
|
|
531
|
+
|
|
532
|
+
Run `test_run` token checkpoint, then `end + report + session` close-out.
|
|
533
|
+
|
|
534
|
+
### Step 7 — Update the mobile step catalog
|
|
535
|
+
|
|
536
|
+
Append every new step definition and any new/extended screen class to the Phase 1 catalog.
|
|
537
|
+
|
|
538
|
+
### Step 8 — Hand-off Summary
|
|
539
|
+
|
|
540
|
+
```
|
|
541
|
+
✅ Mobile automation agent complete for <CARD-ID>
|
|
542
|
+
|
|
543
|
+
Platform(s) run: <ios | android | both>
|
|
544
|
+
Feature file: <path per discovered repo layout>
|
|
545
|
+
Steps file: <path, or "none — full reuse">
|
|
546
|
+
Screen POM file: <path, or "extended existing: <class>">
|
|
547
|
+
|
|
548
|
+
Scenarios covered:
|
|
549
|
+
- <Rule 1>: <n> Example(s), <n> Outline(s)
|
|
550
|
+
|
|
551
|
+
Reuse: {N} steps total | {N} exact | {N} parameterized | {N} new ({X}% reuse)
|
|
552
|
+
resource-id / accessibility-id added to source: <element list or "none required">
|
|
553
|
+
Dry-run: PASSED
|
|
554
|
+
Test run:
|
|
555
|
+
Android: {PASSED | FAILED after 3 heal attempts: <reason> | SKIPPED — no device available | N/A — not in project matrix}
|
|
556
|
+
iOS: {PASSED | FAILED after 3 heal attempts: <reason> | SKIPPED — no device available | N/A — not in project matrix}
|
|
557
|
+
Bug candidates from test run: <list, with crash report reference if applicable, or "none">
|
|
558
|
+
|
|
559
|
+
Ready for: bug-reporting agent
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Post Hand-off — Write Product Context
|
|
563
|
+
|
|
564
|
+
Unlike the web `automation` skill (which can skip context-file creation because qa-agent's
|
|
565
|
+
Step 6 reliably creates it afterward), **this skill has no orchestrator that ever runs after
|
|
566
|
+
it** — it's always standalone. If it also skipped creating the file, a product's first mobile
|
|
567
|
+
run would leave no persisted context at all. So: create the file here if missing, don't just
|
|
568
|
+
skip.
|
|
569
|
+
|
|
570
|
+
```
|
|
571
|
+
CONTEXT_FILE = .claude/skills/qa-agent/product_context/{PRODUCT_FOLDER}/context.md
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
**If context file exists — append to its tables (Edit tool, never overwrite existing rows):**
|
|
575
|
+
- `Runs Log`: date | `{CARD_ID}` | `Automation` (per `CONTEXT_SCHEMA.md`'s fixed Manual/
|
|
576
|
+
Automation/Both values — don't invent a fourth) | outcome | bugs filed (candidates from
|
|
577
|
+
Step 6b, or "—") | reuse % | one-line note starting `"mobile (ios/android): "` so it's
|
|
578
|
+
distinguishable from a web automation run in the same log
|
|
579
|
+
- `Element Selectors`: `[mobile] {Element Label}` | `mobile:{bundleId}/{ScreenName}` | Locator | Method | resource-id/accessibility-id value or "none" | Card ID
|
|
580
|
+
- `Covered Flows`: Rule text | Example count | Card ID | date
|
|
581
|
+
|
|
582
|
+
**If context file does not exist — create it now**, using
|
|
583
|
+
`.claude/skills/qa-agent/product_context/CONTEXT_SCHEMA.md` as the template (same schema
|
|
584
|
+
qa-agent Step 6c uses for the web pipeline — this is the same file, not a mobile-specific
|
|
585
|
+
variant). Fill in: Jira project key, product name, environment (from the resolved platform/
|
|
586
|
+
device, not a URL), auth method (if the flow under test logs in), OTP required (yes/no only).
|
|
587
|
+
Never write credentials — those stay in `.env`. Then write the same `Runs Log` /
|
|
588
|
+
`Element Selectors` / `Covered Flows` rows described above as the file's first entries.
|
|
589
|
+
|
|
590
|
+
One-line confirmation either way:
|
|
591
|
+
```
|
|
592
|
+
Mobile context saved → .claude/skills/qa-agent/product_context/{PRODUCT_FOLDER}/context.md ({N} elements, {N} flows).
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
**Then report to the team dashboard (optional, silent)** — using the same values just
|
|
596
|
+
written to the Runs Log row:
|
|
597
|
+
|
|
598
|
+
```
|
|
599
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs report-run \
|
|
600
|
+
--skill mobile-automation --product {PRODUCT_FOLDER} --card {CARD_ID} \
|
|
601
|
+
--phase Automation \
|
|
602
|
+
--outcome {OUTCOME} --bugs "{comma-separated bug IDs or empty}" \
|
|
603
|
+
--reuse {reuse % number}
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
Only pass `--product`/`--card`/`--phase`/`--outcome`/`--bugs`/`--reuse` — short,
|
|
607
|
+
structurally-constrained values (see "Never inline arbitrary text" in
|
|
608
|
+
`SKILLS_CONTEXT.md`). `report-run` has no `--notes` flag; don't inline the freeform
|
|
609
|
+
Runs Log note here. This is a no-op unless `QA_DASHBOARD_REPO`/`QA_DASHBOARD_TOKEN` are
|
|
610
|
+
set in `.env` — never print anything about it, never retry, never treat a non-zero exit
|
|
611
|
+
as a run failure.
|
|
@@ -370,6 +370,21 @@ Write `context.md`, then print one line:
|
|
|
370
370
|
Product context saved → .claude/skills/qa-agent/product_context/{PRODUCT_FOLDER}/context.md
|
|
371
371
|
```
|
|
372
372
|
|
|
373
|
+
### 6f — Report to team dashboard (optional, silent)
|
|
374
|
+
|
|
375
|
+
Immediately after 6e, using the same values just written to the Runs Log row, shell out:
|
|
376
|
+
|
|
377
|
+
```
|
|
378
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs report-run \
|
|
379
|
+
--skill qa-agent --product {PRODUCT_FOLDER} --card {CARD_ID} \
|
|
380
|
+
--phase {Manual|Automation|Both} \
|
|
381
|
+
--outcome {OUTCOME} --bugs "{comma-separated bug IDs or empty}" \
|
|
382
|
+
--reuse {reuse % number, omit for manual-only runs}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
This is a no-op unless `QA_DASHBOARD_REPO`/`QA_DASHBOARD_TOKEN` are set in `.env` — never
|
|
386
|
+
print anything about it, never retry, never treat a non-zero exit as a run failure.
|
|
387
|
+
|
|
373
388
|
---
|
|
374
389
|
|
|
375
390
|
## Post-run Cleanup (all phases)
|