World's most superior macOS GUI testing framework with background testing
Reason this release was yanked:
Deprecated. Use: cargo install axterminator --features cli
Project description
AXTerminator
World's Most Superior macOS GUI Testing Framework
Background testing • ~250µs element access • Self-healing locators • AI vision fallback
Quick Start • Features • API • Examples • Docs
🏆 World First: True Background Testing
Test macOS apps without stealing focus. Continue working while tests run in the background.
import axterminator as ax
# Tests run IN THE BACKGROUND - your active window stays focused!
calculator = ax.app(name="Calculator")
calculator.find("5").click() # No focus stealing
calculator.find("+").click() # Continue your work
calculator.find("3").click() # Tests just work
calculator.find("=").click() # Magic ✨
⚡ Why AXTerminator?
| Capability | AXTerminator | XCUITest | Appium | Others |
|---|---|---|---|---|
| Background Testing | ✅ WORLD FIRST | ❌ | ❌ | ❌ |
| Element Access | ~250µs | ~200ms | ~500ms-2s | 800-8000× slower |
| Cross-App Testing | ✅ Native | ❌ | Limited | ❌ |
| Self-Healing | 7 strategies | ❌ | Basic | 1-2 |
| AI Vision Fallback | ✅ VLM | ❌ | ❌ | ❌ |
Quick Start
Installation
pip install axterminator
Basic Usage
import axterminator as ax
# 1. Check accessibility permissions
if not ax.is_accessibility_enabled():
print("Enable in System Settings > Privacy > Accessibility")
exit(1)
# 2. Connect to app
app = ax.app(name="Calculator")
# 3. Interact (background mode by default!)
app.find("7").click()
app.find("+").click()
app.find("3").click()
app.find("=").click()
# Result: 10
CLI Tool
# Check permissions
axterminator check
# Find elements
axterminator find Calculator "5"
# Click elements
axterminator click Calculator "+"
# Record interactions
axterminator record Calculator
Features
🎭 Background Testing
# User continues working while tests run!
for i in range(100):
app.find("Refresh").click() # All in background
🔧 Self-Healing Locators (7 Strategies)
# Element survives UI changes via fallback strategies:
# 1. data_testid - Developer-set stable IDs
# 2. aria_label - Accessibility labels
# 3. identifier - AX identifier
# 4. title - Element title (fuzzy matching)
# 5. xpath - Structural path
# 6. position - Relative position
# 7. visual_vlm - AI vision fallback
🤖 AI Vision Detection (VLM)
# When all else fails, use AI to find elements
ax.configure_vlm(backend="mlx") # Local (fast, private)
ax.configure_vlm(backend="anthropic") # Claude Vision
ax.configure_vlm(backend="openai") # GPT-4V
ax.configure_vlm(backend="gemini") # Gemini Vision
ax.configure_vlm(backend="ollama") # Local Ollama
# Natural language element description
app.find("the blue Save button in the toolbar")
🧪 pytest Integration
import pytest
@pytest.mark.ax_requires_app("Calculator")
def test_addition(ax_app, ax_wait):
app = ax_app("Calculator")
app.find("7").click()
app.find("+").click()
app.find("3").click()
app.find("=").click()
ax_wait(0.1)
🎬 Recording Mode
from axterminator import Recorder
recorder = Recorder(app)
recorder.start()
# ... perform actions ...
recorder.stop()
# Generate test code
print(recorder.generate_test())
API Reference
App Connection
# By name
app = ax.app(name="Safari")
# By bundle ID (recommended)
app = ax.app(bundle_id="com.apple.Safari")
# By PID
app = ax.app(pid=12345)
# Launch if not running
app = ax.app(name="Notes", launch=True)
Finding Elements
# By text/title
button = app.find("Save")
# With timeout
button = app.find("Save", timeout_ms=5000)
# By role
text_field = app.find("", role="AXTextField")
# Find all matching
buttons = app.find_all("role:AXButton")
Actions
# Clicks (background by default)
element.click()
element.double_click()
element.right_click()
# Focused mode (for text input)
element.click(mode=ax.FOCUS)
element.type_text("Hello World!")
# Get properties
print(element.title)
print(element.value)
print(element.role)
Synchronization
from axterminator.sync import wait_for_idle, wait_for_element
# Wait for app to settle
wait_for_idle(app, timeout_ms=5000)
# Wait for element to appear
button = wait_for_element(app, "Done", timeout_ms=3000)
Examples
See examples/ for real-world automation:
| Script | Description |
|---|---|
basic_usage.py |
Calculator automation |
system_preferences.py |
System Settings navigation |
finder_automation.py |
Finder file operations |
notes_app.py |
Notes app automation |
textedit_automation.py |
Document creation |
pytest_example.py |
pytest integration |
self_healing_locators.py |
Locator strategies |
vlm_visual_detection.py |
VLM fallback demo |
Browser Extension
Record browser interactions → generate axterminator code:
- Load
browser-extension/in Chrome (Developer mode) - Click extension → Start Recording
- Interact with web pages
- Copy generated Python code
Installation Options
# Basic
pip install axterminator
# With VLM backends
pip install axterminator[vlm] # Local MLX
pip install axterminator[vlm-anthropic] # Claude Vision
pip install axterminator[vlm-openai] # GPT-4V
pip install axterminator[vlm-gemini] # Gemini Vision
pip install axterminator[vlm-ollama] # Ollama
pip install axterminator[vlm-all] # All backends
Requirements
- macOS 12+ (Monterey or later)
- Python 3.9+
- Accessibility permissions granted to terminal/IDE
Building from Source
git clone https://github.com/MikkoParkkola/axterminator
cd axterminator
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Build
pip install maturin
maturin develop
# Test
pytest python/tests/
Performance
| Operation | Time |
|---|---|
| Element access | ~250µs |
| Click | ~1ms |
| Type text | ~5ms |
| Find element | ~10-50ms |
Benchmarked with cargo bench on M1 MacBook Pro
License
MIT OR Apache-2.0
Contributing
Contributions welcome! See docs/ for architecture details.
Built with 🦀 Rust + 🐍 Python
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file axterminator-0.3.2-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: axterminator-0.3.2-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 396.9 kB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
19f7f9b948bea718494c5f3db80782c6a3b053fff460f44aaac253c99a30b387
|
|
| MD5 |
15bc13e8201a82957e63d7f6f1fe6b57
|
|
| BLAKE2b-256 |
1328cada40f6375f12bd9bc63d5bbda5a6e25403c1a9f54d03ec9850bf3710d5
|
Provenance
The following attestation bundles were made for axterminator-0.3.2-cp39-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on MikkoParkkola/axterminator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
axterminator-0.3.2-cp39-abi3-macosx_11_0_arm64.whl -
Subject digest:
19f7f9b948bea718494c5f3db80782c6a3b053fff460f44aaac253c99a30b387 - Sigstore transparency entry: 892933076
- Sigstore integration time:
-
Permalink:
MikkoParkkola/axterminator@2cfe4c05f798e06a8c57a10f83a63730301183b2 -
Branch / Tag:
refs/tags/v0.3.2 - Owner: https://github.com/MikkoParkkola
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2cfe4c05f798e06a8c57a10f83a63730301183b2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file axterminator-0.3.2-cp39-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: axterminator-0.3.2-cp39-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 410.5 kB
- Tags: CPython 3.9+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4db9d1f644b56e2d1c50fd3e4a3855c32c9c94d6e4f0cf94e40044120563a605
|
|
| MD5 |
8fdd17e7f40dfcbb8f352f37d69cc1a2
|
|
| BLAKE2b-256 |
32128c8eec60ee33801a8014c7d4feef8896ba319d78d29e4649a1141492cabf
|
Provenance
The following attestation bundles were made for axterminator-0.3.2-cp39-abi3-macosx_10_12_x86_64.whl:
Publisher:
release.yml on MikkoParkkola/axterminator
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
axterminator-0.3.2-cp39-abi3-macosx_10_12_x86_64.whl -
Subject digest:
4db9d1f644b56e2d1c50fd3e4a3855c32c9c94d6e4f0cf94e40044120563a605 - Sigstore transparency entry: 892933370
- Sigstore integration time:
-
Permalink:
MikkoParkkola/axterminator@2cfe4c05f798e06a8c57a10f83a63730301183b2 -
Branch / Tag:
refs/tags/v0.3.2 - Owner: https://github.com/MikkoParkkola
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2cfe4c05f798e06a8c57a10f83a63730301183b2 -
Trigger Event:
push
-
Statement type: