qapytest 0.3.1__tar.gz → 0.3.2__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.
- {qapytest-0.3.1 → qapytest-0.3.2}/CHANGELOG.md +13 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/PKG-INFO +5 -1
- {qapytest-0.3.1 → qapytest-0.3.2}/README.md +4 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/docs/CLI.md +17 -1
- {qapytest-0.3.1 → qapytest-0.3.2}/pyproject.toml +1 -1
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/_plugin.py +60 -0
- qapytest-0.3.2/tests/encoding.py +55 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/uv.lock +1 -1
- {qapytest-0.3.1 → qapytest-0.3.2}/.gitignore +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/.pre-commit-config.yaml +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/LICENSE +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/NOTICE +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/THIRD_PARTY_NOTICES.txt +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/demo.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/docs/API.md +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/licenses/faker.LICENSE +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/licenses/httpx.LICENSE +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/licenses/jinja2.LICENSE +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/licenses/jsonschema.LICENSE +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/licenses/playwright-python.LICENSE +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/licenses/pytest-playwright.LICENSE +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/licenses/pytest.LICENSE +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/licenses/python_dotenv.LICENSE +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/licenses/redis-py.LICENSE +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/licenses/sqlalchemy.LICENSE +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/__init__.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/_assets/_log_tree.html.jinja2 +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/_assets/report.html.jinja2 +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/_assets/scripts.js +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/_assets/styles.css +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/_attach.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/_client_http.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/_config.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/_config_http.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/_internal.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/_json_validation.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/_redis.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/_report.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/_soft_assert.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/_sql.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/_step.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/qapytest/py.typed +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/tests/test_attach.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/tests/test_graphql_client.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/tests/test_http_client.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/tests/test_integration.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/tests/test_internal_functions.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/tests/test_markers.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/tests/test_redis_client.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/tests/test_soft_assert.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/tests/test_sql_client.py +0 -0
- {qapytest-0.3.1 → qapytest-0.3.2}/tests/test_step.py +0 -0
|
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.3.2] - 2025-10-29
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- 🌍 **Terminal Unicode support** - proper display of Unicode characters (Cyrillic, Arabic, Chinese, etc.) in terminal output for parametrized test names
|
|
13
|
+
- ⚙️ **`--disable-unicode-terminal`** CLI option - compatibility flag for older terminals and CI systems
|
|
14
|
+
|
|
15
|
+
### Enhanced
|
|
16
|
+
|
|
17
|
+
- 📝 **Terminal output** - Unicode escape sequences in test names are now automatically decoded for better readability
|
|
18
|
+
- 🛠️ **Compatibility** - added fallback option for environments that don't support Unicode display
|
|
19
|
+
|
|
8
20
|
## [0.3.1] - 2025-10-28
|
|
9
21
|
|
|
10
22
|
### Fixed
|
|
@@ -137,6 +149,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
137
149
|
- Configurable attachment size limits
|
|
138
150
|
- Professional report styling with responsive design
|
|
139
151
|
|
|
152
|
+
[0.3.2]: https://github.com/o73k51i/qapytest/releases/tag/v0.3.2
|
|
140
153
|
[0.3.1]: https://github.com/o73k51i/qapytest/releases/tag/v0.3.1
|
|
141
154
|
[0.3.0]: https://github.com/o73k51i/qapytest/releases/tag/v0.3.0
|
|
142
155
|
[0.3.0]: https://github.com/o73k51i/qapytest/releases/tag/v0.3.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qapytest
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: A powerful testing framework based on pytest, specifically designed for QA engineers
|
|
5
5
|
Project-URL: Homepage, https://github.com/o73k51i/qapytest
|
|
6
6
|
Project-URL: Repository, https://github.com/o73k51i/qapytest
|
|
@@ -97,6 +97,8 @@ debugging needs.
|
|
|
97
97
|
data.
|
|
98
98
|
- **JSON Schema validation:** function to validate API responses or test
|
|
99
99
|
artifacts with support for soft-assert and strict mode.
|
|
100
|
+
- **Unicode support:** proper display of Unicode characters (Cyrillic, Arabic,
|
|
101
|
+
Chinese, etc.) in terminal and HTML reports.
|
|
100
102
|
|
|
101
103
|
## 👥 Ideal for
|
|
102
104
|
|
|
@@ -279,6 +281,8 @@ def test_user_login():
|
|
|
279
281
|
- **`--report-title NAME`** : set the HTML report title.
|
|
280
282
|
- **`--report-theme {light,dark,auto}`** : choose the report theme: `light`,
|
|
281
283
|
`dark` or `auto` (default).
|
|
284
|
+
- **`--disable-unicode-terminal`** : disable Unicode character display in
|
|
285
|
+
terminal for compatibility with older systems.
|
|
282
286
|
|
|
283
287
|
More about CLI options on the [documentation page](https://github.com/o73k51i/qapytest/blob/main/docs/CLI.md).
|
|
284
288
|
|
|
@@ -41,6 +41,8 @@ debugging needs.
|
|
|
41
41
|
data.
|
|
42
42
|
- **JSON Schema validation:** function to validate API responses or test
|
|
43
43
|
artifacts with support for soft-assert and strict mode.
|
|
44
|
+
- **Unicode support:** proper display of Unicode characters (Cyrillic, Arabic,
|
|
45
|
+
Chinese, etc.) in terminal and HTML reports.
|
|
44
46
|
|
|
45
47
|
## 👥 Ideal for
|
|
46
48
|
|
|
@@ -223,6 +225,8 @@ def test_user_login():
|
|
|
223
225
|
- **`--report-title NAME`** : set the HTML report title.
|
|
224
226
|
- **`--report-theme {light,dark,auto}`** : choose the report theme: `light`,
|
|
225
227
|
`dark` or `auto` (default).
|
|
228
|
+
- **`--disable-unicode-terminal`** : disable Unicode character display in
|
|
229
|
+
terminal for compatibility with older systems.
|
|
226
230
|
|
|
227
231
|
More about CLI options on the [documentation page](https://github.com/o73k51i/qapytest/blob/main/docs/CLI.md).
|
|
228
232
|
|
|
@@ -23,9 +23,10 @@ Below are the available options, their purpose, and usage examples.
|
|
|
23
23
|
`dark`, or `auto` (default).
|
|
24
24
|
- **`--max-attachment-bytes N`** : maximum attachment size (in bytes) to embed
|
|
25
25
|
in the HTML; larger files will be truncated (default is unlimited).
|
|
26
|
+
- **`--disable-unicode-terminal`** : disable Unicode character display in
|
|
27
|
+
terminal output for compatibility with older terminals or CI systems.
|
|
26
28
|
|
|
27
29
|
### Behavior with `.env`
|
|
28
|
-
### Behavior with `.env`
|
|
29
30
|
|
|
30
31
|
- If the `--env-file` option is not provided, the plugin will try to load
|
|
31
32
|
`.env` in the working directory.
|
|
@@ -47,6 +48,21 @@ pytest --env-file=tests/.env
|
|
|
47
48
|
pytest --env-file=.env --env-override
|
|
48
49
|
```
|
|
49
50
|
|
|
51
|
+
#### Unicode display in terminal
|
|
52
|
+
|
|
53
|
+
By default, QaPyTest displays Unicode characters (Cyrillic, Arabic, Chinese, etc.)
|
|
54
|
+
correctly in terminal output for test names with parametrized IDs. If you
|
|
55
|
+
experience issues with Unicode display in older terminals or CI systems,
|
|
56
|
+
you can disable this feature:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Disable Unicode character display in terminal
|
|
60
|
+
pytest --disable-unicode-terminal --report-html
|
|
61
|
+
|
|
62
|
+
# Normal run with Unicode support (default)
|
|
63
|
+
pytest --report-html
|
|
64
|
+
```
|
|
65
|
+
|
|
50
66
|
### Playwright Options (when using browser automation)
|
|
51
67
|
|
|
52
68
|
For browser automation testing, install Playwright browsers:
|
|
@@ -19,6 +19,56 @@ from qapytest import _internal as utils
|
|
|
19
19
|
from qapytest import _report as report
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
class UnicodeTerminalPlugin:
|
|
23
|
+
"""Plugin to display Unicode characters properly in terminal output."""
|
|
24
|
+
|
|
25
|
+
def __init__(self) -> None:
|
|
26
|
+
self._original_write = None
|
|
27
|
+
self._patched = False
|
|
28
|
+
|
|
29
|
+
@pytest.hookimpl(tryfirst=True)
|
|
30
|
+
def pytest_sessionstart(self, session: pytest.Session) -> None:
|
|
31
|
+
"""Patch terminal reporter at session start."""
|
|
32
|
+
if self._patched:
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
config = session.config
|
|
36
|
+
terminal_reporter = config.pluginmanager.get_plugin("terminalreporter")
|
|
37
|
+
|
|
38
|
+
if terminal_reporter and hasattr(terminal_reporter, "_tw") and hasattr(terminal_reporter._tw, "write"): # noqa: SLF001
|
|
39
|
+
try:
|
|
40
|
+
self._original_write = terminal_reporter._tw.write # noqa: SLF001
|
|
41
|
+
|
|
42
|
+
def unicode_write(s: str, **kwargs: cfg.AnyType) -> None:
|
|
43
|
+
"""Write method that decodes Unicode escapes."""
|
|
44
|
+
if "\\u" in s and ("::" in s or "PASSED" in s or "FAILED" in s):
|
|
45
|
+
decoded_s = utils.decode_unicode_escapes(s)
|
|
46
|
+
self._original_write(decoded_s, **kwargs) # type: ignore[misc]
|
|
47
|
+
else:
|
|
48
|
+
self._original_write(s, **kwargs) # type: ignore[misc]
|
|
49
|
+
|
|
50
|
+
terminal_reporter._tw.write = unicode_write # noqa: SLF001
|
|
51
|
+
self._patched = True
|
|
52
|
+
except Exception: # noqa: S110
|
|
53
|
+
pass
|
|
54
|
+
|
|
55
|
+
@pytest.hookimpl
|
|
56
|
+
def pytest_sessionfinish(self, session: pytest.Session, exitstatus: int) -> None: # noqa: ARG002
|
|
57
|
+
"""Restore original write method at session finish."""
|
|
58
|
+
if not self._patched:
|
|
59
|
+
return
|
|
60
|
+
|
|
61
|
+
config = session.config
|
|
62
|
+
terminal_reporter = config.pluginmanager.get_plugin("terminalreporter")
|
|
63
|
+
|
|
64
|
+
if terminal_reporter and self._original_write:
|
|
65
|
+
try:
|
|
66
|
+
terminal_reporter._tw.write = self._original_write # noqa: SLF001
|
|
67
|
+
self._patched = False
|
|
68
|
+
except Exception: # noqa: S110
|
|
69
|
+
pass
|
|
70
|
+
|
|
71
|
+
|
|
22
72
|
def pytest_addoption(parser: pytest.Parser) -> None:
|
|
23
73
|
group = parser.getgroup("QAPyTest", "QAPyTest custom options")
|
|
24
74
|
group.addoption(
|
|
@@ -67,6 +117,12 @@ def pytest_addoption(parser: pytest.Parser) -> None:
|
|
|
67
117
|
default=None,
|
|
68
118
|
help="Max bytes to embed for any single attachment (text or binary). Larger data will be truncated.",
|
|
69
119
|
)
|
|
120
|
+
group.addoption(
|
|
121
|
+
"--disable-unicode-terminal",
|
|
122
|
+
action="store_true",
|
|
123
|
+
default=False,
|
|
124
|
+
help="Disable Unicode character display in terminal (for compatibility).",
|
|
125
|
+
)
|
|
70
126
|
|
|
71
127
|
|
|
72
128
|
def pytest_configure(config: pytest.Config) -> None:
|
|
@@ -79,6 +135,10 @@ def pytest_configure(config: pytest.Config) -> None:
|
|
|
79
135
|
|
|
80
136
|
cfg.ATTACH_LIMIT_BYTES = config.getoption("max_attachment_bytes")
|
|
81
137
|
|
|
138
|
+
if not config.getoption("disable_unicode_terminal"):
|
|
139
|
+
unicode_plugin = UnicodeTerminalPlugin()
|
|
140
|
+
config.pluginmanager.register(unicode_plugin, "unicode_terminal")
|
|
141
|
+
|
|
82
142
|
report_path = config.getoption("report_html")
|
|
83
143
|
if not report_path:
|
|
84
144
|
return
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""Module to test handling of different languages and Unicode payloads."""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from qapytest import soft_assert, step
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@pytest.mark.parametrize(
|
|
9
|
+
"payload",
|
|
10
|
+
[
|
|
11
|
+
{"input": "English text", "language": "English"},
|
|
12
|
+
{"input": "Український текст", "language": "Ukrainian"},
|
|
13
|
+
{"input": "النص العربي", "language": "Arabic"},
|
|
14
|
+
{"input": "中文测试", "language": "Chinese"},
|
|
15
|
+
{"input": "日本語テスト", "language": "Japanese"},
|
|
16
|
+
{"input": "한국어 테스트", "language": "Korean"},
|
|
17
|
+
{"input": "Texto en español", "language": "Spanish"},
|
|
18
|
+
{"input": "Texte français", "language": "French"},
|
|
19
|
+
{"input": "Deutscher Text", "language": "German"},
|
|
20
|
+
],
|
|
21
|
+
ids=["english", "український", "العربي", "中文", "日本語", "한국어", "español", "français", "deutsch"],
|
|
22
|
+
)
|
|
23
|
+
@pytest.mark.title("Test with different languages and Unicode loads")
|
|
24
|
+
def test_multilingual(payload: dict) -> None:
|
|
25
|
+
"""Test handling of different languages and Unicode payloads."""
|
|
26
|
+
language_map = {
|
|
27
|
+
"English": "Logging payload for {}: {}",
|
|
28
|
+
"Ukrainian": "Логування корисного навантаження для {}: {}",
|
|
29
|
+
"Arabic": "تسجيل البيانات لـ {}: {}",
|
|
30
|
+
"Chinese": "为 {} 记录负载: {}",
|
|
31
|
+
"Japanese": "{}のペイロードをログ記録: {}",
|
|
32
|
+
"Korean": "{}에 대한 페이로드 로깅: {}",
|
|
33
|
+
"Spanish": "Registrando carga útil para {}: {}",
|
|
34
|
+
"French": "Enregistrement de la charge utile pour {} : {}",
|
|
35
|
+
"German": "Protokollierung der Nutzlast für {}: {}",
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
assertion_map = {
|
|
39
|
+
"English": "This soft assertion should pass for {}",
|
|
40
|
+
"Ukrainian": "Це м'яке твердження повинно пройти для {}",
|
|
41
|
+
"Arabic": "يجب أن يمر هذا التأكيد المرن لـ {}",
|
|
42
|
+
"Chinese": "这个软断言应该通过 {}",
|
|
43
|
+
"Japanese": "このソフトアサーションは{}について成功するはずです",
|
|
44
|
+
"Korean": "이 소프트 어설션은 {}에 대해 통과해야 합니다",
|
|
45
|
+
"Spanish": "Esta aserción suave debería pasar para {}",
|
|
46
|
+
"French": "Cette assertion souple devrait réussir pour {}",
|
|
47
|
+
"German": "Diese weiche Assertion sollte für {} bestehen",
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
language = payload["language"]
|
|
51
|
+
step_msg = language_map[language].format(language, payload["input"])
|
|
52
|
+
assertion_msg = assertion_map[language].format(language)
|
|
53
|
+
|
|
54
|
+
with step(step_msg):
|
|
55
|
+
soft_assert(True, assertion_msg)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|