For the developer opening the pull request

Proof that a human ran your change, on the pull request.

You already test a change by hand before you merge it. qa-capture watches that session from outside the app and turns it into evidence a reviewer can trust: every screen, every tap, and every control that did nothing, attached to the pull request. Nothing goes into your app.

npm install -g qa-capture

qa-capturecommented on #1posted

Tested by hand

Brew 1.0.0 · emulator · Android 14 · commit f6db20b

  • Open an order, use Add a tip to pick 15% and check the total updatesscreen reached · 3 steps
  • Tap Pay with tip and check the confirmationscreen reached · 2 steps

Screens this change touched · 5 of 5 reached

6 steps recorded · 1 tap produced no visible change

where the finger landed · an element the diff touched · the whole screen, as recorded; click one for a bigger view

How it works

The person drives. The tool records, from outside the app.

Three mechanisms carry the whole thing: what the tool reads from the device while you drive, how the pull request's diff tells it which screens matter, and how it decides what a tap did. No model is involved in any of them.

Screen screenrecord · frames on change only Touches getevent · the kernel's input layer Screens showing a11y events · logcat · Fragments Keyboard dumpsys input_method · 1 Hz frames taps, with x/y screen, strings up / down one device clock a sync marker pins the video to it diffed matched to a step placed on a screen Steps before / after frame per change Taps, judged caused it · small change · no-op Labels which screen each step was on
What the tool reads while you drive. Four things the platform already exposes to a shell, each stamped with the device's own clock so they line up without an SDK. Touches come from the kernel's input layer, which scripted adb shell input bypasses: a session whose screen changed with no touches recorded is marked partial, not presented as a person's work. On a real phone the clocks disagree by however long the phone has slept; the tool measures the gap at the start of each session and then checks the video timing against the taps themselves (verified on a Galaxy A25).
Pull request diff files and lines Signature classes, ids, strings The screen showing events · tree reads Lossless shot element outlined PR comment via your gh read match the moment it matches attached Checklist item · reached the session was on the screen it names Leads the strip changed ones first names string comparison on your machine · no model · no token · nothing installed in the app
From the diff to the evidence. The diff says which screens a change touches: the Activity and Fragment classes it edits, the ids and test tags it adds, the strings a person will read. While you drive, the tool watches for them and takes a lossless screenshot the moment you land on one, with the changed element outlined. A checklist item whose words name one of those screens is marked reached, never passed: whether it worked is a person's verdict.
A tap lands Did a screen change follow it? within the window, or uncontested up to 6 s yes no Step · the tap caused it before and after frames Is the screen different at the end? compared with where it landed · more than 0.5% yes no Step · it changed a little a chip filled, a total updated No visible change · flagged the screen stayed as it was Typing · one step characters never recorded
How a tap is judged. Change is measured frame to frame and against the last settled frame, so a snackbar that slides in over eight frames is one step. A tap only reads as a dead control when the screen stayed exactly as it was, which is the most useful thing a session can catch and the worst thing to get wrong. A burst of typing is one step with its coordinates withheld, because on a soft keyboard the coordinates are the characters.

What it is not

Four things it deliberately does not do.

Not an agent that tests for you.

That space is crowded and mostly free. The person drives; the tool records.

Not an AI that decides whether the app works.

It reports which checklist items a session reached. Whether they passed is a human verdict, and nothing in the codebase can write one.

Not snapshot testing.

Previews show components in isolation. This shows the flow after three taps, with whatever was really on screen.

Not a QA-team tool yet.

Android, tethered to an emulator or a phone over USB, for the developer opening the pull request. An iOS Simulator producer exists and is early.

Get started

Five commands, from your app's repo.

Anything that sends data somewhere prints what it would send and does nothing until you add --send or --post.

qa-capture doctorCheck adb, ffmpeg, gh and the device before you need them.adb ok · ffmpeg 7.1 ok · gh 2.100 ok · device emulator-5554
qa-capture start --highlight --notifyRecord until Ctrl-C while you drive the app. Changed screens are shot the moment you reach them.capture “Add a tip” - a screen this change touched
qa-capture viewBuild the session page and ask one question: do these steps describe what you did?gestures 4 · steps 6 · no-op taps 1 · live shots 1
qa-capture checklist add "Pay with a tip" --pr 42Items are tied to the screens the diff names, and marked reached when the session was there.chk_01 “Pay with tip”
qa-capture comment --postPut it on the pull request through your own gh login, screenshots attached.Screens this change touched · 5 of 5 reached

Read the docs