Skip to content

Commit b136bac

Browse files
authored
🔨 Enhance diagnostics info in e2e testing (#5962)
1 parent 81b6bd2 commit b136bac

File tree

2 files changed

+85
-9
lines changed

2 files changed

+85
-9
lines changed

tests/e2e-playwright/README.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1-
Auto generate new test
1+
### Auto generate new test
22
`playwright codegen sim4life.io`
33

4-
Run test locally with headed mode
5-
`pytest -s tests/sim4life.py --headed --browser chromium --product-billable --product-url https://sim4life.io/ --user-name YOUR_USERNAME --password YOUR_PASSWORD --service-key simcore/services/dynamic/sim4life-8-0-0-dy --service-test-id studyBrowserListItem_simcore/services/dynamic/sim4life-8-0-0-dy`
4+
### Run test locally with headed mode
5+
```
6+
pytest -s tests/sim4life.py --headed --browser chromium --product-billable --product-url https://sim4life.io/ --user-name YOUR_USERNAME --password YOUR_PASSWORD --service-key simcore/services/dynamic/sim4life-8-0-0-dy --service-test-id studyBrowserListItem_simcore/services/dynamic/sim4life-8-0-0-dy
7+
```
68

7-
Check test results output
9+
### Check test results output
810
`playwright show-trace test-results/tests-sim4life-py-test-billable-sim4life-chromium/trace.zip`
911

10-
Run debug mode
12+
### Run debug mode
1113
`PWDEBUG=1 pytest -s tests/sim4life.py`
1214

13-
Run test in different browsers
15+
### Run test in different browsers
1416
`pytest -s tests/sim4life.py --tracing on --html=report.html --browser chromium --browser firefox`
17+
18+
### Runs in CI
19+
- https://git.speag.com/oSparc/e2e-backend

tests/e2e-playwright/tests/conftest.py

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
# pylint: disable=no-name-in-module
12
# pylint: disable=redefined-outer-name
2-
# pylint: disable=unused-argument
3-
# pylint: disable=unused-variable
43
# pylint: disable=too-many-arguments
54
# pylint: disable=too-many-statements
6-
# pylint: disable=no-name-in-module
5+
# pylint: disable=unused-argument
6+
# pylint: disable=unused-variable
77

8+
import datetime
89
import json
910
import logging
1011
import os
@@ -14,11 +15,13 @@
1415
from contextlib import ExitStack
1516
from typing import Any, Final
1617

18+
import arrow
1719
import pytest
1820
from faker import Faker
1921
from playwright.sync_api import APIRequestContext, BrowserContext, Page, WebSocket
2022
from playwright.sync_api._generated import Playwright
2123
from pydantic import AnyUrl, TypeAdapter
24+
from pytest import Item
2225
from pytest_simcore.logging_utils import log_context
2326
from pytest_simcore.playwright_utils import (
2427
MINUTE,
@@ -100,6 +103,74 @@ def pytest_addoption(parser: pytest.Parser) -> None:
100103
)
101104

102105

106+
# Dictionary to store start times of tests
107+
_test_start_times = {}
108+
109+
110+
def pytest_runtest_setup(item):
111+
"""
112+
Hook to capture the start time of each test.
113+
"""
114+
_test_start_times[item.name] = arrow.now().datetime
115+
116+
117+
_FORMAT: Final = "%Y-%m-%dT%H:%M:%S.%fZ"
118+
119+
120+
def _construct_graylog_url(
121+
product_url: str | None, start_time: datetime.datetime, end_time: datetime.datetime
122+
) -> str:
123+
# Deduce monitoring url
124+
if product_url:
125+
scheme, tail = product_url.split("://", 1)
126+
else:
127+
scheme, tail = "https", "<UNDEFINED>"
128+
monitoring_url = f"{scheme}://monitoring.{tail}"
129+
130+
# build graylog URL
131+
query = f"from={start_time.strftime(_FORMAT)}&to={end_time.strftime(_FORMAT)}"
132+
return f"{monitoring_url}/graylog/search?{query}"
133+
134+
135+
def pytest_runtest_makereport(item: Item, call):
136+
"""
137+
Hook to add extra information when a test fails.
138+
"""
139+
140+
# Check if the test failed
141+
if call.when == "call" and call.excinfo is not None:
142+
test_name = item.name
143+
test_location = item.location
144+
product_url = item.config.getoption("--product-url", default=None)
145+
146+
diagnostics = {
147+
"test_name": test_name,
148+
"test_location": test_location,
149+
"product_url": product_url,
150+
}
151+
152+
# Get the start and end times of the test
153+
start_time = _test_start_times.get(test_name)
154+
end_time = arrow.now().datetime
155+
156+
if start_time:
157+
diagnostics["graylog_url"] = _construct_graylog_url(
158+
product_url, start_time, end_time
159+
)
160+
diagnostics["duration"] = str(end_time - start_time)
161+
162+
# Print the diagnostics report
163+
print(f"\nDiagnostics repoort for {test_name} ---")
164+
print(json.dumps(diagnostics, indent=2))
165+
print("---")
166+
167+
168+
@pytest.hookimpl(tryfirst=True)
169+
def pytest_configure(config):
170+
config.pluginmanager.register(pytest_runtest_setup, "osparc_test_times_plugin")
171+
config.pluginmanager.register(pytest_runtest_makereport, "osparc_makereport_plugin")
172+
173+
103174
@pytest.fixture(autouse=True)
104175
def osparc_test_id_attribute(playwright: Playwright) -> None:
105176
# Set a custom test id attribute

0 commit comments

Comments
 (0)