Metadata-Version: 2.5
Name: tamash-playwright
Version: 0.1.0
Summary: Self-healing bindings for Playwright + pytest: automatically recovers broken selectors using an AI model (Ollama, OpenAI, Anthropic, or Gemini).
Project-URL: Homepage, https://github.com/qtpsudhakarproducts/tamash-playwright-python
Project-URL: Repository, https://github.com/qtpsudhakarproducts/tamash-playwright-python
Project-URL: License, https://github.com/qtpsudhakarproducts/tamash-playwright-python/blob/main/LICENSE
Author: QtpSudhakar / VibeTestQ
License: SEE LICENSE IN LICENSE
License-File: LICENSE
Keywords: anthropic,gemini,llm,ollama,openai,playwright,pytest,self-healing,test-automation
Requires-Python: >=3.9
Requires-Dist: pytest-playwright>=0.4.0
Requires-Dist: python-dotenv>=1.0.0
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.115.0; extra == 'anthropic'
Description-Content-Type: text/markdown

# tamash-playwright

`tamash-playwright` is a plug and play self-healing solution for Playwright + pytest. Install it, add your AI API key details, and wire in one fixture override.

That's it. No changes needed to your actual test functions if you're following standard Playwright/pytest best practices.

> Also available for TypeScript/`@playwright/test` as [`tamash-playwright` on npm](https://www.npmjs.com/package/tamash-playwright) — same name, same idea, separate package per ecosystem.

### Why you need this

Websites change often. A button gets renamed or moved, and your test can't find it anymore — even though the app still works fine for real users. Normally, that just means a broken test.

`tamash-playwright` fixes this automatically. When a test action can't find an element, it asks an AI model to find it on the current page and tries again. If it succeeds, your test keeps going. If not, it fails normally, just like before.

Here are the detailed steps to use this package.

## Step 1: Install it

```sh
pip install tamash-playwright
```

This pulls in `pytest-playwright` as a dependency, so if you're starting fresh you'll also need the Playwright browsers:

```sh
playwright install
```

Using Anthropic (Claude) as your provider needs one extra install:

```sh
pip install "tamash-playwright[anthropic]"
```

## Step 2: Connect an AI model

`tamash-playwright` needs an AI model to decide where a broken element actually went. Pick one of Ollama, OpenAI, Anthropic (Claude), or Google Gemini, and give it an API key.

Create a file named `.env` in your project folder:

```sh
# Master on/off switch. Leave this as true, or remove the line entirely.
HEALER_ENABLED=true

# Pick one: ollama | openai | anthropic | gemini
HEALER_PROVIDER=ollama

# --- Ollama Cloud (https://ollama.com) ---
OLLAMA_MODEL=gpt-oss:120b
OLLAMA_API_KEY=

# --- OpenAI ---
# OPENAI_MODEL=gpt-4.1-mini
# OPENAI_API_KEY=

# --- Anthropic (Claude) ---
# ANTHROPIC_MODEL=claude-haiku-4-5
# ANTHROPIC_API_KEY=

# --- Google Gemini ---
# GEMINI_MODEL=
# GEMINI_API_KEY=
```

Just fill in the API key and model for whichever one you want to use, and leave the rest as-is (or delete them).

### Getting a free Ollama key (fastest way to get started)

Ollama Cloud is a quick, free way to get an API key without signing up for OpenAI/Anthropic/Gemini billing.

1. Go to [ollama.com](https://ollama.com/) and create an account.
2. Once signed in, go to [ollama.com/settings/keys](https://ollama.com/settings/keys).
3. Create a new API key and copy it.
4. Paste it into your `.env` file:

```sh
HEALER_ENABLED=true
HEALER_PROVIDER=ollama
OLLAMA_MODEL=gpt-oss:120b
OLLAMA_API_KEY=paste_your_key_here
```

That's all you need — no other variables required.

## Step 3: Wire it in

Unlike the JS/TS version of this package (where you swap one `import` line per test file), pytest's plugin model means the reliable way to activate self-healing is **one line in your project's `conftest.py`**, added once — not per test file:

```python
# conftest.py
from tamash_playwright.plugin import page  # noqa: F401
```

Why this line, and not nothing at all: `tamash-playwright` registers itself as a pytest plugin automatically on install, and its `page` fixture *may* already override `pytest-playwright`'s own `page` fixture depending on plugin load order — but that order isn't something pytest guarantees across environments. A `conftest.py` fixture, on the other hand, is *always* preferred by pytest over a same-named fixture from an installed plugin, so re-exporting it there is the one setup step that's guaranteed to work everywhere, every time.

With that line in place, every test using the `page` fixture — no matter how many test files you have — automatically gets self-healing. Nothing else changes:

```python
def test_login(page):
    page.goto("/")
    page.get_by_placeholder("Username").fill("Admin")  # healed automatically if this breaks
    page.get_by_role("button", name="Login").click()
    from playwright.sync_api import expect
    expect(page.get_by_role("heading", name="Dashboard")).to_be_visible()
```

## Step 4: Check your setup

Run the built-in doctor command to confirm everything's wired up correctly:

```sh
tamash-playwright doctor
```

It checks three things:

1. **AI connectivity** — confirms `HEALER_ENABLED`/`HEALER_PROVIDER` are set correctly and actually calls your configured provider to make sure the API key and model work.
2. **Missing `.describe()` labels** — scans your test files (`tests/` by default, or pass `--dir <path>`) for locators that don't have a `.describe('...')` label, flagging the ones most worth fixing (raw CSS/XPath selectors first).
3. **Locators written directly in test files** — flags any locator defined inline in a test rather than inside a Page Object class, a Playwright best practice regardless of self-healing.

If it finds issues, the fastest fix is to open the project in an AI coding assistant (Claude Code, Cursor, GitHub Copilot, etc.) and ask it to address what it flagged. You can also add a standing rule to that assistant's instructions/skill file (e.g. `CLAUDE.md`, `.cursor/rules`, `.github/copilot-instructions.md`) so it follows both practices automatically on any new test code going forward.

### A quick tip for better results

If you're using plain CSS selectors (like `page.locator('input[name="username"]')`) rather than Playwright's more descriptive locators (`get_by_role`, `get_by_placeholder`, etc.), it helps to add a short, human-readable label so the healer knows what it's actually looking for. Chain `.describe('...')` right onto the locator:

```python
def test_login_using_css_selectors(page):
    page.goto("https://example.com/auth/login")

    txt_username = page.locator('input[name="username"]').describe("User Name Textbox")
    txt_username.fill("testadmin")

    txt_password = page.locator('input[placeholder="Password"]').describe("Password Textbox")
    txt_password.fill("secret")

    btn_login = page.locator('button[type="submit"]').describe("Login Button")
    btn_login.click()
```

This step is optional, but recommended — without it, the healer has to guess purely from a broken CSS selector, which gives it a lot less to work with.

## What gets healed (and what doesn't)

Only real Playwright actions that can be safely retried are healed: `click`, `fill`, `check`, `hover`, `press`, `select_option`, `set_input_files`, `focus`, `blur`, `dblclick`, `tap`, `clear`, `uncheck`. `drag_to` and anything unlisted is intentionally left alone rather than guessed at.

`expect(...)` assertions (`to_have_text`, `to_be_visible`, etc.) are **not** healed — they use Playwright's own built-in auto-retrying assertions, which are a separate mechanism this package doesn't touch. If a locator only ever appears inside an `expect(...)` call and never in an action, `.describe()` on it is a readability nicety, not something that affects healing.

## License

Free to use, including commercially. The source code may not be copied, modified, redistributed, or resold without prior written permission. See the LICENSE file included in this package for the full terms.

## Support

For questions or concerns, contact us at support@vibetestq.com.
