adb-ready 0.5.1 → 0.7.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/CHANGELOG.md +79 -1
- package/COMPATIBILITY.md +31 -0
- package/README.md +33 -11
- package/dist/cli.js +5381 -564
- package/docs/agent-integration.md +64 -17
- package/docs/apps-and-evidence.md +14 -1
- package/docs/automation.md +120 -7
- package/docs/configuration.md +6 -0
- package/docs/firebase-test-lab.md +126 -0
- package/docs/gradle-managed-devices.md +105 -0
- package/docs/logs-and-context.md +34 -0
- package/docs/target-pools.md +151 -0
- package/docs/targets-and-wireless.md +21 -0
- package/docs/threat-model.md +33 -0
- package/docs/troubleshooting.md +39 -0
- package/docs/ui-automation.md +130 -6
- package/examples/README.md +6 -0
- package/examples/ci-emulator/README.md +32 -0
- package/examples/ci-emulator/adb-ready.config.json +20 -0
- package/examples/ci-emulator/dev-service.mjs +14 -0
- package/examples/ci-emulator/verify-emulator.mjs +108 -0
- package/examples/ci-physical/README.md +51 -0
- package/examples/ci-physical/adb-ready.config.json +20 -0
- package/examples/ci-physical/dev-service.mjs +14 -0
- package/examples/ci-physical/github-actions.yml +56 -0
- package/examples/ci-physical/run-job.mjs +77 -0
- package/examples/ci-physical/verify-device.mjs +90 -0
- package/examples/target-pools/README.md +22 -0
- package/examples/target-pools/adb-ready.config.json +29 -0
- package/llms.txt +8 -4
- package/package.json +4 -1
- package/schema/agent-tools-v1.json +1080 -81
- package/schema/config-v1.schema.json +86 -0
- package/skills/adb-ready/SKILL.md +54 -0
|
@@ -26,7 +26,7 @@ it. ADB Ready does not open an MCP network listener.
|
|
|
26
26
|
|
|
27
27
|
## Connect an agent
|
|
28
28
|
|
|
29
|
-
Preview the exact project
|
|
29
|
+
Preview the exact project changes first, then apply them:
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
32
|
adb-ready agent setup codex --dry-run
|
|
@@ -35,7 +35,28 @@ adb-ready agent setup codex
|
|
|
35
35
|
|
|
36
36
|
Replace `codex` with `claude-code`, `cursor`, or `vscode`. Existing unrelated
|
|
37
37
|
configuration is preserved. An existing `adb-ready` entry with different
|
|
38
|
-
settings is reported as a conflict and is never replaced automatically.
|
|
38
|
+
settings is reported as a conflict and is never replaced automatically. The
|
|
39
|
+
same setup installs ADB Ready's version-matched Agent Skill at
|
|
40
|
+
`.agents/skills/adb-ready/SKILL.md`, or `.claude/skills/adb-ready/SKILL.md` for
|
|
41
|
+
Claude Code. A custom skill is never overwritten; generated older versions are
|
|
42
|
+
updated atomically with the MCP configuration.
|
|
43
|
+
|
|
44
|
+
Narrow tool discovery when an agent needs only one workflow:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
adb-ready agent setup codex --mcp-profile debug
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| Profile | Intended work |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| `full` | Complete backward-compatible tool surface; the default |
|
|
53
|
+
| `session` | Target readiness, app lifecycle, and durable development sessions |
|
|
54
|
+
| `ui` | Target readiness, app lifecycle, semantic UI automation, and screenshots |
|
|
55
|
+
| `debug` | Target readiness, app lifecycle, current/saved evidence, and failure diagnosis |
|
|
56
|
+
|
|
57
|
+
Profiles reduce accidental tool selection and client context size; they are not
|
|
58
|
+
an authorization boundary. Start a server directly with `adb-ready mcp
|
|
59
|
+
--mcp-profile ui` when configuration is managed outside `agent setup`.
|
|
39
60
|
|
|
40
61
|
### Codex
|
|
41
62
|
|
|
@@ -49,15 +70,16 @@ default_tools_approval_mode = "writes"
|
|
|
49
70
|
```
|
|
50
71
|
|
|
51
72
|
Codex CLI, the Codex IDE extension, and the ChatGPT desktop app share Codex MCP
|
|
52
|
-
configuration.
|
|
73
|
+
configuration. Codex loads project `.codex/config.toml` only after the project
|
|
74
|
+
is trusted; ADB Ready never changes trust on the user's behalf. See the
|
|
75
|
+
[official Codex configuration guide](https://developers.openai.com/codex/config-basic).
|
|
53
76
|
|
|
54
77
|
### Claude Code
|
|
55
78
|
|
|
56
|
-
Run
|
|
79
|
+
Run the project setup from the project root:
|
|
57
80
|
|
|
58
81
|
```bash
|
|
59
|
-
|
|
60
|
-
claude mcp get adb-ready
|
|
82
|
+
adb-ready agent setup claude-code
|
|
61
83
|
```
|
|
62
84
|
|
|
63
85
|
Claude Code stores project-scoped servers in `.mcp.json` and asks users to
|
|
@@ -126,16 +148,17 @@ starts in the Android project root.
|
|
|
126
148
|
|
|
127
149
|
Ask the agent to follow this sequence:
|
|
128
150
|
|
|
129
|
-
1. Call `
|
|
130
|
-
2. Call `
|
|
151
|
+
1. Call `get_capabilities` and stay within the active profile.
|
|
152
|
+
2. Call `doctor` when host or ADB health is unknown.
|
|
153
|
+
3. Call `ensure_ready`; provide an exact device serial, configured alias, or
|
|
131
154
|
transport ID when more than one ready target exists.
|
|
132
|
-
|
|
155
|
+
4. Start the configured stack with `start_dev_session` when it is not already
|
|
133
156
|
running; retain its task handle and poll `get_dev_session` without holding a
|
|
134
157
|
tool call open.
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
158
|
+
5. Resolve the project app with `resolve_app`.
|
|
159
|
+
6. Use `inspect_app` or `inspect_ui` for bounded current evidence.
|
|
160
|
+
7. Perform one typed action, then inspect again instead of assuming success.
|
|
161
|
+
8. Use `get_session_problems` or `compile_debug_context` for an existing
|
|
139
162
|
development session.
|
|
140
163
|
|
|
141
164
|
The first successful `ensure_ready` binds one target to that MCP connection and
|
|
@@ -156,17 +179,18 @@ UI Automation service per target.
|
|
|
156
179
|
|
|
157
180
|
| Capability | MCP tools |
|
|
158
181
|
| --- | --- |
|
|
159
|
-
|
|
|
182
|
+
| Discovery and readiness | `get_capabilities`, `doctor`, `list_targets`, `ensure_ready` |
|
|
160
183
|
| Durable development lifecycle | `start_dev_session`, `get_dev_session`, `stop_dev_session` |
|
|
161
184
|
| App identity and lifecycle | `resolve_app`, `install_app`, `launch_app`, `restart_app`, `open_url` |
|
|
162
|
-
| Current evidence | `inspect_app`, `inspect_ui`, `capture_screenshot` |
|
|
163
|
-
| Safe UI queries and actions | `audit_ui`, `get_ui`, `find_ui`, `assert_ui`, `compare_ui`, `tap_ui`, `long_press_ui`, `scroll_ui`, `swipe_ui`, `fill_ui`, `clear_ui`, `type_text_ui`, `press_key_ui`, `wait_for_ui` |
|
|
185
|
+
| Current evidence | `inspect_app`, `inspect_failures`, `inspect_ui`, `capture_screenshot` |
|
|
186
|
+
| Safe UI queries and actions | `audit_ui`, `get_ui`, `find_ui`, `assert_ui`, `compare_ui`, `tap_ui`, `long_press_ui`, `scroll_ui`, `swipe_ui`, `fill_ui`, `clear_ui`, `type_text_ui`, `press_key_ui`, `wait_for_ui`, `inspect_keyboard`, `dismiss_keyboard`, `inspect_permission_dialog`, `respond_to_permission_dialog` |
|
|
164
187
|
| Saved diagnostics | `list_sessions`, `get_session_problems`, `compile_debug_context` |
|
|
165
188
|
|
|
166
189
|
MCP resources keep larger read-only context outside tool calls:
|
|
167
190
|
|
|
168
191
|
| Resource | Content |
|
|
169
192
|
| --- | --- |
|
|
193
|
+
| `adb-ready://capabilities` | active profile, profile tool membership, and long-running task compatibility |
|
|
170
194
|
| `adb-ready://targets` | current target inventory and this connection's bound target |
|
|
171
195
|
| `adb-ready://sessions` | bounded saved-session manifests |
|
|
172
196
|
| `adb-ready://sessions/{sessionId}` | one session manifest |
|
|
@@ -176,13 +200,33 @@ MCP resources keep larger read-only context outside tool calls:
|
|
|
176
200
|
Every tool advertises an output schema and returns the same versioned result
|
|
177
201
|
envelope used by CLI JSON output. Screenshot capture additionally returns MCP
|
|
178
202
|
`image` content so a vision-capable agent can inspect the pixels directly; the
|
|
179
|
-
verified project-local PNG remains the evidence source of record.
|
|
203
|
+
verified project-local PNG remains the evidence source of record. Agent
|
|
204
|
+
screenshots default to a 1024×1024 maximum and 4 MiB base64 content budget, with
|
|
205
|
+
explicit crop/dimension controls and a deliberate `fullResolution` opt-in.
|
|
206
|
+
Standard MCP annotations describe read-only, destructive, idempotent, and
|
|
207
|
+
open-world behavior. The namespaced `dev.adbready/tool` metadata adds profile,
|
|
208
|
+
category, target-binding, mutation, and sensitive-data signals. Annotations are
|
|
209
|
+
advisory for clients; ADB Ready still enforces the operation at runtime.
|
|
180
210
|
|
|
181
211
|
The npm package also ships `schema/agent-tools-v1.json`, generated from the
|
|
182
212
|
server's real `tools/list` response during every build. Integrations can inspect
|
|
183
213
|
version-matched input and output schemas plus safety annotations without
|
|
184
214
|
starting ADB.
|
|
185
215
|
|
|
216
|
+
The package also ships `skills/adb-ready/SKILL.md`. It is generated from the
|
|
217
|
+
same real `tools/list` contract during the build, so its workflow cannot name a
|
|
218
|
+
tool missing from that package version. The skill teaches task order and safety;
|
|
219
|
+
the MCP server remains the controlled execution surface.
|
|
220
|
+
|
|
221
|
+
## Long-running task compatibility
|
|
222
|
+
|
|
223
|
+
ADB Ready does not advertise the MCP Tasks extension yet. Its durable
|
|
224
|
+
`start_dev_session`, `get_dev_session`, and `stop_dev_session` handles remain
|
|
225
|
+
available across supported clients and reconnects. `get_capabilities` reports
|
|
226
|
+
this compatibility path explicitly. Native Tasks will be advertised only after
|
|
227
|
+
capability negotiation and end-to-end interoperability are proven in at least
|
|
228
|
+
two supported clients; unnegotiated clients never receive a Tasks claim.
|
|
229
|
+
|
|
186
230
|
`list_sessions` is project-scoped by default and supports status, preset,
|
|
187
231
|
recency, and result-count filters. When more matches remain, pass its opaque
|
|
188
232
|
`nextCursor` back as `cursor`; an expired cursor fails explicitly instead of
|
|
@@ -197,6 +241,9 @@ silently restarting the list.
|
|
|
197
241
|
- UI hierarchy and app inspection are marked sensitive and remain bounded.
|
|
198
242
|
- UI references are checked against a fresh hierarchy digest before mutation;
|
|
199
243
|
stale references are rejected.
|
|
244
|
+
- Secret UI text is referenced by local environment-variable name rather than
|
|
245
|
+
sent in MCP arguments; Unicode input is capability-checked before mutation
|
|
246
|
+
and restores the prior Android IME.
|
|
200
247
|
- Data clearing and uninstall are intentionally absent from the agent surface.
|
|
201
248
|
- Tool annotations help clients request approval, but ADB Ready enforces its
|
|
202
249
|
own target, path, and destructive-action rules.
|
|
@@ -123,6 +123,7 @@ Capture a PNG directly from the selected target:
|
|
|
123
123
|
```bash
|
|
124
124
|
adb-ready capture screenshot
|
|
125
125
|
adb-ready capture screenshot --out artifacts/login.png
|
|
126
|
+
adb-ready capture screenshot --crop 120,300,840,900 --max-width 640
|
|
126
127
|
```
|
|
127
128
|
|
|
128
129
|
Capture a bounded MP4 recording:
|
|
@@ -146,7 +147,10 @@ instead of publishing unusable evidence; create visible activity and retry.
|
|
|
146
147
|
|
|
147
148
|
Some multi-display Android builds, including foldables, emit a short textual
|
|
148
149
|
warning before the screenshot bytes. ADB Ready removes only a bounded text
|
|
149
|
-
preamble and still
|
|
150
|
+
preamble and still decodes the complete PNG, verifies its chunks and checksums,
|
|
151
|
+
and validates its dimensions before publishing the file. `--crop` uses source
|
|
152
|
+
pixels in `X,Y,WIDTH,HEIGHT` order. `--max-width` and `--max-height` preserve
|
|
153
|
+
aspect ratio and never upscale.
|
|
150
154
|
|
|
151
155
|
The result contains:
|
|
152
156
|
|
|
@@ -154,12 +158,21 @@ The result contains:
|
|
|
154
158
|
- media type and byte size;
|
|
155
159
|
- measured duration and video frame count for recordings;
|
|
156
160
|
- SHA-256 digest;
|
|
161
|
+
- capture timestamp, source/output dimensions, effective crop, PNG encoding,
|
|
162
|
+
and whether crop or resize intentionally truncated the original frame;
|
|
157
163
|
- selected target and capture-command provenance.
|
|
158
164
|
|
|
159
165
|
Binary data is stored as a file rather than embedded into JSON or AI context.
|
|
160
166
|
Screenshots and recordings can contain private information; ADB Ready does not
|
|
161
167
|
upload or implicitly attach them to diagnostic context.
|
|
162
168
|
|
|
169
|
+
MCP screenshot results are different by design: `capture_screenshot` returns
|
|
170
|
+
image content to the requesting client, so it defaults to a proportional
|
|
171
|
+
1024×1024 maximum and a 4 MiB base64 content budget. Agents may provide a
|
|
172
|
+
smaller `crop`, `maxWidth`, or `maxHeight`. `fullResolution: true` is an
|
|
173
|
+
explicit escape hatch for clients that can safely accept the complete image;
|
|
174
|
+
it cannot be combined with dimension limits.
|
|
175
|
+
|
|
163
176
|
## Target selection and automation
|
|
164
177
|
|
|
165
178
|
All commands accept the standard target selectors:
|
package/docs/automation.md
CHANGED
|
@@ -158,7 +158,7 @@ leaving a development server open:
|
|
|
158
158
|
|
|
159
159
|
```bash
|
|
160
160
|
adb-ready run --preset expo --run-timeout 10m -- \
|
|
161
|
-
maestro
|
|
161
|
+
maestro test .maestro/smoke.yaml
|
|
162
162
|
```
|
|
163
163
|
|
|
164
164
|
ADB Ready selects and exclusively leases one target, prepares the configured
|
|
@@ -168,9 +168,23 @@ retries a failed product assertion as if it were an infrastructure failure.
|
|
|
168
168
|
|
|
169
169
|
The literal `{target.serial}` inside a verification argument is replaced only
|
|
170
170
|
after ADB Ready selects and leases the target. The child also receives the
|
|
171
|
-
same value as `ANDROID_SERIAL` and `ADB_READY_TARGET_SERIAL
|
|
172
|
-
|
|
173
|
-
|
|
171
|
+
same value as `ANDROID_SERIAL` and `ADB_READY_TARGET_SERIAL`, plus a private
|
|
172
|
+
`ADB_READY_VERIFIER_OUTPUT_DIR` for native artifacts. Tools that already honor
|
|
173
|
+
`ANDROID_SERIAL`, including common Gradle/ADB workflows, need no placeholder.
|
|
174
|
+
|
|
175
|
+
For a direct `maestro test` command, ADB Ready uses Maestro's supported global
|
|
176
|
+
`--device` option to bind the leased serial. Unless the command already names
|
|
177
|
+
them, it also requests Maestro JUnit, test-output, and debug-output files. An
|
|
178
|
+
explicit Maestro device that differs from the leased target fails before
|
|
179
|
+
Maestro starts; ADB Ready never silently retargets it.
|
|
180
|
+
|
|
181
|
+
Android CLI does not expose a single `journey run` command or a stable Journey
|
|
182
|
+
report format. Journeys are evaluated by an agent using the installed Android
|
|
183
|
+
CLI skill. ADB Ready therefore does not invent such a command. It keeps the
|
|
184
|
+
agent workflow target-bound through MCP, and when a finite verifier invokes
|
|
185
|
+
the official `android layout` or `android screen capture` primitives directly,
|
|
186
|
+
ADB Ready supplies their supported `--device` and `--output` options. The
|
|
187
|
+
Journey XML remains owned by Android CLI and the agent.
|
|
174
188
|
|
|
175
189
|
Every executed run prints the path to a project-local evidence directory under
|
|
176
190
|
`.adb-ready/artifacts/`. Its manifest references the structured result,
|
|
@@ -184,6 +198,20 @@ Preview the complete project plan before a device is allocated:
|
|
|
184
198
|
adb-ready run --preset expo --dry-run --json -- npm run test:e2e
|
|
185
199
|
```
|
|
186
200
|
|
|
201
|
+
### Fan out over an explicit pool
|
|
202
|
+
|
|
203
|
+
Named project pools repeat the same bounded verifier without weakening the
|
|
204
|
+
single-target run contract:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
adb-ready run --pool smoke --max-concurrency 2 -- npm run test:e2e
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Each member keeps its own target lease, session, result envelope, evidence, and
|
|
211
|
+
cleanup. Required failures fail the aggregate; optional failures remain
|
|
212
|
+
visible. Queueing is bounded and host-local, never an inferred distributed
|
|
213
|
+
lock. See [Target pools and fan-out](./target-pools.md).
|
|
214
|
+
|
|
187
215
|
### Start an existing AVD and deploy the intended build
|
|
188
216
|
|
|
189
217
|
For a complete local or CI-owned emulator job, name one existing AVD and either
|
|
@@ -196,7 +224,7 @@ adb-ready run \
|
|
|
196
224
|
--artifact android/app/build/outputs/apk/debug/app-debug.apk \
|
|
197
225
|
--package com.example.app \
|
|
198
226
|
--run-timeout 10m \
|
|
199
|
-
-- maestro
|
|
227
|
+
-- maestro test .maestro/smoke.yaml
|
|
200
228
|
|
|
201
229
|
adb-ready run --avd Pixel_9_API_36 --deploy --variant debug -- \
|
|
202
230
|
./gradlew connectedDebugAndroidTest
|
|
@@ -225,8 +253,18 @@ line-oriented `artifact_*`, `deployment_*`, and `emulator_*` fields; `--json`
|
|
|
225
253
|
and `--ndjson` retain the complete structured automation data.
|
|
226
254
|
|
|
227
255
|
The evidence manifest also includes the verifier's bounded, redacted native
|
|
228
|
-
stdout and stderr.
|
|
229
|
-
|
|
256
|
+
stdout and stderr. Supported native JUnit, screenshots, videos, logs, JSON,
|
|
257
|
+
and HTML reports are copied under `verifier-native/`, checksummed, marked
|
|
258
|
+
sensitive, and bounded to 100 files, 20 MiB per file, and 50 MiB total.
|
|
259
|
+
Symlinks and unsupported file types are never followed. Text artifacts are
|
|
260
|
+
redacted; binary screenshots and video remain local sensitive evidence.
|
|
261
|
+
Preparation failures still publish the same result, problems, JUnit, and
|
|
262
|
+
evidence contract after owned-resource cleanup.
|
|
263
|
+
|
|
264
|
+
Structured results classify the verifier independently as `passed`,
|
|
265
|
+
`assertion-failed`, `tool-failed`, `target-failed`, `timed-out`, `cancelled`,
|
|
266
|
+
or `unavailable`. This classification uses process and session state, not
|
|
267
|
+
fragile parsing of human log messages.
|
|
230
268
|
|
|
231
269
|
## CI example
|
|
232
270
|
|
|
@@ -241,3 +279,78 @@ problems, JUnit, and evidence contract after owned-resource cleanup.
|
|
|
241
279
|
USB passthrough, emulators, remote ADB servers, and device labs remain the CI
|
|
242
280
|
environment's responsibility. ADB Ready reports the observed boundary instead
|
|
243
281
|
of simulating a connected device.
|
|
282
|
+
|
|
283
|
+
### GitHub-hosted emulator
|
|
284
|
+
|
|
285
|
+
The repository continuously runs a complete finite ADB Ready job on a real
|
|
286
|
+
headless Linux emulator. The runner layer creates and owns the AVD; ADB Ready
|
|
287
|
+
binds to its exact serial, verifies boot and unlock state, executes the bounded
|
|
288
|
+
check, writes normalized NDJSON and evidence, and leaves emulator teardown to
|
|
289
|
+
the owning layer.
|
|
290
|
+
|
|
291
|
+
Use the maintained, commit-pinned workflow and fixture as the starting point:
|
|
292
|
+
|
|
293
|
+
- [Android emulator workflow](../.github/workflows/android-emulator.yml)
|
|
294
|
+
- [CI emulator fixture](../examples/ci-emulator/)
|
|
295
|
+
|
|
296
|
+
The evidence upload uses `if: always()` so a product assertion or verifier
|
|
297
|
+
failure retains the same manifest, result, JUnit, native files, and GitHub step
|
|
298
|
+
summary as a successful run. A failure before ADB Ready starts cannot produce
|
|
299
|
+
an ADB Ready bundle and is reported by the provisioning step instead.
|
|
300
|
+
|
|
301
|
+
### Self-hosted physical target
|
|
302
|
+
|
|
303
|
+
Use the maintained [physical-device recipe](../examples/ci-physical/) when a
|
|
304
|
+
dedicated self-hosted runner owns one pre-authorized Android phone or tablet.
|
|
305
|
+
The workflow is manual-only, routes through an explicit `android-device`
|
|
306
|
+
runner label, queues competing GitHub jobs, and still relies on ADB Ready's
|
|
307
|
+
host-local target lease as the final ownership boundary.
|
|
308
|
+
|
|
309
|
+
The configured serial must match one `adb devices -l` row exactly. Missing,
|
|
310
|
+
`unauthorized`, `offline`, replaced, and concurrently owned targets fail before
|
|
311
|
+
the verifier can mutate another device. ADB Ready does not restart the shared
|
|
312
|
+
ADB server, approve Android's RSA dialog, or claim a distributed lock across
|
|
313
|
+
runner machines.
|
|
314
|
+
|
|
315
|
+
Do not expose a physical self-hosted runner to untrusted pull requests. Keep
|
|
316
|
+
the runner and its custom label scoped to trusted repositories or runner
|
|
317
|
+
groups, and keep the phone unlocked only when the project's assertions require
|
|
318
|
+
it. The example verifier is read-only and intentionally captures no screenshot
|
|
319
|
+
from a personal device.
|
|
320
|
+
|
|
321
|
+
### Gradle-owned virtual devices
|
|
322
|
+
|
|
323
|
+
When the Android build declares Gradle Managed Devices, keep lifecycle
|
|
324
|
+
ownership with Gradle instead of treating its transient emulator as an ADB
|
|
325
|
+
Ready target:
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
adb-ready test gradle
|
|
329
|
+
adb-ready test gradle :app:pixel2api35DebugAndroidTest --dry-run
|
|
330
|
+
adb-ready test gradle :app:pixel2api35DebugAndroidTest --software-rendering
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
ADB Ready preflights the exact task and normalizes fresh JUnit, HTML, shard,
|
|
334
|
+
and Gradle failure evidence without replacing the build's device definitions
|
|
335
|
+
or test DSL. See [Gradle Managed Devices](./gradle-managed-devices.md) for task
|
|
336
|
+
groups, sharding, outcomes, and the ownership boundary.
|
|
337
|
+
|
|
338
|
+
### Firebase-owned remote devices
|
|
339
|
+
|
|
340
|
+
Use Firebase Test Lab when the provider should own remote physical or virtual
|
|
341
|
+
targets while ADB Ready owns the deterministic invocation, outcome language,
|
|
342
|
+
and bounded evidence handoff:
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
adb-ready test firebase devices --project my-project
|
|
346
|
+
adb-ready test firebase instrumentation \
|
|
347
|
+
--project my-project \
|
|
348
|
+
--app app-debug.apk \
|
|
349
|
+
--test-apk app-debug-androidTest.apk \
|
|
350
|
+
--test-device model=Pixel2.arm,version=35 \
|
|
351
|
+
--dry-run --json
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
See [Firebase Test Lab](./firebase-test-lab.md) for live catalog policy,
|
|
355
|
+
provider-owned lifecycle, result buckets, normalized outcomes, and explicit
|
|
356
|
+
remote cancellation.
|
package/docs/configuration.md
CHANGED
|
@@ -58,6 +58,7 @@ existing file unless `--force` is explicit. Use `--dry-run` first.
|
|
|
58
58
|
| `timeoutMs` | Default bounded operation timeout |
|
|
59
59
|
| `output` | Interactive, animation, color, and Unicode preferences |
|
|
60
60
|
| `targets.aliases` | Friendly name to exact ADB serial mapping |
|
|
61
|
+
| `targets.pools` | Named explicit target sets with bounded concurrency and queue policy |
|
|
61
62
|
| `dev` | Development-session configuration |
|
|
62
63
|
| `profiles` | Named, optionally inherited overrides |
|
|
63
64
|
|
|
@@ -81,6 +82,11 @@ existing file unless `--force` is explicit. Use `--dry-run` first.
|
|
|
81
82
|
Unknown keys and invalid nested values fail validation rather than being
|
|
82
83
|
silently ignored.
|
|
83
84
|
|
|
85
|
+
Target pools accept typed `adb`, `avd`, `remote-adb`, or `firebase` members.
|
|
86
|
+
Every pool requires an explicit `maxConcurrency`; member IDs and resource
|
|
87
|
+
identities must be unique. See [Target pools and fan-out](./target-pools.md) for
|
|
88
|
+
the complete schema, execution semantics, and trust boundaries.
|
|
89
|
+
|
|
84
90
|
`init` detects and writes `packageManager` only for Expo, React Native, and
|
|
85
91
|
Capacitor presets, where it selects the project CLI. Flutter and native Gradle
|
|
86
92
|
use their own launchers, so an unrelated package-manager executable available
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Firebase Test Lab
|
|
2
|
+
|
|
3
|
+
Use this workflow when Firebase should own the remote Android targets. ADB
|
|
4
|
+
Ready validates exact dimensions against the live catalog, starts one bounded
|
|
5
|
+
instrumentation or Robo matrix through `gcloud`, normalizes its outcome, and
|
|
6
|
+
keeps local evidence. It does not create projects, manage billing, provision
|
|
7
|
+
credentials, or replace Firebase's test formats.
|
|
8
|
+
|
|
9
|
+
## Prerequisites
|
|
10
|
+
|
|
11
|
+
Install the current [Google Cloud CLI](https://cloud.google.com/sdk/docs/install),
|
|
12
|
+
authenticate it in the surrounding developer or CI environment, and enable
|
|
13
|
+
Firebase Test Lab for the selected Google Cloud project. Credentials remain in
|
|
14
|
+
Google's credential store; ADB Ready never writes access tokens into config,
|
|
15
|
+
output, or evidence.
|
|
16
|
+
|
|
17
|
+
Inspect the authenticated live catalog before choosing a matrix:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
adb-ready test firebase devices --project my-project
|
|
21
|
+
adb-ready test firebase devices --project my-project --json
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Catalog output joins each model to its supported Android versions and reports
|
|
25
|
+
form, form factor, capacity, and provider tags. A requested unavailable,
|
|
26
|
+
inaccessible, deprecated, reduced-stability, zero-capacity, or low-capacity
|
|
27
|
+
dimension fails before artifact upload. Deprecated, reduced-stability, and
|
|
28
|
+
low-capacity choices require their matching explicit `--allow-*` policy.
|
|
29
|
+
|
|
30
|
+
## Instrumentation
|
|
31
|
+
|
|
32
|
+
Preview the exact direct `gcloud` invocation first:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
adb-ready test firebase instrumentation \
|
|
36
|
+
--project my-project \
|
|
37
|
+
--app app/build/outputs/apk/debug/app-debug.apk \
|
|
38
|
+
--test-apk app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk \
|
|
39
|
+
--test-device model=Pixel2.arm,version=35,locale=en,orientation=portrait \
|
|
40
|
+
--dry-run --json
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Remove `--dry-run` to create the matrix. Repeat `--test-device` for additional
|
|
44
|
+
explicit dimensions. Local paths and private `gs://bucket/object` artifact
|
|
45
|
+
references are supported; signed URLs are rejected so credentials cannot be
|
|
46
|
+
retained accidentally.
|
|
47
|
+
|
|
48
|
+
## Robo
|
|
49
|
+
|
|
50
|
+
Robo needs the app artifact but no instrumentation APK:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
adb-ready test firebase robo \
|
|
54
|
+
--project my-project \
|
|
55
|
+
--app app-debug.apk \
|
|
56
|
+
--test-device model=Pixel2.arm,version=35
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`--test-timeout 10m` controls the provider-side timeout for each execution.
|
|
60
|
+
`--run-timeout 30m` bounds only ADB Ready's local observation.
|
|
61
|
+
|
|
62
|
+
## Results and evidence
|
|
63
|
+
|
|
64
|
+
For deterministic CI retention, use a bucket your job can read and write:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
adb-ready test firebase instrumentation \
|
|
68
|
+
--project my-project \
|
|
69
|
+
--app app-debug.apk \
|
|
70
|
+
--test-apk app-debug-androidTest.apk \
|
|
71
|
+
--test-device model=Pixel2.arm,version=35 \
|
|
72
|
+
--results-bucket gs://my-test-results \
|
|
73
|
+
--results-dir ci/$GITHUB_RUN_ID
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
ADB Ready always retains redacted `gcloud` output and the structured result
|
|
77
|
+
under `.adb-ready/artifacts/firebase-<run-id>/`. With an explicit result bucket,
|
|
78
|
+
it also lists only that exact prefix and downloads a bounded allowlist of native
|
|
79
|
+
JUnit, HTML, JSON, log, screenshot, video, coverage, and protobuf artifacts:
|
|
80
|
+
|
|
81
|
+
- at most 100 provider files;
|
|
82
|
+
- at most 20 MiB per file;
|
|
83
|
+
- at most 50 MiB total;
|
|
84
|
+
- exact post-download size verification; and
|
|
85
|
+
- a local `provider-files.json` source manifest.
|
|
86
|
+
|
|
87
|
+
The structured result reports `complete`, `unavailable`, `remote-running`, or
|
|
88
|
+
`not-configured` evidence collection. Failure to copy requested provider
|
|
89
|
+
evidence is a warning alongside the original test outcome; it never rewrites a
|
|
90
|
+
test assertion into a false pass or a different provider outcome.
|
|
91
|
+
|
|
92
|
+
Without an explicit bucket, the Firebase console URL remains the provider
|
|
93
|
+
result reference and only local normalized evidence is copied.
|
|
94
|
+
|
|
95
|
+
## Outcomes and cancellation
|
|
96
|
+
|
|
97
|
+
ADB Ready preserves the documented `gcloud firebase test android run` result
|
|
98
|
+
classes instead of flattening them:
|
|
99
|
+
|
|
100
|
+
- `passed`;
|
|
101
|
+
- `flaky` — provider roll-up succeeded but at least one test was flaky;
|
|
102
|
+
- `assertion-failed`;
|
|
103
|
+
- `inconclusive`;
|
|
104
|
+
- `unsupported`;
|
|
105
|
+
- `cancelled`;
|
|
106
|
+
- `infrastructure-failed`;
|
|
107
|
+
- `auth-failed`; and
|
|
108
|
+
- local `observation-timed-out` or `observation-stopped`.
|
|
109
|
+
|
|
110
|
+
Stopping or timing out local observation intentionally leaves an identified
|
|
111
|
+
remote matrix running. Cancel exactly one matrix with a separate explicit
|
|
112
|
+
action:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
adb-ready test firebase cancel MATRIX_ID --project my-project --dry-run
|
|
116
|
+
adb-ready test firebase cancel MATRIX_ID --project my-project
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Cancellation obtains a short-lived access token from the authenticated
|
|
120
|
+
`gcloud` process in memory and calls the official Testing API. The token is not
|
|
121
|
+
stored or printed.
|
|
122
|
+
|
|
123
|
+
See Firebase's current [Android CLI guide](https://firebase.google.com/docs/test-lab/android/command-line),
|
|
124
|
+
[available-device guidance](https://firebase.google.com/docs/test-lab/android/available-testing-devices),
|
|
125
|
+
and [result documentation](https://firebase.google.com/docs/test-lab/android/analyzing-results)
|
|
126
|
+
for provider setup, billing, quotas, and native result semantics.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Gradle Managed Devices
|
|
2
|
+
|
|
3
|
+
Use this workflow when the Android build already declares virtual devices or
|
|
4
|
+
device groups in Gradle. Gradle remains the lifecycle owner: it provisions the
|
|
5
|
+
emulator, installs the app and tests, applies sharding, runs instrumentation,
|
|
6
|
+
and tears the target down. ADB Ready does not select, lease, or send commands to
|
|
7
|
+
that transient emulator.
|
|
8
|
+
|
|
9
|
+
## Discover declared tasks
|
|
10
|
+
|
|
11
|
+
Run discovery from the Gradle project root:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
adb-ready test gradle
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
ADB Ready invokes the checked-in `gradlew` or `android/gradlew` Wrapper and
|
|
18
|
+
lists only task descriptions that identify a managed device or device group.
|
|
19
|
+
If the Wrapper lives elsewhere, pass it explicitly:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
adb-ready test gradle --gradle tools/gradlew
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Task names belong to the project. Typical Android Gradle Plugin names resemble
|
|
26
|
+
`pixel2api35DebugAndroidTest` and
|
|
27
|
+
`phoneAndTabletGroupDebugAndroidTest`; ADB Ready does not invent a device,
|
|
28
|
+
variant, or group name.
|
|
29
|
+
|
|
30
|
+
## Preview and run one task
|
|
31
|
+
|
|
32
|
+
Preview the exact direct process invocation without starting Gradle:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
adb-ready test gradle :app:pixel2api35DebugAndroidTest --dry-run --json
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Then execute the same bounded task:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
adb-ready test gradle :app:pixel2api35DebugAndroidTest --run-timeout 20m
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Before execution, ADB Ready asks Gradle to resolve that exact task. A missing
|
|
45
|
+
task fails before test infrastructure starts. The task is passed directly to
|
|
46
|
+
the Wrapper without a shell.
|
|
47
|
+
|
|
48
|
+
## Groups, sharding, and server rendering
|
|
49
|
+
|
|
50
|
+
A declared group task runs through the same boundary:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
adb-ready test gradle :app:phoneAndTabletGroupDebugAndroidTest
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Request Gradle's managed-device sharding property when the build and Android
|
|
57
|
+
Gradle Plugin support it:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
adb-ready test gradle :app:pixel2api35DebugAndroidTest --shards 4
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
On a headless host, opt into Gradle's documented SwiftShader property:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
adb-ready test gradle :app:pixel2api35DebugAndroidTest --software-rendering
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
ADB Ready passes these properties for the current invocation. It never edits
|
|
70
|
+
Gradle files, creates SDK components, or changes a project's declared devices.
|
|
71
|
+
|
|
72
|
+
## Results and evidence
|
|
73
|
+
|
|
74
|
+
After execution, ADB Ready reads native files from the Android Gradle Plugin
|
|
75
|
+
managed-device result and report directories. It retains bounded XML,
|
|
76
|
+
HTML, JSON, logs, text, screenshots, and video under:
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
.adb-ready/artifacts/gradle-managed-<run-id>/
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Machine output keeps these outcomes distinct:
|
|
83
|
+
|
|
84
|
+
- `passed` — Gradle exited successfully and retained JUnit has no failures;
|
|
85
|
+
- `assertion-failed` — fresh JUnit reports a failed or errored test;
|
|
86
|
+
- `infrastructure-failed` — Gradle could not complete provisioning or execution
|
|
87
|
+
and no test assertion explains the failure;
|
|
88
|
+
- `timed-out` — the configured finite timeout expired;
|
|
89
|
+
- `cancelled` — the caller interrupted the task;
|
|
90
|
+
- `GRADLE_MANAGED_TASK_NOT_FOUND` — exact task preflight failed.
|
|
91
|
+
|
|
92
|
+
The original Gradle result and report trees remain the source artifacts. The
|
|
93
|
+
ADB Ready copy is bounded, redacted where textual, and convenient for CI upload
|
|
94
|
+
or an agent. Failed tasks can only classify assertions from files written by
|
|
95
|
+
that execution. A successful up-to-date Gradle task may retain the output that
|
|
96
|
+
Gradle validated from its cache, explicitly marked with `gradle-cache`
|
|
97
|
+
provenance.
|
|
98
|
+
|
|
99
|
+
## Responsibility boundary
|
|
100
|
+
|
|
101
|
+
Use `adb-ready test gradle` for Gradle-owned virtual devices. Use
|
|
102
|
+
`adb-ready run` when ADB Ready must own one already visible ADB target, prepare
|
|
103
|
+
ports and a development service, run a finite verifier, and clean only its own
|
|
104
|
+
resources. Connected-device tasks therefore remain under `run`; they are not
|
|
105
|
+
misrepresented as Gradle Managed Devices.
|
package/docs/logs-and-context.md
CHANGED
|
@@ -62,6 +62,40 @@ and never promoted to application problems. A configured `app.android.package`
|
|
|
62
62
|
or `dev --package APP_ID` scopes the stream directly; Expo sessions retarget it
|
|
63
63
|
to the package that Android resolves for the verified launch URL.
|
|
64
64
|
|
|
65
|
+
## Correlated crash, ANR, and native evidence
|
|
66
|
+
|
|
67
|
+
Inspect one installed application across Android's available failure sources:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
adb-ready inspect failures com.example.app
|
|
71
|
+
adb-ready inspect failures --package com.example.app --since 30m --max-records 25 --json
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
This read-only workflow verifies the selected package and target, records the
|
|
75
|
+
UID and current PID when Android exposes them, uses the target's own clock and
|
|
76
|
+
UTC offset, then correlates a bounded recent window from:
|
|
77
|
+
|
|
78
|
+
- package-scoped `ApplicationExitInfo` exposed by ActivityManager;
|
|
79
|
+
- UID-scoped `main`, `system`, and `crash` logcat buffers;
|
|
80
|
+
- exact package/process matches in supported app crash, native crash, and ANR
|
|
81
|
+
DropBox tags.
|
|
82
|
+
|
|
83
|
+
Java/Kotlin exceptions, native crashes, React Native fatal errors, and ANRs are
|
|
84
|
+
classified separately. Stable numeric `ApplicationExitInfo` reason codes drive
|
|
85
|
+
classification; its human description remains evidence rather than a parsing
|
|
86
|
+
contract. Old exits outside `--since` and DropBox blocks for other packages are
|
|
87
|
+
excluded. Matching evidence from different Android sources is returned as one
|
|
88
|
+
incident with `corroboratedBy`, rather than inflating one crash into multiple
|
|
89
|
+
findings. The default window is 15 minutes and default result limit is 20;
|
|
90
|
+
accepted bounds are one second to seven days and 1 to 100 incidents.
|
|
91
|
+
|
|
92
|
+
Android versions and OEM builds do not expose every source equally. The result
|
|
93
|
+
contains an availability, record count, truncation state, and limitation for
|
|
94
|
+
each source. Missing history or a DropBox permission denial does not become a
|
|
95
|
+
false application failure, and unrelated system/process failures are never
|
|
96
|
+
promoted into the selected app's findings. Returned evidence is sensitive and
|
|
97
|
+
redacted before retention or rendering.
|
|
98
|
+
|
|
65
99
|
## Session history
|
|
66
100
|
|
|
67
101
|
Development sessions incrementally persist redacted NDJSON and an atomic
|