hardpy 0.6.0__tar.gz → 0.7.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.
- {hardpy-0.6.0 → hardpy-0.7.0}/PKG-INFO +19 -28
- {hardpy-0.6.0 → hardpy-0.7.0}/README.md +11 -21
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/__init__.py +28 -26
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/cli/cli.py +8 -8
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/cli/template.py +17 -7
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/common/config.py +15 -14
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/api.py +9 -9
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/asset-manifest.json +3 -3
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/index.html +1 -1
- hardpy-0.7.0/hardpy/hardpy_panel/frontend/dist/static/js/main.942e57d4.js +3 -0
- hardpy-0.7.0/hardpy/hardpy_panel/frontend/dist/static/js/main.942e57d4.js.map +1 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/db/__init__.py +3 -4
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/db/base_connector.py +9 -2
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/db/base_server.py +1 -1
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/db/base_store.py +14 -9
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/db/const.py +3 -1
- hardpy-0.7.0/hardpy/pytest_hardpy/db/runstore.py +28 -0
- hardpy-0.7.0/hardpy/pytest_hardpy/db/schema/__init__.py +9 -0
- hardpy-0.6.0/hardpy/pytest_hardpy/db/schema.py → hardpy-0.7.0/hardpy/pytest_hardpy/db/schema/v1.py +120 -79
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/db/statestore.py +8 -10
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/plugin.py +107 -49
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/pytest_call.py +75 -30
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/pytest_wrapper.py +8 -7
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/reporter/base.py +32 -7
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/reporter/hook_reporter.py +65 -37
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/reporter/runner_reporter.py +6 -8
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/result/couchdb_config.py +20 -16
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/result/report_loader/couchdb_loader.py +2 -2
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/result/report_reader/couchdb_reader.py +36 -20
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/utils/__init__.py +20 -19
- hardpy-0.7.0/hardpy/pytest_hardpy/utils/connection_data.py +15 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/utils/const.py +1 -1
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/utils/dialog_box.py +34 -22
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/utils/exception.py +8 -8
- hardpy-0.7.0/hardpy/pytest_hardpy/utils/machineid.py +15 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/utils/node_info.py +45 -16
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/utils/progress_calculator.py +4 -3
- hardpy-0.7.0/hardpy/pytest_hardpy/utils/singleton.py +30 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/pyproject.toml +16 -26
- hardpy-0.6.0/hardpy/hardpy_panel/frontend/dist/static/js/main.7c954faf.js +0 -3
- hardpy-0.6.0/hardpy/hardpy_panel/frontend/dist/static/js/main.7c954faf.js.map +0 -1
- hardpy-0.6.0/hardpy/pytest_hardpy/db/runstore.py +0 -30
- hardpy-0.6.0/hardpy/pytest_hardpy/utils/connection_data.py +0 -17
- hardpy-0.6.0/hardpy/pytest_hardpy/utils/singleton.py +0 -23
- {hardpy-0.6.0 → hardpy-0.7.0}/.gitignore +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/LICENSE +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/cli/__init__.py +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/common/__init__.py +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/__init__.py +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/favicon.ico +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/logo512.png +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/manifest.json +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/css/main.e8a862f1.css +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/css/main.e8a862f1.css.map +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/js/808.ce070002.chunk.js +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/js/808.ce070002.chunk.js.map +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-16px-paths.d605910e.chunk.js +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-16px-paths.d605910e.chunk.js.map +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-20px-paths.7ee05cc8.chunk.js +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-20px-paths.7ee05cc8.chunk.js.map +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-all-paths-loader.0aa89747.chunk.js +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-all-paths-loader.0aa89747.chunk.js.map +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-all-paths.f63155c9.chunk.js +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-all-paths.f63155c9.chunk.js.map +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-split-paths-by-size-loader.52a072d3.chunk.js +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-split-paths-by-size-loader.52a072d3.chunk.js.map +0 -0
- hardpy-0.6.0/hardpy/hardpy_panel/frontend/dist/static/js/main.7c954faf.js.LICENSE.txt → hardpy-0.7.0/hardpy/hardpy_panel/frontend/dist/static/js/main.942e57d4.js.LICENSE.txt +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-16.520846c6beb41df528c8.eot +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-16.5c52b39c697f2323ce8b.svg +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-16.84db1772f4bfb529f64f.woff +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-16.b67ee1736e20e37a3225.woff2 +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-16.e02ecf515378db143652.ttf +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-20.429cacb8accf72488451.ttf +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-20.6ae3791ee2d86fc228a6.svg +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-20.8cecf62de42997e4d82f.woff2 +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-20.afbadb627d43b7857223.eot +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-20.e857f5a5132b8bfa71a1.woff +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/hardpy_panel/frontend/dist/static/media/logo_smol.5b16f92447a4a9e80331.png +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/__init__.py +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/reporter/__init__.py +1 -1
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/result/__init__.py +1 -1
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/result/report_loader/__init__.py +0 -0
- {hardpy-0.6.0 → hardpy-0.7.0}/hardpy/pytest_hardpy/result/report_reader/__init__.py +0 -0
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: hardpy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: HardPy library for device testing
|
|
5
5
|
Project-URL: Homepage, https://github.com/everypinio/hardpy/
|
|
6
6
|
Project-URL: Documentation, https://everypinio.github.io/hardpy/
|
|
7
7
|
Project-URL: Repository, https://github.com/everypinio/hardpy/
|
|
8
8
|
Project-URL: Changelog, https://everypinio.github.io/hardpy/changelog/
|
|
9
|
-
Author: Everypin
|
|
9
|
+
Author-email: Everypin <info@everypin.io>
|
|
10
|
+
License-Expression: GPL-3.0-or-later
|
|
10
11
|
License-File: LICENSE
|
|
11
12
|
Classifier: Development Status :: 4 - Beta
|
|
12
13
|
Classifier: Framework :: Pytest
|
|
13
14
|
Classifier: Intended Audience :: Developers
|
|
14
|
-
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
15
15
|
Classifier: Operating System :: OS Independent
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
17
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
@@ -22,10 +22,11 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
22
22
|
Classifier: Topic :: Software Development :: Testing
|
|
23
23
|
Classifier: Topic :: Software Development :: Testing :: Acceptance
|
|
24
24
|
Classifier: Topic :: Utilities
|
|
25
|
-
Requires-Python:
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
26
|
Requires-Dist: fastapi>=0.100.1
|
|
27
27
|
Requires-Dist: glom>=23.3.0
|
|
28
28
|
Requires-Dist: natsort>=8.4.0
|
|
29
|
+
Requires-Dist: py-machineid~=0.6.0
|
|
29
30
|
Requires-Dist: pycouchdb>=1.14.2
|
|
30
31
|
Requires-Dist: pydantic>=2.4.0
|
|
31
32
|
Requires-Dist: pytest<9,>=7
|
|
@@ -35,30 +36,27 @@ Requires-Dist: uvicorn>=0.23.2
|
|
|
35
36
|
Provides-Extra: build
|
|
36
37
|
Requires-Dist: build==1.0.3; extra == 'build'
|
|
37
38
|
Provides-Extra: dev
|
|
38
|
-
Requires-Dist:
|
|
39
|
-
Requires-Dist:
|
|
40
|
-
Requires-Dist: wemake-python-styleguide; extra == 'dev'
|
|
39
|
+
Requires-Dist: mypy>=1.11.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: ruff>=0.5.6; extra == 'dev'
|
|
41
|
+
Requires-Dist: wemake-python-styleguide>=0.19.2; extra == 'dev'
|
|
41
42
|
Description-Content-Type: text/markdown
|
|
42
43
|
|
|
43
44
|
<h1 align="center">
|
|
44
|
-
<img src="https://
|
|
45
|
-
</h1>
|
|
46
|
-
|
|
47
|
-
<h1 align="center">
|
|
48
|
-
<b>HardPy</b>
|
|
45
|
+
<img src="https://raw.githubusercontent.com/everypinio/hardpy/main/docs/img/logo256.png" alt="HardPy" style="width:150px;">
|
|
49
46
|
</h1>
|
|
50
47
|
|
|
51
48
|
<p align="center">
|
|
52
49
|
HardPy is a python library for creating a test bench for devices.
|
|
53
50
|
</p>
|
|
54
51
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
**Documentation**: <a href=https://everypinio.github.io/hardpy/ target="_blank">https://everypinio.github.io/hardpy/</a>
|
|
52
|
+
<div align="center">
|
|
58
53
|
|
|
59
|
-
|
|
54
|
+
[](https://badge.fury.io/py/hardpy)
|
|
55
|
+

|
|
56
|
+
[](https://docs.pytest.org/en/latest/)
|
|
57
|
+
[](https://everypinio.github.io/hardpy/)
|
|
60
58
|
|
|
61
|
-
|
|
59
|
+
</div>
|
|
62
60
|
|
|
63
61
|
---
|
|
64
62
|
|
|
@@ -70,6 +68,10 @@ HardPy allows you to:
|
|
|
70
68
|
* Use a browser to view, start, stop, and interact with tests;
|
|
71
69
|
* Store test results in the [CouchDB](https://couchdb.apache.org/) database.
|
|
72
70
|
|
|
71
|
+
<h1 align="center">
|
|
72
|
+
<img src="https://raw.githubusercontent.com/everypinio/hardpy/main/docs/img/hardpy_panel.gif" alt="hardpy panel" style="width:550px;">
|
|
73
|
+
</h1>
|
|
74
|
+
|
|
73
75
|
## To Install
|
|
74
76
|
|
|
75
77
|
```bash
|
|
@@ -92,21 +94,10 @@ docker compose up -d
|
|
|
92
94
|
hardpy run
|
|
93
95
|
```
|
|
94
96
|
4. View operator panel in browser: http://localhost:8000/
|
|
95
|
-
|
|
96
|
-
<h1 align="center">
|
|
97
|
-
<img src="https://everypinio.github.io/hardpy/img/hardpy_operator_panel_hello_hardpy.png"
|
|
98
|
-
alt="hardpy operator panel" style="width:600px;">
|
|
99
|
-
</h1>
|
|
100
|
-
|
|
101
97
|
5. View the latest test report: http://localhost:5984/_utils
|
|
102
98
|
|
|
103
99
|
Login and password: **dev**, database - **runstore**, document - **current**.
|
|
104
100
|
|
|
105
|
-
<h1 align="center">
|
|
106
|
-
<img src="https://everypinio.github.io/hardpy/img/runstore_hello_hardpy.png"
|
|
107
|
-
alt="hardpy runstore" style="width:500px;">
|
|
108
|
-
</h1>
|
|
109
|
-
|
|
110
101
|
## Examples
|
|
111
102
|
|
|
112
103
|
Find more examples of using the **HardPy** in the [examples](https://github.com/everypinio/hardpy/tree/main/examples) folder.
|
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
<h1 align="center">
|
|
2
|
-
<img src="https://
|
|
3
|
-
</h1>
|
|
4
|
-
|
|
5
|
-
<h1 align="center">
|
|
6
|
-
<b>HardPy</b>
|
|
2
|
+
<img src="https://raw.githubusercontent.com/everypinio/hardpy/main/docs/img/logo256.png" alt="HardPy" style="width:150px;">
|
|
7
3
|
</h1>
|
|
8
4
|
|
|
9
5
|
<p align="center">
|
|
10
6
|
HardPy is a python library for creating a test bench for devices.
|
|
11
7
|
</p>
|
|
12
8
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
**Documentation**: <a href=https://everypinio.github.io/hardpy/ target="_blank">https://everypinio.github.io/hardpy/</a>
|
|
9
|
+
<div align="center">
|
|
16
10
|
|
|
17
|
-
|
|
11
|
+
[](https://badge.fury.io/py/hardpy)
|
|
12
|
+

|
|
13
|
+
[](https://docs.pytest.org/en/latest/)
|
|
14
|
+
[](https://everypinio.github.io/hardpy/)
|
|
18
15
|
|
|
19
|
-
|
|
16
|
+
</div>
|
|
20
17
|
|
|
21
18
|
---
|
|
22
19
|
|
|
@@ -28,6 +25,10 @@ HardPy allows you to:
|
|
|
28
25
|
* Use a browser to view, start, stop, and interact with tests;
|
|
29
26
|
* Store test results in the [CouchDB](https://couchdb.apache.org/) database.
|
|
30
27
|
|
|
28
|
+
<h1 align="center">
|
|
29
|
+
<img src="https://raw.githubusercontent.com/everypinio/hardpy/main/docs/img/hardpy_panel.gif" alt="hardpy panel" style="width:550px;">
|
|
30
|
+
</h1>
|
|
31
|
+
|
|
31
32
|
## To Install
|
|
32
33
|
|
|
33
34
|
```bash
|
|
@@ -50,21 +51,10 @@ docker compose up -d
|
|
|
50
51
|
hardpy run
|
|
51
52
|
```
|
|
52
53
|
4. View operator panel in browser: http://localhost:8000/
|
|
53
|
-
|
|
54
|
-
<h1 align="center">
|
|
55
|
-
<img src="https://everypinio.github.io/hardpy/img/hardpy_operator_panel_hello_hardpy.png"
|
|
56
|
-
alt="hardpy operator panel" style="width:600px;">
|
|
57
|
-
</h1>
|
|
58
|
-
|
|
59
54
|
5. View the latest test report: http://localhost:5984/_utils
|
|
60
55
|
|
|
61
56
|
Login and password: **dev**, database - **runstore**, document - **current**.
|
|
62
57
|
|
|
63
|
-
<h1 align="center">
|
|
64
|
-
<img src="https://everypinio.github.io/hardpy/img/runstore_hello_hardpy.png"
|
|
65
|
-
alt="hardpy runstore" style="width:500px;">
|
|
66
|
-
</h1>
|
|
67
|
-
|
|
68
58
|
## Examples
|
|
69
59
|
|
|
70
60
|
Find more examples of using the **HardPy** in the [examples](https://github.com/everypinio/hardpy/tree/main/examples) folder.
|
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
# Copyright (c) 2024 Everypin
|
|
2
2
|
# GNU General Public License v3.0 (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
3
3
|
|
|
4
|
-
from hardpy.pytest_hardpy.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
from hardpy.pytest_hardpy.pytest_call import (
|
|
5
|
+
get_current_attempt,
|
|
6
|
+
get_current_report,
|
|
7
|
+
run_dialog_box,
|
|
8
|
+
set_case_artifact,
|
|
9
|
+
set_driver_info,
|
|
10
|
+
set_dut_info,
|
|
11
|
+
set_dut_part_number,
|
|
12
|
+
set_dut_serial_number,
|
|
13
|
+
set_message,
|
|
14
|
+
set_module_artifact,
|
|
15
|
+
set_operator_message,
|
|
16
|
+
set_run_artifact,
|
|
17
|
+
set_stand_info,
|
|
18
|
+
set_stand_location,
|
|
19
|
+
set_stand_name,
|
|
10
20
|
)
|
|
21
|
+
from hardpy.pytest_hardpy.result import CouchdbLoader
|
|
11
22
|
from hardpy.pytest_hardpy.result.couchdb_config import CouchdbConfig
|
|
12
23
|
from hardpy.pytest_hardpy.utils import (
|
|
24
|
+
CheckboxWidget,
|
|
13
25
|
DialogBox,
|
|
14
|
-
|
|
26
|
+
DuplicatePartNumberError,
|
|
27
|
+
DuplicateSerialNumberError,
|
|
28
|
+
DuplicateTestStandLocationError,
|
|
29
|
+
DuplicateTestStandNameError,
|
|
30
|
+
ImageWidget,
|
|
31
|
+
MultistepWidget,
|
|
15
32
|
NumericInputWidget,
|
|
16
|
-
CheckboxWidget,
|
|
17
33
|
RadiobuttonWidget,
|
|
18
|
-
ImageWidget,
|
|
19
34
|
StepWidget,
|
|
20
|
-
|
|
21
|
-
)
|
|
22
|
-
from hardpy.pytest_hardpy.pytest_call import (
|
|
23
|
-
get_current_report,
|
|
24
|
-
set_dut_info,
|
|
25
|
-
set_dut_serial_number,
|
|
26
|
-
set_dut_part_number,
|
|
27
|
-
set_stand_name,
|
|
28
|
-
set_stand_info,
|
|
29
|
-
set_case_artifact,
|
|
30
|
-
set_module_artifact,
|
|
31
|
-
set_run_artifact,
|
|
32
|
-
set_message,
|
|
33
|
-
set_driver_info,
|
|
34
|
-
run_dialog_box,
|
|
35
|
-
set_operator_message,
|
|
35
|
+
TextInputWidget,
|
|
36
36
|
)
|
|
37
37
|
|
|
38
38
|
__all__ = [
|
|
@@ -44,19 +44,21 @@ __all__ = [
|
|
|
44
44
|
"DuplicateSerialNumberError",
|
|
45
45
|
"DuplicatePartNumberError",
|
|
46
46
|
"DuplicateTestStandNameError",
|
|
47
|
-
"
|
|
47
|
+
"DuplicateTestStandLocationError",
|
|
48
48
|
# Database info
|
|
49
49
|
"set_dut_info",
|
|
50
50
|
"set_dut_serial_number",
|
|
51
51
|
"set_dut_part_number",
|
|
52
52
|
"set_stand_name",
|
|
53
53
|
"set_stand_info",
|
|
54
|
+
"set_stand_location",
|
|
54
55
|
"set_case_artifact",
|
|
55
56
|
"set_module_artifact",
|
|
56
57
|
"set_run_artifact",
|
|
57
58
|
"set_message",
|
|
58
59
|
"set_driver_info",
|
|
59
60
|
"set_operator_message",
|
|
61
|
+
"get_current_attempt",
|
|
60
62
|
# Dialog boxes
|
|
61
63
|
"run_dialog_box",
|
|
62
64
|
"DialogBox",
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# Copyright (c) 2024 Everypin
|
|
2
2
|
# GNU General Public License v3.0 (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
3
|
+
from __future__ import annotations
|
|
3
4
|
|
|
4
|
-
import os
|
|
5
5
|
import sys
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
from typing import Optional
|
|
8
|
-
from typing_extensions import Annotated
|
|
9
8
|
|
|
10
9
|
import typer
|
|
10
|
+
from typing_extensions import Annotated
|
|
11
11
|
from uvicorn import run as uvicorn_run
|
|
12
12
|
|
|
13
13
|
from hardpy.cli.template import TemplateGenerator
|
|
@@ -18,8 +18,8 @@ default_config = ConfigManager().get_config()
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
@cli.command()
|
|
21
|
-
def init( # noqa:
|
|
22
|
-
tests_dir: Annotated[Optional[str], typer.Argument()] = None,
|
|
21
|
+
def init( # noqa: PLR0913
|
|
22
|
+
tests_dir: Annotated[Optional[str], typer.Argument()] = None, # noqa: UP007
|
|
23
23
|
create_database: bool = typer.Option(
|
|
24
24
|
True,
|
|
25
25
|
help="Create CouchDB database.",
|
|
@@ -56,7 +56,7 @@ def init( # noqa: WPS211
|
|
|
56
56
|
default_config.socket.port,
|
|
57
57
|
help="Specify a socket port.",
|
|
58
58
|
),
|
|
59
|
-
):
|
|
59
|
+
) -> None:
|
|
60
60
|
"""Initialize HardPy tests directory.
|
|
61
61
|
|
|
62
62
|
Args:
|
|
@@ -85,11 +85,11 @@ def init( # noqa: WPS211
|
|
|
85
85
|
)
|
|
86
86
|
# create tests directory
|
|
87
87
|
dir_path = Path(Path.cwd() / _tests_dir)
|
|
88
|
-
|
|
88
|
+
Path.mkdir(dir_path, exist_ok=True, parents=True)
|
|
89
89
|
|
|
90
90
|
if create_database:
|
|
91
91
|
# create database directory
|
|
92
|
-
|
|
92
|
+
Path.mkdir(dir_path / "database", exist_ok=True, parents=True)
|
|
93
93
|
|
|
94
94
|
# create hardpy.toml
|
|
95
95
|
ConfigManager().create_config(dir_path)
|
|
@@ -117,7 +117,7 @@ def init( # noqa: WPS211
|
|
|
117
117
|
|
|
118
118
|
|
|
119
119
|
@cli.command()
|
|
120
|
-
def run(tests_dir: Annotated[Optional[str], typer.Argument()] = None):
|
|
120
|
+
def run(tests_dir: Annotated[Optional[str], typer.Argument()] = None) -> None: # noqa: UP007
|
|
121
121
|
"""Run HardPy server.
|
|
122
122
|
|
|
123
123
|
Args:
|
|
@@ -9,7 +9,7 @@ docker_compose_yaml = """version: "3.8"
|
|
|
9
9
|
|
|
10
10
|
services:
|
|
11
11
|
couchserver:
|
|
12
|
-
image: couchdb:3.
|
|
12
|
+
image: couchdb:3.4
|
|
13
13
|
ports:
|
|
14
14
|
- "{}:5984"
|
|
15
15
|
environment:
|
|
@@ -129,7 +129,7 @@ headers = accept, authorization, content-type, origin, referer, x-csrf-token
|
|
|
129
129
|
; changing this.
|
|
130
130
|
[admins]
|
|
131
131
|
;admin = mysecretpassword
|
|
132
|
-
"""
|
|
132
|
+
""" # noqa: E501
|
|
133
133
|
|
|
134
134
|
pytest_ini = """[pytest]
|
|
135
135
|
log_cli = true
|
|
@@ -137,6 +137,9 @@ log_cli_level = INFO
|
|
|
137
137
|
log_cli_format = %%(asctime)s [%%(levelname)s] %%(message)s
|
|
138
138
|
log_cli_date_format = %H:%M:%S
|
|
139
139
|
addopts = --hardpy-pt
|
|
140
|
+
--hardpy-db-url http://{}:{}@{}:{}/
|
|
141
|
+
--hardpy-sh {}
|
|
142
|
+
--hardpy-sp {}
|
|
140
143
|
"""
|
|
141
144
|
|
|
142
145
|
test_1_py = """import pytest
|
|
@@ -169,17 +172,17 @@ def fill_actions_after_test(post_run_functions: list):
|
|
|
169
172
|
class TemplateGenerator:
|
|
170
173
|
"""HardPy template files generator."""
|
|
171
174
|
|
|
172
|
-
def __init__(self, config: HardpyConfig):
|
|
175
|
+
def __init__(self, config: HardpyConfig) -> None:
|
|
173
176
|
self._config = config
|
|
174
177
|
|
|
175
|
-
def create_file(self, file_path: Path, content: str):
|
|
178
|
+
def create_file(self, file_path: Path, content: str) -> None:
|
|
176
179
|
"""Create HardPy template file.
|
|
177
180
|
|
|
178
181
|
Args:
|
|
179
182
|
file_path (Path): file path
|
|
180
183
|
content (str): file content
|
|
181
184
|
"""
|
|
182
|
-
with open(file_path, "w") as file:
|
|
185
|
+
with Path.open(file_path, "w") as file:
|
|
183
186
|
file.write(content)
|
|
184
187
|
|
|
185
188
|
@property
|
|
@@ -199,10 +202,17 @@ class TemplateGenerator:
|
|
|
199
202
|
|
|
200
203
|
@property
|
|
201
204
|
def pytest_ini(self) -> str:
|
|
202
|
-
return pytest_ini
|
|
205
|
+
return pytest_ini.format(
|
|
206
|
+
self._config.database.user,
|
|
207
|
+
self._config.database.password,
|
|
208
|
+
self._config.database.host,
|
|
209
|
+
self._config.database.port,
|
|
210
|
+
self._config.socket.host,
|
|
211
|
+
self._config.socket.port,
|
|
212
|
+
)
|
|
203
213
|
|
|
204
214
|
@property
|
|
205
|
-
def test_1_py(self) -> str:
|
|
215
|
+
def test_1_py(self) -> str:
|
|
206
216
|
return test_1_py
|
|
207
217
|
|
|
208
218
|
@property
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# Copyright (c) 2024 Everypin
|
|
2
2
|
# GNU General Public License v3.0 (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
3
|
+
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
from logging import getLogger
|
|
5
6
|
from pathlib import Path
|
|
@@ -27,7 +28,7 @@ class DatabaseConfig(BaseModel):
|
|
|
27
28
|
str: database connection url
|
|
28
29
|
"""
|
|
29
30
|
credentials = f"{self.user}:{self.password}"
|
|
30
|
-
uri = f"{self.host}:{
|
|
31
|
+
uri = f"{self.host}:{self.port!s}"
|
|
31
32
|
return f"http://{credentials}@{uri}/"
|
|
32
33
|
|
|
33
34
|
|
|
@@ -68,7 +69,7 @@ class ConfigManager:
|
|
|
68
69
|
tests_path = Path.cwd()
|
|
69
70
|
|
|
70
71
|
@classmethod
|
|
71
|
-
def init_config( # noqa:
|
|
72
|
+
def init_config( # noqa: PLR0913
|
|
72
73
|
cls,
|
|
73
74
|
tests_dir: str,
|
|
74
75
|
database_user: str,
|
|
@@ -79,7 +80,7 @@ class ConfigManager:
|
|
|
79
80
|
frontend_port: int,
|
|
80
81
|
socket_host: str,
|
|
81
82
|
socket_port: int,
|
|
82
|
-
):
|
|
83
|
+
) -> None:
|
|
83
84
|
"""Initialize HardPy configuration.
|
|
84
85
|
|
|
85
86
|
Args:
|
|
@@ -104,13 +105,13 @@ class ConfigManager:
|
|
|
104
105
|
cls.obj.socket.port = socket_port
|
|
105
106
|
|
|
106
107
|
@classmethod
|
|
107
|
-
def create_config(cls, parent_dir: Path):
|
|
108
|
+
def create_config(cls, parent_dir: Path) -> None:
|
|
108
109
|
"""Create HardPy configuration.
|
|
109
110
|
|
|
110
111
|
Args:
|
|
111
112
|
parent_dir (Path): Configuration file parent directory.
|
|
112
113
|
"""
|
|
113
|
-
with open(parent_dir / "hardpy.toml", "w") as file:
|
|
114
|
+
with Path.open(parent_dir / "hardpy.toml", "w") as file:
|
|
114
115
|
file.write(rtoml.dumps(cls.obj.model_dump()))
|
|
115
116
|
|
|
116
117
|
@classmethod
|
|
@@ -129,15 +130,15 @@ class ConfigManager:
|
|
|
129
130
|
logger.error(f"File hardpy.toml not found at path: {toml_file}")
|
|
130
131
|
return None
|
|
131
132
|
try:
|
|
132
|
-
with open(toml_path / "hardpy.toml", "r") as f:
|
|
133
|
+
with Path.open(toml_path / "hardpy.toml", "r") as f:
|
|
133
134
|
cls.obj = HardpyConfig(**rtoml.load(f))
|
|
134
|
-
return cls.obj
|
|
135
|
-
except rtoml.TomlParsingError
|
|
136
|
-
logger.
|
|
137
|
-
except rtoml.TomlSerializationError
|
|
138
|
-
logger.
|
|
139
|
-
except ValidationError
|
|
140
|
-
logger.
|
|
135
|
+
return cls.obj # noqa: TRY300
|
|
136
|
+
except rtoml.TomlParsingError:
|
|
137
|
+
logger.exception("Error parsing TOML")
|
|
138
|
+
except rtoml.TomlSerializationError:
|
|
139
|
+
logger.exception("Error parsing TOML")
|
|
140
|
+
except ValidationError:
|
|
141
|
+
logger.exception("Error parsing TOML")
|
|
141
142
|
return None
|
|
142
143
|
|
|
143
144
|
@classmethod
|
|
@@ -150,7 +151,7 @@ class ConfigManager:
|
|
|
150
151
|
return cls.obj
|
|
151
152
|
|
|
152
153
|
@classmethod
|
|
153
|
-
def get_tests_path(cls) -> Path:
|
|
154
|
+
def get_tests_path(cls) -> Path:
|
|
154
155
|
"""Get tests path.
|
|
155
156
|
|
|
156
157
|
Returns:
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Copyright (c) 2024 Everypin
|
|
2
2
|
# GNU General Public License v3.0 (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
3
3
|
|
|
4
|
-
import os
|
|
5
4
|
import re
|
|
6
5
|
from enum import Enum
|
|
6
|
+
from pathlib import Path
|
|
7
7
|
from urllib.parse import unquote
|
|
8
8
|
|
|
9
9
|
from fastapi import FastAPI
|
|
@@ -16,7 +16,7 @@ app = FastAPI()
|
|
|
16
16
|
app.state.pytest_wrp = PyTestWrapper()
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
class Status(str, Enum):
|
|
19
|
+
class Status(str, Enum):
|
|
20
20
|
"""Pytest run status.
|
|
21
21
|
|
|
22
22
|
Statuses, that can be returned by HardPy to frontend.
|
|
@@ -31,7 +31,7 @@ class Status(str, Enum): # noqa: WPS600
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
@app.get("/api/start")
|
|
34
|
-
def start_pytest():
|
|
34
|
+
def start_pytest() -> dict:
|
|
35
35
|
"""Start pytest subprocess.
|
|
36
36
|
|
|
37
37
|
Returns:
|
|
@@ -43,7 +43,7 @@ def start_pytest():
|
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
@app.get("/api/stop")
|
|
46
|
-
def stop_pytest():
|
|
46
|
+
def stop_pytest() -> dict:
|
|
47
47
|
"""Stop pytest subprocess.
|
|
48
48
|
|
|
49
49
|
Returns:
|
|
@@ -55,7 +55,7 @@ def stop_pytest():
|
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
@app.get("/api/collect")
|
|
58
|
-
def collect_pytest():
|
|
58
|
+
def collect_pytest() -> dict:
|
|
59
59
|
"""Collect pytest subprocess.
|
|
60
60
|
|
|
61
61
|
Returns:
|
|
@@ -68,7 +68,7 @@ def collect_pytest():
|
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
@app.get("/api/couch")
|
|
71
|
-
def couch_connection():
|
|
71
|
+
def couch_connection() -> dict:
|
|
72
72
|
"""Get couchdb connection string.
|
|
73
73
|
|
|
74
74
|
Returns:
|
|
@@ -82,7 +82,7 @@ def couch_connection():
|
|
|
82
82
|
|
|
83
83
|
|
|
84
84
|
@app.post("/api/confirm_dialog_box/{dialog_box_output}")
|
|
85
|
-
def confirm_dialog_box(dialog_box_output: str):
|
|
85
|
+
def confirm_dialog_box(dialog_box_output: str) -> dict:
|
|
86
86
|
"""Confirm dialog box.
|
|
87
87
|
|
|
88
88
|
Args:
|
|
@@ -105,7 +105,7 @@ def confirm_dialog_box(dialog_box_output: str):
|
|
|
105
105
|
|
|
106
106
|
|
|
107
107
|
@app.post("/api/confirm_operator_msg/{is_msg_visible}")
|
|
108
|
-
def confirm_operator_msg(is_msg_visible:
|
|
108
|
+
def confirm_operator_msg(is_msg_visible: str) -> dict:
|
|
109
109
|
"""Confirm operator msg.
|
|
110
110
|
|
|
111
111
|
Args:
|
|
@@ -122,7 +122,7 @@ def confirm_operator_msg(is_msg_visible: bool):
|
|
|
122
122
|
app.mount(
|
|
123
123
|
"/",
|
|
124
124
|
StaticFiles(
|
|
125
|
-
directory=(
|
|
125
|
+
directory=Path(__file__).parent / "frontend/dist",
|
|
126
126
|
html=True,
|
|
127
127
|
),
|
|
128
128
|
name="static",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"files": {
|
|
3
3
|
"main.css": "/static/css/main.e8a862f1.css",
|
|
4
|
-
"main.js": "/static/js/main.
|
|
4
|
+
"main.js": "/static/js/main.942e57d4.js",
|
|
5
5
|
"blueprint-icons-all-paths-loader.js": "/static/js/blueprint-icons-all-paths-loader.0aa89747.chunk.js",
|
|
6
6
|
"blueprint-icons-split-paths-by-size-loader.js": "/static/js/blueprint-icons-split-paths-by-size-loader.52a072d3.chunk.js",
|
|
7
7
|
"static/js/808.ce070002.chunk.js": "/static/js/808.ce070002.chunk.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"static/media/logo_smol.png": "/static/media/logo_smol.5b16f92447a4a9e80331.png",
|
|
22
22
|
"index.html": "/index.html",
|
|
23
23
|
"main.e8a862f1.css.map": "/static/css/main.e8a862f1.css.map",
|
|
24
|
-
"main.
|
|
24
|
+
"main.942e57d4.js.map": "/static/js/main.942e57d4.js.map",
|
|
25
25
|
"blueprint-icons-all-paths-loader.0aa89747.chunk.js.map": "/static/js/blueprint-icons-all-paths-loader.0aa89747.chunk.js.map",
|
|
26
26
|
"blueprint-icons-split-paths-by-size-loader.52a072d3.chunk.js.map": "/static/js/blueprint-icons-split-paths-by-size-loader.52a072d3.chunk.js.map",
|
|
27
27
|
"808.ce070002.chunk.js.map": "/static/js/808.ce070002.chunk.js.map",
|
|
@@ -31,6 +31,6 @@
|
|
|
31
31
|
},
|
|
32
32
|
"entrypoints": [
|
|
33
33
|
"static/css/main.e8a862f1.css",
|
|
34
|
-
"static/js/main.
|
|
34
|
+
"static/js/main.942e57d4.js"
|
|
35
35
|
]
|
|
36
36
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>HardPy Operator Panel</title><script defer="defer" src="/static/js/main.
|
|
1
|
+
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>HardPy Operator Panel</title><script defer="defer" src="/static/js/main.942e57d4.js"></script><link href="/static/css/main.e8a862f1.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|