Skip to content

Commit bc71bdf

Browse files
committed
chore: init
1 parent 7d8a54f commit bc71bdf

File tree

8 files changed

+489
-2
lines changed

8 files changed

+489
-2
lines changed

.github/workflows/test.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Playwright Pytest Tests
2+
on:
3+
push:
4+
branches: [ main, master ]
5+
pull_request:
6+
branches: [ main, master ]
7+
jobs:
8+
test:
9+
timeout-minutes: 60
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
- name: Set up Python
14+
uses: actions/setup-python@v4
15+
with:
16+
python-version: '3.11'
17+
- name: Install uv
18+
uses: astral-sh/setup-uv@v5
19+
- name: Install dependencies
20+
run: |
21+
uv sync pyproject.toml
22+
- name: Ensure browsers are installed
23+
run: python -m playwright install --with-deps
24+
- name: Run your tests
25+
run: pytest --tracing=retain-on-failure --output=reports --screenshot=only-on-failure --junitxml=reports/junit.xml
26+
- run: npx testbeats@latest publish --slack ${{ secrets.SLACK_MVP_URL }} --junit reports/junit.xml --ci-info --chart-test-summary
27+
if: always()
28+
env:
29+
TEST_BEATS_API_KEY: ${{ secrets.TEST_BEATS_API_KEY }}
30+
TEST_BEATS_PROJECT: "testbeats/examples"

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Python-generated files
2+
__pycache__/
3+
*.py[oc]
4+
build/
5+
dist/
6+
wheels/
7+
*.egg-info
8+
9+
# Virtual environments
10+
.venv
11+
.DS_Store

README.md

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,73 @@
1-
# example-playwright-pytest-testbeats
2-
About example repo to showcase integration of playwright and pytest with testbeats
1+
# Example Playwright Pytest Project with TestBeats Integration
2+
3+
This is an example project demonstrating how to run Playwright tests with Pytest and report results, presumably to TestBeats.
4+
5+
## Setup
6+
7+
1. **Clone the repository:**
8+
```bash
9+
git clone <repository-url>
10+
cd <repository-directory>
11+
```
12+
13+
2. **Create a virtual environment (recommended):**
14+
```bash
15+
python -m venv .venv
16+
source .venv/bin/activate
17+
```
18+
19+
3. **Install dependencies:**
20+
This project uses `uv` for dependency management.
21+
```bash
22+
uv sync pyproject.toml
23+
```
24+
25+
4. **Install Playwright browsers:**
26+
```bash
27+
playwright install
28+
```
29+
30+
## Running Tests
31+
32+
To run the tests, use Pytest:
33+
34+
```bash
35+
pytest --output=reports --screenshot=only-on-failure --junitxml=reports/junit.xml
36+
```
37+
38+
This will execute the tests found in files like `test_example.py`.
39+
40+
## Reporting Results to TestBeats
41+
42+
This project is configured to generate a JUnit XML report, which is a common format for test reporting tools like TestBeats.
43+
44+
1. **Generate JUnit XML report:**
45+
Pytest can generate a JUnit XML report using the `--junitxml` flag.
46+
```bash
47+
pytest --junitxml=reports/junit.xml
48+
```
49+
50+
Make sure the `reports` directory exists, or create it:
51+
```bash
52+
mkdir -p reports
53+
```
54+
55+
2. **Upload to TestBeats:**
56+
The method for uploading `reports/junit.xml` to TestBeats depends on your specific TestBeats setup. This typically involves:
57+
* Using a TestBeats CLI tool.
58+
* A CI/CD integration that automatically picks up the report.
59+
60+
Please refer to the TestBeats documentation for the specific command or procedure to upload the JUnit XML file.
61+
62+
**Example (conceptual - replace with actual TestBeats command):**
63+
```bash
64+
npx testbeats@latest publish --slack <slack-webhook-url> --junit reports/junit.xml
65+
```
66+
67+
## Contributing
68+
69+
Please feel free to submit issues and pull requests.
70+
71+
## License
72+
73+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details, which mentions TestBeats.

pyproject.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[project]
2+
name = "example-playwright-pytest-testbeats"
3+
version = "0.1.0"
4+
description = "Example Playwright Pytest TestBeats"
5+
readme = "README.md"
6+
requires-python = ">=3.11"
7+
dependencies = [
8+
"playwright>=1.52.0",
9+
"pytest-playwright>=0.7.0",
10+
]

reports/junit.xml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<testsuites>
3+
<testsuite name="pytest" errors="0" failures="1" skipped="0" tests="3" time="33.708" timestamp="2025-05-14T17:30:52.184166+05:30" hostname="user.local">
4+
<testcase classname="test_example" name="test_has_title[chromium]" time="2.138" />
5+
<testcase classname="test_example" name="test_get_started_link[chromium]" time="0.807" />
6+
<testcase classname="test_example" name="test_unknown_link[chromium]" time="30.650">
7+
<failure message="playwright._impl._errors.TimeoutError: Locator.click: Timeout 30000ms exceeded.&#10;Call log:&#10; - waiting for get_by_role(&quot;link&quot;, name=&quot;Unknow Link&quot;)">page = &lt;Page url='https://playwright.dev/'&gt;
8+
9+
def test_unknown_link(page: Page):
10+
page.goto("https://playwright.dev/")
11+
12+
# Click the get started link.
13+
&gt; page.get_by_role("link", name="Unknow Link").click()
14+
15+
test_example.py:23:
16+
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
17+
.venv/lib/python3.11/site-packages/playwright/sync_api/_generated.py:15512: in click
18+
self._sync(
19+
.venv/lib/python3.11/site-packages/playwright/_impl/_locator.py:160: in click
20+
return await self._frame.click(self._selector, strict=True, **params)
21+
.venv/lib/python3.11/site-packages/playwright/_impl/_frame.py:488: in click
22+
await self._channel.send("click", locals_to_params(locals()))
23+
.venv/lib/python3.11/site-packages/playwright/_impl/_connection.py:61: in send
24+
return await self._connection.wrap_api_call(
25+
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
26+
27+
self = &lt;playwright._impl._connection.Connection object at 0x104b45390&gt;
28+
cb = &lt;function Channel.send.&lt;locals&gt;.&lt;lambda&gt; at 0x106a60b80&gt;, is_internal = False
29+
30+
async def wrap_api_call(
31+
self, cb: Callable[[], Any], is_internal: bool = False
32+
) -&gt; Any:
33+
if self._api_zone.get():
34+
return await cb()
35+
task = asyncio.current_task(self._loop)
36+
st: List[inspect.FrameInfo] = getattr(task, "__pw_stack__", inspect.stack())
37+
parsed_st = _extract_stack_trace_information_from_stack(st, is_internal)
38+
self._api_zone.set(parsed_st)
39+
try:
40+
return await cb()
41+
except Exception as error:
42+
&gt; raise rewrite_error(error, f"{parsed_st['apiName']}: {error}") from None
43+
E playwright._impl._errors.TimeoutError: Locator.click: Timeout 30000ms exceeded.
44+
E Call log:
45+
E - waiting for get_by_role("link", name="Unknow Link")
46+
47+
.venv/lib/python3.11/site-packages/playwright/_impl/_connection.py:528: TimeoutError
48+
</failure>
49+
</testcase>
50+
</testsuite>
51+
</testsuites>
Loading

test_example.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import re
2+
from playwright.sync_api import Page, expect
3+
4+
def test_has_title(page: Page):
5+
page.goto("https://playwright.dev/")
6+
7+
# Expect a title "to contain" a substring.
8+
expect(page).to_have_title(re.compile("Playwright"))
9+
10+
def test_get_started_link(page: Page):
11+
page.goto("https://playwright.dev/")
12+
13+
# Click the get started link.
14+
page.get_by_role("link", name="Get started").click()
15+
16+
# Expects page to have a heading with the name of Installation.
17+
expect(page.get_by_role("heading", name="Installation")).to_be_visible()
18+
19+
def test_unknown_link(page: Page):
20+
page.goto("https://playwright.dev/")
21+
22+
# Click the get started link.
23+
page.get_by_role("link", name="Unknow Link").click()

0 commit comments

Comments
 (0)