Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions qase-python-commons/changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# qase-python-commons@3.5.6

## What's new

- Added support for updating external link for a test run.

# qase-python-commons@3.5.5

## What's new
Expand Down
2 changes: 1 addition & 1 deletion qase-python-commons/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "qase-python-commons"
version = "3.5.5"
version = "3.5.6"
description = "A library for Qase TestOps and Qase Report"
readme = "README.md"
authors = [{name = "Qase Team", email = "support@qase.io"}]
Expand Down
37 changes: 36 additions & 1 deletion qase-python-commons/src/qase/commons/client/api_v1_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,13 @@ def create_test_run(self, project_code: str, title: str, description: str, plan_
run_create=RunCreate(**{k: v for k, v in kwargs.items() if v is not None})
)

return result.result.id
run_id = result.result.id

# Update external link if configured
if self.config.testops.run.external_link and run_id:
self.update_external_link(project_code, run_id)

return run_id

except Exception as e:
self.logger.log(f"Error at creating test run: {e}", "error")
Expand All @@ -204,6 +210,35 @@ def check_test_run(self, project_code: str, run_id: int) -> bool:
return True
return False

def update_external_link(self, project_code: str, run_id: int):
"""Update external link for a test run"""
try:
from qase.api_client_v1.models.runexternal_issues import RunexternalIssues
from qase.api_client_v1.models.runexternal_issues_links_inner import RunexternalIssuesLinksInner

external_link = self.config.testops.run.external_link
api_type = external_link.to_api_type()

run_external_issues = RunexternalIssues(
type=api_type,
links=[
RunexternalIssuesLinksInner(
run_id=run_id,
external_issue=external_link.link
)
]
)

RunsApi(self.client).run_update_external_issue(
code=project_code,
runexternal_issues=run_external_issues
)

self.logger.log(f"External link updated for run {run_id}: {external_link.link}", "debug")

except Exception as e:
self.logger.log(f"Error at updating external link: {e}", "error")

def __should_skip_attachment(self, attachment, result):
if (self.config.framework.playwright.video == Video.failed and
result.execution.status != 'failed' and
Expand Down
16 changes: 16 additions & 0 deletions qase-python-commons/src/qase/commons/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ def __load_file_config(self):
self.config.testops.run.set_tags(
[tag.strip() for tag in run.get("tags")])

if run.get("externalLink"):
self.config.testops.run.set_external_link(
run.get("externalLink"))

if testops.get("batch"):
batch = testops.get("batch")

Expand Down Expand Up @@ -254,6 +258,18 @@ def __load_env_config(self):
self.config.testops.run.set_tags(
[tag.strip() for tag in value.split(',')])

if key == 'QASE_TESTOPS_RUN_EXTERNAL_LINK_TYPE':
if not self.config.testops.run.external_link:
from .models.external_link import ExternalLinkConfig
self.config.testops.run.external_link = ExternalLinkConfig()
self.config.testops.run.external_link.set_type(value)

if key == 'QASE_TESTOPS_RUN_EXTERNAL_LINK_URL':
if not self.config.testops.run.external_link:
from .models.external_link import ExternalLinkConfig
self.config.testops.run.external_link = ExternalLinkConfig()
self.config.testops.run.external_link.set_link(value)

if key == 'QASE_TESTOPS_BATCH_SIZE':
self.config.testops.batch.set_size(value)

Expand Down
14 changes: 13 additions & 1 deletion qase-python-commons/src/qase/commons/models/config/run.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import List
from typing import List, Optional
from ..basemodel import BaseModel
from ..external_link import ExternalLinkConfig
from ... import QaseUtils


Expand All @@ -9,11 +10,13 @@ class RunConfig(BaseModel):
complete: bool = None
id: int = None
tags: List[str] = None
external_link: Optional[ExternalLinkConfig] = None


def __init__(self):
self.complete = True
self.tags = []
self.external_link = None

def set_title(self, title: str):
self.title = title
Expand All @@ -29,3 +32,12 @@ def set_id(self, id: int):

def set_tags(self, tags: List[str]):
self.tags = tags

def set_external_link(self, external_link: dict):
"""Set external link configuration from dictionary"""
if external_link:
self.external_link = ExternalLinkConfig()
if 'type' in external_link:
self.external_link.set_type(external_link['type'])
if 'link' in external_link:
self.external_link.set_link(external_link['link'])
41 changes: 41 additions & 0 deletions qase-python-commons/src/qase/commons/models/external_link.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from enum import Enum
from typing import Optional
from .basemodel import BaseModel


class ExternalLinkType(Enum):
"""External link types supported by Qase TestOps"""
JIRA_CLOUD = 'jiraCloud'
JIRA_SERVER = 'jiraServer'


class ExternalLinkConfig(BaseModel):
"""Configuration for external link"""
type: ExternalLinkType = None
link: str = None

def __init__(self, type: ExternalLinkType = None, link: str = None):
self.type = type
self.link = link

def set_type(self, type: str):
"""Set external link type from string"""
if type == 'jiraCloud':
self.type = ExternalLinkType.JIRA_CLOUD
elif type == 'jiraServer':
self.type = ExternalLinkType.JIRA_SERVER
else:
raise ValueError(f"Invalid external link type: {type}. Supported types: jiraCloud, jiraServer")

def set_link(self, link: str):
"""Set external link URL or identifier"""
self.link = link

def to_api_type(self) -> str:
"""Convert to API enum value"""
if self.type == ExternalLinkType.JIRA_CLOUD:
return 'jira-cloud'
elif self.type == ExternalLinkType.JIRA_SERVER:
return 'jira-server'
else:
raise ValueError(f"Invalid external link type: {self.type}")