pytest-translate 1.0.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.
@@ -0,0 +1,162 @@
1
+ Metadata-Version: 2.2
2
+ Name: pytest-translate
3
+ Version: 1.0.0
4
+ Summary: pytest terminal output in your language — 134 languages supported
5
+ Author-email: Julien Mer <contact@julienmerconsulting.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/julienmerconsulting/pytest-translate
8
+ Project-URL: Repository, https://github.com/julienmerconsulting/pytest-translate
9
+ Project-URL: Issues, https://github.com/julienmerconsulting/pytest-translate/issues
10
+ Keywords: pytest,i18n,internationalization,translation,multilingual,localization
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Framework :: Pytest
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Testing
22
+ Classifier: Topic :: Software Development :: Internationalization
23
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/markdown
25
+ Requires-Dist: pytest>=7.0.0
26
+ Requires-Dist: deep-translator>=1.9.0
27
+
28
+ <div align="center">
29
+
30
+ # 🌍 pytest-translate
31
+
32
+ ### pytest terminal output in your language — automatically
33
+
34
+ [![Python](https://img.shields.io/badge/Python-3.9+-3776AB?style=for-the-badge&logo=python&logoColor=white)](https://python.org)
35
+ [![pytest](https://img.shields.io/badge/pytest-Plugin-0A9EDC?style=for-the-badge&logo=pytest&logoColor=white)](https://pytest.org)
36
+ [![PyPI](https://img.shields.io/badge/PyPI-pytest--translate-blue?style=for-the-badge&logo=pypi&logoColor=white)](https://pypi.org/project/pytest-translate/)
37
+ [![Languages](https://img.shields.io/badge/Languages-134-brightgreen?style=for-the-badge)]()
38
+ [![License](https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge)](LICENSE)
39
+
40
+ <br/>
41
+
42
+ **Why should pytest speak only English?**
43
+
44
+ A Chinese developer, a Japanese tester, an Arabic QA engineer — they all use pytest.
45
+ They all read `FAILED` and `short test summary info` in English.
46
+ Not anymore.
47
+
48
+ </div>
49
+
50
+ ---
51
+
52
+ ## ⚡ Quick Start
53
+
54
+ ```bash
55
+ pip install pytest-translate
56
+ ```
57
+
58
+ That's it. pytest now speaks your OS language automatically.
59
+
60
+ ```bash
61
+ pytest tests/ # auto-detects your OS locale
62
+ pytest tests/ --lang=zh_CN # force Chinese
63
+ pytest tests/ --lang=fr_FR # force French
64
+ pytest tests/ --lang=ja # force Japanese
65
+ pytest tests/ --lang=ar # force Arabic
66
+ pytest tests/ --lang=yi # force Yiddish (yes, really)
67
+ pytest tests/ --lang=sa # force Sanskrit (Hindu priests approved)
68
+ pytest tests/ --lang=off # back to English
69
+ ```
70
+
71
+ ---
72
+
73
+ ## 🗺️ How it works
74
+
75
+ `pytest-translate` hooks into pytest's terminal reporter and translates:
76
+
77
+ - **Test statuses** — `PASSED`, `FAILED`, `SKIPPED`, `ERROR`
78
+ - **Summary line** — `6 failed, 1 passed in 142s`
79
+ - **Section headers** — `FAILURES SUMMARY`, `short test summary`
80
+
81
+ Translation is done via **Google Translate** through `deep-translator` — 134 languages supported, zero configuration required.
82
+
83
+ ---
84
+
85
+ ## 🌐 Language detection priority
86
+
87
+ 1. `--lang=zh_CN` CLI argument
88
+ 2. `PYTEST_LANG=zh_CN` environment variable
89
+ 3. OS locale (automatic — `fr_FR` on a French system, `zh_CN` on a Chinese system)
90
+ 4. English fallback if detection fails
91
+
92
+ ---
93
+
94
+ ## 📦 Installation
95
+
96
+ ```bash
97
+ pip install pytest-translate
98
+ ```
99
+
100
+ Or with pip + deep-translator explicitly:
101
+
102
+ ```bash
103
+ pip install pytest-translate deep-translator
104
+ ```
105
+
106
+ ---
107
+
108
+ ## ⚙️ Configuration
109
+
110
+ ### CLI
111
+
112
+ ```bash
113
+ pytest tests/ --lang=zh_CN
114
+ ```
115
+
116
+ ### Environment variable
117
+
118
+ ```bash
119
+ export PYTEST_LANG=zh_CN
120
+ pytest tests/
121
+ ```
122
+
123
+ ### pyproject.toml (permanent)
124
+
125
+ ```toml
126
+ [tool.pytest.ini_options]
127
+ addopts = "--lang=zh_CN"
128
+ ```
129
+
130
+ ---
131
+
132
+ ## 🗾 Supported languages (134)
133
+
134
+ Afrikaans, Albanian, Amharic, Arabic, Armenian, Azerbaijani, Basque, Bengali, Bosnian, Bulgarian, Catalan, Chinese (Simplified), Chinese (Traditional), Croatian, Czech, Danish, Dutch, English, Esperanto, Estonian, Filipino, Finnish, French, Galician, Georgian, German, Greek, Gujarati, Haitian Creole, Hausa, Hawaiian, Hebrew, Hindi, Hungarian, Icelandic, Indonesian, Irish, Italian, Japanese, Javanese, Kannada, Kazakh, Khmer, Korean, Kurdish, Kyrgyz, Lao, **Latin**, Latvian, Lithuanian, Macedonian, Malagasy, Malay, Malayalam, Maltese, Maori, Marathi, Mongolian, Myanmar, Nepali, Norwegian, Persian, Polish, Portuguese, Punjabi, Romanian, Russian, **Sanskrit**, Serbian, Sinhala, Slovak, Slovenian, Somali, Spanish, Swahili, Swedish, Tajik, Tamil, Telugu, Thai, Turkish, Ukrainian, Urdu, Uzbek, Vietnamese, Welsh, **Yiddish**, Yoruba, Zulu...
135
+
136
+ ---
137
+
138
+ ## 🤝 Contributors
139
+
140
+ | Contributor | Contribution |
141
+ |:------------|:-------------|
142
+ | [Julien Mer](https://github.com/julienmerconsulting) | Original author |
143
+
144
+ ---
145
+
146
+ ## 📄 License
147
+
148
+ MIT — do whatever you want with it.
149
+
150
+ ---
151
+
152
+ <div align="center">
153
+
154
+ **Created by [Julien Mer](https://www.linkedin.com/in/julienmer/) — JMer Consulting**
155
+
156
+ *QA Architect · 20+ years · Katalon Top Partner Europe*
157
+
158
+ [![Newsletter](https://img.shields.io/badge/Newsletter-Bonnes_Pratiques_QA-blue?style=flat-square)](https://www.linkedin.com/newsletters/bonnes-pratiques-qa-6878703775620636672)
159
+
160
+ *Also check out [qa-autopilot](https://pypi.org/project/qa-autopilot/) — AI-powered diagnostic for Playwright test failures in 134 languages.*
161
+
162
+ </div>
@@ -0,0 +1,135 @@
1
+ <div align="center">
2
+
3
+ # 🌍 pytest-translate
4
+
5
+ ### pytest terminal output in your language — automatically
6
+
7
+ [![Python](https://img.shields.io/badge/Python-3.9+-3776AB?style=for-the-badge&logo=python&logoColor=white)](https://python.org)
8
+ [![pytest](https://img.shields.io/badge/pytest-Plugin-0A9EDC?style=for-the-badge&logo=pytest&logoColor=white)](https://pytest.org)
9
+ [![PyPI](https://img.shields.io/badge/PyPI-pytest--translate-blue?style=for-the-badge&logo=pypi&logoColor=white)](https://pypi.org/project/pytest-translate/)
10
+ [![Languages](https://img.shields.io/badge/Languages-134-brightgreen?style=for-the-badge)]()
11
+ [![License](https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge)](LICENSE)
12
+
13
+ <br/>
14
+
15
+ **Why should pytest speak only English?**
16
+
17
+ A Chinese developer, a Japanese tester, an Arabic QA engineer — they all use pytest.
18
+ They all read `FAILED` and `short test summary info` in English.
19
+ Not anymore.
20
+
21
+ </div>
22
+
23
+ ---
24
+
25
+ ## ⚡ Quick Start
26
+
27
+ ```bash
28
+ pip install pytest-translate
29
+ ```
30
+
31
+ That's it. pytest now speaks your OS language automatically.
32
+
33
+ ```bash
34
+ pytest tests/ # auto-detects your OS locale
35
+ pytest tests/ --lang=zh_CN # force Chinese
36
+ pytest tests/ --lang=fr_FR # force French
37
+ pytest tests/ --lang=ja # force Japanese
38
+ pytest tests/ --lang=ar # force Arabic
39
+ pytest tests/ --lang=yi # force Yiddish (yes, really)
40
+ pytest tests/ --lang=sa # force Sanskrit (Hindu priests approved)
41
+ pytest tests/ --lang=off # back to English
42
+ ```
43
+
44
+ ---
45
+
46
+ ## 🗺️ How it works
47
+
48
+ `pytest-translate` hooks into pytest's terminal reporter and translates:
49
+
50
+ - **Test statuses** — `PASSED`, `FAILED`, `SKIPPED`, `ERROR`
51
+ - **Summary line** — `6 failed, 1 passed in 142s`
52
+ - **Section headers** — `FAILURES SUMMARY`, `short test summary`
53
+
54
+ Translation is done via **Google Translate** through `deep-translator` — 134 languages supported, zero configuration required.
55
+
56
+ ---
57
+
58
+ ## 🌐 Language detection priority
59
+
60
+ 1. `--lang=zh_CN` CLI argument
61
+ 2. `PYTEST_LANG=zh_CN` environment variable
62
+ 3. OS locale (automatic — `fr_FR` on a French system, `zh_CN` on a Chinese system)
63
+ 4. English fallback if detection fails
64
+
65
+ ---
66
+
67
+ ## 📦 Installation
68
+
69
+ ```bash
70
+ pip install pytest-translate
71
+ ```
72
+
73
+ Or with pip + deep-translator explicitly:
74
+
75
+ ```bash
76
+ pip install pytest-translate deep-translator
77
+ ```
78
+
79
+ ---
80
+
81
+ ## ⚙️ Configuration
82
+
83
+ ### CLI
84
+
85
+ ```bash
86
+ pytest tests/ --lang=zh_CN
87
+ ```
88
+
89
+ ### Environment variable
90
+
91
+ ```bash
92
+ export PYTEST_LANG=zh_CN
93
+ pytest tests/
94
+ ```
95
+
96
+ ### pyproject.toml (permanent)
97
+
98
+ ```toml
99
+ [tool.pytest.ini_options]
100
+ addopts = "--lang=zh_CN"
101
+ ```
102
+
103
+ ---
104
+
105
+ ## 🗾 Supported languages (134)
106
+
107
+ Afrikaans, Albanian, Amharic, Arabic, Armenian, Azerbaijani, Basque, Bengali, Bosnian, Bulgarian, Catalan, Chinese (Simplified), Chinese (Traditional), Croatian, Czech, Danish, Dutch, English, Esperanto, Estonian, Filipino, Finnish, French, Galician, Georgian, German, Greek, Gujarati, Haitian Creole, Hausa, Hawaiian, Hebrew, Hindi, Hungarian, Icelandic, Indonesian, Irish, Italian, Japanese, Javanese, Kannada, Kazakh, Khmer, Korean, Kurdish, Kyrgyz, Lao, **Latin**, Latvian, Lithuanian, Macedonian, Malagasy, Malay, Malayalam, Maltese, Maori, Marathi, Mongolian, Myanmar, Nepali, Norwegian, Persian, Polish, Portuguese, Punjabi, Romanian, Russian, **Sanskrit**, Serbian, Sinhala, Slovak, Slovenian, Somali, Spanish, Swahili, Swedish, Tajik, Tamil, Telugu, Thai, Turkish, Ukrainian, Urdu, Uzbek, Vietnamese, Welsh, **Yiddish**, Yoruba, Zulu...
108
+
109
+ ---
110
+
111
+ ## 🤝 Contributors
112
+
113
+ | Contributor | Contribution |
114
+ |:------------|:-------------|
115
+ | [Julien Mer](https://github.com/julienmerconsulting) | Original author |
116
+
117
+ ---
118
+
119
+ ## 📄 License
120
+
121
+ MIT — do whatever you want with it.
122
+
123
+ ---
124
+
125
+ <div align="center">
126
+
127
+ **Created by [Julien Mer](https://www.linkedin.com/in/julienmer/) — JMer Consulting**
128
+
129
+ *QA Architect · 20+ years · Katalon Top Partner Europe*
130
+
131
+ [![Newsletter](https://img.shields.io/badge/Newsletter-Bonnes_Pratiques_QA-blue?style=flat-square)](https://www.linkedin.com/newsletters/bonnes-pratiques-qa-6878703775620636672)
132
+
133
+ *Also check out [qa-autopilot](https://pypi.org/project/qa-autopilot/) — AI-powered diagnostic for Playwright test failures in 134 languages.*
134
+
135
+ </div>
@@ -0,0 +1,46 @@
1
+ [build-system]
2
+ requires = ["setuptools>=42,<77", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pytest-translate"
7
+ version = "1.0.0"
8
+ description = "pytest terminal output in your language — 134 languages supported"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.9"
12
+ authors = [
13
+ {name = "Julien Mer", email = "contact@julienmerconsulting.com"},
14
+ ]
15
+ keywords = ["pytest", "i18n", "internationalization", "translation", "multilingual", "localization"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Framework :: Pytest",
19
+ "Intended Audience :: Developers",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Topic :: Software Development :: Testing",
28
+ "Topic :: Software Development :: Internationalization",
29
+ ]
30
+
31
+ dependencies = [
32
+ "pytest>=7.0.0",
33
+ "deep-translator>=1.9.0",
34
+ ]
35
+
36
+ [project.urls]
37
+ Homepage = "https://github.com/julienmerconsulting/pytest-translate"
38
+ Repository = "https://github.com/julienmerconsulting/pytest-translate"
39
+ Issues = "https://github.com/julienmerconsulting/pytest-translate/issues"
40
+
41
+ [project.entry-points.pytest11]
42
+ pytest-translate = "pytest_translate"
43
+
44
+ [tool.setuptools]
45
+ py-modules = ["pytest_translate"]
46
+ license-files = []
@@ -0,0 +1,162 @@
1
+ Metadata-Version: 2.2
2
+ Name: pytest-translate
3
+ Version: 1.0.0
4
+ Summary: pytest terminal output in your language — 134 languages supported
5
+ Author-email: Julien Mer <contact@julienmerconsulting.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/julienmerconsulting/pytest-translate
8
+ Project-URL: Repository, https://github.com/julienmerconsulting/pytest-translate
9
+ Project-URL: Issues, https://github.com/julienmerconsulting/pytest-translate/issues
10
+ Keywords: pytest,i18n,internationalization,translation,multilingual,localization
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Framework :: Pytest
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Testing
22
+ Classifier: Topic :: Software Development :: Internationalization
23
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/markdown
25
+ Requires-Dist: pytest>=7.0.0
26
+ Requires-Dist: deep-translator>=1.9.0
27
+
28
+ <div align="center">
29
+
30
+ # 🌍 pytest-translate
31
+
32
+ ### pytest terminal output in your language — automatically
33
+
34
+ [![Python](https://img.shields.io/badge/Python-3.9+-3776AB?style=for-the-badge&logo=python&logoColor=white)](https://python.org)
35
+ [![pytest](https://img.shields.io/badge/pytest-Plugin-0A9EDC?style=for-the-badge&logo=pytest&logoColor=white)](https://pytest.org)
36
+ [![PyPI](https://img.shields.io/badge/PyPI-pytest--translate-blue?style=for-the-badge&logo=pypi&logoColor=white)](https://pypi.org/project/pytest-translate/)
37
+ [![Languages](https://img.shields.io/badge/Languages-134-brightgreen?style=for-the-badge)]()
38
+ [![License](https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge)](LICENSE)
39
+
40
+ <br/>
41
+
42
+ **Why should pytest speak only English?**
43
+
44
+ A Chinese developer, a Japanese tester, an Arabic QA engineer — they all use pytest.
45
+ They all read `FAILED` and `short test summary info` in English.
46
+ Not anymore.
47
+
48
+ </div>
49
+
50
+ ---
51
+
52
+ ## ⚡ Quick Start
53
+
54
+ ```bash
55
+ pip install pytest-translate
56
+ ```
57
+
58
+ That's it. pytest now speaks your OS language automatically.
59
+
60
+ ```bash
61
+ pytest tests/ # auto-detects your OS locale
62
+ pytest tests/ --lang=zh_CN # force Chinese
63
+ pytest tests/ --lang=fr_FR # force French
64
+ pytest tests/ --lang=ja # force Japanese
65
+ pytest tests/ --lang=ar # force Arabic
66
+ pytest tests/ --lang=yi # force Yiddish (yes, really)
67
+ pytest tests/ --lang=sa # force Sanskrit (Hindu priests approved)
68
+ pytest tests/ --lang=off # back to English
69
+ ```
70
+
71
+ ---
72
+
73
+ ## 🗺️ How it works
74
+
75
+ `pytest-translate` hooks into pytest's terminal reporter and translates:
76
+
77
+ - **Test statuses** — `PASSED`, `FAILED`, `SKIPPED`, `ERROR`
78
+ - **Summary line** — `6 failed, 1 passed in 142s`
79
+ - **Section headers** — `FAILURES SUMMARY`, `short test summary`
80
+
81
+ Translation is done via **Google Translate** through `deep-translator` — 134 languages supported, zero configuration required.
82
+
83
+ ---
84
+
85
+ ## 🌐 Language detection priority
86
+
87
+ 1. `--lang=zh_CN` CLI argument
88
+ 2. `PYTEST_LANG=zh_CN` environment variable
89
+ 3. OS locale (automatic — `fr_FR` on a French system, `zh_CN` on a Chinese system)
90
+ 4. English fallback if detection fails
91
+
92
+ ---
93
+
94
+ ## 📦 Installation
95
+
96
+ ```bash
97
+ pip install pytest-translate
98
+ ```
99
+
100
+ Or with pip + deep-translator explicitly:
101
+
102
+ ```bash
103
+ pip install pytest-translate deep-translator
104
+ ```
105
+
106
+ ---
107
+
108
+ ## ⚙️ Configuration
109
+
110
+ ### CLI
111
+
112
+ ```bash
113
+ pytest tests/ --lang=zh_CN
114
+ ```
115
+
116
+ ### Environment variable
117
+
118
+ ```bash
119
+ export PYTEST_LANG=zh_CN
120
+ pytest tests/
121
+ ```
122
+
123
+ ### pyproject.toml (permanent)
124
+
125
+ ```toml
126
+ [tool.pytest.ini_options]
127
+ addopts = "--lang=zh_CN"
128
+ ```
129
+
130
+ ---
131
+
132
+ ## 🗾 Supported languages (134)
133
+
134
+ Afrikaans, Albanian, Amharic, Arabic, Armenian, Azerbaijani, Basque, Bengali, Bosnian, Bulgarian, Catalan, Chinese (Simplified), Chinese (Traditional), Croatian, Czech, Danish, Dutch, English, Esperanto, Estonian, Filipino, Finnish, French, Galician, Georgian, German, Greek, Gujarati, Haitian Creole, Hausa, Hawaiian, Hebrew, Hindi, Hungarian, Icelandic, Indonesian, Irish, Italian, Japanese, Javanese, Kannada, Kazakh, Khmer, Korean, Kurdish, Kyrgyz, Lao, **Latin**, Latvian, Lithuanian, Macedonian, Malagasy, Malay, Malayalam, Maltese, Maori, Marathi, Mongolian, Myanmar, Nepali, Norwegian, Persian, Polish, Portuguese, Punjabi, Romanian, Russian, **Sanskrit**, Serbian, Sinhala, Slovak, Slovenian, Somali, Spanish, Swahili, Swedish, Tajik, Tamil, Telugu, Thai, Turkish, Ukrainian, Urdu, Uzbek, Vietnamese, Welsh, **Yiddish**, Yoruba, Zulu...
135
+
136
+ ---
137
+
138
+ ## 🤝 Contributors
139
+
140
+ | Contributor | Contribution |
141
+ |:------------|:-------------|
142
+ | [Julien Mer](https://github.com/julienmerconsulting) | Original author |
143
+
144
+ ---
145
+
146
+ ## 📄 License
147
+
148
+ MIT — do whatever you want with it.
149
+
150
+ ---
151
+
152
+ <div align="center">
153
+
154
+ **Created by [Julien Mer](https://www.linkedin.com/in/julienmer/) — JMer Consulting**
155
+
156
+ *QA Architect · 20+ years · Katalon Top Partner Europe*
157
+
158
+ [![Newsletter](https://img.shields.io/badge/Newsletter-Bonnes_Pratiques_QA-blue?style=flat-square)](https://www.linkedin.com/newsletters/bonnes-pratiques-qa-6878703775620636672)
159
+
160
+ *Also check out [qa-autopilot](https://pypi.org/project/qa-autopilot/) — AI-powered diagnostic for Playwright test failures in 134 languages.*
161
+
162
+ </div>
@@ -0,0 +1,11 @@
1
+ README.md
2
+ pyproject.toml
3
+ pytest_translate.py
4
+ pytest_translate.egg-info/PKG-INFO
5
+ pytest_translate.egg-info/SOURCES.txt
6
+ pytest_translate.egg-info/dependency_links.txt
7
+ pytest_translate.egg-info/entry_points.txt
8
+ pytest_translate.egg-info/requires.txt
9
+ pytest_translate.egg-info/top_level.txt
10
+ tests/test_qa_autopilot_unit.py
11
+ tests/test_traps.py
@@ -0,0 +1,2 @@
1
+ [pytest11]
2
+ pytest-translate = pytest_translate
@@ -0,0 +1,2 @@
1
+ pytest>=7.0.0
2
+ deep-translator>=1.9.0
@@ -0,0 +1 @@
1
+ pytest_translate
@@ -0,0 +1,183 @@
1
+ """
2
+ pytest-translate — Terminal pytest dans ta langue natale
3
+ =========================================================
4
+ Par Julien Mer / JMer Consulting
5
+
6
+ Traduit automatiquement la sortie terminal de pytest dans la langue
7
+ de ton OS — ou dans la langue de ton choix via --translate-lang.
8
+
9
+ Usage :
10
+ pytest tests/ # auto-détection locale OS
11
+ pytest tests/ --translate-lang=zh_CN # force le chinois
12
+ pytest tests/ --translate-lang=yi # yiddish
13
+ pytest tests/ --translate-lang=sa # sanskrit
14
+ pytest tests/ --translate-lang=off # désactive la traduction
15
+
16
+ Installation :
17
+ pip install pytest-translate
18
+
19
+ Note : sans réseau ou sans deep-translator, le plugin revient
20
+ silencieusement au texte source. Il ne casse jamais une session.
21
+ """
22
+
23
+ import locale
24
+ import os
25
+
26
+ # ============================================================
27
+ # ETAT GLOBAL — résolu une seule fois dans pytest_configure
28
+ # ============================================================
29
+
30
+ _ACTIVE_LANG = None
31
+ _CACHE = {}
32
+
33
+
34
+ def _resolve_lang(config):
35
+ """Résout la langue active une seule fois au démarrage."""
36
+ global _ACTIVE_LANG
37
+ try:
38
+ val = config.getoption("--translate-lang", default=None, skip=True)
39
+ except Exception:
40
+ val = None
41
+ if val is None:
42
+ val = os.getenv("PYTEST_LANG", "auto")
43
+ if val == "off" or val is None:
44
+ _ACTIVE_LANG = None
45
+ return
46
+ if val == "auto":
47
+ try:
48
+ lang = locale.getlocale()[0]
49
+ except Exception:
50
+ lang = None
51
+ _ACTIVE_LANG = lang if lang and not lang.startswith("en") else None
52
+ return
53
+ _ACTIVE_LANG = val if not val.startswith("en") else None
54
+
55
+
56
+ def _normalize_code(lang):
57
+ """Normalise le code langue pour deep_translator."""
58
+ if not lang:
59
+ return None
60
+ low = lang.lower()
61
+ if low.startswith("zh"):
62
+ return "zh-CN" if "tw" not in low else "zh-TW"
63
+ return lang.replace("_", "-").split("-")[0]
64
+
65
+
66
+ def _t(text):
67
+ """Traduit un texte dans la langue active — silencieux si echec."""
68
+ if not _ACTIVE_LANG:
69
+ return text
70
+ key = f"{_ACTIVE_LANG}:{text}"
71
+ if key in _CACHE:
72
+ return _CACHE[key]
73
+ try:
74
+ from deep_translator import GoogleTranslator
75
+ code = _normalize_code(_ACTIVE_LANG)
76
+ result = GoogleTranslator(source="auto", target=code).translate(text)
77
+ _CACHE[key] = result
78
+ return result
79
+ except Exception:
80
+ _CACHE[key] = text
81
+ return text
82
+
83
+
84
+ # ============================================================
85
+ # HOOKS PYTEST
86
+ # ============================================================
87
+
88
+ def pytest_addoption(parser):
89
+ """Ajoute l'option --translate-lang a pytest."""
90
+ parser.addoption(
91
+ "--translate-lang",
92
+ action="store",
93
+ default=None,
94
+ metavar="LANG",
95
+ help=(
96
+ "Langue du terminal pytest. "
97
+ "Ex: zh_CN, fr_FR, de_DE, ja, yi, sa, ar, hi... "
98
+ "Valeurs speciales: auto (locale OS, defaut), off (desactive). "
99
+ "134 langues supportees via Google Translate."
100
+ ),
101
+ )
102
+
103
+
104
+ def pytest_configure(config):
105
+ """Resout la langue active une seule fois au demarrage."""
106
+ _resolve_lang(config)
107
+ _patch_summary_stats()
108
+ # Supprimer short_test_summary natif si traduction active
109
+ if _ACTIVE_LANG:
110
+ try:
111
+ config.option.reportchars = ""
112
+ except Exception:
113
+ pass
114
+
115
+
116
+ def pytest_report_teststatus(report, config):
117
+ """Traduit les statuts PASSED / FAILED / ERROR / SKIPPED."""
118
+ if not _ACTIVE_LANG or report.when != "call":
119
+ return
120
+ if report.passed:
121
+ return report.outcome, ".", _t("PASSED")
122
+ elif report.failed:
123
+ return report.outcome, "F", _t("FAILED")
124
+ elif report.skipped:
125
+ return report.outcome, "s", _t("SKIPPED")
126
+
127
+
128
+ def pytest_terminal_summary(terminalreporter, exitstatus, config):
129
+ """Traduit et reecrit le resume final."""
130
+ if not _ACTIVE_LANG:
131
+ return
132
+
133
+ tr = terminalreporter
134
+ passed = len(tr.stats.get("passed", []))
135
+ failed = len(tr.stats.get("failed", []))
136
+ error = len(tr.stats.get("error", []))
137
+ skipped = len(tr.stats.get("skipped", []))
138
+
139
+ # Duree compatible pytest 7.x et 9.x
140
+ try:
141
+ elapsed = tr._session_start.elapsed()
142
+ duration_str = f"{elapsed.seconds:.2f}s"
143
+ except Exception:
144
+ try:
145
+ import time
146
+ duration_str = f"{time.time() - tr._session_start:.2f}s"
147
+ except Exception:
148
+ duration_str = ""
149
+
150
+ parts = []
151
+ if failed: parts.append(f"{failed} {_t('failed')}")
152
+ if error: parts.append(f"{error} {_t('error')}")
153
+ if passed: parts.append(f"{passed} {_t('passed')}")
154
+ if skipped: parts.append(f"{skipped} {_t('skipped')}")
155
+ if not parts:
156
+ parts.append(_t("no tests ran"))
157
+
158
+ summary = ", ".join(parts)
159
+ line = f"{summary} {_t('in')} {duration_str}" if duration_str else summary
160
+
161
+ # Supprimer summary_stats natif de pytest avec restauration garantie
162
+ original = tr.__class__.summary_stats
163
+ tr.__class__.summary_stats = lambda self: None
164
+ try:
165
+ tr.write_sep("=", line, bold=True)
166
+ finally:
167
+ tr.__class__.summary_stats = original
168
+
169
+
170
+ def _patch_summary_stats():
171
+ """Patch summary_stats avec restauration garantie via un flag."""
172
+ try:
173
+ from _pytest.terminal import TerminalReporter
174
+ original = TerminalReporter.summary_stats
175
+
176
+ def patched_summary_stats(self):
177
+ if _ACTIVE_LANG:
178
+ return # on laisse pytest_terminal_summary gérer
179
+ original(self)
180
+
181
+ TerminalReporter.summary_stats = patched_summary_stats
182
+ except Exception:
183
+ pass
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,48 @@
1
+ from pathlib import Path
2
+ import sys
3
+
4
+ # Permet l'exécution via `pytest` sans dépendre d'un PYTHONPATH externe.
5
+ ROOT = Path(__file__).resolve().parents[1]
6
+ if str(ROOT) not in sys.path:
7
+ sys.path.insert(0, str(ROOT))
8
+
9
+ import qa_autopilot
10
+
11
+
12
+ class DummyPage:
13
+ def __init__(self):
14
+ self.url = "https://example.test"
15
+
16
+
17
+ def test_get_console_errors_filters_only_errors():
18
+ interceptor = qa_autopilot.QAInterceptor(DummyPage())
19
+ interceptor._console = [
20
+ qa_autopilot.CapturedConsole(type="warning", text="warn", url=""),
21
+ qa_autopilot.CapturedConsole(type="error", text="err", url=""),
22
+ qa_autopilot.CapturedConsole(type="info", text="info", url=""),
23
+ ]
24
+
25
+ errors = interceptor.get_console_errors()
26
+
27
+ assert [entry["type"] for entry in errors] == ["error"]
28
+
29
+
30
+ def test_build_failure_context_keeps_warnings_separate_from_errors():
31
+ interceptor = qa_autopilot.QAInterceptor(DummyPage())
32
+ interceptor._console = [
33
+ qa_autopilot.CapturedConsole(type="warning", text="warn", url=""),
34
+ qa_autopilot.CapturedConsole(type="error", text="err", url=""),
35
+ ]
36
+
37
+ ctx = interceptor.build_failure_context("boom")
38
+
39
+ assert [entry["type"] for entry in ctx.console_errors] == ["error"]
40
+ assert [entry["type"] for entry in ctx.console_warnings] == ["warning"]
41
+
42
+
43
+ def test_build_pytest_command_does_not_use_invalid_dash_c_for_conftest():
44
+ cmd = qa_autopilot.build_pytest_command(["tests/"], "python")
45
+
46
+ assert "-c" not in cmd
47
+ assert cmd[:5] == ["python", "-m", "pytest", "--qa-autopilot", "-v"]
48
+ assert cmd[-1] == "tests/"
@@ -0,0 +1,124 @@
1
+ """
2
+ Tests VICIEUX — Pièges de pro
3
+ ================================
4
+ Chaque test a un bug subtil et traître, le genre qui te fait
5
+ perdre 2 heures avant de comprendre. On va voir si l'IA trouve.
6
+
7
+ Lance : pytest tests/test_traps.py --qa-autopilot --headed -v
8
+ """
9
+ from playwright.sync_api import expect, Page
10
+ import re
11
+
12
+
13
+ def test_element_cache_par_overlay(page: Page):
14
+ """
15
+ PIÈGE : L'élément existe dans le DOM, le sélecteur est bon,
16
+ MAIS il est recouvert par le bandeau cookies.
17
+ Playwright trouve l'élément, essaie de cliquer → intercept error.
18
+
19
+ C'est le cauchemar n°1 en E2E : "mais le sélecteur est bon ?!"
20
+ """
21
+ page.goto("https://www.lemonde.fr")
22
+ page.click("a[href='/international/']", timeout=5000)
23
+
24
+
25
+ def test_iframe_invisible(page: Page):
26
+ """
27
+ PIÈGE : Le formulaire de recherche est dans un iframe.
28
+ Le sélecteur est correct DANS l'iframe, mais le test
29
+ cherche dans le main frame → élément introuvable.
30
+
31
+ Bug classique avec les widgets tiers (paiement, captcha, chat).
32
+ """
33
+ page.goto("https://www.w3schools.com/html/html_iframe.asp")
34
+ page.click("text=HTML Tutorial", timeout=5000)
35
+ iframe = page.frame_locator("iframe[src='/html/default.asp']")
36
+ expect(page.locator(".w3-sidebar")).to_be_visible(timeout=3000)
37
+
38
+
39
+ def test_stale_element_apres_ajax(page: Page):
40
+ """
41
+ PIÈGE : On récupère un locator, puis une action AJAX recharge
42
+ le DOM, et le locator pointe vers un élément qui a été remplacé.
43
+
44
+ Race condition classique avec les SPA.
45
+ """
46
+ page.goto("https://fr.wikipedia.org")
47
+ page.fill("#searchInput", "Python")
48
+
49
+ suggestion = page.locator(".cdx-menu-item__text").first
50
+
51
+ page.fill("#searchInput", "Java")
52
+ page.wait_for_timeout(500)
53
+
54
+ suggestion.click(timeout=3000)
55
+
56
+ expect(page.locator("#firstHeading")).to_have_text("Python (langage)")
57
+
58
+
59
+ def test_navigation_redirect_silencieux(page: Page):
60
+ """
61
+ PIÈGE : La page fait un redirect 301/302 silencieux.
62
+ Le test attend des éléments de la page originale,
63
+ mais on est déjà sur une autre URL.
64
+
65
+ Classique avec les pages de login qui redirigent.
66
+ """
67
+ page.goto("https://fr.wikipedia.org/wiki/Accueil")
68
+ expect(page).to_have_url("https://fr.wikipedia.org/wiki/Accueil")
69
+
70
+
71
+ def test_element_visible_mais_disabled(page: Page):
72
+ """
73
+ PIÈGE : Le bouton est visible, le sélecteur est bon,
74
+ mais il est disabled. Le click ne fait rien, et le test
75
+ continue en pensant que l'action a réussi.
76
+ Puis l'assertion suivante fail sans raison apparente.
77
+
78
+ Le genre de bug où tu te dis "mais j'ai cliqué dessus ?!"
79
+ """
80
+ page.goto("https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_button_disabled")
81
+
82
+ result_frame = page.frame_locator("#iframeResult")
83
+
84
+ btn = result_frame.locator("button")
85
+ expect(btn).to_be_visible(timeout=5000)
86
+
87
+ btn.click()
88
+
89
+ expect(result_frame.locator("#result")).to_be_visible(timeout=3000)
90
+
91
+
92
+ def test_regex_assertion_subtile(page: Page):
93
+ """
94
+ PIÈGE : L'assertion utilise une regex qui semble correcte
95
+ mais échoue à cause d'un caractère spécial Unicode
96
+ dans le texte réel de la page.
97
+
98
+ Cauchemar i18n / encodage.
99
+ """
100
+ page.goto("https://fr.wikipedia.org/wiki/Zinédine_Zidane")
101
+
102
+ heading = page.locator("#firstHeading")
103
+ expect(heading).to_be_visible()
104
+
105
+ expect(heading).to_have_text(re.compile(r"^Zinedine Zidane$"))
106
+
107
+
108
+ def test_double_click_piege(page: Page):
109
+ """
110
+ PIÈGE : Le test fait un simple click() sur un élément
111
+ qui nécessite un double-click pour déclencher l'action.
112
+ Le click passe sans erreur, mais l'état attendu n'arrive jamais.
113
+
114
+ Subtil car pas d'erreur technique.
115
+ """
116
+ page.goto("https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_ev_ondblclick")
117
+
118
+ result_frame = page.frame_locator("#iframeResult")
119
+ button = result_frame.locator("button")
120
+ expect(button).to_be_visible(timeout=5000)
121
+
122
+ button.click()
123
+
124
+ expect(result_frame.locator("#demo")).to_have_text("Hello World", timeout=3000)