testrelic-playwright 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- testrelic_playwright-0.1.0/.gitignore +11 -0
- testrelic_playwright-0.1.0/CHANGELOG.md +26 -0
- testrelic_playwright-0.1.0/LICENSE +21 -0
- testrelic_playwright-0.1.0/PKG-INFO +252 -0
- testrelic_playwright-0.1.0/README.md +209 -0
- testrelic_playwright-0.1.0/pyproject.toml +110 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/__init__.py +61 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/_version.py +1 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/api_request_tracker.py +140 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/ci_detector.py +82 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/cli.py +93 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/cloud/__init__.py +13 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/cloud/client.py +52 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/cloud/queue.py +83 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/code_extractor.py +29 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/config.py +200 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/html_report.py +127 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/merge.py +82 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/navigation_tracker.py +66 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/plugin.py +262 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/redaction.py +54 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/reporter.py +171 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/schema.py +14 -0
- testrelic_playwright-0.1.0/src/testrelic_playwright/types.py +130 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Build artifacts (also covered by repo-root .gitignore but kept here for clarity)
|
|
2
|
+
dist/
|
|
3
|
+
build/
|
|
4
|
+
*.egg-info/
|
|
5
|
+
|
|
6
|
+
# Reporter output produced by the package's own pytest runs
|
|
7
|
+
test-results/
|
|
8
|
+
|
|
9
|
+
# Local cloud queue
|
|
10
|
+
.testrelic/queue/
|
|
11
|
+
.testrelic/cache/
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `testrelic-playwright` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-05-21
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial Python port of `@testrelic/playwright-analytics`.
|
|
12
|
+
- `pytest` plugin that auto-loads via the `pytest11` entry point and wraps the
|
|
13
|
+
`pytest-playwright` `page` / `context` / `request` fixtures.
|
|
14
|
+
- Navigation timeline capture (`goto`, link click, back/forward, SPA route,
|
|
15
|
+
hash changes) via Playwright `framenavigated` events.
|
|
16
|
+
- API call tracking with method, URL, status, request/response headers and
|
|
17
|
+
bodies, response times, and assertion outcomes.
|
|
18
|
+
- Network statistics per navigation (total/failed requests, bytes, type
|
|
19
|
+
breakdown).
|
|
20
|
+
- CI metadata auto-detection (GitHub Actions, GitLab CI, Jenkins, CircleCI).
|
|
21
|
+
- Failure diagnostics with optional stack traces and source code snippets.
|
|
22
|
+
- Built-in redaction of AWS keys, Bearer tokens, private keys, credential URLs,
|
|
23
|
+
and sensitive headers / body fields.
|
|
24
|
+
- Self-contained HTML report alongside the JSON.
|
|
25
|
+
- Shard report merge via `testrelic-playwright merge`.
|
|
26
|
+
- Cloud upload scaffold matching the `cloud:` schema of the JS package.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 TestRelic AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: testrelic-playwright
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Playwright/pytest test analytics reporter — navigation timeline, API call capture, network stats, failure diagnostics, and interactive HTML reports.
|
|
5
|
+
Project-URL: Homepage, https://testrelic.ai
|
|
6
|
+
Project-URL: Documentation, https://docs.testrelic.ai/playwright
|
|
7
|
+
Project-URL: Repository, https://github.com/testrelic-ai/testrelic-python-sdk
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/testrelic-ai/testrelic-python-sdk/issues
|
|
9
|
+
Author-email: TestRelic AI <hello@testrelic.ai>
|
|
10
|
+
License: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: analytics,api-testing,api-tracking,assertions,ci,e2e-testing,html-report,navigation,network,playwright,pytest,redaction,reporter,test,test-automation,test-results,testing
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Framework :: Pytest
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
24
|
+
Classifier: Topic :: Software Development :: Testing
|
|
25
|
+
Requires-Python: >=3.9
|
|
26
|
+
Requires-Dist: httpx<1.0,>=0.27
|
|
27
|
+
Requires-Dist: platformdirs>=4.0
|
|
28
|
+
Requires-Dist: playwright>=1.35
|
|
29
|
+
Requires-Dist: pydantic<3.0,>=2.6
|
|
30
|
+
Requires-Dist: pytest-playwright>=0.5.0
|
|
31
|
+
Requires-Dist: pytest>=7.0
|
|
32
|
+
Requires-Dist: tomli-w>=1.0
|
|
33
|
+
Requires-Dist: tomli>=2.0; python_version < '3.11'
|
|
34
|
+
Requires-Dist: typer<1.0,>=0.12
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
37
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: respx>=0.21; extra == 'dev'
|
|
40
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
41
|
+
Requires-Dist: twine>=5.1; extra == 'dev'
|
|
42
|
+
Description-Content-Type: text/markdown
|
|
43
|
+
|
|
44
|
+
# testrelic-playwright
|
|
45
|
+
|
|
46
|
+
A pytest + Playwright analytics reporter that generates structured JSON and HTML
|
|
47
|
+
reports from your Playwright test runs — capturing navigation timelines, API
|
|
48
|
+
call tracking, network statistics, failure diagnostics, and CI metadata. The
|
|
49
|
+
Python port of [`@testrelic/playwright-analytics`](https://www.npmjs.com/package/@testrelic/playwright-analytics).
|
|
50
|
+
|
|
51
|
+
## What it does
|
|
52
|
+
|
|
53
|
+
When you run your tests with the TestRelic pytest plugin you get a JSON + HTML
|
|
54
|
+
report that captures:
|
|
55
|
+
|
|
56
|
+
- **Navigation timeline** — every URL visited during each test in chronological
|
|
57
|
+
order, with navigation type detection (`goto`, link click, back/forward, SPA
|
|
58
|
+
route changes, hash changes).
|
|
59
|
+
- **API call tracking** — HTTP method, URL, status code, request/response
|
|
60
|
+
headers and bodies, response times, and assertions for every API call.
|
|
61
|
+
- **Network statistics** — total requests, failed requests, bytes transferred,
|
|
62
|
+
and resource-type breakdowns (scripts, images, stylesheets, fonts, XHR).
|
|
63
|
+
- **Test results** — pass/fail/flaky status, duration, retry count, and tags.
|
|
64
|
+
- **Failure diagnostics** — error messages, source-code snippets pointing to
|
|
65
|
+
the exact failure line, and optional stack traces.
|
|
66
|
+
- **CI metadata** — auto-detection of GitHub Actions, GitLab CI, Jenkins, and
|
|
67
|
+
CircleCI with build id, commit sha, and branch.
|
|
68
|
+
- **Sensitive-data redaction** — AWS keys, Bearer tokens, private keys,
|
|
69
|
+
credential URLs, and sensitive API headers / body fields.
|
|
70
|
+
- **HTML report** — self-contained interactive HTML alongside the JSON.
|
|
71
|
+
|
|
72
|
+
## Quick start
|
|
73
|
+
|
|
74
|
+
### 1. Install
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install pytest-playwright testrelic-playwright
|
|
78
|
+
playwright install
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The reporter activates automatically because `testrelic-playwright` registers a
|
|
82
|
+
`pytest11` entry point. No `conftest.py` plumbing required.
|
|
83
|
+
|
|
84
|
+
### 2. Write a test
|
|
85
|
+
|
|
86
|
+
Use the standard `page` and `context` fixtures from `pytest-playwright`. The
|
|
87
|
+
TestRelic plugin auto-attaches listeners and records navigation / API calls.
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
# tests/test_homepage.py
|
|
91
|
+
from playwright.sync_api import Page, expect
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def test_homepage_loads(page: Page) -> None:
|
|
95
|
+
page.goto("https://example.com")
|
|
96
|
+
expect(page.locator("h1")).to_be_visible()
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
API tests work the same way using `pytest-playwright`'s built-in
|
|
100
|
+
`APIRequestContext` fixture:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
from playwright.sync_api import APIRequestContext
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def test_fetch_posts(playwright) -> None:
|
|
107
|
+
request = playwright.request.new_context()
|
|
108
|
+
response = request.get("https://api.example.com/posts")
|
|
109
|
+
assert response.status == 200
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 3. Run
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
pytest
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Outputs land in:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
test-results/
|
|
122
|
+
├── analytics-timeline.json
|
|
123
|
+
└── analytics-timeline.html
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Configuration
|
|
127
|
+
|
|
128
|
+
Reporter options can be supplied three ways (highest priority first):
|
|
129
|
+
|
|
130
|
+
1. **Environment variables** (`TESTRELIC_API_KEY`, `TESTRELIC_CLOUD_ENDPOINT`,
|
|
131
|
+
`TESTRELIC_UPLOAD_STRATEGY`, `TESTRELIC_CLOUD_TIMEOUT`).
|
|
132
|
+
2. **`pytest.ini` / `pyproject.toml`** `testrelic_options` ini block.
|
|
133
|
+
3. **`.testrelic/testrelic-config.json`** in the project root.
|
|
134
|
+
|
|
135
|
+
### `pytest.ini`
|
|
136
|
+
|
|
137
|
+
```ini
|
|
138
|
+
[pytest]
|
|
139
|
+
testrelic_options =
|
|
140
|
+
outputPath=./reports/run.json
|
|
141
|
+
includeStackTrace=true
|
|
142
|
+
captureRequestBody=true
|
|
143
|
+
captureResponseBody=true
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### `pyproject.toml`
|
|
147
|
+
|
|
148
|
+
```toml
|
|
149
|
+
[tool.pytest.ini_options]
|
|
150
|
+
testrelic_options = [
|
|
151
|
+
"outputPath=./reports/run.json",
|
|
152
|
+
"includeStackTrace=true",
|
|
153
|
+
]
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### CLI flags
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
pytest --testrelic-output ./reports/custom.json
|
|
160
|
+
pytest --testrelic-disable # turn the reporter off for this run
|
|
161
|
+
pytest --testrelic-quiet # suppress banner output
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Full option list
|
|
165
|
+
|
|
166
|
+
| Option | Type | Default | Description |
|
|
167
|
+
|---|---|---|---|
|
|
168
|
+
| `outputPath` | str | `./test-results/analytics-timeline.json` | JSON report path |
|
|
169
|
+
| `htmlReportPath` | str | derived from `outputPath` | HTML report path |
|
|
170
|
+
| `includeStackTrace` | bool | `false` | Include full stack traces in failures |
|
|
171
|
+
| `includeCodeSnippets` | bool | `true` | Include source code around the failure line |
|
|
172
|
+
| `codeContextLines` | int | `3` | Lines of context above / below the failure line |
|
|
173
|
+
| `includeNetworkStats` | bool | `true` | Track network requests and bytes per navigation |
|
|
174
|
+
| `includeArtifacts` | bool | `true` | Include screenshots and videos |
|
|
175
|
+
| `includeActionSteps` | bool | `true` | Capture pytest test steps |
|
|
176
|
+
| `captureConsoleLogs` | bool | `true` | Capture browser console messages |
|
|
177
|
+
| `trackApiCalls` | bool | `true` | Enable / disable API call tracking |
|
|
178
|
+
| `captureRequestHeaders` | bool | `true` | Capture request headers |
|
|
179
|
+
| `captureResponseHeaders` | bool | `true` | Capture response headers |
|
|
180
|
+
| `captureRequestBody` | bool | `true` | Capture request bodies |
|
|
181
|
+
| `captureResponseBody` | bool | `true` | Capture response bodies |
|
|
182
|
+
| `redactHeaders` | list[str] | `[authorization, cookie, set-cookie, x-api-key]` | Header names to redact |
|
|
183
|
+
| `redactBodyFields` | list[str] | `[password, secret, token, apiKey, api_key]` | JSON body field names to scrub |
|
|
184
|
+
| `apiIncludeUrls` | list[str] | `[]` | Only track API calls matching these patterns |
|
|
185
|
+
| `apiExcludeUrls` | list[str] | `[]` | Exclude API calls matching these patterns |
|
|
186
|
+
| `quiet` | bool | `false` | Suppress banner output |
|
|
187
|
+
|
|
188
|
+
### Cloud integration
|
|
189
|
+
|
|
190
|
+
Set `TESTRELIC_API_KEY` and the reporter uploads the batch payload to
|
|
191
|
+
`https://platform.testrelic.ai/api/v1/test-runs` at session end.
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
export TESTRELIC_API_KEY=tk_live_...
|
|
195
|
+
export TESTRELIC_UPLOAD_STRATEGY=both # realtime | batch | both
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Or use a project file:
|
|
199
|
+
|
|
200
|
+
```json
|
|
201
|
+
// .testrelic/testrelic-config.json
|
|
202
|
+
{
|
|
203
|
+
"cloud": {
|
|
204
|
+
"apiKey": "$TESTRELIC_API_KEY",
|
|
205
|
+
"endpoint": "https://platform.testrelic.ai/api/v1",
|
|
206
|
+
"upload": "both"
|
|
207
|
+
},
|
|
208
|
+
"testrelic-repo": {
|
|
209
|
+
"name": "my-project"
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Network failures are queued to `.testrelic/queue/` and can be retried with:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
testrelic-playwright drain
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## CLI
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
testrelic-playwright merge shard-1.json shard-2.json -o merged.json
|
|
224
|
+
testrelic-playwright serve ./test-results --port 9323
|
|
225
|
+
testrelic-playwright drain
|
|
226
|
+
testrelic-playwright version
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Manual navigation hook
|
|
230
|
+
|
|
231
|
+
For navigation the auto-tracker can't see (custom routing, iframes), use
|
|
232
|
+
`record_navigation`:
|
|
233
|
+
|
|
234
|
+
```python
|
|
235
|
+
from testrelic_playwright import record_navigation
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def test_with_manual_nav(page, testrelic_state) -> None:
|
|
239
|
+
page.goto("https://example.com")
|
|
240
|
+
record_navigation(testrelic_state, "https://example.com/spa/profile", "spa_route")
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Compatibility
|
|
244
|
+
|
|
245
|
+
- Python 3.9 – 3.12
|
|
246
|
+
- pytest 7.0+
|
|
247
|
+
- pytest-playwright 0.5+
|
|
248
|
+
- Playwright 1.35+
|
|
249
|
+
|
|
250
|
+
## License
|
|
251
|
+
|
|
252
|
+
MIT
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# testrelic-playwright
|
|
2
|
+
|
|
3
|
+
A pytest + Playwright analytics reporter that generates structured JSON and HTML
|
|
4
|
+
reports from your Playwright test runs — capturing navigation timelines, API
|
|
5
|
+
call tracking, network statistics, failure diagnostics, and CI metadata. The
|
|
6
|
+
Python port of [`@testrelic/playwright-analytics`](https://www.npmjs.com/package/@testrelic/playwright-analytics).
|
|
7
|
+
|
|
8
|
+
## What it does
|
|
9
|
+
|
|
10
|
+
When you run your tests with the TestRelic pytest plugin you get a JSON + HTML
|
|
11
|
+
report that captures:
|
|
12
|
+
|
|
13
|
+
- **Navigation timeline** — every URL visited during each test in chronological
|
|
14
|
+
order, with navigation type detection (`goto`, link click, back/forward, SPA
|
|
15
|
+
route changes, hash changes).
|
|
16
|
+
- **API call tracking** — HTTP method, URL, status code, request/response
|
|
17
|
+
headers and bodies, response times, and assertions for every API call.
|
|
18
|
+
- **Network statistics** — total requests, failed requests, bytes transferred,
|
|
19
|
+
and resource-type breakdowns (scripts, images, stylesheets, fonts, XHR).
|
|
20
|
+
- **Test results** — pass/fail/flaky status, duration, retry count, and tags.
|
|
21
|
+
- **Failure diagnostics** — error messages, source-code snippets pointing to
|
|
22
|
+
the exact failure line, and optional stack traces.
|
|
23
|
+
- **CI metadata** — auto-detection of GitHub Actions, GitLab CI, Jenkins, and
|
|
24
|
+
CircleCI with build id, commit sha, and branch.
|
|
25
|
+
- **Sensitive-data redaction** — AWS keys, Bearer tokens, private keys,
|
|
26
|
+
credential URLs, and sensitive API headers / body fields.
|
|
27
|
+
- **HTML report** — self-contained interactive HTML alongside the JSON.
|
|
28
|
+
|
|
29
|
+
## Quick start
|
|
30
|
+
|
|
31
|
+
### 1. Install
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install pytest-playwright testrelic-playwright
|
|
35
|
+
playwright install
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The reporter activates automatically because `testrelic-playwright` registers a
|
|
39
|
+
`pytest11` entry point. No `conftest.py` plumbing required.
|
|
40
|
+
|
|
41
|
+
### 2. Write a test
|
|
42
|
+
|
|
43
|
+
Use the standard `page` and `context` fixtures from `pytest-playwright`. The
|
|
44
|
+
TestRelic plugin auto-attaches listeners and records navigation / API calls.
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
# tests/test_homepage.py
|
|
48
|
+
from playwright.sync_api import Page, expect
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_homepage_loads(page: Page) -> None:
|
|
52
|
+
page.goto("https://example.com")
|
|
53
|
+
expect(page.locator("h1")).to_be_visible()
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
API tests work the same way using `pytest-playwright`'s built-in
|
|
57
|
+
`APIRequestContext` fixture:
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from playwright.sync_api import APIRequestContext
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_fetch_posts(playwright) -> None:
|
|
64
|
+
request = playwright.request.new_context()
|
|
65
|
+
response = request.get("https://api.example.com/posts")
|
|
66
|
+
assert response.status == 200
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 3. Run
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pytest
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Outputs land in:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
test-results/
|
|
79
|
+
├── analytics-timeline.json
|
|
80
|
+
└── analytics-timeline.html
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Configuration
|
|
84
|
+
|
|
85
|
+
Reporter options can be supplied three ways (highest priority first):
|
|
86
|
+
|
|
87
|
+
1. **Environment variables** (`TESTRELIC_API_KEY`, `TESTRELIC_CLOUD_ENDPOINT`,
|
|
88
|
+
`TESTRELIC_UPLOAD_STRATEGY`, `TESTRELIC_CLOUD_TIMEOUT`).
|
|
89
|
+
2. **`pytest.ini` / `pyproject.toml`** `testrelic_options` ini block.
|
|
90
|
+
3. **`.testrelic/testrelic-config.json`** in the project root.
|
|
91
|
+
|
|
92
|
+
### `pytest.ini`
|
|
93
|
+
|
|
94
|
+
```ini
|
|
95
|
+
[pytest]
|
|
96
|
+
testrelic_options =
|
|
97
|
+
outputPath=./reports/run.json
|
|
98
|
+
includeStackTrace=true
|
|
99
|
+
captureRequestBody=true
|
|
100
|
+
captureResponseBody=true
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### `pyproject.toml`
|
|
104
|
+
|
|
105
|
+
```toml
|
|
106
|
+
[tool.pytest.ini_options]
|
|
107
|
+
testrelic_options = [
|
|
108
|
+
"outputPath=./reports/run.json",
|
|
109
|
+
"includeStackTrace=true",
|
|
110
|
+
]
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### CLI flags
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
pytest --testrelic-output ./reports/custom.json
|
|
117
|
+
pytest --testrelic-disable # turn the reporter off for this run
|
|
118
|
+
pytest --testrelic-quiet # suppress banner output
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Full option list
|
|
122
|
+
|
|
123
|
+
| Option | Type | Default | Description |
|
|
124
|
+
|---|---|---|---|
|
|
125
|
+
| `outputPath` | str | `./test-results/analytics-timeline.json` | JSON report path |
|
|
126
|
+
| `htmlReportPath` | str | derived from `outputPath` | HTML report path |
|
|
127
|
+
| `includeStackTrace` | bool | `false` | Include full stack traces in failures |
|
|
128
|
+
| `includeCodeSnippets` | bool | `true` | Include source code around the failure line |
|
|
129
|
+
| `codeContextLines` | int | `3` | Lines of context above / below the failure line |
|
|
130
|
+
| `includeNetworkStats` | bool | `true` | Track network requests and bytes per navigation |
|
|
131
|
+
| `includeArtifacts` | bool | `true` | Include screenshots and videos |
|
|
132
|
+
| `includeActionSteps` | bool | `true` | Capture pytest test steps |
|
|
133
|
+
| `captureConsoleLogs` | bool | `true` | Capture browser console messages |
|
|
134
|
+
| `trackApiCalls` | bool | `true` | Enable / disable API call tracking |
|
|
135
|
+
| `captureRequestHeaders` | bool | `true` | Capture request headers |
|
|
136
|
+
| `captureResponseHeaders` | bool | `true` | Capture response headers |
|
|
137
|
+
| `captureRequestBody` | bool | `true` | Capture request bodies |
|
|
138
|
+
| `captureResponseBody` | bool | `true` | Capture response bodies |
|
|
139
|
+
| `redactHeaders` | list[str] | `[authorization, cookie, set-cookie, x-api-key]` | Header names to redact |
|
|
140
|
+
| `redactBodyFields` | list[str] | `[password, secret, token, apiKey, api_key]` | JSON body field names to scrub |
|
|
141
|
+
| `apiIncludeUrls` | list[str] | `[]` | Only track API calls matching these patterns |
|
|
142
|
+
| `apiExcludeUrls` | list[str] | `[]` | Exclude API calls matching these patterns |
|
|
143
|
+
| `quiet` | bool | `false` | Suppress banner output |
|
|
144
|
+
|
|
145
|
+
### Cloud integration
|
|
146
|
+
|
|
147
|
+
Set `TESTRELIC_API_KEY` and the reporter uploads the batch payload to
|
|
148
|
+
`https://platform.testrelic.ai/api/v1/test-runs` at session end.
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
export TESTRELIC_API_KEY=tk_live_...
|
|
152
|
+
export TESTRELIC_UPLOAD_STRATEGY=both # realtime | batch | both
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Or use a project file:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
// .testrelic/testrelic-config.json
|
|
159
|
+
{
|
|
160
|
+
"cloud": {
|
|
161
|
+
"apiKey": "$TESTRELIC_API_KEY",
|
|
162
|
+
"endpoint": "https://platform.testrelic.ai/api/v1",
|
|
163
|
+
"upload": "both"
|
|
164
|
+
},
|
|
165
|
+
"testrelic-repo": {
|
|
166
|
+
"name": "my-project"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Network failures are queued to `.testrelic/queue/` and can be retried with:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
testrelic-playwright drain
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## CLI
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
testrelic-playwright merge shard-1.json shard-2.json -o merged.json
|
|
181
|
+
testrelic-playwright serve ./test-results --port 9323
|
|
182
|
+
testrelic-playwright drain
|
|
183
|
+
testrelic-playwright version
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Manual navigation hook
|
|
187
|
+
|
|
188
|
+
For navigation the auto-tracker can't see (custom routing, iframes), use
|
|
189
|
+
`record_navigation`:
|
|
190
|
+
|
|
191
|
+
```python
|
|
192
|
+
from testrelic_playwright import record_navigation
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def test_with_manual_nav(page, testrelic_state) -> None:
|
|
196
|
+
page.goto("https://example.com")
|
|
197
|
+
record_navigation(testrelic_state, "https://example.com/spa/profile", "spa_route")
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Compatibility
|
|
201
|
+
|
|
202
|
+
- Python 3.9 – 3.12
|
|
203
|
+
- pytest 7.0+
|
|
204
|
+
- pytest-playwright 0.5+
|
|
205
|
+
- Playwright 1.35+
|
|
206
|
+
|
|
207
|
+
## License
|
|
208
|
+
|
|
209
|
+
MIT
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.21"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "testrelic-playwright"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Playwright/pytest test analytics reporter — navigation timeline, API call capture, network stats, failure diagnostics, and interactive HTML reports."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
requires-python = ">=3.9"
|
|
13
|
+
authors = [{ name = "TestRelic AI", email = "hello@testrelic.ai" }]
|
|
14
|
+
keywords = [
|
|
15
|
+
"playwright",
|
|
16
|
+
"pytest",
|
|
17
|
+
"test",
|
|
18
|
+
"analytics",
|
|
19
|
+
"reporter",
|
|
20
|
+
"api-testing",
|
|
21
|
+
"e2e-testing",
|
|
22
|
+
"navigation",
|
|
23
|
+
"network",
|
|
24
|
+
"html-report",
|
|
25
|
+
"test-results",
|
|
26
|
+
"api-tracking",
|
|
27
|
+
"assertions",
|
|
28
|
+
"redaction",
|
|
29
|
+
"ci",
|
|
30
|
+
"testing",
|
|
31
|
+
"test-automation",
|
|
32
|
+
]
|
|
33
|
+
classifiers = [
|
|
34
|
+
"Development Status :: 4 - Beta",
|
|
35
|
+
"Framework :: Pytest",
|
|
36
|
+
"Intended Audience :: Developers",
|
|
37
|
+
"License :: OSI Approved :: MIT License",
|
|
38
|
+
"Operating System :: OS Independent",
|
|
39
|
+
"Programming Language :: Python :: 3",
|
|
40
|
+
"Programming Language :: Python :: 3.9",
|
|
41
|
+
"Programming Language :: Python :: 3.10",
|
|
42
|
+
"Programming Language :: Python :: 3.11",
|
|
43
|
+
"Programming Language :: Python :: 3.12",
|
|
44
|
+
"Topic :: Software Development :: Testing",
|
|
45
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
46
|
+
]
|
|
47
|
+
dependencies = [
|
|
48
|
+
"pytest>=7.0",
|
|
49
|
+
"pytest-playwright>=0.5.0",
|
|
50
|
+
"playwright>=1.35",
|
|
51
|
+
"httpx>=0.27,<1.0",
|
|
52
|
+
"pydantic>=2.6,<3.0",
|
|
53
|
+
"typer>=0.12,<1.0",
|
|
54
|
+
"platformdirs>=4.0",
|
|
55
|
+
"tomli>=2.0; python_version<'3.11'",
|
|
56
|
+
"tomli-w>=1.0",
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
[project.optional-dependencies]
|
|
60
|
+
dev = [
|
|
61
|
+
"pytest-cov>=5.0",
|
|
62
|
+
"respx>=0.21",
|
|
63
|
+
"ruff>=0.6",
|
|
64
|
+
"mypy>=1.10",
|
|
65
|
+
"build>=1.2",
|
|
66
|
+
"twine>=5.1",
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
[project.urls]
|
|
70
|
+
Homepage = "https://testrelic.ai"
|
|
71
|
+
Documentation = "https://docs.testrelic.ai/playwright"
|
|
72
|
+
Repository = "https://github.com/testrelic-ai/testrelic-python-sdk"
|
|
73
|
+
"Bug Tracker" = "https://github.com/testrelic-ai/testrelic-python-sdk/issues"
|
|
74
|
+
|
|
75
|
+
[project.scripts]
|
|
76
|
+
testrelic-playwright = "testrelic_playwright.cli:app"
|
|
77
|
+
|
|
78
|
+
[project.entry-points.pytest11]
|
|
79
|
+
testrelic_playwright = "testrelic_playwright.plugin"
|
|
80
|
+
|
|
81
|
+
[tool.hatch.version]
|
|
82
|
+
path = "src/testrelic_playwright/_version.py"
|
|
83
|
+
|
|
84
|
+
[tool.hatch.build.targets.wheel]
|
|
85
|
+
packages = ["src/testrelic_playwright"]
|
|
86
|
+
|
|
87
|
+
[tool.hatch.build.targets.sdist]
|
|
88
|
+
include = [
|
|
89
|
+
"src/testrelic_playwright",
|
|
90
|
+
"README.md",
|
|
91
|
+
"LICENSE",
|
|
92
|
+
"CHANGELOG.md",
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
[tool.ruff]
|
|
96
|
+
line-length = 100
|
|
97
|
+
target-version = "py39"
|
|
98
|
+
|
|
99
|
+
[tool.ruff.lint]
|
|
100
|
+
select = ["E", "F", "I", "B", "UP", "RUF"]
|
|
101
|
+
ignore = ["E501"]
|
|
102
|
+
|
|
103
|
+
[tool.mypy]
|
|
104
|
+
python_version = "3.9"
|
|
105
|
+
strict = true
|
|
106
|
+
ignore_missing_imports = true
|
|
107
|
+
|
|
108
|
+
[tool.pytest.ini_options]
|
|
109
|
+
testpaths = ["tests"]
|
|
110
|
+
addopts = "-v --tb=short"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""TestRelic Playwright analytics — pytest plugin and helpers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from testrelic_playwright._version import __version__
|
|
6
|
+
from testrelic_playwright.config import (
|
|
7
|
+
DEFAULT_REDACT_BODY_FIELDS,
|
|
8
|
+
DEFAULT_REDACT_HEADERS,
|
|
9
|
+
DEFAULT_REDACTION_PATTERNS,
|
|
10
|
+
ReporterConfig,
|
|
11
|
+
resolve_config,
|
|
12
|
+
)
|
|
13
|
+
from testrelic_playwright.merge import merge_reports
|
|
14
|
+
from testrelic_playwright.reporter import record_navigation
|
|
15
|
+
from testrelic_playwright.schema import (
|
|
16
|
+
ATTACHMENT_CONTENT_TYPE,
|
|
17
|
+
ATTACHMENT_NAME,
|
|
18
|
+
PAYLOAD_VERSION,
|
|
19
|
+
SCHEMA_VERSION,
|
|
20
|
+
)
|
|
21
|
+
from testrelic_playwright.types import (
|
|
22
|
+
ApiAssertion,
|
|
23
|
+
ApiCallRecord,
|
|
24
|
+
AssertionLocation,
|
|
25
|
+
AssertionType,
|
|
26
|
+
CIMetadata,
|
|
27
|
+
FailureDiagnostic,
|
|
28
|
+
NavigationType,
|
|
29
|
+
NetworkStats,
|
|
30
|
+
Summary,
|
|
31
|
+
TestResult,
|
|
32
|
+
TestRunReport,
|
|
33
|
+
TimelineEntry,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
__all__ = [
|
|
37
|
+
"ATTACHMENT_CONTENT_TYPE",
|
|
38
|
+
"ATTACHMENT_NAME",
|
|
39
|
+
"ApiAssertion",
|
|
40
|
+
"ApiCallRecord",
|
|
41
|
+
"AssertionLocation",
|
|
42
|
+
"AssertionType",
|
|
43
|
+
"CIMetadata",
|
|
44
|
+
"DEFAULT_REDACTION_PATTERNS",
|
|
45
|
+
"DEFAULT_REDACT_BODY_FIELDS",
|
|
46
|
+
"DEFAULT_REDACT_HEADERS",
|
|
47
|
+
"FailureDiagnostic",
|
|
48
|
+
"NavigationType",
|
|
49
|
+
"NetworkStats",
|
|
50
|
+
"PAYLOAD_VERSION",
|
|
51
|
+
"ReporterConfig",
|
|
52
|
+
"SCHEMA_VERSION",
|
|
53
|
+
"Summary",
|
|
54
|
+
"TestResult",
|
|
55
|
+
"TestRunReport",
|
|
56
|
+
"TimelineEntry",
|
|
57
|
+
"__version__",
|
|
58
|
+
"merge_reports",
|
|
59
|
+
"record_navigation",
|
|
60
|
+
"resolve_config",
|
|
61
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|