Metadata-Version: 2.4
Name: testrelic-playwright
Version: 0.1.0
Summary: Playwright/pytest test analytics reporter — navigation timeline, API call capture, network stats, failure diagnostics, and interactive HTML reports.
Project-URL: Homepage, https://testrelic.ai
Project-URL: Documentation, https://docs.testrelic.ai/playwright
Project-URL: Repository, https://github.com/testrelic-ai/testrelic-python-sdk
Project-URL: Bug Tracker, https://github.com/testrelic-ai/testrelic-python-sdk/issues
Author-email: TestRelic AI <hello@testrelic.ai>
License: MIT
License-File: LICENSE
Keywords: analytics,api-testing,api-tracking,assertions,ci,e2e-testing,html-report,navigation,network,playwright,pytest,redaction,reporter,test,test-automation,test-results,testing
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: Pytest
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.9
Requires-Dist: httpx<1.0,>=0.27
Requires-Dist: platformdirs>=4.0
Requires-Dist: playwright>=1.35
Requires-Dist: pydantic<3.0,>=2.6
Requires-Dist: pytest-playwright>=0.5.0
Requires-Dist: pytest>=7.0
Requires-Dist: tomli-w>=1.0
Requires-Dist: tomli>=2.0; python_version < '3.11'
Requires-Dist: typer<1.0,>=0.12
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Requires-Dist: twine>=5.1; extra == 'dev'
Description-Content-Type: text/markdown

# testrelic-playwright

A pytest + Playwright analytics reporter that generates structured JSON and HTML
reports from your Playwright test runs — capturing navigation timelines, API
call tracking, network statistics, failure diagnostics, and CI metadata. The
Python port of [`@testrelic/playwright-analytics`](https://www.npmjs.com/package/@testrelic/playwright-analytics).

## What it does

When you run your tests with the TestRelic pytest plugin you get a JSON + HTML
report that captures:

- **Navigation timeline** — every URL visited during each test in chronological
  order, with navigation type detection (`goto`, link click, back/forward, SPA
  route changes, hash changes).
- **API call tracking** — HTTP method, URL, status code, request/response
  headers and bodies, response times, and assertions for every API call.
- **Network statistics** — total requests, failed requests, bytes transferred,
  and resource-type breakdowns (scripts, images, stylesheets, fonts, XHR).
- **Test results** — pass/fail/flaky status, duration, retry count, and tags.
- **Failure diagnostics** — error messages, source-code snippets pointing to
  the exact failure line, and optional stack traces.
- **CI metadata** — auto-detection of GitHub Actions, GitLab CI, Jenkins, and
  CircleCI with build id, commit sha, and branch.
- **Sensitive-data redaction** — AWS keys, Bearer tokens, private keys,
  credential URLs, and sensitive API headers / body fields.
- **HTML report** — self-contained interactive HTML alongside the JSON.

## Quick start

### 1. Install

```bash
pip install pytest-playwright testrelic-playwright
playwright install
```

The reporter activates automatically because `testrelic-playwright` registers a
`pytest11` entry point. No `conftest.py` plumbing required.

### 2. Write a test

Use the standard `page` and `context` fixtures from `pytest-playwright`. The
TestRelic plugin auto-attaches listeners and records navigation / API calls.

```python
# tests/test_homepage.py
from playwright.sync_api import Page, expect


def test_homepage_loads(page: Page) -> None:
    page.goto("https://example.com")
    expect(page.locator("h1")).to_be_visible()
```

API tests work the same way using `pytest-playwright`'s built-in
`APIRequestContext` fixture:

```python
from playwright.sync_api import APIRequestContext


def test_fetch_posts(playwright) -> None:
    request = playwright.request.new_context()
    response = request.get("https://api.example.com/posts")
    assert response.status == 200
```

### 3. Run

```bash
pytest
```

Outputs land in:

```
test-results/
├── analytics-timeline.json
└── analytics-timeline.html
```

## Configuration

Reporter options can be supplied three ways (highest priority first):

1. **Environment variables** (`TESTRELIC_API_KEY`, `TESTRELIC_CLOUD_ENDPOINT`,
   `TESTRELIC_UPLOAD_STRATEGY`, `TESTRELIC_CLOUD_TIMEOUT`).
2. **`pytest.ini` / `pyproject.toml`** `testrelic_options` ini block.
3. **`.testrelic/testrelic-config.json`** in the project root.

### `pytest.ini`

```ini
[pytest]
testrelic_options =
    outputPath=./reports/run.json
    includeStackTrace=true
    captureRequestBody=true
    captureResponseBody=true
```

### `pyproject.toml`

```toml
[tool.pytest.ini_options]
testrelic_options = [
  "outputPath=./reports/run.json",
  "includeStackTrace=true",
]
```

### CLI flags

```bash
pytest --testrelic-output ./reports/custom.json
pytest --testrelic-disable    # turn the reporter off for this run
pytest --testrelic-quiet      # suppress banner output
```

### Full option list

| Option | Type | Default | Description |
|---|---|---|---|
| `outputPath` | str | `./test-results/analytics-timeline.json` | JSON report path |
| `htmlReportPath` | str | derived from `outputPath` | HTML report path |
| `includeStackTrace` | bool | `false` | Include full stack traces in failures |
| `includeCodeSnippets` | bool | `true` | Include source code around the failure line |
| `codeContextLines` | int | `3` | Lines of context above / below the failure line |
| `includeNetworkStats` | bool | `true` | Track network requests and bytes per navigation |
| `includeArtifacts` | bool | `true` | Include screenshots and videos |
| `includeActionSteps` | bool | `true` | Capture pytest test steps |
| `captureConsoleLogs` | bool | `true` | Capture browser console messages |
| `trackApiCalls` | bool | `true` | Enable / disable API call tracking |
| `captureRequestHeaders` | bool | `true` | Capture request headers |
| `captureResponseHeaders` | bool | `true` | Capture response headers |
| `captureRequestBody` | bool | `true` | Capture request bodies |
| `captureResponseBody` | bool | `true` | Capture response bodies |
| `redactHeaders` | list[str] | `[authorization, cookie, set-cookie, x-api-key]` | Header names to redact |
| `redactBodyFields` | list[str] | `[password, secret, token, apiKey, api_key]` | JSON body field names to scrub |
| `apiIncludeUrls` | list[str] | `[]` | Only track API calls matching these patterns |
| `apiExcludeUrls` | list[str] | `[]` | Exclude API calls matching these patterns |
| `quiet` | bool | `false` | Suppress banner output |

### Cloud integration

Set `TESTRELIC_API_KEY` and the reporter uploads the batch payload to
`https://platform.testrelic.ai/api/v1/test-runs` at session end.

```bash
export TESTRELIC_API_KEY=tk_live_...
export TESTRELIC_UPLOAD_STRATEGY=both   # realtime | batch | both
```

Or use a project file:

```json
// .testrelic/testrelic-config.json
{
  "cloud": {
    "apiKey": "$TESTRELIC_API_KEY",
    "endpoint": "https://platform.testrelic.ai/api/v1",
    "upload": "both"
  },
  "testrelic-repo": {
    "name": "my-project"
  }
}
```

Network failures are queued to `.testrelic/queue/` and can be retried with:

```bash
testrelic-playwright drain
```

## CLI

```bash
testrelic-playwright merge shard-1.json shard-2.json -o merged.json
testrelic-playwright serve ./test-results --port 9323
testrelic-playwright drain
testrelic-playwright version
```

## Manual navigation hook

For navigation the auto-tracker can't see (custom routing, iframes), use
`record_navigation`:

```python
from testrelic_playwright import record_navigation


def test_with_manual_nav(page, testrelic_state) -> None:
    page.goto("https://example.com")
    record_navigation(testrelic_state, "https://example.com/spa/profile", "spa_route")
```

## Compatibility

- Python 3.9 – 3.12
- pytest 7.0+
- pytest-playwright 0.5+
- Playwright 1.35+

## License

MIT
