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/testastamash-playwrighton npm — 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
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:
playwright install
Using Anthropic (Claude) as your provider needs one extra install:
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:
# 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.
- Go to ollama.com and create an account.
- Once signed in, go to ollama.com/settings/keys.
- Create a new API key and copy it.
- Paste it into your
.envfile:
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:
# 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:
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:
tamash-playwright doctor
It checks three things:
- AI connectivity — confirms
HEALER_ENABLED/HEALER_PROVIDERare set correctly and actually calls your configured provider to make sure the API key and model work. - 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). - 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:
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.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
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 tamash_playwright-0.1.0.tar.gz.
File metadata
- Download URL: tamash_playwright-0.1.0.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
441b2e175588b2c252cf0bdb666c30b1aa15208f71339833bc02e5463477523f
|
|
| MD5 |
c6a0a1199ec3f4e23d5791dd1c62c82e
|
|
| BLAKE2b-256 |
c3fbb3f6f9a68a714c40bd627ba0affd1dc9523e1a8e47d1b571c0d6bf3dab5a
|
File details
Details for the file tamash_playwright-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tamash_playwright-0.1.0-py3-none-any.whl
- Upload date:
- Size: 23.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
56b4de5de4505caee8782b4d5adbc21df5482d3a19c6a5e6f911a30dd7e42ebe
|
|
| MD5 |
c4d014ce7f9e289498069cd9e1825d15
|
|
| BLAKE2b-256 |
a0e62684fb8f9b6f295666cd2f136b05063d8cbdc4d2deceace9bfe4950aeb81
|