qase-python-commons 3.5.5__tar.gz → 3.5.7__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.

Potentially problematic release.


This version of qase-python-commons might be problematic. Click here for more details.

Files changed (47) hide show
  1. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/PKG-INFO +1 -1
  2. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/pyproject.toml +1 -1
  3. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/client/api_v1_client.py +36 -1
  4. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/config.py +16 -0
  5. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/config/run.py +13 -1
  6. qase_python_commons-3.5.7/src/qase/commons/models/external_link.py +41 -0
  7. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/step.py +24 -4
  8. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase_python_commons.egg-info/PKG-INFO +1 -1
  9. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase_python_commons.egg-info/SOURCES.txt +1 -0
  10. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/README.md +0 -0
  11. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/setup.cfg +0 -0
  12. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/__init__.py +0 -0
  13. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/client/api_v2_client.py +0 -0
  14. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/client/base_api_client.py +0 -0
  15. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/exceptions/reporter.py +0 -0
  16. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/loader.py +0 -0
  17. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/logger.py +0 -0
  18. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/__init__.py +0 -0
  19. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/attachment.py +0 -0
  20. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/basemodel.py +0 -0
  21. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/config/api.py +0 -0
  22. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/config/batch.py +0 -0
  23. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/config/connection.py +0 -0
  24. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/config/framework.py +0 -0
  25. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/config/plan.py +0 -0
  26. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/config/qaseconfig.py +0 -0
  27. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/config/report.py +0 -0
  28. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/config/testops.py +0 -0
  29. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/relation.py +0 -0
  30. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/result.py +0 -0
  31. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/run.py +0 -0
  32. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/models/runtime.py +0 -0
  33. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/profilers/__init__.py +0 -0
  34. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/profilers/db.py +0 -0
  35. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/profilers/network.py +0 -0
  36. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/profilers/sleep.py +0 -0
  37. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/reporters/__init__.py +0 -0
  38. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/reporters/core.py +0 -0
  39. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/reporters/report.py +0 -0
  40. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/reporters/testops.py +0 -0
  41. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/util/__init__.py +0 -0
  42. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/util/host_data.py +0 -0
  43. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/utils.py +0 -0
  44. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase/commons/validators/base.py +0 -0
  45. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase_python_commons.egg-info/dependency_links.txt +0 -0
  46. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase_python_commons.egg-info/requires.txt +0 -0
  47. {qase_python_commons-3.5.5 → qase_python_commons-3.5.7}/src/qase_python_commons.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qase-python-commons
3
- Version: 3.5.5
3
+ Version: 3.5.7
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "qase-python-commons"
7
- version = "3.5.5"
7
+ version = "3.5.7"
8
8
  description = "A library for Qase TestOps and Qase Report"
9
9
  readme = "README.md"
10
10
  authors = [{name = "Qase Team", email = "support@qase.io"}]
@@ -191,7 +191,13 @@ class ApiV1Client(BaseApiClient):
191
191
  run_create=RunCreate(**{k: v for k, v in kwargs.items() if v is not None})
192
192
  )
193
193
 
194
- return result.result.id
194
+ run_id = result.result.id
195
+
196
+ # Update external link if configured
197
+ if self.config.testops.run.external_link and run_id:
198
+ self.update_external_link(project_code, run_id)
199
+
200
+ return run_id
195
201
 
196
202
  except Exception as e:
197
203
  self.logger.log(f"Error at creating test run: {e}", "error")
@@ -204,6 +210,35 @@ class ApiV1Client(BaseApiClient):
204
210
  return True
205
211
  return False
206
212
 
213
+ def update_external_link(self, project_code: str, run_id: int):
214
+ """Update external link for a test run"""
215
+ try:
216
+ from qase.api_client_v1.models.runexternal_issues import RunexternalIssues
217
+ from qase.api_client_v1.models.runexternal_issues_links_inner import RunexternalIssuesLinksInner
218
+
219
+ external_link = self.config.testops.run.external_link
220
+ api_type = external_link.to_api_type()
221
+
222
+ run_external_issues = RunexternalIssues(
223
+ type=api_type,
224
+ links=[
225
+ RunexternalIssuesLinksInner(
226
+ run_id=run_id,
227
+ external_issue=external_link.link
228
+ )
229
+ ]
230
+ )
231
+
232
+ RunsApi(self.client).run_update_external_issue(
233
+ code=project_code,
234
+ runexternal_issues=run_external_issues
235
+ )
236
+
237
+ self.logger.log(f"External link updated for run {run_id}: {external_link.link}", "debug")
238
+
239
+ except Exception as e:
240
+ self.logger.log(f"Error at updating external link: {e}", "error")
241
+
207
242
  def __should_skip_attachment(self, attachment, result):
208
243
  if (self.config.framework.playwright.video == Video.failed and
209
244
  result.execution.status != 'failed' and
@@ -121,6 +121,10 @@ class ConfigManager:
121
121
  self.config.testops.run.set_tags(
122
122
  [tag.strip() for tag in run.get("tags")])
123
123
 
124
+ if run.get("externalLink"):
125
+ self.config.testops.run.set_external_link(
126
+ run.get("externalLink"))
127
+
124
128
  if testops.get("batch"):
125
129
  batch = testops.get("batch")
126
130
 
@@ -254,6 +258,18 @@ class ConfigManager:
254
258
  self.config.testops.run.set_tags(
255
259
  [tag.strip() for tag in value.split(',')])
256
260
 
261
+ if key == 'QASE_TESTOPS_RUN_EXTERNAL_LINK_TYPE':
262
+ if not self.config.testops.run.external_link:
263
+ from .models.external_link import ExternalLinkConfig
264
+ self.config.testops.run.external_link = ExternalLinkConfig()
265
+ self.config.testops.run.external_link.set_type(value)
266
+
267
+ if key == 'QASE_TESTOPS_RUN_EXTERNAL_LINK_URL':
268
+ if not self.config.testops.run.external_link:
269
+ from .models.external_link import ExternalLinkConfig
270
+ self.config.testops.run.external_link = ExternalLinkConfig()
271
+ self.config.testops.run.external_link.set_link(value)
272
+
257
273
  if key == 'QASE_TESTOPS_BATCH_SIZE':
258
274
  self.config.testops.batch.set_size(value)
259
275
 
@@ -1,5 +1,6 @@
1
- from typing import List
1
+ from typing import List, Optional
2
2
  from ..basemodel import BaseModel
3
+ from ..external_link import ExternalLinkConfig
3
4
  from ... import QaseUtils
4
5
 
5
6
 
@@ -9,11 +10,13 @@ class RunConfig(BaseModel):
9
10
  complete: bool = None
10
11
  id: int = None
11
12
  tags: List[str] = None
13
+ external_link: Optional[ExternalLinkConfig] = None
12
14
 
13
15
 
14
16
  def __init__(self):
15
17
  self.complete = True
16
18
  self.tags = []
19
+ self.external_link = None
17
20
 
18
21
  def set_title(self, title: str):
19
22
  self.title = title
@@ -29,3 +32,12 @@ class RunConfig(BaseModel):
29
32
 
30
33
  def set_tags(self, tags: List[str]):
31
34
  self.tags = tags
35
+
36
+ def set_external_link(self, external_link: dict):
37
+ """Set external link configuration from dictionary"""
38
+ if external_link:
39
+ self.external_link = ExternalLinkConfig()
40
+ if 'type' in external_link:
41
+ self.external_link.set_type(external_link['type'])
42
+ if 'link' in external_link:
43
+ self.external_link.set_link(external_link['link'])
@@ -0,0 +1,41 @@
1
+ from enum import Enum
2
+ from typing import Optional
3
+ from .basemodel import BaseModel
4
+
5
+
6
+ class ExternalLinkType(Enum):
7
+ """External link types supported by Qase TestOps"""
8
+ JIRA_CLOUD = 'jiraCloud'
9
+ JIRA_SERVER = 'jiraServer'
10
+
11
+
12
+ class ExternalLinkConfig(BaseModel):
13
+ """Configuration for external link"""
14
+ type: ExternalLinkType = None
15
+ link: str = None
16
+
17
+ def __init__(self, type: ExternalLinkType = None, link: str = None):
18
+ self.type = type
19
+ self.link = link
20
+
21
+ def set_type(self, type: str):
22
+ """Set external link type from string"""
23
+ if type == 'jiraCloud':
24
+ self.type = ExternalLinkType.JIRA_CLOUD
25
+ elif type == 'jiraServer':
26
+ self.type = ExternalLinkType.JIRA_SERVER
27
+ else:
28
+ raise ValueError(f"Invalid external link type: {type}. Supported types: jiraCloud, jiraServer")
29
+
30
+ def set_link(self, link: str):
31
+ """Set external link URL or identifier"""
32
+ self.link = link
33
+
34
+ def to_api_type(self) -> str:
35
+ """Convert to API enum value"""
36
+ if self.type == ExternalLinkType.JIRA_CLOUD:
37
+ return 'jira-cloud'
38
+ elif self.type == ExternalLinkType.JIRA_SERVER:
39
+ return 'jira-server'
40
+ else:
41
+ raise ValueError(f"Invalid external link type: {self.type}")
@@ -43,10 +43,20 @@ class StepRequestData(BaseModel):
43
43
  self.response_body = None
44
44
  self.status_code = None
45
45
  if isinstance(request_body, bytes):
46
- request_body = request_body.decode('utf-8')
46
+ try:
47
+ request_body = request_body.decode('utf-8')
48
+ except UnicodeDecodeError:
49
+ # For binary data (like file uploads), keep as base64 encoded string
50
+ import base64
51
+ request_body = base64.b64encode(request_body).decode('ascii')
47
52
  self.request_body = request_body
48
53
  if isinstance(request_headers, bytes):
49
- request_headers = request_headers.decode('utf-8')
54
+ try:
55
+ request_headers = request_headers.decode('utf-8')
56
+ except UnicodeDecodeError:
57
+ # For binary headers, keep as base64 encoded string
58
+ import base64
59
+ request_headers = base64.b64encode(request_headers).decode('ascii')
50
60
  self.request_headers = request_headers
51
61
  self.request_method = request_method
52
62
  self.request_url = request_url
@@ -56,10 +66,20 @@ class StepRequestData(BaseModel):
56
66
  self.status_code = status_code
57
67
 
58
68
  if isinstance(response_body, bytes):
59
- response_body = response_body.decode('utf-8')
69
+ try:
70
+ response_body = response_body.decode('utf-8')
71
+ except UnicodeDecodeError:
72
+ # For binary data (like file downloads), keep as base64 encoded string
73
+ import base64
74
+ response_body = base64.b64encode(response_body).decode('ascii')
60
75
  self.response_body = response_body
61
76
  if isinstance(response_headers, bytes):
62
- response_headers = response_headers.decode('utf-8')
77
+ try:
78
+ response_headers = response_headers.decode('utf-8')
79
+ except UnicodeDecodeError:
80
+ # For binary headers, keep as base64 encoded string
81
+ import base64
82
+ response_headers = base64.b64encode(response_headers).decode('ascii')
63
83
  self.response_headers = response_headers
64
84
 
65
85
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qase-python-commons
3
- Version: 3.5.5
3
+ Version: 3.5.7
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
@@ -12,6 +12,7 @@ src/qase/commons/exceptions/reporter.py
12
12
  src/qase/commons/models/__init__.py
13
13
  src/qase/commons/models/attachment.py
14
14
  src/qase/commons/models/basemodel.py
15
+ src/qase/commons/models/external_link.py
15
16
  src/qase/commons/models/relation.py
16
17
  src/qase/commons/models/result.py
17
18
  src/qase/commons/models/run.py