Skip to main content

AI-powered self-healing locators for Playwright Python tests

Project description

playwright-self-healing

AI-powered self-healing locators for Playwright Python tests using Claude API.

When your Playwright locators fail, Claude automatically analyzes screenshots and HTML to find working locators and caches them for future use.

Features

  • Automatic Healing: When a locator fails, Claude Vision analyzes the page and finds the element
  • YAML Cache: Working locators are cached to avoid repeated API calls
  • Rate Limiting: Max 3 Claude API calls per test session (configurable)
  • Screenshot Caching: 30-second TTL to avoid repeated captures
  • Zero Code Changes: Simple decorator pattern - wrap your Page and you're done
  • pytest-playwright Compatible: Works seamlessly with existing test suites

Installation

pip install playwright-self-healing

Quick Start

from playwright.sync_api import sync_playwright, expect  # Use expect as normal!
from playwright_self_healing import SelfHealingPage
import os

# Enable self-healing (explicit opt-in for security)
os.environ["ENABLE_SELF_HEALING"] = "true"
# Set your Claude API key
os.environ["ANTHROPIC_API_KEY"] = "sk-ant-..."

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()

    # Wrap page with self-healing
    sh_page = SelfHealingPage(page)

    # Use like normal Playwright - healing happens automatically
    sh_page.goto("https://example.com")
    sh_page.get_by_role("button", name="Submit").click()

    # expect() works automatically with SelfHealingLocators - no changes needed!
    heading = sh_page.locator("h1")
    expect(heading).to_be_visible()  # ✅ Just works!

    browser.close()

Security Notice

⚠️ IMPORTANT: Self-healing sends page screenshots and HTML to Anthropic's API for analysis.

  • Explicit opt-in required: Set ENABLE_SELF_HEALING=true to activate
  • Data transmitted: Screenshots and HTML DOM are sent to Anthropic's Claude API
  • Sensitive data: Avoid using on pages with PII, credentials, tokens, or confidential information
  • Test environments only: Recommended for staging/test environments, not production

This library requires explicit opt-in to ensure you're aware of data transmission to external APIs.

How It Works

  1. You use a locator: sh_page.get_by_role("button", name="Submit").click()
  2. If it fails (TimeoutError), the library:
    • Checks the YAML cache for a working locator
    • If not cached, captures a screenshot
    • Sends screenshot + HTML to Claude API
    • Claude analyzes and returns a working locator
    • Tests the new locator
    • Caches it in .cache/locators.yaml
    • Retries your operation with the healed locator
  3. Next time, uses the cached locator (no API call)

Configuration

All configuration via environment variables:

# Required
export ENABLE_SELF_HEALING="true"  # Explicit opt-in (security)
export ANTHROPIC_API_KEY="sk-ant-..."

# Optional (defaults shown)
export CLAUDE_MODEL="claude-sonnet-4.5"
export SELF_HEALING_MAX_RETRIES="3"
export SCREENSHOT_CACHE_TTL="30"
export SELF_HEALING_CACHE_DIR=".cache"
export SELF_HEALING_DEBUG="false"

Pytest Integration

# conftest.py
import pytest
from playwright.sync_api import Page
from playwright_self_healing import SelfHealingPage

@pytest.fixture
def sh_page(page: Page):
    return SelfHealingPage(page)

# test_example.py
from playwright.sync_api import expect  # ✅ Works as-is, no changes needed!

def test_login(sh_page):
    sh_page.goto("https://example.com/login")
    sh_page.get_by_label("Email").fill("test@example.com")
    sh_page.get_by_role("button", name="Login").click()

    # expect() automatically works with SelfHealingLocators
    welcome_message = sh_page.get_by_text("Welcome")
    expect(welcome_message).to_be_visible()  # ✅ Just works!

Zero Code Changes: The library automatically patches Playwright's expect() function to handle SelfHealingLocators. You can continue using from playwright.sync_api import expect in all your existing code - no changes needed!

Cost Estimates

  • Claude API: ~$0.01-0.05 per healed locator
  • Max 3 API calls per session = ~$0.15 max per test run
  • Cached locators cost nothing on subsequent runs

Examples

See the examples/ directory:

API Reference

SelfHealingPage

Main class that wraps a Playwright Page.

from playwright_self_healing import SelfHealingPage

sh_page = SelfHealingPage(page, context="Optional page context")

Methods (same as Playwright Page):

  • get_by_role(role, **kwargs) - Get element by role (with healing)
  • get_by_label(text, **kwargs) - Get element by label (with healing)
  • get_by_text(text, **kwargs) - Get element by text (with healing)
  • get_by_placeholder(text, **kwargs) - Get element by placeholder (with healing)
  • locator(selector) - Get element by CSS (with healing)
  • goto(url), reload(), title(), etc. - All standard Page methods

Additional methods:

  • get_healing_stats() - Returns dictionary with cache/rate limiter stats

SelfHealingLocator

Locators returned by SelfHealingPage methods support all standard Playwright Locator operations:

Actions:

  • click(), fill(), type(), clear() - Text input and clicks
  • check(), uncheck(), set_checked() - Checkbox operations
  • select_option() - Select dropdown options
  • hover(), focus(), blur() - Focus and hover operations
  • press() - Keyboard input
  • set_input_files() - File uploads
  • tap() - Touch interactions
  • drag_to() - Drag and drop

Queries:

  • is_visible(), is_hidden() - Visibility checks
  • is_enabled(), is_disabled() - Enablement checks
  • is_editable(), is_checked() - State checks
  • text_content(), inner_text(), inner_html() - Content extraction
  • all_inner_texts(), all_text_contents() - Batch text extraction
  • get_attribute(), input_value() - Attribute access
  • bounding_box() - Element position/size
  • count() - Number of matching elements

Chaining:

  • .first, .last - Access first/last matching element (properties)
  • nth(index) - Access specific element by index
  • all() - Get all matching elements as a list
  • filter() - Filter matched elements
  • locator() - Create sub-locator
  • or_() - Chain locators with OR logic

Other:

  • wait_for() - Wait for element state
  • screenshot() - Capture element screenshot
  • evaluate() - Execute JavaScript
  • dispatch_event() - Dispatch custom events
  • scroll_into_view_if_needed() - Scroll element into view

All locator operations support self-healing - if any operation fails, Claude will attempt to find the element automatically.

Environment Variables

Variable Required Default Description
ENABLE_SELF_HEALING Yes false Explicit opt-in to enable self-healing (security)
ANTHROPIC_API_KEY Yes - Your Claude API key
CLAUDE_MODEL No claude-sonnet-4.5 Claude model to use
SELF_HEALING_MAX_RETRIES No 3 Max API calls per session
SCREENSHOT_CACHE_TTL No 30 Screenshot cache duration (seconds)
SELF_HEALING_CACHE_DIR No .cache Directory for locator cache
SELF_HEALING_DEBUG No false Enable debug logging

Cache Format

Healed locators are stored in .cache/locators.yaml:

get_by_role(button, name=Submit):
  locator: "page.get_by_role('button', name='Submit')"
  last_updated: "2025-12-24T10:30:00Z"
  original_locator: "page.get_by_role('button', name='Submit')"
  heal_count: 1

Limitations

  • Rate limiting: Max 3 Claude API calls per test session (configurable)
  • Timeout: If Claude fails, the original exception is re-raised
  • Cost: Each API call costs ~$0.01-0.05 (see Claude pricing)
  • Python only: Currently supports Playwright Python only (not Node.js)

Development

# Clone repository
git clone https://github.com/yourusername/playwright-self-healing.git
cd playwright-self-healing

# Install dependencies
pip install -r requirements-dev.txt

# Run tests
pytest

# Format code
black .

# Run linter
flake8 playwright_self_healing/

Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for your changes
  4. Run the test suite
  5. Submit a pull request

License

MIT License - see LICENSE for details.

Credits

Built with:

Support


Made with ❤️ for the Playwright testing community.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

playwright_self_healing-0.2.0.tar.gz (27.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

playwright_self_healing-0.2.0-py3-none-any.whl (28.6 kB view details)

Uploaded Python 3

File details

Details for the file playwright_self_healing-0.2.0.tar.gz.

File metadata

  • Download URL: playwright_self_healing-0.2.0.tar.gz
  • Upload date:
  • Size: 27.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.6

File hashes

Hashes for playwright_self_healing-0.2.0.tar.gz
Algorithm Hash digest
SHA256 a689ef0bb11ad8ec92c22c7ee37c3257326c8963f4a81beb350e84c28a64351d
MD5 5d043e68679baf7eb05142cd8124bb31
BLAKE2b-256 cee32269d70e3b2db7b2267b11b16b82fe425f54fba1202eeead93ef2b9545d9

See more details on using hashes here.

File details

Details for the file playwright_self_healing-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for playwright_self_healing-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ad290414125bf42ae9b37d0473e496f7c7244eb3307e1c1def25aac5dafc60ba
MD5 d0ee51efe895e3446f8567728433a18e
BLAKE2b-256 a868c383d6f43951cc392b6d75da7d3d0bfcd67050af88857978dcd328a33199

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page