"In the ancient dojo of broken tests, where failed assertions echo like battle cries in the night, there walks a lone warrior. Armed with the swift blade of Claude AI and the ancient scrolls of code wisdom, Autofix strikes without mercy. One test. One fix. One path to honor. When your UI tests fall in disgrace, only one master can restore balance to the codebase. His weapon? Autonomous intelligence. His mission? Vengeance against bugs. His name is whispered in fear by broken assertions everywhere: Autofix - The Code Ronin."
A Toei Company Production Β· Directed by Kinji Fukasaku Β· Starring Claude-3.5-Haiku as The Silent Debugger
An autonomous AI agent that automatically fixes failing iOS UI tests using Claude AI and intelligent code analysis tools.
Autofix analyzes failed iOS UI tests, explores your codebase, and autonomously makes code changes to fix the failures. It can work in two modes depending on whether you want to fix your application code or your test code.
- π Intelligent Test Analysis: Parses XCTest results and identifies failure details
- πΌοΈ Visual Context: Analyzes simulator screenshots to understand UI state
- π οΈ Autonomous Code Editing: Makes targeted code changes automatically
- β Verification Loop: Builds and runs tests to verify fixes work
- π Dual Modes: Fix app code OR test code based on your needs
- π€ Multi-Provider Support: Use Claude, OpenAI, or local Ollama models
- π§ Tool-Based Architecture: Uses specialized tools for inspection, editing, and testing
- Rust (edition 2024)
- Xcode and
xcodebuildcommand-line tools - LLM Provider (choose one):
- Claude (Anthropic) - Recommended, default
- OpenAI (GPT-4, GPT-4o, etc.)
- Ollama (Local models)
git clone <repository-url>
cd autofix
cargo build --releaseAutofix supports three LLM providers. Choose the one that works best for you:
Get your API key from console.anthropic.com
export ANTHROPIC_API_KEY="sk-ant-api03-..."
# Optional: Override default model
export AUTOFIX_MODEL="claude-sonnet-4" # or claude-opus-4, claude-haiku-3.5Get your API key from platform.openai.com
export AUTOFIX_PROVIDER=openai
export OPENAI_API_KEY="sk-..."
# Optional: Override default model
export AUTOFIX_MODEL="gpt-4o" # or gpt-4-turbo, gpt-4OpenAI-Compatible Servers (Together.ai, Groq, vLLM, etc.):
export AUTOFIX_PROVIDER=openai
export AUTOFIX_API_BASE="https://your-server.com/v1"
export OPENAI_API_KEY="your-key"
export AUTOFIX_MODEL="your-model-name"Install and start Ollama, then pull a model:
# Install Ollama from ollama.ai
ollama serve
ollama pull llama2 # or llama3, codellama, mistral, etc.
# Configure autofix
export AUTOFIX_PROVIDER=ollama
export AUTOFIX_MODEL="llama2" # or your preferred modelAlternatively, create a .env file (see .env.example for all options):
cp .env.example .env
# Edit .env with your API keys and preferencesAutofix includes smart rate limiting to prevent hitting API limits:
# Maximum tokens per minute (provider-specific defaults)
export AUTOFIX_RATE_LIMIT_TPM=50000Default limits by provider:
- Claude: 30,000 TPM
- OpenAI: 90,000 TPM
- Ollama: Unlimited (local)
Assumes your app is correct and the test needs adjustment:
# Using Claude (default)
autofix --ios \
--test-result path/to/test.xcresult \
--workspace path/to/workspace
# Using OpenAI
autofix --ios \
--provider openai \
--test-result path/to/test.xcresult \
--workspace path/to/workspace
# Using Ollama (local)
autofix --ios \
--provider ollama \
--test-result path/to/test.xcresult \
--workspace path/to/workspaceWith verbose debug output:
autofix --ios \
--test-result path/to/test.xcresult \
--workspace path/to/workspace \
--verboseOverride model:
autofix --ios \
--provider openai \
--model gpt-4o \
--test-result path/to/test.xcresult \
--workspace path/to/workspaceWhat it does:
- β Analyzes test failures
- β Fixes test code (selectors, waits, expectations)
- β Adds accessibility identifiers to app code (for testability)
- β Verifies fixes by running tests
Assumes your test is correct and the app needs fixing:
autofix --ios \
--test-result path/to/test.xcresult \
--workspace path/to/workspace \
--knightriderWhat it does:
- β Treats test as source of truth
- β Fixes application source code only
- β Adds missing UI elements, labels, identifiers
- β Never modifies test files
Add the -v or --verbose flag to any command to enable detailed debug output:
autofix --ios \
--test-result path/to/test.xcresult \
--workspace path/to/workspace \
--verbose # or -vWhat verbose mode shows:
- File paths and directories being processed
- Test identifiers and metadata
- Tool execution details (operations, inputs, outputs)
- Token usage and rate limit statistics
- File sizes and content lengths
- Success/failure details for each operation
Note: AI conversation output is ALWAYS printed, regardless of verbose mode.
Get detailed analysis for a single test:
autofix test --ios \
--test-result path/to/test.xcresult \
--workspace path/to/workspace \
--test-id "test://com.apple.xcode/MyApp/MyTests/MyTests/testExample"| Mode | Assumption | Primary Target | Can Modify App? | Can Modify Test? |
|---|---|---|---|---|
| Standard (default) | App is correct | Fix test code | β Yes (accessibility) | β Yes |
Knight Rider (--knightrider) |
Test is correct | Fix app code | β Yes (only this) | β No |
Autofix uses a multi-stage pipeline:
- Attachment Fetching: Extracts screenshots and attachments from
.xcresultbundles - Test File Location: Finds the Swift test file in your workspace
- AI Analysis: Claude analyzes the failure with visual context
- Autonomous Fixing (with tools):
DirectoryInspectorTool: Explores codebase, reads files, searches for patternsCodeEditorTool: Makes precise code edits via string replacementTestRunnerTool: Builds and runs tests to verify fixes
βββββββββββββββββββββββββββββββββββββββ
β Failed Test: testLoginButton() β
β Error: Button not found β
βββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββ
β π€ Autofix analyzes screenshot β
β Sees button exists visually β
βββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββ
β π Explores codebase β
β Finds LoginView.swift β
βββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββ
β βοΈ Adds accessibility ID β
β Button("Login") β
β .accessibilityIdentifier("...") β
βββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββ
β π§ͺ Runs test β
β β
Test passes! β
βββββββββββββββββββββββββββββββββββββββ
autofix/
βββ src/
β βββ main.rs # CLI entry point
β βββ llm/ # LLM provider abstraction
β β βββ mod.rs # Core types & factory
β β βββ provider_trait.rs # LLMProvider trait
β β βββ config.rs # Provider configuration
β β βββ claude_provider.rs # Claude/Anthropic impl
β β βββ openai_provider.rs # OpenAI impl
β β βββ ollama_provider.rs # Ollama impl
β βββ pipeline/ # Core pipeline logic
β β βββ mod.rs # Module declarations
β β βββ autofix_pipeline.rs # Pipeline implementation
β β βββ prompts.rs # AI prompt generation
β βββ tools/ # AI agent tools
β β βββ directory_inspector_tool.rs # File exploration
β β βββ code_editor_tool.rs # Code editing
β β βββ test_runner_tool.rs # Build & test execution
β βββ autofix_command.rs # Process all failed tests
β βββ test_command.rs # Single test processing
β βββ rate_limiter.rs # Provider-aware rate limiting
β βββ xcresultparser.rs # Parse XCResult bundles
β βββ xctestresultdetailparser.rs # Parse test details
β βββ xc_test_result_attachment_handler.rs # Extract attachments
β βββ xc_workspace_file_locator.rs # Locate test files
βββ Cargo.toml
βββ .env.example # Configuration template
βββ README.md
Autofix provides the LLM with three specialized tools:
- Operations:
list,read,search,find - Purpose: Explore workspace, read files, search for patterns
- Example: Find all Swift files with a specific class
- Operation: Exact string replacement
- Purpose: Make targeted code edits
- Safety: Validates old content exists before replacing
- Operations:
build,test - Purpose: Compile code and run specific tests
- Output: Exit codes, stdout, stderr for verification
π€ Knight Rider iteration 1...
π Claude says:
I'll explore the codebase to understand the app structure and locate the relevant view files.
π§ Tool call: directory_inspector (id: toolu_123)
Input: {"operation": "list", "path": "MyApp"}
π§ Tool call: directory_inspector (id: toolu_456)
Input: {"operation": "read", "path": "MyApp/Views/LoginView.swift"}
π€ Knight Rider iteration 2...
π Claude says:
I found the issue. The button exists but lacks an accessibility identifier.
π§ Tool call: code_editor (id: toolu_789)
Input: {...}
βοΈ Edit result: Successfully edited file: MyApp/Views/LoginView.swift
π§ Tool call: test_runner (id: toolu_abc)
Input: {"operation": "test", "test_identifier": "..."}
π§ͺ Test result: Test passed (exit code: 0)
β
SUCCESS!
β Knight Rider finished!cargo testRUST_LOG=debug cargo run -- --ios --test-result ... --workspace ...cargo build --release
./target/release/autofix --helpProblem: Test can't find UI elements
Solution: Autofix adds .accessibilityIdentifier() to views
Problem: Test uses wrong element query Solution: Autofix updates test to use correct selector
Problem: Test fails due to animation/loading Solution: Autofix adds proper wait conditions
Problem: Test expects incorrect text/state Solution: Autofix updates test assertions
Problem: App missing button/label test expects Solution: (Knight Rider mode) Autofix adds missing elements to app
- iOS/Xcode projects only (Android support planned)
- Requires
xcodebuildcommand-line tools - Works best with structured, well-named code
- May need multiple iterations for complex fixes
- Requires valid API key for Claude/OpenAI, or local Ollama setup
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
cargo test - Submit a pull request
- Built with support for multiple LLM providers:
- Anthropic Claude via anthropic-sdk-rust
- OpenAI via async-openai
- Ollama for local model support
- Inspired by the need for better UI test maintenance
Made with β€οΈ and π€ AI