Skip to content
Open
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
13 changes: 13 additions & 0 deletions tests/test_cmd_add_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,19 @@ def test_clear_assigned_to_id_mutually_exclusive_with_assigned_to_id(self, mock_
assert result.exit_code == 1
assert "cannot be used together" in result.output

@mock.patch("trcli.cli.Environment.check_for_required_parameters")
def test_run_case_ids_mutually_exclusive_with_run_include_all(self, mock_check):
"""Test that --run-case-ids and --run-include-all are mutually exclusive"""
runner = CliRunner()

result = runner.invoke(
cmd_add_run.cli,
["--title", "Test Run", "--run-case-ids", "1,2,3", "--run-include-all"],
)

assert result.exit_code == 1
assert "cannot be used together" in result.output


class TestApiRequestHandlerReferences:
"""Test class for reference management functionality"""
Expand Down
13 changes: 12 additions & 1 deletion trcli/api/api_request_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,20 @@ def update_run(
refs: str = None,
refs_action: str = "add",
assigned_to_id: Union[int, None] = ...,
include_all: Union[bool, type(...)] = ...,
case_ids: Union[List[int], type(...)] = ...,
) -> Tuple[dict, str]:
return self.run_handler.update_run(
run_id, run_name, start_date, end_date, milestone_id, refs, refs_action, assigned_to_id
run_id,
run_name,
start_date,
end_date,
milestone_id,
refs,
refs_action,
assigned_to_id,
include_all,
case_ids,
)

def _manage_references(self, existing_refs: str, new_refs: str, action: str) -> str:
Expand Down
14 changes: 14 additions & 0 deletions trcli/api/project_based_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,18 @@ def create_or_update_test_run(self) -> Tuple[int, str]:
else:
assigned_to_id = ... # Don't change (sentinel value)

# Determine include_all and case_ids based on user input
if self.environment.run_include_all:
include_all = True
case_ids = ... # Ignore case_ids when include_all is True
elif self.environment.run_case_ids:
include_all = False
case_ids = self.environment.run_case_ids
else:
# Neither provided - preserve existing settings
include_all = ...
case_ids = ...

run, error_message = self.api_request_handler.update_run(
run_id,
self.run_name,
Expand All @@ -231,6 +243,8 @@ def create_or_update_test_run(self) -> Tuple[int, str]:
refs=self.environment.run_refs,
refs_action=getattr(self.environment, "run_refs_action", "add"),
assigned_to_id=assigned_to_id,
include_all=include_all,
case_ids=case_ids,
)
if self.environment.auto_close_run:
self.environment.log("Closing run. ", new_line=False)
Expand Down
46 changes: 32 additions & 14 deletions trcli/api/run_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ def update_run(
refs: str = None,
refs_action: str = "add",
assigned_to_id: Union[int, None] = ...,
include_all: Union[bool, type(...)] = ...,
case_ids: Union[List[int], type(...)] = ...,
) -> Tuple[dict, str]:
"""
Updates an existing run
Expand All @@ -148,6 +150,8 @@ def update_run(
:param refs: references to manage
:param refs_action: action to perform ('add', 'update', 'delete')
:param assigned_to_id: user ID to assign (int), None to clear, or ... to leave unchanged
:param include_all: include all cases (bool) or ... to leave unchanged
:param case_ids: specific case IDs (List[int]) or ... to leave unchanged
:returns: Tuple with run and error string.
"""
run_response = self.client.send_get(f"get_run/{run_id}")
Expand All @@ -174,22 +178,36 @@ def update_run(
add_run_data["assignedto_id"] = assigned_to_id # Can be None (clears) or int (sets)
# else: Don't include assignedto_id in payload (no change to existing assignee)

existing_include_all = run_response.response_text.get("include_all", False)
add_run_data["include_all"] = existing_include_all

if not existing_include_all:
# Only manage explicit case_ids when include_all=False
run_tests, error_message = self.__get_all_tests_in_run(run_id)
if error_message:
return None, f"Failed to get tests in run: {error_message}"
run_case_ids = [test["case_id"] for test in run_tests]
report_case_ids = add_run_data["case_ids"]
joint_case_ids = list(set(report_case_ids + run_case_ids))
add_run_data["case_ids"] = joint_case_ids
# Handle include_all - only change if explicitly provided
if include_all is not ...:
add_run_data["include_all"] = include_all
else:
# include_all=True: TestRail includes all suite cases automatically
# Do NOT send case_ids array (TestRail ignores it anyway)
# Preserve existing value
existing_include_all = run_response.response_text.get("include_all", False)
add_run_data["include_all"] = existing_include_all

# Handle case_ids based on include_all state
if add_run_data["include_all"]:
# include_all=True: Remove case_ids (TestRail includes all suite cases automatically)
add_run_data.pop("case_ids", None)
else:
# include_all=False: Handle case_ids
if case_ids is not ...:
# User explicitly provided case_ids - use them
add_run_data["case_ids"] = case_ids
else:
# Preserve existing case_ids
run_tests, error_message = self.__get_all_tests_in_run(run_id)
if error_message:
return None, f"Failed to get tests in run: {error_message}"
run_case_ids = [test["case_id"] for test in run_tests]
# Merge with any case_ids from data provider (from report files)
report_case_ids = add_run_data.get("case_ids", [])
if report_case_ids:
joint_case_ids = list(set(report_case_ids + run_case_ids))
add_run_data["case_ids"] = joint_case_ids
else:
add_run_data["case_ids"] = run_case_ids

plan_id = run_response.response_text["plan_id"]
config_ids = run_response.response_text["config_ids"]
Expand Down
4 changes: 4 additions & 0 deletions trcli/commands/cmd_add_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ def cli(environment: Environment, context: click.Context, *args, **kwargs):
if environment.run_refs_action == "delete" and not environment.run_refs and environment.run_id:
environment.run_refs = ""

if environment.run_case_ids and environment.run_include_all:
environment.elog("Error: --run-case-ids and --run-include-all cannot be used together.")
exit(1)

print_config(environment)

project_client = ProjectBasedClient(
Expand Down
Loading