diff --git a/qase-python-commons/changelog.md b/qase-python-commons/changelog.md index 352a7c6d..d007564c 100644 --- a/qase-python-commons/changelog.md +++ b/qase-python-commons/changelog.md @@ -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 diff --git a/qase-python-commons/pyproject.toml b/qase-python-commons/pyproject.toml index fad6ba65..41cd6e7c 100644 --- a/qase-python-commons/pyproject.toml +++ b/qase-python-commons/pyproject.toml @@ -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"}] diff --git a/qase-python-commons/src/qase/commons/client/api_v1_client.py b/qase-python-commons/src/qase/commons/client/api_v1_client.py index 0cb3c8bf..4115238d 100644 --- a/qase-python-commons/src/qase/commons/client/api_v1_client.py +++ b/qase-python-commons/src/qase/commons/client/api_v1_client.py @@ -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") @@ -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 diff --git a/qase-python-commons/src/qase/commons/config.py b/qase-python-commons/src/qase/commons/config.py index 50bec06d..f568f580 100644 --- a/qase-python-commons/src/qase/commons/config.py +++ b/qase-python-commons/src/qase/commons/config.py @@ -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") @@ -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) diff --git a/qase-python-commons/src/qase/commons/models/config/run.py b/qase-python-commons/src/qase/commons/models/config/run.py index 36882a94..28a9f687 100644 --- a/qase-python-commons/src/qase/commons/models/config/run.py +++ b/qase-python-commons/src/qase/commons/models/config/run.py @@ -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 @@ -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 @@ -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']) diff --git a/qase-python-commons/src/qase/commons/models/external_link.py b/qase-python-commons/src/qase/commons/models/external_link.py new file mode 100644 index 00000000..f6db78b2 --- /dev/null +++ b/qase-python-commons/src/qase/commons/models/external_link.py @@ -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}")