# AppTestCircuit
A Claude Code plugin that gives Claude eyes and hands on the iOS Simulator. Build your Swift app, launch it on the simulator, inspect the UI, test interactions, find issues, fix the code, and retest — all in an automated loop.
## How it works
```
You: /AppTestCircuit:test-loop xcodebuild -scheme MyApp ... "Verify the login flow"
Claude:
1. Builds the app (fixes compile errors if needed)
2. Installs and launches on the simulator
3. Takes a screenshot + reads the accessibility tree
4. Tests the requested flow (tap, type, verify)
5. If something's wrong → fixes the Swift code → rebuilds → retests
6. Repeats until it works
```
## Prerequisites
This skill assumes that you have Xcode installed, which comes with iOS simulator. It automatically installs iosef (https://github.com/riwsky/iosef), if not already installed, which interacts with iOS simulator to test your application.
## Install the plugin
```
# From within Claude Code:
/plugin marketplace add webcoyote/AppTestCircuit
/plugin install AppTestCircuit
```
## Usage
### Full build-test-fix loop
With xcodebuild:
```
/AppTestCircuit:test-loop xcodebuild -project MyApp.xcodeproj -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 16' build
```
With a custom build script:
```
/AppTestCircuit:test-loop ./path/to/build-script Verify the signup form validates email and shows an error for invalid input
```
Custom build scripts are fully supported. The test loop will read your script to understand what it does — whether it only compiles, or also handles simulator boot/install/launch — and adapt accordingly. Scripts that do everything in one shot work just as well as scripts that only build.
## Preparing your Swift app
For best results, add `accessibilityIdentifier` to interactive elements in your SwiftUI views:
```swift
Button("Sign In") { signIn() }
.accessibilityIdentifier("sign-in-button")
TextField("Email", text: $email)
.accessibilityIdentifier("email-field")
Text("Welcome, \(username)")
.accessibilityIdentifier("welcome-label")
```
Or in UIKit:
```swift
signInButton.accessibilityIdentifier = "sign-in-button"
emailField.accessibilityIdentifier = "email-field"
```
Tips:
- Use stable, descriptive names: `"login-email-field"` not `"field1"`
- `accessibilityIdentifier` is for automation (not read by VoiceOver)
- `accessibilityLabel` is for VoiceOver users — set both when appropriate
## How it connects to the simulator
The plugin uses two tools:
1. **`xcrun simctl`** (built into Xcode) — simulator lifecycle: boot, grant permissions
2. **`iosef`** (open source) — UI interaction and inspection: install, launch, screenshot, accessibility tree, tap, type, swipe, logs
iosef runs as an MCP server (`iosef mcp`), giving Claude structured tools for each action. Everything runs locally on your Mac.
# License
AppTestCircuit Copyright © 2026 Patrick Wyatt
MIT License — see [LICENSE.md](LICENSE.md) for details.
# Thanks to
This project builds on the great works of other open-source authors:
- [iosef](https://github.com/riwsky/iosef): MCP server for iOS Simulator
- [Claude](https://www.anthropic.com/claude): AI coding assistant
- [Homebrew](https://brew.sh): 🍺 The missing package manager for macOS
- [Shellcheck](https://www.shellcheck.net): finds bugs in your shell scripts
- [uv](https://docs.astral.sh/uv/): An extremely fast Python package and project manager, written in Rust
... as well as GNU, BSD, Linux, Git, Sqlite, Node, Python, netcat, jq, and more. "We stand upon the shoulders of giants."