Metadata-Version: 2.4
Name: testmuai-playwright-bindings
Version: 0.1.47
Summary: TestMu binding for Playwright Python — thin test runtime for TestMu-exported tests on the LambdaTest grid
Author-email: TestMu AI <engineering@testmu.ai>
License-Expression: MIT
Project-URL: Homepage, https://github.com/LambdaTest/testmuai-bindings
Project-URL: Repository, https://github.com/LambdaTest/testmuai-bindings
Project-URL: Issues, https://github.com/LambdaTest/testmuai-bindings/issues
Keywords: testing,playwright,lambdatest,testmu,automation,e2e
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Topic :: Software Development :: Testing
Classifier: Framework :: Pytest
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: playwright>=1.57.0
Requires-Dist: pyotp>=2.9.0
Requires-Dist: aiohttp
Requires-Dist: httpx>=0.27.0
Requires-Dist: Pillow>=11.0.0
Requires-Dist: requests>=2.28.0
Requires-Dist: websockets>=12
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: jsonschema>=4.18.0
Requires-Dist: python-jsonpath>=2.2.1
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
Dynamic: license-file

# testmuai-playwright-bindings

[![PyPI version](https://img.shields.io/pypi/v/testmuai-playwright-bindings.svg)](https://pypi.org/project/testmuai-playwright-bindings/)
[![Python versions](https://img.shields.io/pypi/pyversions/testmuai-playwright-bindings.svg)](https://pypi.org/project/testmuai-playwright-bindings/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

TestMu binding for Playwright Python — a thin test runtime for running TestMu-exported tests locally or on the LambdaTest grid.

## Installation

```bash
pip install testmuai-playwright-bindings
```

Then install the Playwright browsers (one-time):

```bash
playwright install
```

## Quick Start

Set credentials (LambdaTest grid) once in your environment:

```bash
export LT_USERNAME="your_username"
export LT_ACCESS_KEY="your_access_key"
```

Then write a test:

```python
import testmu

@testmu.test
async def my_test(page):
    async with testmu.step("Open site"):
        await page.goto("https://example.com")

    async with testmu.step("Verify title"):
        await testmu.expect(page).to_have_title("Example Domain")

testmu.run(my_test)
```

`testmu.run()` is a synchronous entry point — it sets up the session,
launches the browser, runs your test, and tears everything down.

## Configuration

Configuration is sourced from environment variables. See [`.env.example`](.env.example) for the full list. The most common ones:

| Variable          | Purpose                               | Required           |
| ----------------- | ------------------------------------- | ------------------ |
| `LT_USERNAME`     | LambdaTest grid username              | For cloud features |
| `LT_ACCESS_KEY`   | LambdaTest grid access key            | For cloud features |
| `TESTMU_HEADLESS` | `true` (default) or `false`           | No                 |
| `TESTMU_SMART`    | `1` to enable vision/heal AI features | No                 |

Test-level metadata (build, name, variables, etc.) can be passed via
`testmu.configure(...)` at the top of generated test files.

## Runtime modes (`kane_version`)

Generated tests pick a runtime mode with `testmu.configure(kane_version=...)`:
`"v4"` (the default) or `"v3"`. Every public name (`testmu.var`,
`testmu.execute_js`, `testmu.Condition`, …) follows the mode **at call time**, so
a name imported before `configure()` runs still does the right thing:

```python
import testmu
from testmu import var            # bound before configure()

testmu.configure(kane_version="v3")
var("{{price}}")                  # served by the v3 implementation
```

### Package layout (for contributors)

The two modes live in separate implementation packages behind a small shared
layer, so a change to one mode can't change the other:

| Path | What |
|---|---|
| `testmu/__init__.py` | public surface: shared names + per-mode forwarders |
| `testmu/_router.py` | picks the mode's package on each call; installs the heal patch on `Locator` once |
| `testmu/_configure.py`, `_config.py`, `_errors.py`, `_step.py`, `_heal_cache.py`, `_test_state.py` | shared: one of each whatever the mode |
| `testmu/_condition_enums.py`, `_devtools_types.py`, `_clipboard_store.py` | shared classes identical in both modes (`PossibleCondition`, `NetworkEntry`, `ClipboardStore`, …): `testmu.<name>` is the real class |
| `testmu/_aliases.py` | keeps old private paths working (below) |
| `testmu/_v4/` | the v4 implementation |
| `testmu/_v3/` | the v3 implementation |

`_v4/` and `_v3/` never import each other; each imports only itself and the
shared modules. Neither checks `kane_version`: the router already picked the
package, so each holds only its own mode's code paths. A change for one mode goes in that mode's folder only; a fix
both modes need is made in both. Tests follow the same split: `tests/v4/`,
`tests/v3/` (where v3 is the default mode) and `tests/shared/` (public
surface, routing, aliases).

**Old private paths still work.** Modules that used to live at
`testmu.<name>` (`testmu._vars`, `testmu._helpers.devtools_network`,
`testmu.playwright_async`, …) are aliases of the v4 modules: importing the old
path returns the *same* module object, so state and `mock.patch` / `setattr`
through it reach the real module. Old paths always mean v4. Prefer the public
`testmu.<name>` API, which follows the configured mode.

**Routed classes.** `testmu.Condition` and `testmu.ResolvedCondition` differ by
mode, so they are proxies: calling one builds the active mode's class, and
`isinstance` holds for either mode's instances. They can't be subclassed
(`TypeError`), and `typing.get_type_hints` on them is empty. Every other public
class is identical in both modes and is exported as the real class.

## Features

- **`@testmu.test`** — decorator that wraps async Playwright tests with session lifecycle management
- **`testmu.step(...)`** — context manager for structured test steps
- **`testmu.var()` / `testmu.set_var()`** — template-based variable resolution (with ATMS lookup when authed)
- **Helpers** — `execute_js`, `execute_api`, `execute_db`, `vision_query`, `network_query`, `smartui_snapshot_async`, and more
- **Reporters** — local console reporter and TestMu cloud reporter (LambdaTest dashboard)
- **Self-healing locators** — automatic locator recovery via heal patch (when smart mode enabled)

## Requirements

- Python ≥ 3.11
- Playwright ≥ 1.57.0

## Links

- **PyPI**: https://pypi.org/project/testmuai-playwright-bindings/
- **TestMu**: https://testmu.ai
- **LambdaTest grid**: https://www.lambdatest.com
- **Issues**: https://github.com/LambdaTest/testmuai-bindings/issues

## License

Released under the [MIT License](LICENSE).
