Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Manually verify UI features on an iOS or macOS simulator after unit tests pass — when to delegate, how to brief a subagent, screenshot tap coordinates, and safety rules. Use when finishing a UI feature, before shipping, or when tests are green but "nothing happens" bugs are suspected. Delegate the actual driving to a smaller-model subagent (e.g. simulator-verifier).
.claude/skills/miguelaperez-verify-on-simulator/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 32% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 5% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 8% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 9% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 7% | 0% |
A green test suite does not mean the feature works. UI bugs that tests miss are often nothing happens failures — inert taps, .task on conditional views, unreachable menus, mis-placed .searchable, missing navigationDestination registrations. Catch these by driving the feature on a simulator.
This skill covers when to verify, how to delegate, and how to brief the agent doing the driving. Project-specific build commands and off-limits controls live in the repo's CLAUDE.md (or equivalent).
actions, context menus, or empty states
Skip when the change is logic-only (no new taps, pushes, or visible flows).
Simulator verification is screenshot-heavy and iterative — dozens of screenshot → tap → screenshot cycles. That burns expensive context on mechanical work.
Hand driving to a smaller-model subagent (e.g. simulator-verifier with Sonnet or Haiku), not the main model. Keep on the main model:
Launch the subagent with this skill plus the repo's build/run section.
bash # Example — replace with project CLAUDE.md commands xcodebuild -project <Project>.xcodeproj -scheme <Scheme> -configuration Debug \ -destination 'platform=iOS Simulator,name=<Device>'
xcrun simctl list devices booted)."test the feature").
forms that mutate production, payment, etc.).
CLAUDE.mdbuild/run + testing sections.
Include all of the following in the subagent prompt:
| Item | Detail | |------|--------| | Device | Booted simulator UDID — not a device name | | Checklist | Numbered checks; expect PASS / FAIL / BLOCKED per item | | Credentials | Explicitly: do not enter credentials | | Data | Do not mutate real/production data — opening a sheet to check focus is OK; submitting is not | | Destructive UI | Name specific buttons/controls that are off-limits and where they appear (e.g. bottom action bar merge button) | | Reporting | Require stating what could not be verified; "probably fine" is not PASS | | Accidents | Report any accidental tap or state change immediately |
Tap/swipe coordinates are device points, not screenshot pixels. Convert by fraction of the image, never by the device's native scale factor:
x_points = (x_pixels / screenshot_width_pixels) * reported_width_points
y_points = (y_pixels / screenshot_height_pixels) * reported_height_pointsThe simulator MCP tool reports point space on every attach/launch (e.g. 402x874 points) — that is the authority.
Do not assume "screenshot is ~3x point dimensions, divide by 3." The tool often downsamples before returning the image, so the true factor differs from the device scale. Wrong conversion overshoots taps — especially dangerous on compact toolbars and bottom action bars where destructive buttons live. Large targets (tab bar) may still land by luck, which hides the error until a critical control is hit.
For each new or changed UI surface:
Subagent returns a table or list:
| # | Check | Result | Notes |
|---|-------|--------|-------|
| 1 | Tap repo row → detail | PASS | |
| 2 | Swipe delete on entry | FAIL | Menu never appears |
| 3 | Create PR submit | BLOCKED | No fixture account |Any FAIL blocks ship until fixed or explicitly accepted. BLOCKED items need a documented reason (missing fixture, needs credentials, etc.).
Resolve build/test commands from the project repo, not this skill.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 15,781 | 12,522 | -21% | 1 | 1 | 0% | 2,338 | 3,088 | +32% | 0 | 0 | — |
case-02 | fail→pass | 20,245 | 13,759 | -32% | 1 | 1 | 0% | 3,178 | 3,344 | +5% | 0 | 0 | — |
case-03 | pass→pass | 15,055 | 6,762 | -55% | 1 | 1 | 0% | 2,501 | 2,468 | -1% | 0 | 0 | — |
case-04 | pass→pass | 17,883 | 8,710 | -51% | 1 | 1 | 0% | 2,813 | 2,579 | -8% | 0 | 0 | — |
case-05 | pass→pass | 11,838 | 5,671 | -52% | 1 | 1 | 0% | 1,775 | 2,048 | +15% | 0 | 0 | — |
case-06 | fail→fail | 14,404 | 10,871 | -25% | 1 | 1 | 0% | 2,096 | 2,388 | +14% | 0 | 0 | — |
case-07 | fail→pass | 17,177 | 9,358 | -46% | 1 | 1 | 0% | 2,477 | 2,676 | +8% | 0 | 0 | — |
case-08 | pass→pass | 12,749 | 4,594 | -64% | 1 | 1 | 0% | 2,180 | 1,959 | -10% | 0 | 0 | — |
case-09 | fail→pass | 18,408 | 11,643 | -37% | 1 | 1 | 0% | 2,670 | 2,910 | +9% | 0 | 0 | — |
case-10 | fail→fail | 8,480 | 4,710 | -44% | 1 | 1 | 0% | 1,315 | 1,861 | +42% | 0 | 0 | — |
case-11 | pass→pass | 12,927 | 5,046 | -61% | 1 | 1 | 0% | 1,838 | 1,948 | +6% | 0 | 0 | — |
case-12 | fail→pass | 18,276 | 14,069 | -23% | 1 | 1 | 0% | 2,883 | 3,099 | +7% | 0 | 0 | — |
case-13 | pass→pass | 11,738 | 4,192 | -64% | 1 | 1 | 0% | 1,913 | 1,781 | -7% | 0 | 0 | — |
case-14 | pass→pass | 12,954 | 8,399 | -35% | 1 | 1 | 0% | 1,662 | 2,357 | +42% | 0 | 0 | — |
case-15 | fail→pass | 16,559 | 12,149 | -27% | 1 | 1 | 0% | 2,655 | 2,908 | +10% | 0 | 0 | — |
case-16 | pass→pass | 13,248 | 12,258 | -7% | 1 | 1 | 0% | 2,208 | 3,032 | +37% | 0 | 0 | — |
case-17 | fail→pass | 13,893 | 6,578 | -53% | 1 | 1 | 0% | 2,068 | 2,244 | +9% | 0 | 0 | — |
case-18 | fail→pass | 15,286 | 6,102 | -60% | 1 | 1 | 0% | 2,352 | 2,138 | -9% | 0 | 0 | — |
case-19 | fail→pass | 10,196 | 3,119 | -69% | 1 | 1 | 0% | 1,655 | 1,606 | -3% | 0 | 0 | — |
case-20 | pass→pass | 14,269 | 9,011 | -37% | 1 | 1 | 0% | 2,103 | 2,432 | +16% | 0 | 0 | — |
case-21 | pass→pass | 4,896 | 3,963 | -19% | 1 | 1 | 0% | 664 | 1,540 | +132% | 0 | 0 | — |
case-22 | pass→pass | 19,044 | 15,362 | -19% | 1 | 1 | 0% | 2,900 | 3,486 | +20% | 0 | 0 | — |
case-23 | pass→pass | 17,225 | 7,827 | -55% | 1 | 1 | 0% | 2,662 | 2,335 | -12% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +39 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.