hardpy 0.2.0__py3-none-any.whl → 0.4.0__py3-none-any.whl

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.
Files changed (28) hide show
  1. hardpy/__init__.py +9 -1
  2. hardpy/hardpy_panel/api.py +15 -0
  3. hardpy/hardpy_panel/frontend/dist/asset-manifest.json +3 -3
  4. hardpy/hardpy_panel/frontend/dist/index.html +1 -1
  5. hardpy/hardpy_panel/frontend/dist/static/js/main.37744128.js +3 -0
  6. hardpy/hardpy_panel/frontend/dist/static/js/main.37744128.js.map +1 -0
  7. hardpy/hardpy_panel/runner.py +2 -0
  8. hardpy/pytest_hardpy/db/base_store.py +21 -11
  9. hardpy/pytest_hardpy/db/const.py +1 -0
  10. hardpy/pytest_hardpy/db/schema.py +23 -2
  11. hardpy/pytest_hardpy/plugin.py +72 -4
  12. hardpy/pytest_hardpy/pytest_call.py +100 -11
  13. hardpy/pytest_hardpy/pytest_wrapper.py +29 -0
  14. hardpy/pytest_hardpy/reporter/base.py +30 -12
  15. hardpy/pytest_hardpy/reporter/hook_reporter.py +38 -40
  16. hardpy/pytest_hardpy/utils/__init__.py +17 -1
  17. hardpy/pytest_hardpy/utils/config_data.py +5 -1
  18. hardpy/pytest_hardpy/utils/dialog_box.py +100 -0
  19. hardpy/pytest_hardpy/utils/exception.py +7 -0
  20. hardpy/pytest_hardpy/utils/node_info.py +66 -0
  21. {hardpy-0.2.0.dist-info → hardpy-0.4.0.dist-info}/METADATA +9 -2
  22. {hardpy-0.2.0.dist-info → hardpy-0.4.0.dist-info}/RECORD +26 -25
  23. hardpy/hardpy_panel/frontend/dist/static/js/main.8ef63e9b.js +0 -3
  24. hardpy/hardpy_panel/frontend/dist/static/js/main.8ef63e9b.js.map +0 -1
  25. /hardpy/hardpy_panel/frontend/dist/static/js/{main.8ef63e9b.js.LICENSE.txt → main.37744128.js.LICENSE.txt} +0 -0
  26. {hardpy-0.2.0.dist-info → hardpy-0.4.0.dist-info}/WHEEL +0 -0
  27. {hardpy-0.2.0.dist-info → hardpy-0.4.0.dist-info}/entry_points.txt +0 -0
  28. {hardpy-0.2.0.dist-info → hardpy-0.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -25,23 +25,23 @@ class HookReporter(BaseReporter):
25
25
  Args:
26
26
  doc_name (str): test run name
27
27
  """
28
- self.set_db_value(DF.NAME, doc_name)
29
- self.set_db_value(DF.STATUS, TestStatus.READY)
30
- self.set_db_value(DF.START_TIME, None)
31
- self.set_db_value(DF.TIMEZONE, None)
32
- self.set_db_value(DF.STOP_TIME, None)
33
- self.set_db_value(DF.PROGRESS, 0)
34
- self.set_db_value(DF.DRIVERS, {})
35
- self.set_db_value(DF.ARTIFACT, {}, is_statestore=False)
28
+ self.set_doc_value(DF.NAME, doc_name)
29
+ self.set_doc_value(DF.STATUS, TestStatus.READY)
30
+ self.set_doc_value(DF.START_TIME, None)
31
+ self.set_doc_value(DF.TIMEZONE, None)
32
+ self.set_doc_value(DF.STOP_TIME, None)
33
+ self.set_doc_value(DF.PROGRESS, 0)
34
+ self.set_doc_value(DF.DRIVERS, {})
35
+ self.set_doc_value(DF.ARTIFACT, {}, runstore_only=True)
36
36
 
37
37
  def start(self):
38
38
  """Start test."""
39
39
  self._log.debug("Starting test run.")
40
40
  start_time = int(time())
41
- self.set_db_value(DF.START_TIME, start_time)
42
- self.set_db_value(DF.STATUS, TestStatus.RUN)
43
- self.set_db_value(DF.TIMEZONE, tzname) # noqa: WPS432
44
- self.set_db_value(DF.PROGRESS, 0)
41
+ self.set_doc_value(DF.START_TIME, start_time)
42
+ self.set_doc_value(DF.STATUS, TestStatus.RUN)
43
+ self.set_doc_value(DF.TIMEZONE, tzname) # noqa: WPS432
44
+ self.set_doc_value(DF.PROGRESS, 0)
45
45
 
46
46
  def finish(self, status: RunStatus):
47
47
  """Finish test.
@@ -50,15 +50,11 @@ class HookReporter(BaseReporter):
50
50
  """
51
51
  self._log.debug("Finishing test run.")
52
52
  stop_time = int(time())
53
- self.set_db_value(DF.STOP_TIME, stop_time)
54
- self.set_db_value(DF.STATUS, status)
55
-
56
- if self._statestore.get_document():
57
- self._log.debug("Report StateStore has been successfully validated.")
58
-
59
- if self._runstore.get_document():
60
- self._log.debug("Report RunStore has been successfully validated.")
53
+ self.set_doc_value(DF.STOP_TIME, stop_time)
54
+ self.set_doc_value(DF.STATUS, status)
61
55
 
56
+ def compact_all(self):
57
+ """Compact all databases"""
62
58
  self._statestore.compact()
63
59
  self._runstore.compact()
64
60
 
@@ -68,7 +64,7 @@ class HookReporter(BaseReporter):
68
64
  Args:
69
65
  progress (int): test progress
70
66
  """
71
- self.set_db_value(DF.PROGRESS, progress)
67
+ self.set_doc_value(DF.PROGRESS, progress)
72
68
 
73
69
  def set_assertion_msg(self, module_id: str, case_id: str, msg: str | None):
74
70
  """Set case assertion message.
@@ -81,7 +77,7 @@ class HookReporter(BaseReporter):
81
77
  key = self.generate_key(
82
78
  DF.MODULES, module_id, DF.CASES, case_id, DF.ASSERTION_MSG
83
79
  )
84
- self.set_db_value(key, msg)
80
+ self.set_doc_value(key, msg)
85
81
 
86
82
  def add_case(self, node_info: NodeInfo):
87
83
  """Add test case to document.
@@ -90,18 +86,15 @@ class HookReporter(BaseReporter):
90
86
  node_info (NodeInfo): node info
91
87
  """
92
88
  key = DF.MODULES
89
+
93
90
  item_statestore = self._statestore.get_field(key)
94
91
  item_runstore = self._runstore.get_field(key)
95
92
 
96
- new_item_statestore = self._init_case(item_statestore, node_info)
97
- new_item_runstore = self._init_case(
98
- item_runstore,
99
- node_info,
100
- is_use_artifact=True,
101
- )
93
+ self._init_case(item_statestore, node_info, is_only_statestore=True)
94
+ self._init_case(item_runstore, node_info, is_only_runstore=True)
102
95
 
103
- self.set_db_value(key, new_item_statestore, is_runstore=False)
104
- self.set_db_value(key, new_item_runstore, is_statestore=False)
96
+ self.set_doc_value(key, item_statestore, statestore_only=True)
97
+ self.set_doc_value(key, item_runstore, runstore_only=True)
105
98
 
106
99
  def set_case_status(self, module_id: str, case_id: str, status: TestStatus):
107
100
  """Set test case status.
@@ -112,7 +105,7 @@ class HookReporter(BaseReporter):
112
105
  status (TestStatus): test case status
113
106
  """
114
107
  key = self.generate_key(DF.MODULES, module_id, DF.CASES, case_id, DF.STATUS)
115
- self.set_db_value(key, status)
108
+ self.set_doc_value(key, status)
116
109
 
117
110
  def set_case_start_time(self, module_id: str, case_id: str):
118
111
  """Set test case start_time.
@@ -142,7 +135,7 @@ class HookReporter(BaseReporter):
142
135
  status (TestStatus): test module status
143
136
  """
144
137
  key = self.generate_key(DF.MODULES, module_id, DF.STATUS)
145
- self.set_db_value(key, status)
138
+ self.set_doc_value(key, status)
146
139
 
147
140
  def set_module_start_time(self, module_id: str):
148
141
  """Set test module status.
@@ -175,16 +168,20 @@ class HookReporter(BaseReporter):
175
168
  rm_outdated_nodes = self._remove_outdate_node(old_modules, modules_copy, nodes)
176
169
  updated_case_order = self._update_case_order(rm_outdated_nodes, nodes)
177
170
  updated_module_order = self._update_module_order(updated_case_order)
178
- self.set_db_value(key, updated_module_order, is_runstore=False)
171
+ self.set_doc_value(key, updated_module_order, statestore_only=True)
179
172
 
180
173
  def _set_time(self, key: str):
181
174
  current_time = self._statestore.get_field(key)
182
175
  if current_time is None:
183
- self.set_db_value(key, int(time()))
176
+ self.set_doc_value(key, int(time()))
184
177
 
185
178
  def _init_case(
186
- self, item: dict, node_info: NodeInfo, is_use_artifact: bool = False
187
- ) -> dict:
179
+ self,
180
+ item: dict,
181
+ node_info: NodeInfo,
182
+ is_only_runstore: bool = False,
183
+ is_only_statestore: bool = False,
184
+ ):
188
185
  module_default = { # noqa: WPS204
189
186
  DF.STATUS: TestStatus.READY,
190
187
  DF.NAME: self._get_module_name(node_info),
@@ -202,7 +199,7 @@ class HookReporter(BaseReporter):
202
199
  }
203
200
 
204
201
  if item.get(node_info.module_id) is None: # noqa: WPS204
205
- if is_use_artifact:
202
+ if is_only_runstore:
206
203
  module_default[DF.ARTIFACT] = {}
207
204
  item[node_info.module_id] = module_default # noqa: WPS204
208
205
  else:
@@ -212,11 +209,12 @@ class HookReporter(BaseReporter):
212
209
  item[node_info.module_id][DF.STOP_TIME] = None
213
210
  item[node_info.module_id][DF.NAME] = self._get_module_name(node_info)
214
211
 
215
- if is_use_artifact:
212
+ if is_only_runstore:
216
213
  case_default[DF.ARTIFACT] = {}
217
- item[node_info.module_id][DF.CASES][node_info.case_id] = case_default
218
214
 
219
- return item
215
+ if is_only_statestore:
216
+ case_default[DF.DIALOG_BOX] = {}
217
+ item[node_info.module_id][DF.CASES][node_info.case_id] = case_default
220
218
 
221
219
  def _remove_outdate_node(
222
220
  self, old_modules: dict, new_modules: dict, nodes: dict
@@ -6,7 +6,17 @@ from hardpy.pytest_hardpy.utils.progress_calculator import ProgressCalculator
6
6
  from hardpy.pytest_hardpy.utils.const import TestStatus, RunStatus
7
7
  from hardpy.pytest_hardpy.utils.singleton import Singleton
8
8
  from hardpy.pytest_hardpy.utils.config_data import ConfigData
9
- from hardpy.pytest_hardpy.utils.exception import DuplicateSerialNumberError
9
+ from hardpy.pytest_hardpy.utils.exception import (
10
+ DuplicateSerialNumberError,
11
+ DuplicateDialogBoxError,
12
+ )
13
+ from hardpy.pytest_hardpy.utils.dialog_box import (
14
+ DialogBox,
15
+ DialogBoxWidget,
16
+ DialogBoxWidgetType,
17
+ generate_dialog_box_dict,
18
+ get_dialog_box_data,
19
+ )
10
20
 
11
21
  __all__ = [
12
22
  "NodeInfo",
@@ -16,4 +26,10 @@ __all__ = [
16
26
  "Singleton",
17
27
  "ConfigData",
18
28
  "DuplicateSerialNumberError",
29
+ "DuplicateDialogBoxError",
30
+ "DialogBox",
31
+ "DialogBoxWidget",
32
+ "DialogBoxWidgetType",
33
+ "generate_dialog_box_dict",
34
+ "get_dialog_box_data",
19
35
  ]
@@ -1,9 +1,11 @@
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.utils.singleton import Singleton
4
+ from socket import gethostname
5
5
  from pathlib import Path
6
6
 
7
+ from hardpy.pytest_hardpy.utils.singleton import Singleton
8
+
7
9
 
8
10
  class ConfigData(Singleton):
9
11
  """Web connection data storage."""
@@ -17,6 +19,8 @@ class ConfigData(Singleton):
17
19
  self.web_host: str = "0.0.0.0"
18
20
  self.web_port: int = 8000
19
21
  self.tests_dir = Path.cwd()
22
+ self.socket_port: int = 6525
23
+ self.socket_addr: str = gethostname()
20
24
  self._initialized = True
21
25
 
22
26
  @property
@@ -0,0 +1,100 @@
1
+ # Copyright (c) 2024 Everypin
2
+ # GNU General Public License v3.0 (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
3
+
4
+ from enum import Enum
5
+ from dataclasses import dataclass
6
+ from typing import Any
7
+
8
+
9
+ class DialogBoxWidgetType(Enum):
10
+ """Dialog box widget type."""
11
+
12
+ RADIOBUTTON = "radiobutton"
13
+ CHECKBOX = "checkbox"
14
+ TEXT_INPUT = "textinput"
15
+ NUMERIC_INPUT = "numericinput"
16
+
17
+
18
+ @dataclass
19
+ class DialogBoxWidget:
20
+ """Dialog box widget.
21
+
22
+ Args:
23
+ type (DialogBoxWidgetType): widget type
24
+ info (dict | None): widget info
25
+ """
26
+
27
+ type: DialogBoxWidgetType
28
+ info: dict | None = None
29
+
30
+
31
+ @dataclass
32
+ class DialogBox:
33
+ """Dialog box data.
34
+
35
+ Args:
36
+ dialog_text (str): dialog text
37
+ title_bar (str | None): title bar
38
+ widget (DialogBoxWidget | None): widget info
39
+ """
40
+
41
+ dialog_text: str
42
+ title_bar: str | None = None
43
+ widget: DialogBoxWidget | None = None
44
+
45
+
46
+ def generate_dialog_box_dict(dialog_box_data: DialogBox) -> dict:
47
+ """Generate dialog box dictionary.
48
+
49
+ Args:
50
+ dialog_box_data (DialogBox): dialog box data
51
+
52
+ Returns:
53
+ dict: dialog box dictionary
54
+ """
55
+ if dialog_box_data.widget is None:
56
+ data_dict = {
57
+ "title_bar": dialog_box_data.title_bar,
58
+ "dialog_text": dialog_box_data.dialog_text,
59
+ "widget": None,
60
+ }
61
+ else:
62
+ data_dict = {
63
+ "title_bar": dialog_box_data.title_bar,
64
+ "dialog_text": dialog_box_data.dialog_text,
65
+ "widget": {
66
+ "info": dialog_box_data.widget.info,
67
+ "type": dialog_box_data.widget.type.value,
68
+ },
69
+ }
70
+ return data_dict
71
+
72
+
73
+ def get_dialog_box_data(
74
+ input_data: str, widget: DialogBoxWidget | None
75
+ ) -> Any:
76
+ """Get the dialog box data in the correct format.
77
+
78
+ Args:
79
+ input_data (str): input string
80
+ widget (DialogBoxWidget | None): widget info
81
+
82
+ Returns:
83
+ Any: Dialog box data in the correct format
84
+ """
85
+ if widget is None:
86
+ return None
87
+
88
+ if widget.type is None:
89
+ raise ValueError("Widget type is `None`, but widget data is not empty")
90
+
91
+ match widget.type:
92
+ case DialogBoxWidgetType.NUMERIC_INPUT:
93
+ try:
94
+ return float(input_data)
95
+ except ValueError:
96
+ return None
97
+ case DialogBoxWidgetType.TEXT_INPUT:
98
+ return input_data
99
+ case _:
100
+ return None
@@ -14,3 +14,10 @@ class DuplicateSerialNumberError(HardpyError):
14
14
 
15
15
  def __init__(self):
16
16
  super().__init__(self.__doc__) # type: ignore
17
+
18
+
19
+ class DuplicateDialogBoxError(HardpyError):
20
+ """The dialog box has already been determined."""
21
+
22
+ def __init__(self):
23
+ super().__init__(self.__doc__) # type: ignore
@@ -1,12 +1,24 @@
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 re
4
5
  from logging import getLogger
5
6
  from pathlib import Path
7
+ from typing import NamedTuple
6
8
 
7
9
  from pytest import Item, Mark
8
10
 
9
11
 
12
+ class TestDependencyInfo(NamedTuple):
13
+ """Test info."""
14
+
15
+ def __repr__(self) -> str:
16
+ return f"Dependency: {self.module_id}::{self.case_id}"
17
+
18
+ module_id: str
19
+ case_id: str | None
20
+
21
+
10
22
  class NodeInfo(object):
11
23
  """Test node info."""
12
24
 
@@ -22,25 +34,59 @@ class NodeInfo(object):
22
34
  item.parent.own_markers,
23
35
  "module_name",
24
36
  )
37
+
38
+ self._dependency = self._get_dependency_info(
39
+ item.own_markers + item.parent.own_markers
40
+ )
41
+
25
42
  self._module_id = Path(item.parent.nodeid).stem
26
43
  self._case_id = item.name
27
44
 
28
45
  @property
29
46
  def module_id(self):
47
+ """Get module id.
48
+
49
+ Returns:
50
+ str: module id
51
+ """
30
52
  return self._module_id
31
53
 
32
54
  @property
33
55
  def case_id(self):
56
+ """Get case id.
57
+
58
+ Returns:
59
+ str: case id
60
+ """
34
61
  return self._case_id
35
62
 
36
63
  @property
37
64
  def module_name(self):
65
+ """Get module name.
66
+
67
+ Returns:
68
+ str: module name
69
+ """
38
70
  return self._module_name
39
71
 
40
72
  @property
41
73
  def case_name(self):
74
+ """Get case name.
75
+
76
+ Returns:
77
+ str: case name
78
+ """
42
79
  return self._case_name
43
80
 
81
+ @property
82
+ def dependency(self):
83
+ """Get dependency information.
84
+
85
+ Returns:
86
+ TestDependencyInfo | str: Parsed dependency information.
87
+ """
88
+ return self._dependency
89
+
44
90
  def _get_human_name(self, markers: list[Mark], marker_name: str) -> str:
45
91
  """Get human name from markers.
46
92
 
@@ -57,3 +103,23 @@ class NodeInfo(object):
57
103
  return marker.args[0]
58
104
 
59
105
  return ""
106
+
107
+ def _get_dependency_info(self, markers: list[Mark]) -> TestDependencyInfo | str:
108
+ """Extract and parse dependency information.
109
+
110
+ Args:
111
+ markers (list[Mark]): item markers list
112
+ marker_name (str): marker name
113
+
114
+ Returns:
115
+ TestDependencyInfo | str | None: Parsed dependency information.
116
+ """
117
+ dependency_value = self._get_human_name(markers, "dependency")
118
+ dependency_data = re.search(r"(\w+)::(\w+)", dependency_value)
119
+ if dependency_data:
120
+ return TestDependencyInfo(*dependency_data.groups())
121
+ elif re.search(r"^\w+$", dependency_value):
122
+ return TestDependencyInfo(dependency_value, None)
123
+ elif dependency_data is None and dependency_value == "":
124
+ return ""
125
+ raise ValueError
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hardpy
3
- Version: 0.2.0
3
+ Version: 0.4.0
4
4
  Summary: HardPy library for device testing
5
5
  Project-URL: repository, https://github.com/everypindevices/hardpy
6
6
  Author: Everypin
@@ -62,7 +62,7 @@ HardPy is a python library for creating a test bench for devices.
62
62
  HardPy allows you to:
63
63
 
64
64
  * Create test benches for devices using [pytest](https://docs.pytest.org/);
65
- * Use a browser to view, run, and stop tests;
65
+ * Use a browser to view, start, stop, and interact with tests;
66
66
  * Store test results in the [CouchDB](https://couchdb.apache.org/) database.
67
67
 
68
68
  ## To Install
@@ -84,6 +84,7 @@ For Windows, follow the instructions from the
84
84
  [documentation](https://everypinio.github.io/hardpy/documentation/database/#couchdb-instance).
85
85
 
86
86
  Launch CouchDB with Docker.
87
+ The Docker version must be 24.0.0 or higher.
87
88
  Create `couchdb.ini` file:
88
89
 
89
90
  ```ini
@@ -103,6 +104,12 @@ Run the Docker container from folder with couchdb.ini file:
103
104
  docker run --rm --name couchdb -p 5984:5984 -e COUCHDB_USER=dev -e COUCHDB_PASSWORD=dev -v ./couchdb.ini:/opt/couchdb/etc/local.ini couchdb:3.3
104
105
  ```
105
106
 
107
+ Command for Windows:
108
+
109
+ ```bash
110
+ docker run --rm --name couchdb -p 5984:5984 -e COUCHDB_USER=dev -e COUCHDB_PASSWORD=dev -v .\couchdb.ini:/opt/couchdb/etc/local.ini couchdb:3.3.2
111
+ ```
112
+
106
113
  #### Test steps
107
114
 
108
115
  Add simple test to `tests` folder
@@ -1,10 +1,10 @@
1
- hardpy/__init__.py,sha256=RwEQwrdXAtjf2UKOTyXiOUvMKOpXCy7TrJR03V4HY98,864
1
+ hardpy/__init__.py,sha256=kn64nKBEVYJMYJedvIV2sQqR1ucoes_LeO7gemwO7oA,1043
2
2
  hardpy/hardpy_panel/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- hardpy/hardpy_panel/api.py,sha256=ool8MvCH9SFGHooOloboListg1Mas4FciMQsyRjhWGE,1567
4
- hardpy/hardpy_panel/runner.py,sha256=J8c2Pzemwr1Xzs0SOIqLqUNNf_4Jb5BJN_fo4pU3Za4,1866
5
- hardpy/hardpy_panel/frontend/dist/asset-manifest.json,sha256=Z6KDx9WMNghh4d_7w52kTSdEec-lup56JR6JEP3WY94,2824
3
+ hardpy/hardpy_panel/api.py,sha256=zm24Spyhl7bqqJTcfyIydajq0_mqrAaxzac53V-Y_-Q,1979
4
+ hardpy/hardpy_panel/runner.py,sha256=lJFVFAbh-y6utBKW7pEqlbAPgS1PLGTP3s-YRE52Sq4,2121
5
+ hardpy/hardpy_panel/frontend/dist/asset-manifest.json,sha256=dknw2XV7tgYq_ciUOwtYAon3pURFH1LNSEpgbcCDehw,2824
6
6
  hardpy/hardpy_panel/frontend/dist/favicon.ico,sha256=sgIk5PKUKEKBDpkSrc8dJgjpObp0iF82Mec0GpfKId4,15406
7
- hardpy/hardpy_panel/frontend/dist/index.html,sha256=u1IJG5LkBLmaPgL-dYJ4rIfmxzf0xNhmmOupezuobgg,656
7
+ hardpy/hardpy_panel/frontend/dist/index.html,sha256=RLLhIgyucL-mXa6EWwU9_ZH6QFgyUhFAfKuyZ6cVYc0,656
8
8
  hardpy/hardpy_panel/frontend/dist/logo512.png,sha256=-fIMbqX7PYUpheK4kX1C1erRTe_hHZwFQYDLrAbhFRU,34188
9
9
  hardpy/hardpy_panel/frontend/dist/manifest.json,sha256=PfmJlN2JMJtHS6OnhU4b4X5wPQC_yRBdjesjoirObSA,502
10
10
  hardpy/hardpy_panel/frontend/dist/static/css/main.e8a862f1.css,sha256=gNl6kGMBhtswNrUU6X2S6uosRU7xhxqI_p9gsEtBUqE,318244
@@ -21,9 +21,9 @@ hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-all-paths.f63155c9.c
21
21
  hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-all-paths.f63155c9.chunk.js.map,sha256=p1xKHRK4AZutkZsQHiWSNU61tYp7I3iUuyLLm3eqkHQ,2833
22
22
  hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-split-paths-by-size-loader.52a072d3.chunk.js,sha256=Jl5xm_jQ9IXKhCagHHvnIhwYXb379Q5FFBiqPoKdUIE,605
23
23
  hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-split-paths-by-size-loader.52a072d3.chunk.js.map,sha256=amJiG2QaJMRR9Y2M0C2soOqd75xdQHhsVKjwrDSIIT0,2224
24
- hardpy/hardpy_panel/frontend/dist/static/js/main.8ef63e9b.js,sha256=9SXZe8r-m8MAvgrl4PaSoD0o6oBWPHudDGDuyCoGQwY,982299
25
- hardpy/hardpy_panel/frontend/dist/static/js/main.8ef63e9b.js.LICENSE.txt,sha256=ForPNukClWMEP3pF9LMYoU-ve-LsyCH-rYU8eLki_FY,2315
26
- hardpy/hardpy_panel/frontend/dist/static/js/main.8ef63e9b.js.map,sha256=P_8SM0ZMRM_x_RqxwaL6yF0DS7na9I_aMnBgBu8x8Fg,4943986
24
+ hardpy/hardpy_panel/frontend/dist/static/js/main.37744128.js,sha256=ssTeNO5sKL6UzOS2wHRWcbOjD8pp951j5cVNEGMd3Gs,1050817
25
+ hardpy/hardpy_panel/frontend/dist/static/js/main.37744128.js.LICENSE.txt,sha256=ForPNukClWMEP3pF9LMYoU-ve-LsyCH-rYU8eLki_FY,2315
26
+ hardpy/hardpy_panel/frontend/dist/static/js/main.37744128.js.map,sha256=6jCBcnbF5mXljOi7LGADG-lE2NN1oWTo5h5dGdNMBS8,5247867
27
27
  hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-16.520846c6beb41df528c8.eot,sha256=PTCTrQYNHX2hIPUaYWtOKrI30-iQGXt_EGxq6JCXie0,117628
28
28
  hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-16.5c52b39c697f2323ce8b.svg,sha256=lDCQy06aS-9bmhwuFOUs-EdcR8MP2wqwAwky5oamtkQ,509417
29
29
  hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-16.84db1772f4bfb529f64f.woff,sha256=edyqQN0nw4dNBs1pgr7pQB7nJhhR6T_YfklFcG_fHj0,53344
@@ -36,20 +36,20 @@ hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-20.afbadb627d43b7
36
36
  hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-20.e857f5a5132b8bfa71a1.woff,sha256=mQZTxE1PyyAL16VWuASOvXlZFwuI4aCPvbrhfgpdIdU,55356
37
37
  hardpy/hardpy_panel/frontend/dist/static/media/logo_smol.5b16f92447a4a9e80331.png,sha256=E4K7drvhJCg9HcTpRihOXZhVJVBZ7-W97Se-3tDb46o,14485
38
38
  hardpy/pytest_hardpy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- hardpy/pytest_hardpy/plugin.py,sha256=_qVu3F54qikloIGhV6Enb0-m2Oy6h_VBOo4jwNzOLdc,8415
40
- hardpy/pytest_hardpy/pytest_call.py,sha256=wyMDt4AwQC4qg6pYnevQv7FIhIvHNYreQdU1kEenqdY,5910
41
- hardpy/pytest_hardpy/pytest_wrapper.py,sha256=bC8ROwAEjo3TpXpNtHXUS-C_fpIyeCPtgfGBSZ82aI8,3554
39
+ hardpy/pytest_hardpy/plugin.py,sha256=JjVFuAiea5sP_G1kQ1LJKJf2pZ6iWKqJuasu5mU4rWY,11369
40
+ hardpy/pytest_hardpy/pytest_call.py,sha256=ds3Xofm_gbqCVvM99qFonp8l6dbI2UDQ8URqn3A1TWc,8449
41
+ hardpy/pytest_hardpy/pytest_wrapper.py,sha256=18kCuS-TVXcXC2QiMsrbc5gHjv48tIMv0F3xAJCdi_U,4508
42
42
  hardpy/pytest_hardpy/db/__init__.py,sha256=MxDufncz0zgRAxrndvPXXW4NrU7rRP7MzIrR7S5Cwwo,558
43
43
  hardpy/pytest_hardpy/db/base_connector.py,sha256=7KUgPY-GmAo8MFN4OFpG5y3WH1xjohRnpeQ1gxQF1tg,751
44
44
  hardpy/pytest_hardpy/db/base_server.py,sha256=uBnq5zGkzEIq_EGzLw0C8kfDEDvQyN52Y6L41KKL9FQ,397
45
- hardpy/pytest_hardpy/db/base_store.py,sha256=iKh8qN-sPu79Ogp5857TR0t5RbGssC8V7iFAZAF5aFU,2504
46
- hardpy/pytest_hardpy/db/const.py,sha256=ffYW54TP0aNF5LhW3g_2G5kVuvqAMWfuJqNDzWZg2nI,618
45
+ hardpy/pytest_hardpy/db/base_store.py,sha256=DiYaBOwufEOdtDpo9dUb3ZaZ7-c1FInAWjLpUXSEFHA,2668
46
+ hardpy/pytest_hardpy/db/const.py,sha256=b4Hq0gaT8SF5YBg21EIHoF3RMMHD3nRJBpvGmvVYQn0,648
47
47
  hardpy/pytest_hardpy/db/runstore.py,sha256=50amoTIO7OTqd5Ks1_7uTzqjCldLpTapkxbIQOgj1sQ,1023
48
- hardpy/pytest_hardpy/db/schema.py,sha256=iIclTudP0tauTWLYiEW9MMlvBfuWOteA7eRzDU5gKwI,6859
48
+ hardpy/pytest_hardpy/db/schema.py,sha256=AAf1qXEge0Bd2xwwx4A2DBOtUkbE36DTpbsOPczPUZ4,7529
49
49
  hardpy/pytest_hardpy/db/statestore.py,sha256=1BUfA4oqG4vx7z5v_uUYi_Un6YA769JeuShxDicrl9Q,636
50
50
  hardpy/pytest_hardpy/reporter/__init__.py,sha256=RONapygH3c_FyXokAlyCVJXGV2cV_jCYDxLymvvA1uE,322
51
- hardpy/pytest_hardpy/reporter/base.py,sha256=kHYSLVxiq5Fyf4V-xGtgfOS3nImN1j5c13zcvqK1sq0,1343
52
- hardpy/pytest_hardpy/reporter/hook_reporter.py,sha256=_7mM3B0U_vsuGGAKuX7jtuS045XVRouCeF0Q8uSUAwY,10181
51
+ hardpy/pytest_hardpy/reporter/base.py,sha256=M-lwli64ty9FW8HlGEpUyoFsZv48tyNgzPjCWVUrATY,1941
52
+ hardpy/pytest_hardpy/reporter/hook_reporter.py,sha256=kZ3jx--ne9l3a27TmVdZCPBoqy53EuHYg2fHDGuJNes,10068
53
53
  hardpy/pytest_hardpy/reporter/runner_reporter.py,sha256=NXkBIoERqmLI-GYtHavmOWC5t6NIpcAE-NECrUKIAJs,827
54
54
  hardpy/pytest_hardpy/result/__init__.py,sha256=NMeCGx3yh8ds9VpaUpuNFDxbwgYFq3e-o7W6rYIv8uI,346
55
55
  hardpy/pytest_hardpy/result/couchdb_config.py,sha256=QZryfA2QoHIjzbVT3OAD76DCNppCghtRWdZMZ5v7KhY,611
@@ -57,15 +57,16 @@ hardpy/pytest_hardpy/result/report_loader/__init__.py,sha256=FuHuD6IFZyaKj0yu5ur
57
57
  hardpy/pytest_hardpy/result/report_loader/couchdb_loader.py,sha256=1BGncK1NnwYJanm5TYETjMkqR7tmrUfGK8Sgnp2JZC8,2203
58
58
  hardpy/pytest_hardpy/result/report_reader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
59
  hardpy/pytest_hardpy/result/report_reader/couchdb_reader.py,sha256=WqetspIsQzu3iJ_HGo3XNkx4iXj6RC9o_SaRqyT-c-c,5634
60
- hardpy/pytest_hardpy/utils/__init__.py,sha256=IeOr27pgzvMolQtEXJxODJKNdQAFww8EjjW-Gy1Gx2M,684
61
- hardpy/pytest_hardpy/utils/config_data.py,sha256=F8khHsvkEsJjDnoHeLjI0rgsAfETN7nSlEP2snf2kio,990
60
+ hardpy/pytest_hardpy/utils/__init__.py,sha256=nG06N4aT95i7RU-xIzFu18nbz4Jtg-5kJlBtodg8kes,1049
61
+ hardpy/pytest_hardpy/utils/config_data.py,sha256=953nSUndqfiqk6oVMb7GYA4RYCFPIKkPpSthXgKtKKY,1113
62
62
  hardpy/pytest_hardpy/utils/const.py,sha256=rjW1Rzhe2vCr8GeQqeN_pafepGDYhjhY4u1VfTOVI6U,625
63
- hardpy/pytest_hardpy/utils/exception.py,sha256=5GnVkOchSPDEXaOXaruO0YzKXoY7b3Y5mVU5-51ZKRg,457
64
- hardpy/pytest_hardpy/utils/node_info.py,sha256=9aK8X-lNrY3unjHAR-DBS6GFKyo7rEoDH-CTy_WGdFw,1437
63
+ hardpy/pytest_hardpy/utils/dialog_box.py,sha256=TC2kNFOmvu0-Z84aT-sV3IW50Ii5pucoxmIYN-7_csY,2460
64
+ hardpy/pytest_hardpy/utils/exception.py,sha256=VRBYs8zL7r2L1VTe_G336HYpjNdJ_ajwyxioFFhERUk,637
65
+ hardpy/pytest_hardpy/utils/node_info.py,sha256=VnEbhKBNAL5xpuFtJTCg90TmkjkFCQA59F5W2RcOlx4,3157
65
66
  hardpy/pytest_hardpy/utils/progress_calculator.py,sha256=r0qb3p6_yDIyLeCshF3Ceo5pCzd3BoTahL4rCD2oMNw,1041
66
67
  hardpy/pytest_hardpy/utils/singleton.py,sha256=C8cgRDydnG2b5dcN1LCLw4aM-AUMAvJc1W39mTkNWlQ,614
67
- hardpy-0.2.0.dist-info/METADATA,sha256=ZyxZaCBvj2QYXPcwWFvrEvZaOGPKeK1kY8VByYTEtCY,3870
68
- hardpy-0.2.0.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
69
- hardpy-0.2.0.dist-info/entry_points.txt,sha256=q73g5GfznSUpjkayi0SV4uaAtrf7D-7rmDoWoEZmZe0,120
70
- hardpy-0.2.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
71
- hardpy-0.2.0.dist-info/RECORD,,
68
+ hardpy-0.4.0.dist-info/METADATA,sha256=Zy37donDAM87tsAVl6m8Qk7BYIPLf5J-ctoxrTpJowo,4113
69
+ hardpy-0.4.0.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
70
+ hardpy-0.4.0.dist-info/entry_points.txt,sha256=q73g5GfznSUpjkayi0SV4uaAtrf7D-7rmDoWoEZmZe0,120
71
+ hardpy-0.4.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
72
+ hardpy-0.4.0.dist-info/RECORD,,