# Simulator Audio E2e

> Build and run repeatable react-native-nitro-sound recorder/player regression tests on an iOS Simulator or Android emulator, with explicit virtual-device selection, microphone permission, Maestro evidence, native log inspection, and cleanup. Use after dependency, Nitro, TypeScript, Swift, Kotlin, generated-binding, or audio state-machine changes when a physical device is not required.

- Skill: `hyochan/simulator-audio-e2e` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add hyochan/simulator-audio-e2e`
- Raw SKILL.md: https://api.skillmd.com/api/skills/hyochan/simulator-audio-e2e/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: hyochan (https://skillmd.com/u/hyochan)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/hyochan/simulator-audio-e2e

---


# Simulator Audio E2E

Verify real native recording and playback on virtual devices without touching a
connected physical phone. Treat builds, UI automation, callback state, and log
inspection as separate evidence.

## Safety Boundary

- Require explicit permission in the current request before recording. State
  that `sound.example` records a short non-sensitive clip through the host or
  emulator microphone. A request to run audio E2E is sufficient permission.
- Select a concrete iOS Simulator UDID or Android serial beginning with
  `emulator-`. Never allow an implicit destination when physical devices are
  connected.
- Do not upload, transcribe, or retain the recording. Keep only screenshots,
  JUnit output, and redacted logs needed to diagnose the run.
- Do not claim Bluetooth, interruptions, backgrounding, audio focus, route
  changes, or audible fidelity from this lane; those require targeted tests and
  can require a physical device.

## Preflight

1. Read `AGENTS.md`, `.claude/commands/e2e-tests.md`, the changed source, and
   `references/flow-contract.md`.
2. Preserve `git status --short --branch`; never clean unrelated work.
3. Run `scripts/preflight.sh` and select one available virtual destination.
4. Run `yarn install --immutable`, `yarn prepare`, `yarn typecheck`,
   `yarn lint`, and `yarn test --runInBand`.
5. Confirm `sound.example` declares microphone permission and no Metro process
   conflict exists on port 8081.

## Build And Install

For iOS, boot the selected Simulator and build the Debug app for that exact
UDID. Install the produced `.app` with `xcrun simctl install`. For Android,
start the selected AVD, wait for boot completion, and build/install Debug with
`ANDROID_SERIAL` set to the selected emulator serial.

Start Metro from the repository root with `yarn start --reset-cache`. Keep its
session and save errors separately from native device logs. Grant microphone
permission to `sound.example` on the selected virtual device before the flow.

## Run The Runtime Contract

Run the repository flow through the guarded helper:

```bash
.codex/skills/simulator-audio-e2e/scripts/run-maestro.sh ios <simulator-udid>
.codex/skills/simulator-audio-e2e/scripts/run-maestro.sh android <emulator-serial>
```

The flow must prove both direct and hook APIs can:

1. Start recording and emit increasing record time.
2. Pause and resume the recorder without a crash or duplicate instance.
3. Stop and expose a playable path.
4. Start, pause, resume, and stop playback with matching UI state.
5. Complete with no visible error alert.

Do not weaken selectors or remove state assertions to make a failed flow pass.
Fix the product or explain a platform limitation.

## Inspect Native Evidence

After Maestro, inspect simulator logs for the current app process only:

- iOS: `xcrun simctl spawn <udid> log show` with a short time bound and a
  `sound.example` predicate.
- Android: `adb -s <serial> logcat --pid=$(adb -s <serial> shell pidof
  sound.example)` captured around the run.

Fail the runtime lane for uncaught exceptions, native crashes, rejected
promises, MediaRecorder/AVAudio errors, or leaked-resource warnings attributable
to the tested flow. Ignore unrelated host and OS noise with an explanation.

## Report And Cleanup

Report `BUILD PASS/FAIL` and `RUNTIME PASS/FAIL/BLOCKED` per platform. Include
the exact UDID/serial, OS/API level, RN and Nitro versions, flow path, callback
states observed, JUnit result, and relevant redacted log findings. List every
untested device-only row.

Terminate only Metro/emulators started by this run. Leave user-owned devices
and processes intact. Use the guarded runner's mandatory cleanup and verify
that no recording remains in the selected app container or `e2e/artifacts/`.
Report `RUNTIME BLOCKED` if cleanup fails or cannot be confirmed. JUnit,
screenshots, debug output, and redacted logs under `e2e/artifacts/` remain
disposable and ignored by Git.

