Metadata-Version: 2.4
Name: playwright-smart-locators
Version: 0.1.0
Summary: AI-powered self-healing smart locators for Playwright (Python).
Author: R&D Team
License: MIT
Keywords: ai,anthropic,e2e,llm,locators,ollama,openai,playwright,pytest,self-healing
Requires-Python: >=3.9
Requires-Dist: httpx>=0.24
Requires-Dist: playwright>=1.40
Requires-Dist: pytest-playwright>=0.4
Requires-Dist: pytest>=7
Provides-Extra: dev
Requires-Dist: fastapi; extra == 'dev'
Requires-Dist: mypy; extra == 'dev'
Requires-Dist: pytest-xdist>=3; extra == 'dev'
Requires-Dist: respx>=0.20; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Requires-Dist: uvicorn; extra == 'dev'
Description-Content-Type: text/markdown

# playwright_smart_locators (Python)

[![PyPI](https://img.shields.io/pypi/v/playwright-smart-locators.svg)](https://pypi.org/project/playwright-smart-locators/)

AI-powered self-healing smart locators for Playwright tests (Python port of
[@axeforging/playwright-smart-locators](https://github.com/AxeForging/playwright-smart-locators)).

When a Playwright locator fails, `playwright_smart_locators` intercepts the
timeout, queries an LLM with the broken selector and live/cached DOM, and
retries with the top 7 AI-suggested locators. After the run, it writes
`*-healed.py` suggestion files for review.

## Install

```bash
pip install playwright_smart_locators
playwright install chromium
```

## Configure

In your `conftest.py` (opt-in):

```python
import pytest
from playwright_smart_locators import smart_page

@pytest.fixture
def page(smart_page):
    return smart_page
```

In `pyproject.toml` or `pytest.ini`:

```toml
[tool.pytest.ini_options]
addopts = [
    "--enable-auto-heal",
    "--ai-model=qwen2.5:7b",
    "--ai-pipe-url=http://localhost:11434",
    "--ai-admin-key=sk-",
]
```

Or via environment variables (recommended for Docker / CI):

| Env var | Default | Notes |
|---|---|---|
| `ENABLE_AUTO_HEAL` | `false` | `true` / `1` / `yes` / `on` to activate |
| `AI_MODEL` | `qwen2.5:7b` | Any model name your provider accepts |
| `AI_PIPE_URL` | `http://localhost:11434` | Base URL — OpenAI provider appends `/v1/chat/completions` |
| `AI_ADMIN_KEY` | (empty) | Bearer token; leave empty for local Ollama |
| `AI_PROVIDER` | `openai` | `openai` or `anthropic` |
| `AI_RATE_PER_MIN` | `30` | In-process token bucket rate |

Precedence: **env var > CLI flag > built-in default**. Env wins so Docker / CI configs don't have to be repeated on the command line. Empty env values fall back to the CLI value (so you can set `AI_ADMIN_KEY=` in a `.env` to mean "leave unset" without overriding the CLI flag).

**Provider auto-detect**: if `AI_PIPE_URL` ends with `/anthropic` (e.g. `https://api.example.com/anthropic`), the plugin automatically sets `ai_provider=anthropic` and emits a `UserWarning`. This lets Anthropic-compatible services (like MiniMax) work without setting `AI_PROVIDER=anthropic` explicitly. To opt out, set `AI_PIPE_URL` to a path that doesn't end with `/anthropic` (e.g. add a suffix like `/v1`).

```bash
# Examples
export ENABLE_AUTO_HEAL=true
export AI_MODEL=gpt-4o
export AI_PIPE_URL=https://api.openai.com
export AI_ADMIN_KEY=sk-xxx
pytest
```

## AI Providers

Built-in:
- `openai` (also works with Ollama, Open WebUI, vLLM, LocalAI)
- `anthropic`

Register your own:

```python
from playwright_smart_locators import register_provider

class MyProvider:
    def complete(self, *, system, user, model, timeout=30.0) -> str:
        return '{"locators": [".my-locator"]}'

register_provider("custom", MyProvider)
```

## POM Support

When a locator fails inside a Page Object Model method, the auto-healer
uses `inspect.stack()` to find the real caller file/line. The
`*-healed.py` is written next to the POM file (e.g. `pages/login_page-healed.py`),
not the test spec.

## CI

Disable in CI (no LLM available):

```bash
# CI: don't pass --enable-auto-heal
pytest --browser=chromium
```

## License

MIT
