qase-python-commons 3.1.8__py3-none-any.whl → 3.2.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.
Potentially problematic release.
This version of qase-python-commons might be problematic. Click here for more details.
- qase/commons/client/api_v1_client.py +22 -2
- qase/commons/client/api_v2_client.py +8 -6
- qase/commons/models/__init__.py +0 -2
- qase/commons/models/config/framework.py +44 -0
- qase/commons/models/relation.py +16 -6
- qase/commons/models/result.py +3 -18
- qase/commons/reporters/report.py +7 -1
- {qase_python_commons-3.1.8.dist-info → qase_python_commons-3.2.0.dist-info}/METADATA +2 -2
- {qase_python_commons-3.1.8.dist-info → qase_python_commons-3.2.0.dist-info}/RECORD +11 -12
- {qase_python_commons-3.1.8.dist-info → qase_python_commons-3.2.0.dist-info}/WHEEL +1 -1
- qase/commons/models/suite.py +0 -13
- {qase_python_commons-3.1.8.dist-info → qase_python_commons-3.2.0.dist-info}/top_level.txt +0 -0
|
@@ -8,6 +8,7 @@ from .. import Logger
|
|
|
8
8
|
from .base_api_client import BaseApiClient
|
|
9
9
|
from ..exceptions.reporter import ReporterException
|
|
10
10
|
from ..models import Attachment, Result, Step
|
|
11
|
+
from ..models.config.framework import Video, Trace
|
|
11
12
|
from ..models.config.qaseconfig import QaseConfig
|
|
12
13
|
from ..models.step import StepType
|
|
13
14
|
|
|
@@ -137,6 +138,8 @@ class ApiV1Client(BaseApiClient):
|
|
|
137
138
|
attached = []
|
|
138
139
|
if result.attachments:
|
|
139
140
|
for attachment in result.attachments:
|
|
141
|
+
if self.__should_skip_attachment(attachment, result):
|
|
142
|
+
continue
|
|
140
143
|
attach_id = self._upload_attachment(project_code, attachment)
|
|
141
144
|
if attach_id:
|
|
142
145
|
attached.extend(attach_id)
|
|
@@ -168,8 +171,14 @@ class ApiV1Client(BaseApiClient):
|
|
|
168
171
|
case_data["layer"] = result.get_field('layer')
|
|
169
172
|
|
|
170
173
|
suite = None
|
|
171
|
-
if result.
|
|
172
|
-
|
|
174
|
+
if result.relations is not None and result.relations.suite is not None and len(
|
|
175
|
+
result.relations.suite.data) != 0:
|
|
176
|
+
suites = []
|
|
177
|
+
|
|
178
|
+
for raw in result.relations.suite.data:
|
|
179
|
+
suites.append(raw.title)
|
|
180
|
+
|
|
181
|
+
suite = "\t".join(suites)
|
|
173
182
|
|
|
174
183
|
if result.get_field('suite'):
|
|
175
184
|
suite = result.get_field('suite')
|
|
@@ -278,3 +287,14 @@ class ApiV1Client(BaseApiClient):
|
|
|
278
287
|
self.__authors[author] = authors.result.entities[0].author_id
|
|
279
288
|
|
|
280
289
|
return authors.result.entities[0].author_id
|
|
290
|
+
|
|
291
|
+
def __should_skip_attachment(self, attachment, result):
|
|
292
|
+
if (self.config.framework.playwright.video == Video.failed and
|
|
293
|
+
result.execution.status != 'failed' and
|
|
294
|
+
attachment.file_name == 'video.webm'):
|
|
295
|
+
return True
|
|
296
|
+
if (self.config.framework.playwright.trace == Trace.failed and
|
|
297
|
+
result.execution.status != 'failed' and
|
|
298
|
+
attachment.file_name == 'trace.zip'):
|
|
299
|
+
return True
|
|
300
|
+
return False
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Dict
|
|
2
2
|
|
|
3
3
|
import certifi
|
|
4
|
-
from qase.api_client_v2 import ResultsApi
|
|
4
|
+
from qase.api_client_v2 import ResultsApi, ResultCreateFields
|
|
5
5
|
from qase.api_client_v2.api_client import ApiClient
|
|
6
6
|
from qase.api_client_v2.configuration import Configuration
|
|
7
7
|
from qase.api_client_v2.models.create_results_request_v2 import CreateResultsRequestV2
|
|
@@ -75,23 +75,25 @@ class ApiV2Client(ApiV1Client):
|
|
|
75
75
|
execution=ResultExecution(start_time=result.execution.start_time, end_time=result.execution.end_time,
|
|
76
76
|
status=result.execution.status, duration=result.execution.duration,
|
|
77
77
|
stacktrace=result.execution.stacktrace, thread=result.execution.thread),
|
|
78
|
-
fields=result.fields,
|
|
78
|
+
fields=ResultCreateFields.from_dict(result.fields),
|
|
79
79
|
attachments=[attach.hash for attach in attached],
|
|
80
80
|
steps=steps,
|
|
81
|
-
|
|
81
|
+
steps_type=ResultStepsType.CLASSIC,
|
|
82
82
|
params=result.params,
|
|
83
|
+
param_groups=result.param_groups,
|
|
83
84
|
muted=False,
|
|
84
85
|
message=result.message,
|
|
85
86
|
)
|
|
86
87
|
|
|
87
|
-
if result.
|
|
88
|
+
if result.relations is not None and result.relations.suite is not None and len(
|
|
89
|
+
result.relations.suite.data) != 0:
|
|
88
90
|
data = []
|
|
89
91
|
root_suite = self.config.root_suite
|
|
90
92
|
if root_suite:
|
|
91
93
|
data.append(RelationSuiteItem(title=root_suite))
|
|
92
94
|
|
|
93
|
-
for
|
|
94
|
-
data.append(RelationSuiteItem(title=
|
|
95
|
+
for raw in result.relations.suite.data:
|
|
96
|
+
data.append(RelationSuiteItem(title=raw.title))
|
|
95
97
|
|
|
96
98
|
result_model_v2.relations = ResultRelations(suite=RelationSuite(data=data))
|
|
97
99
|
|
qase/commons/models/__init__.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from .result import Result, Field
|
|
2
2
|
from .run import Run
|
|
3
3
|
from .attachment import Attachment
|
|
4
|
-
from .suite import Suite
|
|
5
4
|
from .relation import Relation
|
|
6
5
|
from .step import Step
|
|
7
6
|
from .runtime import Runtime
|
|
@@ -10,7 +9,6 @@ __all__ = [
|
|
|
10
9
|
Result,
|
|
11
10
|
Run,
|
|
12
11
|
Attachment,
|
|
13
|
-
Suite,
|
|
14
12
|
Relation,
|
|
15
13
|
Step,
|
|
16
14
|
Runtime,
|
|
@@ -1,7 +1,22 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from typing import Type, Union
|
|
3
|
+
|
|
1
4
|
from ..basemodel import BaseModel
|
|
2
5
|
from ... import QaseUtils
|
|
3
6
|
|
|
4
7
|
|
|
8
|
+
class Video(Enum):
|
|
9
|
+
off = "off"
|
|
10
|
+
on = "on"
|
|
11
|
+
failed = "retain-on-failure"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Trace(Enum):
|
|
15
|
+
off = "off"
|
|
16
|
+
on = "on"
|
|
17
|
+
failed = "retain-on-failure"
|
|
18
|
+
|
|
19
|
+
|
|
5
20
|
class PytestConfig(BaseModel):
|
|
6
21
|
capture_logs: bool = None
|
|
7
22
|
|
|
@@ -12,8 +27,37 @@ class PytestConfig(BaseModel):
|
|
|
12
27
|
self.capture_logs = QaseUtils.parse_bool(capture_logs)
|
|
13
28
|
|
|
14
29
|
|
|
30
|
+
class PlaywrightConfig(BaseModel):
|
|
31
|
+
output_dir: str = None
|
|
32
|
+
video: Video = None
|
|
33
|
+
trace: Trace = None
|
|
34
|
+
|
|
35
|
+
def __init__(self):
|
|
36
|
+
self.output_dir = "test-results"
|
|
37
|
+
self.video = Video.off
|
|
38
|
+
self.trace = Trace.off
|
|
39
|
+
|
|
40
|
+
def set_output_dir(self, output_dir: str):
|
|
41
|
+
self.output_dir = output_dir
|
|
42
|
+
|
|
43
|
+
def set_video(self, value: str):
|
|
44
|
+
self.video = self.__set_mode(Video, value)
|
|
45
|
+
|
|
46
|
+
def set_trace(self, value: str):
|
|
47
|
+
self.trace = self.__set_mode(Trace, value)
|
|
48
|
+
|
|
49
|
+
@staticmethod
|
|
50
|
+
def __set_mode(enum_class: Type[Union[Video, Trace]], value: str):
|
|
51
|
+
for mode in enum_class:
|
|
52
|
+
if mode.value == value:
|
|
53
|
+
return mode
|
|
54
|
+
return None
|
|
55
|
+
|
|
56
|
+
|
|
15
57
|
class Framework(BaseModel):
|
|
16
58
|
pytest: PytestConfig = None
|
|
59
|
+
playwright: PlaywrightConfig = None
|
|
17
60
|
|
|
18
61
|
def __init__(self):
|
|
19
62
|
self.pytest = PytestConfig()
|
|
63
|
+
self.playwright = PlaywrightConfig()
|
qase/commons/models/relation.py
CHANGED
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
from .basemodel import BaseModel
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
class
|
|
5
|
-
def __init__(self,
|
|
6
|
-
self.
|
|
4
|
+
class SuiteData(BaseModel):
|
|
5
|
+
def __init__(self, title: str) -> None:
|
|
6
|
+
self.public_id = None
|
|
7
7
|
self.title = title
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
class RelationSuite(BaseModel):
|
|
11
|
+
def __init__(self) -> None:
|
|
12
|
+
self.data = []
|
|
13
|
+
|
|
14
|
+
def add_data(self, data: SuiteData) -> None:
|
|
15
|
+
self.data.append(data)
|
|
16
|
+
|
|
17
|
+
|
|
10
18
|
class Relation(BaseModel):
|
|
11
|
-
def __init__(self
|
|
12
|
-
self.
|
|
13
|
-
|
|
19
|
+
def __init__(self):
|
|
20
|
+
self.suite = RelationSuite()
|
|
21
|
+
|
|
22
|
+
def add_suite(self, suite: SuiteData) -> None:
|
|
23
|
+
self.suite.add_data(suite)
|
qase/commons/models/result.py
CHANGED
|
@@ -4,7 +4,6 @@ import uuid
|
|
|
4
4
|
from typing import Type, Optional, Union, Dict, List
|
|
5
5
|
from .basemodel import BaseModel
|
|
6
6
|
from .step import Step
|
|
7
|
-
from .suite import Suite
|
|
8
7
|
from .attachment import Attachment
|
|
9
8
|
from .relation import Relation
|
|
10
9
|
from .. import QaseUtils
|
|
@@ -79,10 +78,9 @@ class Result(BaseModel):
|
|
|
79
78
|
self.params: Optional[dict] = {}
|
|
80
79
|
self.param_groups: Optional[List[List[str]]] = []
|
|
81
80
|
self.author: Optional[str] = None
|
|
82
|
-
self.relations:
|
|
81
|
+
self.relations: Type[Relation] = None
|
|
83
82
|
self.muted: bool = False
|
|
84
83
|
self.message: Optional[str] = None
|
|
85
|
-
self.suite: Optional[Type[Suite]] = None
|
|
86
84
|
QaseUtils.get_host_data()
|
|
87
85
|
|
|
88
86
|
def add_message(self, message: str) -> None:
|
|
@@ -97,20 +95,14 @@ class Result(BaseModel):
|
|
|
97
95
|
def add_attachment(self, attachment: Attachment) -> None:
|
|
98
96
|
self.attachments.append(attachment)
|
|
99
97
|
|
|
100
|
-
def add_relation(self, relation: Type[Relation]) -> None:
|
|
101
|
-
self.relations.append(relation)
|
|
102
|
-
|
|
103
98
|
def add_param(self, key: str, value: str) -> None:
|
|
104
99
|
self.params[key] = value
|
|
105
100
|
|
|
106
101
|
def add_param_groups(self, values: List[str]) -> None:
|
|
107
102
|
self.param_groups.append(values)
|
|
108
103
|
|
|
109
|
-
def
|
|
110
|
-
self.relations
|
|
111
|
-
|
|
112
|
-
def add_suite(self, suite: Type[Suite]) -> None:
|
|
113
|
-
self.suite = suite
|
|
104
|
+
def set_relation(self, relation: Relation) -> None:
|
|
105
|
+
self.relations = relation
|
|
114
106
|
|
|
115
107
|
def get_status(self) -> Optional[str]:
|
|
116
108
|
return self.execution.status
|
|
@@ -127,17 +119,10 @@ class Result(BaseModel):
|
|
|
127
119
|
return None
|
|
128
120
|
|
|
129
121
|
def get_testops_id(self) -> Optional[int]:
|
|
130
|
-
if self.testops_id is None:
|
|
131
|
-
# Hack for old API
|
|
132
|
-
return 0
|
|
133
122
|
return self.testops_id
|
|
134
123
|
|
|
135
124
|
def get_duration(self) -> int:
|
|
136
125
|
return self.execution.duration
|
|
137
126
|
|
|
138
|
-
def get_suite_title(self) -> Optional[str]:
|
|
139
|
-
if self.suite:
|
|
140
|
-
return self.suite.title
|
|
141
|
-
|
|
142
127
|
def set_run_id(self, run_id: str) -> None:
|
|
143
128
|
self.run_id = run_id
|
qase/commons/reporters/report.py
CHANGED
|
@@ -68,13 +68,19 @@ class QaseReport:
|
|
|
68
68
|
mode = "w"
|
|
69
69
|
if isinstance(attachment.content, bytes):
|
|
70
70
|
mode = "wb"
|
|
71
|
-
|
|
71
|
+
|
|
72
|
+
file_path = f"{self.report_path}/attachments/{attachment.id}-{attachment.file_name}"
|
|
73
|
+
with open(file_path, mode) as f:
|
|
72
74
|
f.write(attachment.content)
|
|
73
75
|
# Clear content to save memory and avoid double writing
|
|
74
76
|
attachment.content = None
|
|
77
|
+
attachment.file_path = file_path
|
|
78
|
+
|
|
75
79
|
elif attachment.file_path:
|
|
80
|
+
file_path = f"{self.report_path}/attachments/{attachment.id}-{attachment.file_name}"
|
|
76
81
|
shutil.copy2(os.path.abspath(attachment.file_path),
|
|
77
82
|
f"{self.report_path}/attachments/{attachment.id}-{attachment.file_name}")
|
|
83
|
+
attachment.file_path = file_path
|
|
78
84
|
|
|
79
85
|
def _persist_attachments_in_steps(self, steps: list):
|
|
80
86
|
for step in steps:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: qase-python-commons
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.2.0
|
|
4
4
|
Summary: A library for Qase TestOps and Qase Report
|
|
5
5
|
Author-email: Qase Team <support@qase.io>
|
|
6
6
|
Project-URL: Homepage, https://github.com/qase-tms/qase-python/tree/master/qase-python-commons
|
|
@@ -23,7 +23,7 @@ Description-Content-Type: text/markdown
|
|
|
23
23
|
Requires-Dist: certifi>=2024.2.2
|
|
24
24
|
Requires-Dist: attrs>=23.2.0
|
|
25
25
|
Requires-Dist: qase-api-client~=1.1.1
|
|
26
|
-
Requires-Dist: qase-api-v2-client~=1.
|
|
26
|
+
Requires-Dist: qase-api-v2-client~=1.1.0
|
|
27
27
|
Requires-Dist: more-itertools
|
|
28
28
|
Provides-Extra: testing
|
|
29
29
|
Requires-Dist: pytest; extra == "testing"
|
|
@@ -3,23 +3,22 @@ qase/commons/config.py,sha256=meRRgDrsA9qQ9fZR4fnP0VdngrKiGcHF9nnJkf3eJpg,8320
|
|
|
3
3
|
qase/commons/loader.py,sha256=-MMY4HgSI6q1xq3NaJoq_w4liM73qdFKjYLVCT1E7Pc,1064
|
|
4
4
|
qase/commons/logger.py,sha256=ka5chQYBXLUB5pM4YHDBo3QCZfBTGMtC3H33tI4NbPQ,1027
|
|
5
5
|
qase/commons/utils.py,sha256=OOr6kQ5hPZEyHXwbwiTOTkonRxmmtkyZPPGqXQKp5vY,2799
|
|
6
|
-
qase/commons/client/api_v1_client.py,sha256=
|
|
7
|
-
qase/commons/client/api_v2_client.py,sha256=
|
|
6
|
+
qase/commons/client/api_v1_client.py,sha256=YIaRWu9txJoIljcvPJ-4MECqgw72oae-o6z0Bl9t-Jo,12715
|
|
7
|
+
qase/commons/client/api_v2_client.py,sha256=sh748gx9jjqBm42IrSeOduBWs6jKzz5QqCWSKcURDOA,7440
|
|
8
8
|
qase/commons/client/base_api_client.py,sha256=H8JnjqSrBFNfghDd3T3zxYOyKYHYe9QiJQXol1JqdQk,2613
|
|
9
9
|
qase/commons/exceptions/reporter.py,sha256=dP-Mwcq8HKBOjgu3YqhyULDmDGU09BmT6Fh9HjICaUc,45
|
|
10
|
-
qase/commons/models/__init__.py,sha256=
|
|
10
|
+
qase/commons/models/__init__.py,sha256=FTt5dYASBX4r6-tQi-_JAUVx4uvJs9GTxROdAZEV6Jo,272
|
|
11
11
|
qase/commons/models/attachment.py,sha256=Rjq1mAP11uk7TN2RrtImntw6DUMV7U0R-44TYj8O5j0,1432
|
|
12
12
|
qase/commons/models/basemodel.py,sha256=nyDSXhpQUecKdzhB-eWqujmso20oXB9p_42qpOsGVuQ,213
|
|
13
|
-
qase/commons/models/relation.py,sha256=
|
|
14
|
-
qase/commons/models/result.py,sha256=
|
|
13
|
+
qase/commons/models/relation.py,sha256=HymHeh1uBcoQnTs4Vra7WJ_KFkhryj5o7cShjoGQImI,511
|
|
14
|
+
qase/commons/models/result.py,sha256=RWryOX85T-_T3AngrGuREtwmPq6FyOPvM77H949vm1I,3953
|
|
15
15
|
qase/commons/models/run.py,sha256=KkplvlHJNvVLORzVkdz5mHsLFBTUAdtuEYCqCy_RcvU,2469
|
|
16
16
|
qase/commons/models/runtime.py,sha256=mfK-mOViD1orXOx-jP6nIgtnN0tUmRYY1aMH0qFDmXA,1287
|
|
17
17
|
qase/commons/models/step.py,sha256=M-btRYZ4febYavDhwFqmKcCdLAgrhtuv7E_M3TKZdfg,4281
|
|
18
|
-
qase/commons/models/suite.py,sha256=Z2tlxdeIsuzjIoPnuyVq23pt59Yt6LVmofcew5Njk_s,348
|
|
19
18
|
qase/commons/models/config/api.py,sha256=IyYY2f3ncESUAEGvkE3-meatebBFJdvgo7KNOQnxLE0,288
|
|
20
19
|
qase/commons/models/config/batch.py,sha256=X0H8SVOCCD2pV6LSMqjI-tIjRcLifnrM5MareK2FhQw,321
|
|
21
20
|
qase/commons/models/config/connection.py,sha256=wK2fGjc0G0rMVVhPnjw_t_M1YWZwANlhwl-awmI7XSo,516
|
|
22
|
-
qase/commons/models/config/framework.py,sha256=
|
|
21
|
+
qase/commons/models/config/framework.py,sha256=N4vSS1EAu8LEzYSbpy3Z4rNY2DbpWQ4Mh1mknRfMDRM,1432
|
|
23
22
|
qase/commons/models/config/plan.py,sha256=JbAY7qfGXYreXOLa32OLxw6z0paeCCf87-2b1m8xkks,137
|
|
24
23
|
qase/commons/models/config/qaseconfig.py,sha256=-tuTsd6s4YSAkSca7vvNaFZbqhbWkxuw-mjeqhwmjlc,1722
|
|
25
24
|
qase/commons/models/config/report.py,sha256=g3Z2B3Tewaasjc1TMj2mkXxz0Zc1C39sHeTXH0MRM2Y,497
|
|
@@ -31,10 +30,10 @@ qase/commons/profilers/network.py,sha256=zKNBnTQG4BMg8dn8O--tQzQLpu-qs5ADhHEnqIa
|
|
|
31
30
|
qase/commons/profilers/sleep.py,sha256=HT6h0R-2XHZAoBYRxS2T_KC8RrnEoVjP7MXusaE4Nec,1624
|
|
32
31
|
qase/commons/reporters/__init__.py,sha256=J0aNLzb_MPPT_zF8BtX_w9nj_U7Ad06RGpyWK5Pxq1o,169
|
|
33
32
|
qase/commons/reporters/core.py,sha256=0x5G-KVfEOWyXiXaX5__7JBIr3Rxy8vhy0cByUSZUc0,8021
|
|
34
|
-
qase/commons/reporters/report.py,sha256=
|
|
33
|
+
qase/commons/reporters/report.py,sha256=zyGeUOcJCOEoGtsewCOf3kypbPttJH7EM-LmZ_Y5huY,4829
|
|
35
34
|
qase/commons/reporters/testops.py,sha256=f5BcorFwIK5BSeA4Rv4IKDddkWrAXL_w-Y5Xn--NdYs,6264
|
|
36
35
|
qase/commons/validators/base.py,sha256=wwSn-4YiuXtfGMGnSKgo9Vm5hAKevVmmfd2Ro6Q7MYQ,173
|
|
37
|
-
qase_python_commons-3.
|
|
38
|
-
qase_python_commons-3.
|
|
39
|
-
qase_python_commons-3.
|
|
40
|
-
qase_python_commons-3.
|
|
36
|
+
qase_python_commons-3.2.0.dist-info/METADATA,sha256=7HxmqCpafL3UdsAHcKASQNFBnrubf9S3Crud2NQM8QQ,1859
|
|
37
|
+
qase_python_commons-3.2.0.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
38
|
+
qase_python_commons-3.2.0.dist-info/top_level.txt,sha256=Mn5aFk7H7Uia4s1NRDsvebu8vCrFy9nOuRIBfkIY5kQ,5
|
|
39
|
+
qase_python_commons-3.2.0.dist-info/RECORD,,
|
qase/commons/models/suite.py
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import uuid
|
|
2
|
-
|
|
3
|
-
from typing import List, Optional
|
|
4
|
-
|
|
5
|
-
from .basemodel import BaseModel
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Suite(BaseModel):
|
|
9
|
-
def __init__(self, title: str, description: Optional[str] = None, parent_id: Optional[str] = None):
|
|
10
|
-
self.title = title
|
|
11
|
-
self.description = description
|
|
12
|
-
self.parent_id = parent_id
|
|
13
|
-
self.id = str(uuid.uuid4())
|
|
File without changes
|