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.
- pytest_translate-1.0.0/PKG-INFO +162 -0
- pytest_translate-1.0.0/README.md +135 -0
- pytest_translate-1.0.0/pyproject.toml +46 -0
- pytest_translate-1.0.0/pytest_translate.egg-info/PKG-INFO +162 -0
- pytest_translate-1.0.0/pytest_translate.egg-info/SOURCES.txt +11 -0
- pytest_translate-1.0.0/pytest_translate.egg-info/dependency_links.txt +1 -0
- pytest_translate-1.0.0/pytest_translate.egg-info/entry_points.txt +2 -0
- pytest_translate-1.0.0/pytest_translate.egg-info/requires.txt +2 -0
- pytest_translate-1.0.0/pytest_translate.egg-info/top_level.txt +1 -0
- pytest_translate-1.0.0/pytest_translate.py +183 -0
- pytest_translate-1.0.0/setup.cfg +4 -0
- pytest_translate-1.0.0/tests/test_qa_autopilot_unit.py +48 -0
- pytest_translate-1.0.0/tests/test_traps.py +124 -0
|
@@ -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
|
+
[](https://python.org)
|
|
35
|
+
[](https://pytest.org)
|
|
36
|
+
[](https://pypi.org/project/pytest-translate/)
|
|
37
|
+
[]()
|
|
38
|
+
[](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
|
+
[](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
|
+
[](https://python.org)
|
|
8
|
+
[](https://pytest.org)
|
|
9
|
+
[](https://pypi.org/project/pytest-translate/)
|
|
10
|
+
[]()
|
|
11
|
+
[](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
|
+
[](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
|
+
[](https://python.org)
|
|
35
|
+
[](https://pytest.org)
|
|
36
|
+
[](https://pypi.org/project/pytest-translate/)
|
|
37
|
+
[]()
|
|
38
|
+
[](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
|
+
[](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 @@
|
|
|
1
|
+
|
|
@@ -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,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)
|