Metadata-Version: 2.4
Name: specterqa-ios
Version: 16.0.0a3
Summary: SpecterQA iOS Simulator Driver — AI-driven iOS testing via Claude Computer Use
Author-email: SyncTek LLC <info@synctek.io>
License-Expression: Elastic-2.0
Project-URL: Homepage, https://synctek.io/specterqa
Project-URL: Repository, https://github.com/SyncTek-LLC/specterqa-ios
Project-URL: Issues, https://github.com/SyncTek-LLC/specterqa-ios/issues
Project-URL: Changelog, https://github.com/SyncTek-LLC/specterqa-ios/blob/main/CHANGELOG.md
Keywords: ios,testing,qa,xctest,simulator,mcp,ai,agent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: MacOS
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Pillow>=10.0
Requires-Dist: click>=8.0
Requires-Dist: rich>=13.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: requests>=2.31
Requires-Dist: pyobjc-framework-Quartz>=10.0
Requires-Dist: pyobjc-framework-Cocoa>=10.0
Requires-Dist: pyobjc-framework-ApplicationServices>=10.0
Provides-Extra: native
Requires-Dist: pyobjc-framework-Quartz>=10.0; extra == "native"
Requires-Dist: pyobjc-framework-Cocoa>=10.0; extra == "native"
Provides-Extra: mcp
Requires-Dist: mcp>=1.0; extra == "mcp"
Provides-Extra: orchestration
Requires-Dist: anthropic>=0.39.0; extra == "orchestration"
Requires-Dist: numpy>=1.24; extra == "orchestration"
Provides-Extra: browserstack
Provides-Extra: license
Requires-Dist: httpx>=0.27.0; extra == "license"
Requires-Dist: pyyaml>=6.0; extra == "license"
Requires-Dist: stripe>=8.0; extra == "license"
Requires-Dist: fastapi>=0.110.0; extra == "license"
Requires-Dist: uvicorn>=0.29.0; extra == "license"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: httpx>=0.27.0; extra == "dev"
Requires-Dist: specterqa-ios[orchestration]; extra == "dev"
Dynamic: license-file

# SpecterQA iOS

AI-driven iOS testing that records once and replays free in CI — no AI cost on repeat runs.

## Install

```bash
pip install "git+https://github.com/SyncTek-LLC/specterqa-ios.git"
```

## Quick Start with Claude Code (MCP)

```bash
pip install 'specterqa-ios[mcp]'
```

Add to `.claude/mcp.json`:

```json
{
  "mcpServers": {
    "specterqa-ios": {
      "command": "specterqa-ios-mcp",
      "env": { "ANTHROPIC_API_KEY": "sk-ant-..." }
    }
  }
}
```

Then in Claude Code: _"Run a smoke test on the Palace app, record it as palace-smoke"_. Claude drives the simulator, records every action. After that, CI runs it free — no AI involved.

### Your First Session (30 seconds)

```python
# Claude calls these 6 MCP tools in order:
ios_start_session(bundle_id="com.example.app")
ios_screenshot()                          # see what's on screen
ios_tap(label="Sign In")                  # tap by label
ios_screenshot()                          # verify result
ios_stop_recording(name="signin-smoke")   # save replay YAML to .specterqa/replays/
ios_stop_session()                        # clean up
```

The replay YAML is now in `.specterqa/replays/signin-smoke.yaml`. Run it in CI with:
```bash
specterqa-ios replay .specterqa/replays/signin-smoke.yaml
```
No AI needed on replay — it runs the deterministic engine directly.

## Dual-Mode Architecture

| Phase | Who drives | Cost |
|-------|-----------|------|
| **Record** (once) | Claude AI via MCP | AI tokens |
| **Replay** (every CI run) | Deterministic replay engine | Free |

Record once with Claude, replay forever without it. This is the key advantage over traditional frameworks.

## Maestro-Compatible YAML

Users migrating from Maestro can use familiar shorthand — SpecterQA understands it natively:

```yaml
replay:
  bundle_id: com.example.app
  steps:
    - tapOn: "Sign In"            # same as: action: tap, element_label: Sign In
    - inputText: "user@example.com"
    - assertVisible: "Dashboard"  # asserts element is present
    - assertNotVisible: "Loading"
    - waitFor: "Feed"             # waits up to 10s for element
```

All Maestro shortcuts work alongside native SpecterQA syntax in the same file.

## CI Commands

```bash
# Run all replays (shared runner on by default — ~10x faster)
specterqa-ios ci .specterqa/replays/

# Parallel execution — run 4 replays simultaneously
specterqa-ios ci --parallel 4

# Per-replay isolation (full reset between each replay)
specterqa-ios ci --no-reuse-runner

# Validate a replay file before running it
specterqa-ios validate-replay .specterqa/replays/smoke.yaml
```

## Full CLI Reference

| Command | Description |
|---------|-------------|
| `setup` | Check Xcode, simulators, API key |
| `devices` | List available iOS simulators |
| `boot` | Boot a simulator |
| `install <app.app>` | Install app on simulator |
| `init` | Scaffold `.specterqa/` project files |
| `validate --product <slug>` | Validate product/journey config |
| `validate-replay <file>` | Validate a replay YAML (schema + references) |
| `run --product <slug> --journey <id>` | Run a test journey (AI-driven) |
| `smoke --product <slug>` | Quick smoke test |
| `replay <file>` | Replay a recorded session |
| `ci [dir]` | Run all replays in CI mode |
| `serve` | Start the MCP server |

## vs. Maestro / Appium / XCUITest

| | SpecterQA | Maestro | Appium | XCUITest |
|---|---|---|---|---|
| No AI in CI | Yes | Yes | Yes | Yes |
| AI-assisted recording | Yes | No | No | No |
| Maestro YAML syntax | Yes | Native | No | No |
| Parallel CI | Yes (`--parallel N`) | No | Yes | Yes |
| Zero config | Yes | Yes | No | No |
| Claude Code native | Yes (MCP) | No | No | No |

## Physical device support (experimental)

SpecterQA can drive a connected iOS device (iPhone or iPad) in addition to the simulator. Physical device support uses `devicectl`-based deployment and communicates with the XCTest runner over the device's IP address, exactly as in the simulator path.

To opt in, set the environment variable `SPECTERQA_ALLOW_PHYSICAL_DEVICE=1` and pass `device_type="physical"` when calling `ios_start_session`:

```bash
export SPECTERQA_ALLOW_PHYSICAL_DEVICE=1
```

```python
# In your MCP tool call:
ios_start_session(bundle_id="com.example.app", device_id="<device-udid>", device_type="physical")
```

Call `ios_get_capabilities()` first to confirm the physical device type is advertised and check whether `opt_in_active` is `true`. Known limitations: xcodebuild integration has rough edges on iOS 26 that can cause intermittent failures; the install/deploy step is slower than the simulator path; and there is no guarantee of stability on non-GM OS builds. The simulator (`device_type="simulator"`, the default) remains the fully supported path.

## Requirements

- macOS + Xcode 15+
- Python 3.10+
- `ANTHROPIC_API_KEY` (recording only — not needed for replay)

## License

Elastic License 2.0 — see [LICENSE](LICENSE).
