qase-python-commons 3.3.2__py3-none-any.whl → 3.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.
Potentially problematic release.
This version of qase-python-commons might be problematic. Click here for more details.
- qase/commons/client/api_v1_client.py +6 -171
- qase/commons/client/api_v2_client.py +3 -3
- qase/commons/config.py +0 -5
- qase/commons/models/__init__.py +2 -3
- qase/commons/models/config/testops.py +0 -4
- qase/commons/models/result.py +3 -89
- qase/commons/reporters/core.py +3 -15
- qase/commons/reporters/report.py +3 -3
- qase/commons/reporters/testops.py +11 -15
- {qase_python_commons-3.3.2.dist-info → qase_python_commons-3.4.0.dist-info}/METADATA +3 -3
- {qase_python_commons-3.3.2.dist-info → qase_python_commons-3.4.0.dist-info}/RECORD +13 -13
- {qase_python_commons-3.3.2.dist-info → qase_python_commons-3.4.0.dist-info}/WHEEL +1 -1
- {qase_python_commons-3.3.2.dist-info → qase_python_commons-3.4.0.dist-info}/top_level.txt +0 -0
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
from datetime import datetime, timezone
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import Union
|
|
3
3
|
|
|
4
4
|
import certifi
|
|
5
5
|
from qase.api_client_v1 import ApiClient, ProjectsApi, Project, EnvironmentsApi, RunsApi, AttachmentsApi, \
|
|
6
|
-
AttachmentGet, RunCreate
|
|
6
|
+
AttachmentGet, RunCreate
|
|
7
7
|
from qase.api_client_v1.configuration import Configuration
|
|
8
8
|
from .. import Logger
|
|
9
9
|
from .base_api_client import BaseApiClient
|
|
10
10
|
from ..exceptions.reporter import ReporterException
|
|
11
|
-
from ..models import Attachment
|
|
11
|
+
from ..models import Attachment
|
|
12
12
|
from ..models.config.framework import Video, Trace
|
|
13
13
|
from ..models.config.qaseconfig import QaseConfig
|
|
14
|
-
from ..models.step import StepType
|
|
15
14
|
|
|
16
15
|
|
|
17
16
|
class ApiV1Client(BaseApiClient):
|
|
@@ -123,173 +122,6 @@ class ApiV1Client(BaseApiClient):
|
|
|
123
122
|
return True
|
|
124
123
|
return False
|
|
125
124
|
|
|
126
|
-
def send_results(self, project_code: str, run_id: str, results: []) -> None:
|
|
127
|
-
api_results = ResultsApi(self.client)
|
|
128
|
-
results_to_send = [self._prepare_result(project_code, result) for result in results]
|
|
129
|
-
self.logger.log_debug(f"Sending results for run {run_id}: {results_to_send}")
|
|
130
|
-
api_results.create_result_bulk(
|
|
131
|
-
code=project_code,
|
|
132
|
-
id=run_id,
|
|
133
|
-
resultcreate_bulk=ResultcreateBulk(
|
|
134
|
-
results=results_to_send
|
|
135
|
-
)
|
|
136
|
-
)
|
|
137
|
-
self.logger.log_debug(f"Results for run {run_id} sent successfully")
|
|
138
|
-
|
|
139
|
-
def _prepare_result(self, project_code: str, result: InternalResult) -> Dict:
|
|
140
|
-
attached = []
|
|
141
|
-
if result.attachments:
|
|
142
|
-
for attachment in result.attachments:
|
|
143
|
-
if self.__should_skip_attachment(attachment, result):
|
|
144
|
-
continue
|
|
145
|
-
attach_id = self._upload_attachment(project_code, attachment)
|
|
146
|
-
if attach_id:
|
|
147
|
-
attached.extend(attach_id)
|
|
148
|
-
|
|
149
|
-
steps = []
|
|
150
|
-
for step in result.steps:
|
|
151
|
-
prepared = self._prepare_step(project_code, step)
|
|
152
|
-
steps.append(prepared)
|
|
153
|
-
|
|
154
|
-
case_data = {
|
|
155
|
-
"title": result.get_title(),
|
|
156
|
-
"description": result.get_field('description'),
|
|
157
|
-
"preconditions": result.get_field('preconditions'),
|
|
158
|
-
"postconditions": result.get_field('postconditions'),
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
for key, param in result.params.items():
|
|
162
|
-
# Hack to match old TestOps API
|
|
163
|
-
if param == "":
|
|
164
|
-
result.params[key] = "empty"
|
|
165
|
-
|
|
166
|
-
if result.get_field('severity'):
|
|
167
|
-
case_data["severity"] = result.get_field('severity')
|
|
168
|
-
|
|
169
|
-
if result.get_field('priority'):
|
|
170
|
-
case_data["priority"] = result.get_field('priority')
|
|
171
|
-
|
|
172
|
-
if result.get_field('layer'):
|
|
173
|
-
case_data["layer"] = result.get_field('layer')
|
|
174
|
-
|
|
175
|
-
suite = None
|
|
176
|
-
if result.relations is not None and result.relations.suite is not None and len(
|
|
177
|
-
result.relations.suite.data) != 0:
|
|
178
|
-
suites = []
|
|
179
|
-
|
|
180
|
-
for raw in result.relations.suite.data:
|
|
181
|
-
suites.append(raw.title)
|
|
182
|
-
|
|
183
|
-
suite = "\t".join(suites)
|
|
184
|
-
|
|
185
|
-
if result.get_field('suite'):
|
|
186
|
-
suite = result.get_field('suite')
|
|
187
|
-
|
|
188
|
-
root_suite = self.config.root_suite
|
|
189
|
-
if root_suite:
|
|
190
|
-
suite = f"{root_suite}\t{suite}"
|
|
191
|
-
|
|
192
|
-
if suite:
|
|
193
|
-
case_data["suite_title"] = suite
|
|
194
|
-
|
|
195
|
-
result_model = {
|
|
196
|
-
"status": result.execution.status,
|
|
197
|
-
"stacktrace": result.execution.stacktrace,
|
|
198
|
-
"time_ms": result.execution.duration,
|
|
199
|
-
"comment": result.message,
|
|
200
|
-
"attachments": [attach.hash for attach in attached],
|
|
201
|
-
"steps": steps,
|
|
202
|
-
"param": result.params,
|
|
203
|
-
"param_groups": result.param_groups,
|
|
204
|
-
"defect": self.config.testops.defect,
|
|
205
|
-
"case": case_data
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
test_ops_id = result.get_testops_id()
|
|
209
|
-
|
|
210
|
-
if test_ops_id:
|
|
211
|
-
result_model["case_id"] = test_ops_id
|
|
212
|
-
|
|
213
|
-
if result.get_field('author'):
|
|
214
|
-
author_id = self._get_author_id(result.get_field('author'))
|
|
215
|
-
if author_id:
|
|
216
|
-
result_model["author_id"] = author_id
|
|
217
|
-
|
|
218
|
-
self.logger.log_debug(f"Prepared result: {result_model}")
|
|
219
|
-
|
|
220
|
-
return result_model
|
|
221
|
-
|
|
222
|
-
def _prepare_step(self, project_code: str, step: Step) -> Dict:
|
|
223
|
-
prepared_children = []
|
|
224
|
-
|
|
225
|
-
try:
|
|
226
|
-
prepared_step = {"time": step.execution.duration, "status": step.execution.status}
|
|
227
|
-
|
|
228
|
-
if step.execution.status == 'untested':
|
|
229
|
-
prepared_step["status"] = 'passed'
|
|
230
|
-
|
|
231
|
-
if step.execution.status == 'skipped':
|
|
232
|
-
prepared_step["status"] = 'blocked'
|
|
233
|
-
|
|
234
|
-
if step.step_type == StepType.TEXT:
|
|
235
|
-
prepared_step['action'] = step.data.action
|
|
236
|
-
if step.data.expected_result:
|
|
237
|
-
prepared_step['expected_result'] = step.data.expected_result
|
|
238
|
-
|
|
239
|
-
if step.step_type == StepType.REQUEST:
|
|
240
|
-
prepared_step['action'] = step.data.request_method + " " + step.data.request_url
|
|
241
|
-
if step.data.request_body:
|
|
242
|
-
step.attachments.append(
|
|
243
|
-
Attachment(file_name='request_body.txt', content=step.data.request_body, mime_type='text/plain',
|
|
244
|
-
temporary=True))
|
|
245
|
-
if step.data.request_headers:
|
|
246
|
-
step.attachments.append(
|
|
247
|
-
Attachment(file_name='request_headers.txt', content=step.data.request_headers,
|
|
248
|
-
mime_type='text/plain', temporary=True))
|
|
249
|
-
if step.data.response_body:
|
|
250
|
-
step.attachments.append(Attachment(file_name='response_body.txt', content=step.data.response_body,
|
|
251
|
-
mime_type='text/plain', temporary=True))
|
|
252
|
-
if step.data.response_headers:
|
|
253
|
-
step.attachments.append(
|
|
254
|
-
Attachment(file_name='response_headers.txt', content=step.data.response_headers,
|
|
255
|
-
mime_type='text/plain', temporary=True))
|
|
256
|
-
|
|
257
|
-
if step.step_type == StepType.GHERKIN:
|
|
258
|
-
prepared_step['action'] = step.data.keyword
|
|
259
|
-
|
|
260
|
-
if step.step_type == StepType.SLEEP:
|
|
261
|
-
prepared_step['action'] = f"Sleep for {step.data.duration} seconds"
|
|
262
|
-
|
|
263
|
-
if step.attachments:
|
|
264
|
-
uploaded_attachments = []
|
|
265
|
-
for file in step.attachments:
|
|
266
|
-
attach_id = self._upload_attachment(project_code, file)
|
|
267
|
-
if attach_id:
|
|
268
|
-
uploaded_attachments.extend(attach_id)
|
|
269
|
-
prepared_step['attachments'] = [attach.hash for attach in uploaded_attachments]
|
|
270
|
-
|
|
271
|
-
if step.steps:
|
|
272
|
-
for substep in step.steps:
|
|
273
|
-
prepared_children.append(self._prepare_step(project_code, substep))
|
|
274
|
-
prepared_step["steps"] = prepared_children
|
|
275
|
-
return prepared_step
|
|
276
|
-
except Exception as e:
|
|
277
|
-
self.logger.log(f"Error at preparing step: {e}", "error")
|
|
278
|
-
raise ReporterException(e)
|
|
279
|
-
|
|
280
|
-
def _get_author_id(self, author: str) -> Union[str, None]:
|
|
281
|
-
if author in self.__authors:
|
|
282
|
-
return self.__authors[author]
|
|
283
|
-
|
|
284
|
-
author_api = AuthorsApi(self.client)
|
|
285
|
-
authors = author_api.get_authors(search=author)
|
|
286
|
-
if authors.result.total == 0:
|
|
287
|
-
return None
|
|
288
|
-
|
|
289
|
-
self.__authors[author] = authors.result.entities[0].author_id
|
|
290
|
-
|
|
291
|
-
return authors.result.entities[0].author_id
|
|
292
|
-
|
|
293
125
|
def __should_skip_attachment(self, attachment, result):
|
|
294
126
|
if (self.config.framework.playwright.video == Video.failed and
|
|
295
127
|
result.execution.status != 'failed' and
|
|
@@ -300,3 +132,6 @@ class ApiV1Client(BaseApiClient):
|
|
|
300
132
|
attachment.file_name == 'trace.zip'):
|
|
301
133
|
return True
|
|
302
134
|
return False
|
|
135
|
+
|
|
136
|
+
def send_results(self, project_code: str, run_id: str, results: []) -> None:
|
|
137
|
+
raise NotImplementedError("use ApiV2Client instead")
|
|
@@ -17,7 +17,7 @@ from .api_v1_client import ApiV1Client
|
|
|
17
17
|
from .. import Logger
|
|
18
18
|
from ..exceptions.reporter import ReporterException
|
|
19
19
|
from ..models.config.framework import Video, Trace
|
|
20
|
-
from ..models import Attachment,
|
|
20
|
+
from ..models import Attachment, Result
|
|
21
21
|
from ..models.config.qaseconfig import QaseConfig
|
|
22
22
|
from ..models.step import StepType, Step
|
|
23
23
|
|
|
@@ -53,7 +53,7 @@ class ApiV2Client(ApiV1Client):
|
|
|
53
53
|
create_results_request_v2=CreateResultsRequestV2(results=results_to_send))
|
|
54
54
|
self.logger.log_debug(f"Results for run {run_id} sent successfully")
|
|
55
55
|
|
|
56
|
-
def _prepare_result(self, project_code: str, result:
|
|
56
|
+
def _prepare_result(self, project_code: str, result: Result) -> ResultCreate:
|
|
57
57
|
attached = []
|
|
58
58
|
if result.attachments:
|
|
59
59
|
for attachment in result.attachments:
|
|
@@ -76,7 +76,7 @@ class ApiV2Client(ApiV1Client):
|
|
|
76
76
|
result_model_v2 = ResultCreate(
|
|
77
77
|
title=result.get_title(),
|
|
78
78
|
signature=result.signature,
|
|
79
|
-
|
|
79
|
+
testops_ids=result.get_testops_ids(),
|
|
80
80
|
execution=ResultExecution(status=result.execution.status, duration=result.execution.duration,
|
|
81
81
|
start_time=result.execution.start_time, end_time=result.execution.end_time,
|
|
82
82
|
stacktrace=result.execution.stacktrace, thread=result.execution.thread),
|
qase/commons/config.py
CHANGED
qase/commons/models/__init__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from .result import Result,
|
|
1
|
+
from .result import Result, Field
|
|
2
2
|
from .run import Run
|
|
3
3
|
from .attachment import Attachment
|
|
4
4
|
from .relation import Relation
|
|
@@ -12,6 +12,5 @@ __all__ = [
|
|
|
12
12
|
Relation,
|
|
13
13
|
Step,
|
|
14
14
|
Runtime,
|
|
15
|
-
Field
|
|
16
|
-
InternalResult
|
|
15
|
+
Field
|
|
17
16
|
]
|
|
@@ -20,13 +20,9 @@ class TestopsConfig(BaseModel):
|
|
|
20
20
|
self.batch = BatchConfig()
|
|
21
21
|
self.plan = PlanConfig()
|
|
22
22
|
self.defect = False
|
|
23
|
-
self.use_v2 = True
|
|
24
23
|
|
|
25
24
|
def set_project(self, project: str):
|
|
26
25
|
self.project = project
|
|
27
26
|
|
|
28
27
|
def set_defect(self, defect):
|
|
29
28
|
self.defect = QaseUtils.parse_bool(defect)
|
|
30
|
-
|
|
31
|
-
def set_use_v2(self, use_v2):
|
|
32
|
-
self.use_v2 = QaseUtils.parse_bool(use_v2)
|
qase/commons/models/result.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import copy
|
|
2
1
|
import time
|
|
3
2
|
import uuid
|
|
4
3
|
|
|
@@ -71,7 +70,7 @@ class Result(BaseModel):
|
|
|
71
70
|
self.title: str = title
|
|
72
71
|
self.signature: str = signature
|
|
73
72
|
self.run_id: Optional[str] = None
|
|
74
|
-
self.
|
|
73
|
+
self.testops_ids: Optional[List[int]] = None
|
|
75
74
|
self.execution: Type[Execution] = Execution()
|
|
76
75
|
self.fields: Dict[Type[Field]] = {}
|
|
77
76
|
self.attachments: List[Attachment] = []
|
|
@@ -119,96 +118,11 @@ class Result(BaseModel):
|
|
|
119
118
|
return self.fields[name]
|
|
120
119
|
return None
|
|
121
120
|
|
|
122
|
-
def
|
|
123
|
-
return self.
|
|
121
|
+
def get_testops_ids(self) -> Optional[List[int]]:
|
|
122
|
+
return self.testops_ids
|
|
124
123
|
|
|
125
124
|
def get_duration(self) -> int:
|
|
126
125
|
return self.execution.duration
|
|
127
126
|
|
|
128
127
|
def set_run_id(self, run_id: str) -> None:
|
|
129
128
|
self.run_id = run_id
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
class InternalResult(BaseModel):
|
|
133
|
-
def __init__(self, title: str, signature: str) -> None:
|
|
134
|
-
self.id: str = str(uuid.uuid4())
|
|
135
|
-
self.title: str = title
|
|
136
|
-
self.signature: str = signature
|
|
137
|
-
self.run_id: Optional[str] = None
|
|
138
|
-
self.testops_id: Optional[int] = None
|
|
139
|
-
self.execution: Type[Execution] = Execution()
|
|
140
|
-
self.fields: Dict[Type[Field]] = {}
|
|
141
|
-
self.attachments: List[Attachment] = []
|
|
142
|
-
self.steps: List[Type[Step]] = []
|
|
143
|
-
self.params: Optional[dict] = {}
|
|
144
|
-
self.param_groups: Optional[List[List[str]]] = []
|
|
145
|
-
self.author: Optional[str] = None
|
|
146
|
-
self.relations: Type[Relation] = None
|
|
147
|
-
self.muted: bool = False
|
|
148
|
-
self.message: Optional[str] = None
|
|
149
|
-
QaseUtils.get_host_data()
|
|
150
|
-
|
|
151
|
-
def add_message(self, message: str) -> None:
|
|
152
|
-
self.message = message
|
|
153
|
-
|
|
154
|
-
def add_field(self, field: Type[Field]) -> None:
|
|
155
|
-
self.fields[field.name] = field.value
|
|
156
|
-
|
|
157
|
-
def add_steps(self, steps: List[Type[Step]]) -> None:
|
|
158
|
-
self.steps = QaseUtils().build_tree(steps)
|
|
159
|
-
|
|
160
|
-
def add_attachment(self, attachment: Attachment) -> None:
|
|
161
|
-
self.attachments.append(attachment)
|
|
162
|
-
|
|
163
|
-
def add_param(self, key: str, value: str) -> None:
|
|
164
|
-
self.params[key] = value
|
|
165
|
-
|
|
166
|
-
def add_param_groups(self, values: List[str]) -> None:
|
|
167
|
-
self.param_groups.append(values)
|
|
168
|
-
|
|
169
|
-
def set_relation(self, relation: Relation) -> None:
|
|
170
|
-
self.relations = relation
|
|
171
|
-
|
|
172
|
-
def get_status(self) -> Optional[str]:
|
|
173
|
-
return self.execution.status
|
|
174
|
-
|
|
175
|
-
def get_id(self) -> str:
|
|
176
|
-
return self.id
|
|
177
|
-
|
|
178
|
-
def get_title(self) -> str:
|
|
179
|
-
return self.title
|
|
180
|
-
|
|
181
|
-
def get_field(self, name: str) -> Optional[Type[Field]]:
|
|
182
|
-
if name in self.fields:
|
|
183
|
-
return self.fields[name]
|
|
184
|
-
return None
|
|
185
|
-
|
|
186
|
-
def get_testops_id(self) -> Optional[int]:
|
|
187
|
-
return self.testops_id
|
|
188
|
-
|
|
189
|
-
def get_duration(self) -> int:
|
|
190
|
-
return self.execution.duration
|
|
191
|
-
|
|
192
|
-
def set_run_id(self, run_id: str) -> None:
|
|
193
|
-
self.run_id = run_id
|
|
194
|
-
|
|
195
|
-
@classmethod
|
|
196
|
-
def convert_from_result(cls, result: Result, testops_id: Optional[int] = None):
|
|
197
|
-
int_result = cls(result.title, result.signature)
|
|
198
|
-
|
|
199
|
-
int_result.id = result.id
|
|
200
|
-
int_result.title = result.title
|
|
201
|
-
int_result.signature = result.signature
|
|
202
|
-
int_result.run_id = result.run_id
|
|
203
|
-
int_result.testops_id = testops_id
|
|
204
|
-
int_result.execution = copy.deepcopy(result.execution)
|
|
205
|
-
int_result.fields = result.fields
|
|
206
|
-
int_result.attachments = result.attachments
|
|
207
|
-
int_result.steps = result.steps
|
|
208
|
-
int_result.params = result.params
|
|
209
|
-
int_result.author = result.author
|
|
210
|
-
int_result.relations = result.relations
|
|
211
|
-
int_result.muted = result.muted
|
|
212
|
-
int_result.message = result.message
|
|
213
|
-
|
|
214
|
-
return int_result
|
qase/commons/reporters/core.py
CHANGED
|
@@ -6,7 +6,7 @@ from ..logger import Logger
|
|
|
6
6
|
from .report import QaseReport
|
|
7
7
|
from .testops import QaseTestOps
|
|
8
8
|
|
|
9
|
-
from ..models import
|
|
9
|
+
from ..models import Result, Attachment, Runtime
|
|
10
10
|
from ..models.config.qaseconfig import Mode
|
|
11
11
|
from typing import Union, List
|
|
12
12
|
|
|
@@ -84,20 +84,8 @@ class QaseCoreReporter:
|
|
|
84
84
|
try:
|
|
85
85
|
ts = time.time()
|
|
86
86
|
self.logger.log_debug(f"Adding result {result}")
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if ids is None:
|
|
90
|
-
int_result = InternalResult.convert_from_result(result)
|
|
91
|
-
self.reporter.add_result(int_result)
|
|
92
|
-
else:
|
|
93
|
-
first = True
|
|
94
|
-
for testops_id in ids:
|
|
95
|
-
int_result = InternalResult.convert_from_result(result, testops_id)
|
|
96
|
-
if not first:
|
|
97
|
-
int_result.execution.duration = 0
|
|
98
|
-
else:
|
|
99
|
-
first = False
|
|
100
|
-
self.reporter.add_result(int_result)
|
|
87
|
+
|
|
88
|
+
self.reporter.add_result(result)
|
|
101
89
|
|
|
102
90
|
self.logger.log_debug(f"Result {result.get_title()} added")
|
|
103
91
|
self.overhead += time.time() - ts
|
qase/commons/reporters/report.py
CHANGED
|
@@ -3,7 +3,7 @@ import os
|
|
|
3
3
|
import shutil
|
|
4
4
|
import json
|
|
5
5
|
import re
|
|
6
|
-
from ..models import
|
|
6
|
+
from ..models import Result, Run, Attachment
|
|
7
7
|
from .. import QaseUtils, Logger
|
|
8
8
|
from ..models.config.connection import Format
|
|
9
9
|
from ..models.config.qaseconfig import QaseConfig
|
|
@@ -40,7 +40,7 @@ class QaseReport:
|
|
|
40
40
|
def complete_worker(self):
|
|
41
41
|
pass
|
|
42
42
|
|
|
43
|
-
def add_result(self, result:
|
|
43
|
+
def add_result(self, result: Result):
|
|
44
44
|
result.set_run_id(self.run_id)
|
|
45
45
|
for attachment in result.attachments:
|
|
46
46
|
self._persist_attachment(attachment)
|
|
@@ -91,7 +91,7 @@ class QaseReport:
|
|
|
91
91
|
self._persist_attachments_in_steps(step.steps)
|
|
92
92
|
|
|
93
93
|
# Method saves result to a file
|
|
94
|
-
def _store_result(self, result:
|
|
94
|
+
def _store_result(self, result: Result):
|
|
95
95
|
self._store_object(result, self.report_path + "/results/", result.id)
|
|
96
96
|
|
|
97
97
|
def _check_report_path(self):
|
|
@@ -2,11 +2,11 @@ import threading
|
|
|
2
2
|
import urllib.parse
|
|
3
3
|
|
|
4
4
|
from datetime import datetime
|
|
5
|
-
from typing import List
|
|
5
|
+
from typing import List, Union
|
|
6
6
|
from .. import Logger, ReporterException
|
|
7
|
-
from ..client.
|
|
7
|
+
from ..client.api_v2_client import ApiV2Client
|
|
8
8
|
from ..client.base_api_client import BaseApiClient
|
|
9
|
-
from ..models import
|
|
9
|
+
from ..models import Result
|
|
10
10
|
from ..models.config.qaseconfig import QaseConfig
|
|
11
11
|
|
|
12
12
|
DEFAULT_BATCH_SIZE = 200
|
|
@@ -69,10 +69,7 @@ class QaseTestOps:
|
|
|
69
69
|
self.client.get_project(self.project_code)
|
|
70
70
|
|
|
71
71
|
def _prepare_client(self) -> BaseApiClient:
|
|
72
|
-
|
|
73
|
-
from ..client.api_v2_client import ApiV2Client
|
|
74
|
-
return ApiV2Client(self.config, self.logger)
|
|
75
|
-
return ApiV1Client(self.config, self.logger)
|
|
72
|
+
return ApiV2Client(self.config, self.logger)
|
|
76
73
|
|
|
77
74
|
def _send_results_threaded(self, results):
|
|
78
75
|
try:
|
|
@@ -129,9 +126,9 @@ class QaseTestOps:
|
|
|
129
126
|
if len(self.results) > 0:
|
|
130
127
|
self._send_results()
|
|
131
128
|
|
|
132
|
-
def add_result(self, result:
|
|
129
|
+
def add_result(self, result: Result) -> None:
|
|
133
130
|
if result.get_status() == 'failed':
|
|
134
|
-
self.__show_link(result.
|
|
131
|
+
self.__show_link(result.testops_ids, result.title)
|
|
135
132
|
self.results.append(result)
|
|
136
133
|
if len(self.results) >= self.batch_size:
|
|
137
134
|
self._send_results()
|
|
@@ -142,15 +139,14 @@ class QaseTestOps:
|
|
|
142
139
|
def set_results(self, results) -> None:
|
|
143
140
|
self.results = results
|
|
144
141
|
|
|
145
|
-
def __show_link(self,
|
|
146
|
-
link = self.__prepare_link(
|
|
142
|
+
def __show_link(self, ids: Union[None, List[int]], title: str):
|
|
143
|
+
link = self.__prepare_link(ids, title)
|
|
147
144
|
self.logger.log(f"See why this test failed: {link}", "info")
|
|
148
145
|
|
|
149
|
-
def __prepare_link(self,
|
|
146
|
+
def __prepare_link(self, ids: Union[None, List[int]], title: str):
|
|
150
147
|
link = f"{self.__baseUrl}/run/{self.project_code}/dashboard/{self.run_id}?source=logs&status=%5B2%5D&search="
|
|
151
|
-
if
|
|
152
|
-
return f"{link}{
|
|
153
|
-
|
|
148
|
+
if ids is not None and len(ids) > 0:
|
|
149
|
+
return f"{link}{ids[0]}"
|
|
154
150
|
return f"{link}{urllib.parse.quote_plus(title)}"
|
|
155
151
|
|
|
156
152
|
@staticmethod
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qase-python-commons
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.4.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/main/qase-python-commons
|
|
@@ -22,8 +22,8 @@ Requires-Python: >=3.7
|
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
Requires-Dist: certifi>=2024.2.2
|
|
24
24
|
Requires-Dist: attrs>=23.2.0
|
|
25
|
-
Requires-Dist: qase-api-client~=1.
|
|
26
|
-
Requires-Dist: qase-api-v2-client~=1.
|
|
25
|
+
Requires-Dist: qase-api-client~=1.2.0
|
|
26
|
+
Requires-Dist: qase-api-v2-client~=1.2.0
|
|
27
27
|
Requires-Dist: more_itertools
|
|
28
28
|
Provides-Extra: testing
|
|
29
29
|
Requires-Dist: pytest; extra == "testing"
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
qase/commons/__init__.py,sha256=3HI65PJES4Q6YvtkSuRPh6tZboTETJo8wbdHlNYaePU,323
|
|
2
|
-
qase/commons/config.py,sha256=
|
|
2
|
+
qase/commons/config.py,sha256=oRIjwNogSRCKQEXzi3AvF-Rg4btEFzR521P-Degp7x4,9052
|
|
3
3
|
qase/commons/loader.py,sha256=-MMY4HgSI6q1xq3NaJoq_w4liM73qdFKjYLVCT1E7Pc,1064
|
|
4
4
|
qase/commons/logger.py,sha256=K_8kE0EqpFbF2RbRU5TBw4Hl6GfK6PacpwkRXqHabl0,1234
|
|
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=9dJsUUM81LhmA2FWTGjWxS9tnBDcf9B6KFVZjCJDB98,6168
|
|
7
|
+
qase/commons/client/api_v2_client.py,sha256=X_T9LrDf4NIYjuv8nuVnNxENZDq1fWBJTJ5KsZLF5WU,8556
|
|
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
13
|
qase/commons/models/relation.py,sha256=HymHeh1uBcoQnTs4Vra7WJ_KFkhryj5o7cShjoGQImI,511
|
|
14
|
-
qase/commons/models/result.py,sha256=
|
|
14
|
+
qase/commons/models/result.py,sha256=0BWFGRacYtCQdno85kqFH2VAwwDh2ZWMm7WbZS77fxE,3968
|
|
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
|
|
@@ -23,19 +23,19 @@ qase/commons/models/config/plan.py,sha256=JbAY7qfGXYreXOLa32OLxw6z0paeCCf87-2b1m
|
|
|
23
23
|
qase/commons/models/config/qaseconfig.py,sha256=-tuTsd6s4YSAkSca7vvNaFZbqhbWkxuw-mjeqhwmjlc,1722
|
|
24
24
|
qase/commons/models/config/report.py,sha256=g3Z2B3Tewaasjc1TMj2mkXxz0Zc1C39sHeTXH0MRM2Y,497
|
|
25
25
|
qase/commons/models/config/run.py,sha256=QPOPq0__J5Pey2MfjnEgTuCCDYgjog-rjMJBjiMBgz4,540
|
|
26
|
-
qase/commons/models/config/testops.py,sha256=
|
|
26
|
+
qase/commons/models/config/testops.py,sha256=_GT0Px04y2JqhmXdRbqC6vvSm4yRIU74L9Sr6eiYVLU,708
|
|
27
27
|
qase/commons/profilers/__init__.py,sha256=GhKT5hRbHbhAC4GhdyChA8XoAsGQOnIb8S2Z4-fdS7Q,222
|
|
28
28
|
qase/commons/profilers/db.py,sha256=Am1tvvLgJq4_A8JsuSeBGf47BD2lnSX-5KiMjSgr-Ko,391
|
|
29
29
|
qase/commons/profilers/network.py,sha256=zKNBnTQG4BMg8dn8O--tQzQLpu-qs5ADhHEnqIas0gM,4950
|
|
30
30
|
qase/commons/profilers/sleep.py,sha256=HT6h0R-2XHZAoBYRxS2T_KC8RrnEoVjP7MXusaE4Nec,1624
|
|
31
31
|
qase/commons/reporters/__init__.py,sha256=J0aNLzb_MPPT_zF8BtX_w9nj_U7Ad06RGpyWK5Pxq1o,169
|
|
32
|
-
qase/commons/reporters/core.py,sha256=
|
|
33
|
-
qase/commons/reporters/report.py,sha256=
|
|
34
|
-
qase/commons/reporters/testops.py,sha256=
|
|
32
|
+
qase/commons/reporters/core.py,sha256=sirQ9CwLNtxLCrqXEm9dOQf8N9zDIVXofo9IKc0Sh88,8230
|
|
33
|
+
qase/commons/reporters/report.py,sha256=zyGeUOcJCOEoGtsewCOf3kypbPttJH7EM-LmZ_Y5huY,4829
|
|
34
|
+
qase/commons/reporters/testops.py,sha256=JRsAGZPtV8kr_fhsgM0cHqPdh9Ojp2qtpJvHGW9FLq4,6200
|
|
35
35
|
qase/commons/util/__init__.py,sha256=0sRRfrMOIPCHpk9tXM94Pj10qrk18B61qEcbLpRjw_I,74
|
|
36
36
|
qase/commons/util/host_data.py,sha256=n8o5PDs8kELCZZ5GR7Jug6LsgZHWJudU7iRmZHRdrlw,5264
|
|
37
37
|
qase/commons/validators/base.py,sha256=wwSn-4YiuXtfGMGnSKgo9Vm5hAKevVmmfd2Ro6Q7MYQ,173
|
|
38
|
-
qase_python_commons-3.
|
|
39
|
-
qase_python_commons-3.
|
|
40
|
-
qase_python_commons-3.
|
|
41
|
-
qase_python_commons-3.
|
|
38
|
+
qase_python_commons-3.4.0.dist-info/METADATA,sha256=mZqLZiNqmif93rQkb9RyYPH1lEn9burKxCVnA8BrshE,1857
|
|
39
|
+
qase_python_commons-3.4.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
40
|
+
qase_python_commons-3.4.0.dist-info/top_level.txt,sha256=Mn5aFk7H7Uia4s1NRDsvebu8vCrFy9nOuRIBfkIY5kQ,5
|
|
41
|
+
qase_python_commons-3.4.0.dist-info/RECORD,,
|
|
File without changes
|